Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : // must be first
22 : #include <canvas/debug.hxx>
23 : #include <tools/diagnose_ex.h>
24 : #include <canvas/verbosetrace.hxx>
25 :
26 : #include <animationfactory.hxx>
27 : #include <attributemap.hxx>
28 :
29 : #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
30 : #include <com/sun/star/animations/AnimationTransformType.hpp>
31 : #include <com/sun/star/beans/XPropertySet.hpp>
32 : #include <com/sun/star/drawing/FillStyle.hpp>
33 : #include <com/sun/star/drawing/LineStyle.hpp>
34 : #include <com/sun/star/awt/FontSlant.hpp>
35 : #include <com/sun/star/awt/FontUnderline.hpp>
36 : #include <com/sun/star/awt/FontWeight.hpp>
37 :
38 : #include <basegfx/polygon/b2dpolygon.hxx>
39 : #include <basegfx/polygon/b2dpolygontools.hxx>
40 : #include <basegfx/polygon/b2dpolypolygontools.hxx>
41 :
42 : #include <functional>
43 :
44 :
45 : using namespace ::com::sun::star;
46 :
47 :
48 : namespace slideshow
49 : {
50 : namespace internal
51 : {
52 : namespace
53 : {
54 : // attention, there is a similar implementation of Animation in
55 : // transitions/transitionfactory.cxx
56 :
57 : template< typename ValueT > class TupleAnimation : public PairAnimation
58 : {
59 : public:
60 0 : TupleAnimation( const ShapeManagerSharedPtr& rShapeManager,
61 : int nFlags,
62 : bool (ShapeAttributeLayer::*pIs1stValid)() const,
63 : bool (ShapeAttributeLayer::*pIs2ndValid)() const,
64 : const ValueT& rDefaultValue,
65 : const ::basegfx::B2DSize& rReferenceSize,
66 : double (ShapeAttributeLayer::*pGet1stValue)() const,
67 : double (ShapeAttributeLayer::*pGet2ndValue)() const,
68 : void (ShapeAttributeLayer::*pSetValue)( const ValueT& ) ) :
69 : mpShape(),
70 : mpAttrLayer(),
71 : mpShapeManager( rShapeManager ),
72 : mpIs1stValidFunc(pIs1stValid),
73 : mpIs2ndValidFunc(pIs2ndValid),
74 : mpGet1stValueFunc(pGet1stValue),
75 : mpGet2ndValueFunc(pGet2ndValue),
76 : mpSetValueFunc(pSetValue),
77 : mnFlags( nFlags ),
78 : maReferenceSize( rReferenceSize ),
79 : maDefaultValue( rDefaultValue ),
80 0 : mbAnimationStarted( false )
81 : {
82 0 : ENSURE_OR_THROW( rShapeManager,
83 : "TupleAnimation::TupleAnimation(): Invalid ShapeManager" );
84 0 : ENSURE_OR_THROW( pIs1stValid && pIs2ndValid && pGet1stValue && pGet2ndValue && pSetValue,
85 : "TupleAnimation::TupleAnimation(): One of the method pointers is NULL" );
86 0 : }
87 :
88 0 : ~TupleAnimation()
89 : {
90 0 : end_();
91 0 : }
92 :
93 : // Animation interface
94 : // -------------------
95 0 : virtual void prefetch( const AnimatableShapeSharedPtr&,
96 : const ShapeAttributeLayerSharedPtr& )
97 0 : {}
98 :
99 0 : virtual void start( const AnimatableShapeSharedPtr& rShape,
100 : const ShapeAttributeLayerSharedPtr& rAttrLayer )
101 : {
102 : OSL_ENSURE( !mpShape,
103 : "TupleAnimation::start(): Shape already set" );
104 : OSL_ENSURE( !mpAttrLayer,
105 : "TupleAnimation::start(): Attribute layer already set" );
106 :
107 0 : mpShape = rShape;
108 0 : mpAttrLayer = rAttrLayer;
109 :
110 0 : ENSURE_OR_THROW( rShape,
111 : "TupleAnimation::start(): Invalid shape" );
112 0 : ENSURE_OR_THROW( rAttrLayer,
113 : "TupleAnimation::start(): Invalid attribute layer" );
114 :
115 0 : if( !mbAnimationStarted )
116 : {
117 0 : mbAnimationStarted = true;
118 :
119 0 : if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
120 0 : mpShapeManager->enterAnimationMode( mpShape );
121 : }
122 0 : }
123 :
124 0 : virtual void end() { end_(); }
125 0 : void end_()
126 : {
127 0 : if( mbAnimationStarted )
128 : {
129 0 : mbAnimationStarted = false;
130 :
131 0 : if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
132 0 : mpShapeManager->leaveAnimationMode( mpShape );
133 :
134 0 : if( mpShape->isContentChanged() )
135 0 : mpShapeManager->notifyShapeUpdate( mpShape );
136 : }
137 0 : }
138 :
139 : // PairAnimation interface
140 : // -----------------------
141 :
142 0 : virtual bool operator()( const ::basegfx::B2DTuple& rValue )
143 : {
144 0 : ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
145 : "TupleAnimation::operator(): Invalid ShapeAttributeLayer" );
146 :
147 : ValueT aValue( rValue.getX(),
148 0 : rValue.getY() );
149 :
150 : // Activitis get values from the expression parser,
151 : // which returns _relative_ sizes/positions.
152 : // Convert back relative to reference coordinate system
153 0 : aValue *= maReferenceSize;
154 :
155 0 : ((*mpAttrLayer).*mpSetValueFunc)( aValue );
156 :
157 0 : if( mpShape->isContentChanged() )
158 0 : mpShapeManager->notifyShapeUpdate( mpShape );
159 :
160 0 : return true;
161 : }
162 :
163 0 : virtual ::basegfx::B2DTuple getUnderlyingValue() const
164 : {
165 0 : ENSURE_OR_THROW( mpAttrLayer,
166 : "TupleAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
167 :
168 0 : ::basegfx::B2DTuple aRetVal;
169 :
170 : // deviated from the (*shared_ptr).*mpFuncPtr
171 : // notation here, since gcc does not seem to parse
172 : // that as a member function call anymore.
173 0 : aRetVal.setX( (mpAttrLayer.get()->*mpIs1stValidFunc)() ?
174 : (mpAttrLayer.get()->*mpGet1stValueFunc)() :
175 : maDefaultValue.getX() );
176 0 : aRetVal.setY( (mpAttrLayer.get()->*mpIs2ndValidFunc)() ?
177 : (mpAttrLayer.get()->*mpGet2ndValueFunc)() :
178 : maDefaultValue.getY() );
179 :
180 : // Activities get values from the expression
181 : // parser, which returns _relative_
182 : // sizes/positions. Convert start value to the
183 : // same coordinate space (i.e. relative to given
184 : // reference size).
185 0 : aRetVal /= maReferenceSize;
186 :
187 0 : return aRetVal;
188 : }
189 :
190 : private:
191 : AnimatableShapeSharedPtr mpShape;
192 : ShapeAttributeLayerSharedPtr mpAttrLayer;
193 : ShapeManagerSharedPtr mpShapeManager;
194 : bool (ShapeAttributeLayer::*mpIs1stValidFunc)() const;
195 : bool (ShapeAttributeLayer::*mpIs2ndValidFunc)() const;
196 : double (ShapeAttributeLayer::*mpGet1stValueFunc)() const;
197 : double (ShapeAttributeLayer::*mpGet2ndValueFunc)() const;
198 : void (ShapeAttributeLayer::*mpSetValueFunc)( const ValueT& );
199 :
200 : const int mnFlags;
201 :
202 : const ::basegfx::B2DSize maReferenceSize;
203 : const ValueT maDefaultValue;
204 : bool mbAnimationStarted;
205 : };
206 :
207 :
208 : class PathAnimation : public NumberAnimation
209 : {
210 : public:
211 0 : PathAnimation( const ::rtl::OUString& rSVGDPath,
212 : sal_Int16 nAdditive,
213 : const ShapeManagerSharedPtr& rShapeManager,
214 : const ::basegfx::B2DVector& rSlideSize,
215 : int nFlags ) :
216 : maPathPoly(),
217 : mpShape(),
218 : mpAttrLayer(),
219 : mpShapeManager( rShapeManager ),
220 : maPageSize( rSlideSize ),
221 : maShapeOrig(),
222 : mnFlags( nFlags ),
223 : mbAnimationStarted( false ),
224 0 : mnAdditive( nAdditive )
225 : {
226 0 : ENSURE_OR_THROW( rShapeManager,
227 : "PathAnimation::PathAnimation(): Invalid ShapeManager" );
228 :
229 0 : ::basegfx::B2DPolyPolygon aPolyPoly;
230 :
231 0 : ENSURE_OR_THROW( ::basegfx::tools::importFromSvgD( aPolyPoly, rSVGDPath ),
232 : "PathAnimation::PathAnimation(): failed to parse SVG:d path" );
233 0 : ENSURE_OR_THROW( aPolyPoly.count() == 1,
234 : "PathAnimation::PathAnimation(): motion path consists of multiple/zero polygon(s)" );
235 :
236 : // TODO(F2): Since getPositionRelative() currently
237 : // cannot handle beziers, have to subdivide.
238 : // AW: Should be no longer necessary; getPositionRelative is now bezier-safe
239 0 : maPathPoly = ::basegfx::tools::adaptiveSubdivideByAngle(aPolyPoly.getB2DPolygon(0) );
240 0 : }
241 :
242 0 : ~PathAnimation()
243 0 : {
244 0 : end_();
245 0 : }
246 :
247 : // Animation interface
248 : // -------------------
249 0 : virtual void prefetch( const AnimatableShapeSharedPtr&,
250 : const ShapeAttributeLayerSharedPtr& )
251 0 : {}
252 :
253 0 : virtual void start( const AnimatableShapeSharedPtr& rShape,
254 : const ShapeAttributeLayerSharedPtr& rAttrLayer )
255 : {
256 : OSL_ENSURE( !mpShape,
257 : "PathAnimation::start(): Shape already set" );
258 : OSL_ENSURE( !mpAttrLayer,
259 : "PathAnimation::start(): Attribute layer already set" );
260 :
261 0 : mpShape = rShape;
262 0 : mpAttrLayer = rAttrLayer;
263 :
264 0 : ENSURE_OR_THROW( rShape,
265 : "PathAnimation::start(): Invalid shape" );
266 0 : ENSURE_OR_THROW( rAttrLayer,
267 : "PathAnimation::start(): Invalid attribute layer" );
268 :
269 : // TODO(F1): Check whether _shape_ bounds are correct here.
270 : // Theoretically, our AttrLayer is way down the stack, and
271 : // we only have to consider _that_ value, not the one from
272 : // the top of the stack as returned by Shape::getBounds()
273 0 : if( mnAdditive == animations::AnimationAdditiveMode::SUM )
274 0 : maShapeOrig = mpShape->getBounds().getCenter();
275 : else
276 0 : maShapeOrig = mpShape->getDomBounds().getCenter();
277 :
278 0 : if( !mbAnimationStarted )
279 : {
280 0 : mbAnimationStarted = true;
281 :
282 0 : if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
283 0 : mpShapeManager->enterAnimationMode( mpShape );
284 : }
285 0 : }
286 :
287 0 : virtual void end() { end_(); }
288 0 : void end_()
289 : {
290 0 : if( mbAnimationStarted )
291 : {
292 0 : mbAnimationStarted = false;
293 :
294 0 : if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
295 0 : mpShapeManager->leaveAnimationMode( mpShape );
296 :
297 0 : if( mpShape->isContentChanged() )
298 0 : mpShapeManager->notifyShapeUpdate( mpShape );
299 : }
300 0 : }
301 :
302 : // NumberAnimation interface
303 : // -----------------------
304 :
305 0 : virtual bool operator()( double nValue )
306 : {
307 0 : ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
308 : "PathAnimation::operator(): Invalid ShapeAttributeLayer" );
309 :
310 : ::basegfx::B2DPoint rOutPos = ::basegfx::tools::getPositionRelative( maPathPoly,
311 0 : nValue );
312 :
313 : // TODO(F1): Determine whether the path is
314 : // absolute, or shape-relative.
315 :
316 : // interpret path as page-relative. Scale up with page size
317 0 : rOutPos *= maPageSize;
318 :
319 : // TODO(F1): Determine whether the path origin is
320 : // absolute, or shape-relative.
321 :
322 : // interpret path as shape-originated. Offset to shape position
323 :
324 0 : rOutPos += maShapeOrig;
325 :
326 0 : mpAttrLayer->setPosition( rOutPos );
327 :
328 0 : if( mpShape->isContentChanged() )
329 0 : mpShapeManager->notifyShapeUpdate( mpShape );
330 :
331 0 : return true;
332 : }
333 :
334 0 : virtual double getUnderlyingValue() const
335 : {
336 0 : ENSURE_OR_THROW( mpAttrLayer,
337 : "PathAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
338 :
339 0 : return 0.0; // though this should be used in concert with
340 : // ActivitiesFactory::createSimpleActivity, better
341 : // explicitly name our start value.
342 : // Permissible range for operator() above is [0,1]
343 : }
344 :
345 : private:
346 : ::basegfx::B2DPolygon maPathPoly;
347 : AnimatableShapeSharedPtr mpShape;
348 : ShapeAttributeLayerSharedPtr mpAttrLayer;
349 : ShapeManagerSharedPtr mpShapeManager;
350 : const ::basegfx::B2DSize maPageSize;
351 : ::basegfx::B2DPoint maShapeOrig;
352 : const int mnFlags;
353 : bool mbAnimationStarted;
354 : sal_Int16 mnAdditive;
355 : };
356 :
357 :
358 : /** GenericAnimation template
359 :
360 : This template makes heavy use of SFINAE, only one of
361 : the operator()() methods will compile for each of the
362 : base classes.
363 :
364 : Note that we omit the virtual keyword on the
365 : operator()() overrides and getUnderlyingValue() methods on
366 : purpose; those that actually do override baseclass
367 : virtual methods inherit the property, and the others
368 : won't increase our vtable. What's more, having all
369 : those methods in the vtable actually creates POIs for
370 : them, which breaks the whole SFINAE concept (IOW, this
371 : template won't compile any longer).
372 :
373 : @tpl AnimationBase
374 : Type of animation to generate (determines the
375 : interface GenericAnimation will implement). Must be
376 : one of NumberAnimation, ColorAnimation,
377 : StringAnimation, PairAnimation or BoolAnimation.
378 :
379 : @tpl ModifierFunctor
380 : Type of a functor object, which can optionally be used to
381 : modify the getter/setter values.
382 : */
383 : template< typename AnimationBase, typename ModifierFunctor > class GenericAnimation : public AnimationBase
384 : {
385 : public:
386 : typedef typename AnimationBase::ValueType ValueT;
387 :
388 : /** Create generic animation
389 :
390 : @param pIsValid
391 : Function pointer to one of the is*Valid
392 : methods. Used to either take the given getter
393 : method, or the given default value for the start value.
394 :
395 : @param rDefaultValue
396 : Default value, to take as the start value if
397 : is*Valid returns false.
398 :
399 : @param pGetValue
400 : Getter method, to fetch start value if valid.
401 :
402 : @param pSetValue
403 : Setter method. This one puts the current animation
404 : value to the ShapeAttributeLayer.
405 :
406 : @param rGetterModifier
407 : Modifies up values retrieved from the pGetValue method.
408 : Must provide operator()( const ValueT& ) method.
409 :
410 : @param rSetterModifier
411 : Modifies up values before passing them to the pSetValue method.
412 : Must provide operator()( const ValueT& ) method.
413 : */
414 0 : GenericAnimation( const ShapeManagerSharedPtr& rShapeManager,
415 : int nFlags,
416 : bool (ShapeAttributeLayer::*pIsValid)() const,
417 : const ValueT& rDefaultValue,
418 : ValueT (ShapeAttributeLayer::*pGetValue)() const,
419 : void (ShapeAttributeLayer::*pSetValue)( const ValueT& ),
420 : const ModifierFunctor& rGetterModifier,
421 : const ModifierFunctor& rSetterModifier ) :
422 : mpShape(),
423 : mpAttrLayer(),
424 : mpShapeManager( rShapeManager ),
425 : mpIsValidFunc(pIsValid),
426 : mpGetValueFunc(pGetValue),
427 : mpSetValueFunc(pSetValue),
428 : maGetterModifier( rGetterModifier ),
429 : maSetterModifier( rSetterModifier ),
430 : mnFlags( nFlags ),
431 : maDefaultValue(rDefaultValue),
432 0 : mbAnimationStarted( false )
433 : {
434 0 : ENSURE_OR_THROW( rShapeManager,
435 : "GenericAnimation::GenericAnimation(): Invalid ShapeManager" );
436 0 : ENSURE_OR_THROW( pIsValid && pGetValue && pSetValue,
437 : "GenericAnimation::GenericAnimation(): One of the method pointers is NULL" );
438 0 : }
439 :
440 0 : ~GenericAnimation()
441 : {
442 0 : end_();
443 0 : }
444 :
445 : // Animation interface
446 : // -------------------
447 0 : virtual void prefetch( const AnimatableShapeSharedPtr&,
448 : const ShapeAttributeLayerSharedPtr& )
449 0 : {}
450 :
451 0 : virtual void start( const AnimatableShapeSharedPtr& rShape,
452 : const ShapeAttributeLayerSharedPtr& rAttrLayer )
453 : {
454 : OSL_ENSURE( !mpShape,
455 : "GenericAnimation::start(): Shape already set" );
456 : OSL_ENSURE( !mpAttrLayer,
457 : "GenericAnimation::start(): Attribute layer already set" );
458 :
459 0 : mpShape = rShape;
460 0 : mpAttrLayer = rAttrLayer;
461 :
462 0 : ENSURE_OR_THROW( rShape,
463 : "GenericAnimation::start(): Invalid shape" );
464 0 : ENSURE_OR_THROW( rAttrLayer,
465 : "GenericAnimation::start(): Invalid attribute layer" );
466 :
467 : // only start animation once per repeated start() call,
468 : // and only if sprites should be used for display
469 0 : if( !mbAnimationStarted )
470 : {
471 0 : mbAnimationStarted = true;
472 :
473 0 : if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
474 0 : mpShapeManager->enterAnimationMode( mpShape );
475 : }
476 0 : }
477 :
478 0 : virtual void end() { end_(); }
479 0 : void end_()
480 : {
481 : // TODO(Q2): Factor out common code (most
482 : // prominently start() and end()) into base class
483 :
484 : // only stop animation once per repeated end() call,
485 : // and only if sprites are used for display
486 0 : if( mbAnimationStarted )
487 : {
488 0 : mbAnimationStarted = false;
489 :
490 0 : if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
491 0 : mpShapeManager->leaveAnimationMode( mpShape );
492 :
493 : // Attention, this notifyShapeUpdate() is
494 : // somewhat delicate here. Calling it
495 : // unconditional (i.e. not guarded by
496 : // mbAnimationStarted) will lead to shapes
497 : // snapping back to their original state just
498 : // before the slide ends. Not calling it at
499 : // all might swallow final animation
500 : // states. The current implementation relies
501 : // on the fact that end() is either called by
502 : // the Activity (then, the last animation
503 : // state has been set, and corresponds to the
504 : // shape's hold state), or by the animation
505 : // node (then, it's a forced end, and we
506 : // _have_ to snap back).
507 : //
508 : // To reiterate: normally, we're called from
509 : // the Activity first, thus the
510 : // notifyShapeUpdate() below will update to
511 : // the last activity value.
512 :
513 : // force shape update, activity might have changed
514 : // state in the last round.
515 0 : if( mpShape->isContentChanged() )
516 0 : mpShapeManager->notifyShapeUpdate( mpShape );
517 : }
518 0 : }
519 :
520 : // Derived Animation interface
521 : // ---------------------------
522 :
523 : /** For by-reference interfaces (B2DTuple, OUString)
524 : */
525 0 : bool operator()( const ValueT& x )
526 : {
527 0 : ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
528 : "GenericAnimation::operator(): Invalid ShapeAttributeLayer" );
529 :
530 0 : ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) );
531 :
532 0 : if( mpShape->isContentChanged() )
533 0 : mpShapeManager->notifyShapeUpdate( mpShape );
534 :
535 0 : return true;
536 : }
537 :
538 : /** For by-value interfaces (bool, double)
539 : */
540 0 : bool operator()( ValueT x )
541 : {
542 0 : ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
543 : "GenericAnimation::operator(): Invalid ShapeAttributeLayer" );
544 :
545 0 : ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) );
546 :
547 0 : if( mpShape->isContentChanged() )
548 0 : mpShapeManager->notifyShapeUpdate( mpShape );
549 :
550 0 : return true;
551 : }
552 :
553 0 : ValueT getUnderlyingValue() const
554 : {
555 0 : ENSURE_OR_THROW( mpAttrLayer,
556 : "GenericAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
557 :
558 : // deviated from the (*shared_ptr).*mpFuncPtr
559 : // notation here, since gcc does not seem to parse
560 : // that as a member function call anymore.
561 0 : if( (mpAttrLayer.get()->*mpIsValidFunc)() )
562 0 : return maGetterModifier( ((*mpAttrLayer).*mpGetValueFunc)() );
563 : else
564 0 : return maDefaultValue;
565 : }
566 :
567 : private:
568 : AnimatableShapeSharedPtr mpShape;
569 : ShapeAttributeLayerSharedPtr mpAttrLayer;
570 : ShapeManagerSharedPtr mpShapeManager;
571 : bool (ShapeAttributeLayer::*mpIsValidFunc)() const;
572 : ValueT (ShapeAttributeLayer::*mpGetValueFunc)() const;
573 : void (ShapeAttributeLayer::*mpSetValueFunc)( const ValueT& );
574 :
575 : ModifierFunctor maGetterModifier;
576 : ModifierFunctor maSetterModifier;
577 :
578 : const int mnFlags;
579 :
580 : const ValueT maDefaultValue;
581 : bool mbAnimationStarted;
582 : };
583 :
584 : //Current c++0x draft (apparently) has std::identity, but not operator()
585 : template<typename T> struct SGI_identity : public std::unary_function<T,T>
586 : {
587 0 : T& operator()(T& x) const { return x; }
588 0 : const T& operator()(const T& x) const { return x; }
589 : };
590 :
591 : /** Function template wrapper around GenericAnimation template
592 :
593 : @tpl AnimationBase
594 : Type of animation to generate (determines the
595 : interface GenericAnimation will implement).
596 : */
597 : template< typename AnimationBase > ::boost::shared_ptr< AnimationBase >
598 0 : makeGenericAnimation( const ShapeManagerSharedPtr& rShapeManager,
599 : int nFlags,
600 : bool (ShapeAttributeLayer::*pIsValid)() const,
601 : const typename AnimationBase::ValueType& rDefaultValue,
602 : typename AnimationBase::ValueType (ShapeAttributeLayer::*pGetValue)() const,
603 : void (ShapeAttributeLayer::*pSetValue)( const typename AnimationBase::ValueType& ) )
604 : {
605 : return ::boost::shared_ptr< AnimationBase >(
606 : new GenericAnimation< AnimationBase,
607 : SGI_identity< typename AnimationBase::ValueType > >(
608 : rShapeManager,
609 : nFlags,
610 : pIsValid,
611 : rDefaultValue,
612 : pGetValue,
613 : pSetValue,
614 : // no modification necessary, use identity functor here
615 : SGI_identity< typename AnimationBase::ValueType >(),
616 0 : SGI_identity< typename AnimationBase::ValueType >() ) );
617 : }
618 :
619 : class Scaler
620 : {
621 : public:
622 0 : Scaler( double nScale ) :
623 0 : mnScale( nScale )
624 : {
625 0 : }
626 :
627 0 : double operator()( double nVal ) const
628 : {
629 0 : return mnScale * nVal;
630 : }
631 :
632 : private:
633 : double mnScale;
634 : };
635 :
636 : /** Overload for NumberAnimations which need scaling (width,height,x,y currently)
637 : */
638 0 : NumberAnimationSharedPtr makeGenericAnimation( const ShapeManagerSharedPtr& rShapeManager,
639 : int nFlags,
640 : bool (ShapeAttributeLayer::*pIsValid)() const,
641 : double nDefaultValue,
642 : double (ShapeAttributeLayer::*pGetValue)() const,
643 : void (ShapeAttributeLayer::*pSetValue)( const double& ),
644 : double nScaleValue )
645 : {
646 : return NumberAnimationSharedPtr(
647 : new GenericAnimation< NumberAnimation, Scaler >( rShapeManager,
648 : nFlags,
649 : pIsValid,
650 : nDefaultValue / nScaleValue,
651 : pGetValue,
652 : pSetValue,
653 : Scaler( 1.0/nScaleValue ),
654 0 : Scaler( nScaleValue ) ) );
655 : }
656 :
657 :
658 0 : uno::Any getShapeDefault( const AnimatableShapeSharedPtr& rShape,
659 : const ::rtl::OUString& rPropertyName )
660 : {
661 0 : uno::Reference< drawing::XShape > xShape( rShape->getXShape() );
662 :
663 0 : if( !xShape.is() )
664 0 : return uno::Any(); // no regular shape, no defaults available
665 :
666 :
667 : // extract relevant value from XShape's PropertySet
668 : uno::Reference< beans::XPropertySet > xPropSet( xShape,
669 0 : uno::UNO_QUERY );
670 :
671 0 : ENSURE_OR_THROW( xPropSet.is(),
672 : "getShapeDefault(): Cannot query property set from shape" );
673 :
674 0 : return xPropSet->getPropertyValue( rPropertyName );
675 : }
676 :
677 0 : template< typename ValueType > ValueType getDefault( const AnimatableShapeSharedPtr& rShape,
678 : const ::rtl::OUString& rPropertyName )
679 : {
680 : const uno::Any& rAny( getShapeDefault( rShape,
681 0 : rPropertyName ) );
682 :
683 0 : if( !rAny.hasValue() )
684 : {
685 : OSL_FAIL( "getDefault(): cannot get requested shape property" );
686 : OSL_TRACE( "getDefault(): cannot get '%s' shape property",
687 : ::rtl::OUStringToOString( rPropertyName,
688 : RTL_TEXTENCODING_ASCII_US ).getStr() );
689 0 : return ValueType();
690 : }
691 : else
692 : {
693 0 : ValueType aValue = ValueType();
694 :
695 0 : if( !(rAny >>= aValue) )
696 : {
697 : OSL_FAIL( "getDefault(): cannot extract requested shape property" );
698 : OSL_TRACE( "getDefault(): cannot extract '%s' shape property",
699 : ::rtl::OUStringToOString( rPropertyName,
700 : RTL_TEXTENCODING_ASCII_US ).getStr() );
701 0 : return ValueType();
702 : }
703 :
704 0 : return aValue;
705 : }
706 : }
707 :
708 0 : template<> RGBColor getDefault< RGBColor >( const AnimatableShapeSharedPtr& rShape,
709 : const ::rtl::OUString& rPropertyName )
710 : {
711 : const uno::Any& rAny( getShapeDefault( rShape,
712 0 : rPropertyName ) );
713 :
714 0 : if( !rAny.hasValue() )
715 : {
716 : OSL_FAIL( "getDefault(): cannot get requested shape color property" );
717 : OSL_TRACE( "getDefault(): cannot get '%s' shape color property",
718 : ::rtl::OUStringToOString( rPropertyName,
719 : RTL_TEXTENCODING_ASCII_US ).getStr() );
720 0 : return RGBColor();
721 : }
722 : else
723 : {
724 0 : sal_Int32 nValue = 0;
725 :
726 0 : if( !(rAny >>= nValue) )
727 : {
728 : OSL_FAIL( "getDefault(): cannot extract requested shape color property" );
729 : OSL_TRACE( "getDefault(): cannot extract '%s' shape color property",
730 : ::rtl::OUStringToOString( rPropertyName,
731 : RTL_TEXTENCODING_ASCII_US ).getStr() );
732 0 : return RGBColor();
733 : }
734 :
735 : // convert from 0xAARRGGBB API color to 0xRRGGBB00
736 : // canvas color
737 0 : return RGBColor( (nValue << 8U) & 0xFFFFFF00U );
738 0 : }
739 : }
740 : }
741 :
742 0 : AnimationFactory::AttributeClass AnimationFactory::classifyAttributeName( const ::rtl::OUString& rAttrName )
743 : {
744 : // ATTENTION: When changing this map, also the create*PropertyAnimation() methods must
745 : // be checked and possibly adapted in their switch statements
746 :
747 : // TODO(Q2): Since this map must be coherent with the various switch statements
748 : // in the create*PropertyAnimation methods, try to unify into a single method or table
749 0 : switch( mapAttributeName( rAttrName ) )
750 : {
751 : default:
752 : // FALLTHROUGH intended
753 : case ATTRIBUTE_INVALID:
754 0 : return CLASS_UNKNOWN_PROPERTY;
755 :
756 : case ATTRIBUTE_CHAR_COLOR:
757 : // FALLTHROUGH intended
758 : case ATTRIBUTE_COLOR:
759 : // FALLTHROUGH intended
760 : case ATTRIBUTE_DIMCOLOR:
761 : // FALLTHROUGH intended
762 : case ATTRIBUTE_FILL_COLOR:
763 : // FALLTHROUGH intended
764 : case ATTRIBUTE_LINE_COLOR:
765 0 : return CLASS_COLOR_PROPERTY;
766 :
767 : case ATTRIBUTE_CHAR_FONT_NAME:
768 0 : return CLASS_STRING_PROPERTY;
769 :
770 : case ATTRIBUTE_VISIBILITY:
771 0 : return CLASS_BOOL_PROPERTY;
772 :
773 : case ATTRIBUTE_CHAR_HEIGHT:
774 : // FALLTHROUGH intended
775 : case ATTRIBUTE_CHAR_WEIGHT:
776 : // FALLTHROUGH intended
777 : case ATTRIBUTE_CHAR_ROTATION:
778 : // FALLTHROUGH intended
779 : case ATTRIBUTE_HEIGHT:
780 : // FALLTHROUGH intended
781 : case ATTRIBUTE_OPACITY:
782 : // FALLTHROUGH intended
783 : case ATTRIBUTE_ROTATE:
784 : // FALLTHROUGH intended
785 : case ATTRIBUTE_SKEW_X:
786 : // FALLTHROUGH intended
787 : case ATTRIBUTE_SKEW_Y:
788 : // FALLTHROUGH intended
789 : case ATTRIBUTE_WIDTH:
790 : // FALLTHROUGH intended
791 : case ATTRIBUTE_POS_X:
792 : // FALLTHROUGH intended
793 : case ATTRIBUTE_POS_Y:
794 0 : return CLASS_NUMBER_PROPERTY;
795 :
796 : case ATTRIBUTE_CHAR_UNDERLINE:
797 : // FALLTHROUGH intended
798 : case ATTRIBUTE_FILL_STYLE:
799 : // FALLTHROUGH intended
800 : case ATTRIBUTE_LINE_STYLE:
801 : // FALLTHROUGH intended
802 : case ATTRIBUTE_CHAR_POSTURE:
803 0 : return CLASS_ENUM_PROPERTY;
804 : }
805 : }
806 :
807 0 : NumberAnimationSharedPtr AnimationFactory::createNumberPropertyAnimation( const ::rtl::OUString& rAttrName,
808 : const AnimatableShapeSharedPtr& rShape,
809 : const ShapeManagerSharedPtr& rShapeManager,
810 : const ::basegfx::B2DVector& rSlideSize,
811 : int nFlags )
812 : {
813 : // ATTENTION: When changing this map, also the classifyAttributeName() method must
814 : // be checked and possibly adapted in their switch statement
815 0 : switch( mapAttributeName( rAttrName ) )
816 : {
817 : default:
818 : // FALLTHROUGH intended
819 : case ATTRIBUTE_INVALID:
820 0 : ENSURE_OR_THROW( false,
821 : "AnimationFactory::createNumberPropertyAnimation(): Unknown attribute" );
822 : break;
823 :
824 : case ATTRIBUTE_CHAR_COLOR:
825 : // FALLTHROUGH intended
826 : case ATTRIBUTE_CHAR_FONT_NAME:
827 : // FALLTHROUGH intended
828 : case ATTRIBUTE_CHAR_POSTURE:
829 : // FALLTHROUGH intended
830 : case ATTRIBUTE_CHAR_UNDERLINE:
831 : // FALLTHROUGH intended
832 : case ATTRIBUTE_COLOR:
833 : // FALLTHROUGH intended
834 : case ATTRIBUTE_DIMCOLOR:
835 : // FALLTHROUGH intended
836 : case ATTRIBUTE_FILL_COLOR:
837 : // FALLTHROUGH intended
838 : case ATTRIBUTE_FILL_STYLE:
839 : // FALLTHROUGH intended
840 : case ATTRIBUTE_LINE_COLOR:
841 : // FALLTHROUGH intended
842 : case ATTRIBUTE_LINE_STYLE:
843 : // FALLTHROUGH intended
844 : case ATTRIBUTE_VISIBILITY:
845 0 : ENSURE_OR_THROW( false,
846 : "AnimationFactory::createNumberPropertyAnimation(): Attribute type mismatch" );
847 : break;
848 :
849 : case ATTRIBUTE_CHAR_HEIGHT:
850 : return makeGenericAnimation<NumberAnimation>( rShapeManager,
851 : nFlags,
852 : &ShapeAttributeLayer::isCharScaleValid,
853 : 1.0, // CharHeight is a relative attribute, thus
854 : // default is 1.0
855 : &ShapeAttributeLayer::getCharScale,
856 0 : &ShapeAttributeLayer::setCharScale );
857 :
858 : case ATTRIBUTE_CHAR_WEIGHT:
859 : return makeGenericAnimation<NumberAnimation>( rShapeManager,
860 : nFlags,
861 : &ShapeAttributeLayer::isCharWeightValid,
862 0 : getDefault<double>( rShape, rAttrName ),
863 : &ShapeAttributeLayer::getCharWeight,
864 0 : &ShapeAttributeLayer::setCharWeight );
865 :
866 : case ATTRIBUTE_CHAR_ROTATION:
867 : return makeGenericAnimation<NumberAnimation>( rShapeManager,
868 : nFlags,
869 : &ShapeAttributeLayer::isCharRotationAngleValid,
870 0 : getDefault<double>( rShape, rAttrName ),
871 : &ShapeAttributeLayer::getCharRotationAngle,
872 0 : &ShapeAttributeLayer::setCharRotationAngle );
873 :
874 : case ATTRIBUTE_HEIGHT:
875 : return makeGenericAnimation( rShapeManager,
876 : nFlags,
877 : &ShapeAttributeLayer::isHeightValid,
878 : // TODO(F1): Check whether _shape_ bounds are correct here.
879 : // Theoretically, our AttrLayer is way down the stack, and
880 : // we only have to consider _that_ value, not the one from
881 : // the top of the stack as returned by Shape::getBounds()
882 0 : rShape->getBounds().getHeight(),
883 : &ShapeAttributeLayer::getHeight,
884 : &ShapeAttributeLayer::setHeight,
885 : // convert expression parser value from relative page size
886 0 : rSlideSize.getY() );
887 :
888 : case ATTRIBUTE_OPACITY:
889 : return makeGenericAnimation<NumberAnimation>( rShapeManager,
890 : nFlags,
891 : &ShapeAttributeLayer::isAlphaValid,
892 : // TODO(F1): Provide shape default here (FillTransparency?)
893 : 1.0,
894 : &ShapeAttributeLayer::getAlpha,
895 0 : &ShapeAttributeLayer::setAlpha );
896 :
897 : case ATTRIBUTE_ROTATE:
898 : return makeGenericAnimation<NumberAnimation>( rShapeManager,
899 : nFlags,
900 : &ShapeAttributeLayer::isRotationAngleValid,
901 : // NOTE: Since we paint the shape as-is from metafile,
902 : // rotation angle is always 0.0, even for rotated shapes
903 : 0.0,
904 : &ShapeAttributeLayer::getRotationAngle,
905 0 : &ShapeAttributeLayer::setRotationAngle );
906 :
907 : case ATTRIBUTE_SKEW_X:
908 : return makeGenericAnimation<NumberAnimation>( rShapeManager,
909 : nFlags,
910 : &ShapeAttributeLayer::isShearXAngleValid,
911 : // TODO(F1): Is there any shape property for skew?
912 : 0.0,
913 : &ShapeAttributeLayer::getShearXAngle,
914 0 : &ShapeAttributeLayer::setShearXAngle );
915 :
916 : case ATTRIBUTE_SKEW_Y:
917 : return makeGenericAnimation<NumberAnimation>( rShapeManager,
918 : nFlags,
919 : &ShapeAttributeLayer::isShearYAngleValid,
920 : // TODO(F1): Is there any shape property for skew?
921 : 0.0,
922 : &ShapeAttributeLayer::getShearYAngle,
923 0 : &ShapeAttributeLayer::setShearYAngle );
924 :
925 : case ATTRIBUTE_WIDTH:
926 : return makeGenericAnimation( rShapeManager,
927 : nFlags,
928 : &ShapeAttributeLayer::isWidthValid,
929 : // TODO(F1): Check whether _shape_ bounds are correct here.
930 : // Theoretically, our AttrLayer is way down the stack, and
931 : // we only have to consider _that_ value, not the one from
932 : // the top of the stack as returned by Shape::getBounds()
933 0 : rShape->getBounds().getWidth(),
934 : &ShapeAttributeLayer::getWidth,
935 : &ShapeAttributeLayer::setWidth,
936 : // convert expression parser value from relative page size
937 0 : rSlideSize.getX() );
938 :
939 : case ATTRIBUTE_POS_X:
940 : return makeGenericAnimation( rShapeManager,
941 : nFlags,
942 : &ShapeAttributeLayer::isPosXValid,
943 : // TODO(F1): Check whether _shape_ bounds are correct here.
944 : // Theoretically, our AttrLayer is way down the stack, and
945 : // we only have to consider _that_ value, not the one from
946 : // the top of the stack as returned by Shape::getBounds()
947 0 : rShape->getBounds().getCenterX(),
948 : &ShapeAttributeLayer::getPosX,
949 : &ShapeAttributeLayer::setPosX,
950 : // convert expression parser value from relative page size
951 0 : rSlideSize.getX() );
952 :
953 : case ATTRIBUTE_POS_Y:
954 : return makeGenericAnimation( rShapeManager,
955 : nFlags,
956 : &ShapeAttributeLayer::isPosYValid,
957 : // TODO(F1): Check whether _shape_ bounds are correct here.
958 : // Theoretically, our AttrLayer is way down the stack, and
959 : // we only have to consider _that_ value, not the one from
960 : // the top of the stack as returned by Shape::getBounds()
961 0 : rShape->getBounds().getCenterY(),
962 : &ShapeAttributeLayer::getPosY,
963 : &ShapeAttributeLayer::setPosY,
964 : // convert expression parser value from relative page size
965 0 : rSlideSize.getY() );
966 : }
967 :
968 : return NumberAnimationSharedPtr();
969 : }
970 :
971 0 : EnumAnimationSharedPtr AnimationFactory::createEnumPropertyAnimation( const ::rtl::OUString& rAttrName,
972 : const AnimatableShapeSharedPtr& rShape,
973 : const ShapeManagerSharedPtr& rShapeManager,
974 : const ::basegfx::B2DVector& /*rSlideSize*/,
975 : int nFlags )
976 : {
977 : // ATTENTION: When changing this map, also the classifyAttributeName() method must
978 : // be checked and possibly adapted in their switch statement
979 0 : switch( mapAttributeName( rAttrName ) )
980 : {
981 : default:
982 : // FALLTHROUGH intended
983 : case ATTRIBUTE_INVALID:
984 0 : ENSURE_OR_THROW( false,
985 : "AnimationFactory::createEnumPropertyAnimation(): Unknown attribute" );
986 : break;
987 :
988 : case ATTRIBUTE_CHAR_COLOR:
989 : // FALLTHROUGH intended
990 : case ATTRIBUTE_CHAR_FONT_NAME:
991 : // FALLTHROUGH intended
992 : case ATTRIBUTE_COLOR:
993 : // FALLTHROUGH intended
994 : case ATTRIBUTE_DIMCOLOR:
995 : // FALLTHROUGH intended
996 : case ATTRIBUTE_FILL_COLOR:
997 : // FALLTHROUGH intended
998 : case ATTRIBUTE_LINE_COLOR:
999 : // FALLTHROUGH intended
1000 : case ATTRIBUTE_VISIBILITY:
1001 : // FALLTHROUGH intended
1002 : case ATTRIBUTE_CHAR_HEIGHT:
1003 : // FALLTHROUGH intended
1004 : case ATTRIBUTE_CHAR_WEIGHT:
1005 : // FALLTHROUGH intended
1006 : case ATTRIBUTE_CHAR_ROTATION:
1007 : // FALLTHROUGH intended
1008 : case ATTRIBUTE_HEIGHT:
1009 : // FALLTHROUGH intended
1010 : case ATTRIBUTE_OPACITY:
1011 : // FALLTHROUGH intended
1012 : case ATTRIBUTE_ROTATE:
1013 : // FALLTHROUGH intended
1014 : case ATTRIBUTE_SKEW_X:
1015 : // FALLTHROUGH intended
1016 : case ATTRIBUTE_SKEW_Y:
1017 : // FALLTHROUGH intended
1018 : case ATTRIBUTE_WIDTH:
1019 : // FALLTHROUGH intended
1020 : case ATTRIBUTE_POS_X:
1021 : // FALLTHROUGH intended
1022 : case ATTRIBUTE_POS_Y:
1023 0 : ENSURE_OR_THROW( false,
1024 : "AnimationFactory::createEnumPropertyAnimation(): Attribute type mismatch" );
1025 : break;
1026 :
1027 :
1028 : case ATTRIBUTE_FILL_STYLE:
1029 : return makeGenericAnimation<EnumAnimation>( rShapeManager,
1030 : nFlags,
1031 : &ShapeAttributeLayer::isFillStyleValid,
1032 : sal::static_int_cast<sal_Int16>(
1033 0 : getDefault<drawing::FillStyle>( rShape, rAttrName )),
1034 : &ShapeAttributeLayer::getFillStyle,
1035 0 : &ShapeAttributeLayer::setFillStyle );
1036 :
1037 : case ATTRIBUTE_LINE_STYLE:
1038 : return makeGenericAnimation<EnumAnimation>( rShapeManager,
1039 : nFlags,
1040 : &ShapeAttributeLayer::isLineStyleValid,
1041 : sal::static_int_cast<sal_Int16>(
1042 0 : getDefault<drawing::LineStyle>( rShape, rAttrName )),
1043 : &ShapeAttributeLayer::getLineStyle,
1044 0 : &ShapeAttributeLayer::setLineStyle );
1045 :
1046 : case ATTRIBUTE_CHAR_POSTURE:
1047 : return makeGenericAnimation<EnumAnimation>( rShapeManager,
1048 : nFlags,
1049 : &ShapeAttributeLayer::isCharPostureValid,
1050 : sal::static_int_cast<sal_Int16>(
1051 0 : getDefault<awt::FontSlant>( rShape, rAttrName )),
1052 : &ShapeAttributeLayer::getCharPosture,
1053 0 : &ShapeAttributeLayer::setCharPosture );
1054 :
1055 : case ATTRIBUTE_CHAR_UNDERLINE:
1056 : return makeGenericAnimation<EnumAnimation>( rShapeManager,
1057 : nFlags,
1058 : &ShapeAttributeLayer::isUnderlineModeValid,
1059 0 : getDefault<sal_Int16>( rShape, rAttrName ),
1060 : &ShapeAttributeLayer::getUnderlineMode,
1061 0 : &ShapeAttributeLayer::setUnderlineMode );
1062 : }
1063 :
1064 : return EnumAnimationSharedPtr();
1065 : }
1066 :
1067 0 : ColorAnimationSharedPtr AnimationFactory::createColorPropertyAnimation( const ::rtl::OUString& rAttrName,
1068 : const AnimatableShapeSharedPtr& rShape,
1069 : const ShapeManagerSharedPtr& rShapeManager,
1070 : const ::basegfx::B2DVector& /*rSlideSize*/,
1071 : int nFlags )
1072 : {
1073 : // ATTENTION: When changing this map, also the classifyAttributeName() method must
1074 : // be checked and possibly adapted in their switch statement
1075 0 : switch( mapAttributeName( rAttrName ) )
1076 : {
1077 : default:
1078 : // FALLTHROUGH intended
1079 : case ATTRIBUTE_INVALID:
1080 0 : ENSURE_OR_THROW( false,
1081 : "AnimationFactory::createColorPropertyAnimation(): Unknown attribute" );
1082 : break;
1083 :
1084 : case ATTRIBUTE_CHAR_FONT_NAME:
1085 : // FALLTHROUGH intended
1086 : case ATTRIBUTE_CHAR_HEIGHT:
1087 : // FALLTHROUGH intended
1088 : case ATTRIBUTE_CHAR_POSTURE:
1089 : // FALLTHROUGH intended
1090 : case ATTRIBUTE_CHAR_ROTATION:
1091 : // FALLTHROUGH intended
1092 : case ATTRIBUTE_CHAR_UNDERLINE:
1093 : // FALLTHROUGH intended
1094 : case ATTRIBUTE_CHAR_WEIGHT:
1095 : // FALLTHROUGH intended
1096 : case ATTRIBUTE_FILL_STYLE:
1097 : // FALLTHROUGH intended
1098 : case ATTRIBUTE_HEIGHT:
1099 : // FALLTHROUGH intended
1100 : case ATTRIBUTE_LINE_STYLE:
1101 : // FALLTHROUGH intended
1102 : case ATTRIBUTE_OPACITY:
1103 : // FALLTHROUGH intended
1104 : case ATTRIBUTE_ROTATE:
1105 : // FALLTHROUGH intended
1106 : case ATTRIBUTE_SKEW_X:
1107 : // FALLTHROUGH intended
1108 : case ATTRIBUTE_SKEW_Y:
1109 : // FALLTHROUGH intended
1110 : case ATTRIBUTE_VISIBILITY:
1111 : // FALLTHROUGH intended
1112 : case ATTRIBUTE_WIDTH:
1113 : // FALLTHROUGH intended
1114 : case ATTRIBUTE_POS_X:
1115 : // FALLTHROUGH intended
1116 : case ATTRIBUTE_POS_Y:
1117 0 : ENSURE_OR_THROW( false,
1118 : "AnimationFactory::createColorPropertyAnimation(): Attribute type mismatch" );
1119 : break;
1120 :
1121 : case ATTRIBUTE_CHAR_COLOR:
1122 : return makeGenericAnimation<ColorAnimation>( rShapeManager,
1123 : nFlags,
1124 : &ShapeAttributeLayer::isCharColorValid,
1125 : getDefault<RGBColor>( rShape, rAttrName ),
1126 : &ShapeAttributeLayer::getCharColor,
1127 0 : &ShapeAttributeLayer::setCharColor );
1128 :
1129 : case ATTRIBUTE_COLOR:
1130 : // TODO(F2): This is just mapped to fill color to make it work
1131 : return makeGenericAnimation<ColorAnimation>( rShapeManager,
1132 : nFlags,
1133 : &ShapeAttributeLayer::isFillColorValid,
1134 : getDefault<RGBColor>( rShape, rAttrName ),
1135 : &ShapeAttributeLayer::getFillColor,
1136 0 : &ShapeAttributeLayer::setFillColor );
1137 :
1138 : case ATTRIBUTE_DIMCOLOR:
1139 : return makeGenericAnimation<ColorAnimation>( rShapeManager,
1140 : nFlags,
1141 : &ShapeAttributeLayer::isDimColorValid,
1142 : getDefault<RGBColor>( rShape, rAttrName ),
1143 : &ShapeAttributeLayer::getDimColor,
1144 0 : &ShapeAttributeLayer::setDimColor );
1145 :
1146 : case ATTRIBUTE_FILL_COLOR:
1147 : return makeGenericAnimation<ColorAnimation>( rShapeManager,
1148 : nFlags,
1149 : &ShapeAttributeLayer::isFillColorValid,
1150 : getDefault<RGBColor>( rShape, rAttrName ),
1151 : &ShapeAttributeLayer::getFillColor,
1152 0 : &ShapeAttributeLayer::setFillColor );
1153 :
1154 : case ATTRIBUTE_LINE_COLOR:
1155 : return makeGenericAnimation<ColorAnimation>( rShapeManager,
1156 : nFlags,
1157 : &ShapeAttributeLayer::isLineColorValid,
1158 : getDefault<RGBColor>( rShape, rAttrName ),
1159 : &ShapeAttributeLayer::getLineColor,
1160 0 : &ShapeAttributeLayer::setLineColor );
1161 : }
1162 :
1163 : return ColorAnimationSharedPtr();
1164 : }
1165 :
1166 0 : PairAnimationSharedPtr AnimationFactory::createPairPropertyAnimation( const AnimatableShapeSharedPtr& rShape,
1167 : const ShapeManagerSharedPtr& rShapeManager,
1168 : const ::basegfx::B2DVector& rSlideSize,
1169 : sal_Int16 nTransformType,
1170 : int nFlags )
1171 : {
1172 0 : const ::basegfx::B2DRectangle& rBounds( rShape->getBounds() );
1173 :
1174 0 : switch( nTransformType )
1175 : {
1176 : case animations::AnimationTransformType::SCALE:
1177 : return PairAnimationSharedPtr(
1178 : new TupleAnimation< ::basegfx::B2DSize >(
1179 : rShapeManager,
1180 : nFlags,
1181 : &ShapeAttributeLayer::isWidthValid,
1182 : &ShapeAttributeLayer::isHeightValid,
1183 : // TODO(F1): Check whether _shape_ bounds are correct here.
1184 : // Theoretically, our AttrLayer is way down the stack, and
1185 : // we only have to consider _that_ value, not the one from
1186 : // the top of the stack as returned by Shape::getBounds()
1187 : rBounds.getRange(),
1188 : rBounds.getRange(),
1189 : &ShapeAttributeLayer::getWidth,
1190 : &ShapeAttributeLayer::getHeight,
1191 0 : &ShapeAttributeLayer::setSize ) );
1192 :
1193 : case animations::AnimationTransformType::TRANSLATE:
1194 : return PairAnimationSharedPtr(
1195 : new TupleAnimation< ::basegfx::B2DPoint >(
1196 : rShapeManager,
1197 : nFlags,
1198 : &ShapeAttributeLayer::isPosXValid,
1199 : &ShapeAttributeLayer::isPosYValid,
1200 : // TODO(F1): Check whether _shape_ bounds are correct here.
1201 : // Theoretically, our AttrLayer is way down the stack, and
1202 : // we only have to consider _that_ value, not the one from
1203 : // the top of the stack as returned by Shape::getBounds()
1204 : rBounds.getCenter(),
1205 : rSlideSize,
1206 : &ShapeAttributeLayer::getPosX,
1207 : &ShapeAttributeLayer::getPosY,
1208 0 : &ShapeAttributeLayer::setPosition ) );
1209 :
1210 : default:
1211 0 : ENSURE_OR_THROW( false,
1212 : "AnimationFactory::createPairPropertyAnimation(): Attribute type mismatch" );
1213 : break;
1214 : }
1215 :
1216 : return PairAnimationSharedPtr();
1217 : }
1218 :
1219 0 : StringAnimationSharedPtr AnimationFactory::createStringPropertyAnimation( const ::rtl::OUString& rAttrName,
1220 : const AnimatableShapeSharedPtr& rShape,
1221 : const ShapeManagerSharedPtr& rShapeManager,
1222 : const ::basegfx::B2DVector& /*rSlideSize*/,
1223 : int nFlags )
1224 : {
1225 : // ATTENTION: When changing this map, also the classifyAttributeName() method must
1226 : // be checked and possibly adapted in their switch statement
1227 0 : switch( mapAttributeName( rAttrName ) )
1228 : {
1229 : default:
1230 : // FALLTHROUGH intended
1231 : case ATTRIBUTE_INVALID:
1232 0 : ENSURE_OR_THROW( false,
1233 : "AnimationFactory::createStringPropertyAnimation(): Unknown attribute" );
1234 : break;
1235 :
1236 : case ATTRIBUTE_CHAR_COLOR:
1237 : // FALLTHROUGH intended
1238 : case ATTRIBUTE_CHAR_HEIGHT:
1239 : // FALLTHROUGH intended
1240 : case ATTRIBUTE_CHAR_ROTATION:
1241 : // FALLTHROUGH intended
1242 : case ATTRIBUTE_CHAR_UNDERLINE:
1243 : // FALLTHROUGH intended
1244 : case ATTRIBUTE_COLOR:
1245 : // FALLTHROUGH intended
1246 : case ATTRIBUTE_DIMCOLOR:
1247 : // FALLTHROUGH intended
1248 : case ATTRIBUTE_FILL_COLOR:
1249 : // FALLTHROUGH intended
1250 : case ATTRIBUTE_HEIGHT:
1251 : // FALLTHROUGH intended
1252 : case ATTRIBUTE_LINE_COLOR:
1253 : // FALLTHROUGH intended
1254 : case ATTRIBUTE_OPACITY:
1255 : // FALLTHROUGH intended
1256 : case ATTRIBUTE_ROTATE:
1257 : // FALLTHROUGH intended
1258 : case ATTRIBUTE_SKEW_X:
1259 : // FALLTHROUGH intended
1260 : case ATTRIBUTE_SKEW_Y:
1261 : // FALLTHROUGH intended
1262 : case ATTRIBUTE_VISIBILITY:
1263 : // FALLTHROUGH intended
1264 : case ATTRIBUTE_WIDTH:
1265 : // FALLTHROUGH intended
1266 : case ATTRIBUTE_POS_X:
1267 : // FALLTHROUGH intended
1268 : case ATTRIBUTE_POS_Y:
1269 : // FALLTHROUGH intended
1270 : case ATTRIBUTE_CHAR_POSTURE:
1271 : // FALLTHROUGH intended
1272 : case ATTRIBUTE_CHAR_WEIGHT:
1273 : // FALLTHROUGH intended
1274 : case ATTRIBUTE_FILL_STYLE:
1275 : // FALLTHROUGH intended
1276 : case ATTRIBUTE_LINE_STYLE:
1277 0 : ENSURE_OR_THROW( false,
1278 : "AnimationFactory::createStringPropertyAnimation(): Attribute type mismatch" );
1279 : break;
1280 :
1281 : case ATTRIBUTE_CHAR_FONT_NAME:
1282 : return makeGenericAnimation<StringAnimation>( rShapeManager,
1283 : nFlags,
1284 : &ShapeAttributeLayer::isFontFamilyValid,
1285 : getDefault< ::rtl::OUString >( rShape, rAttrName ),
1286 : &ShapeAttributeLayer::getFontFamily,
1287 0 : &ShapeAttributeLayer::setFontFamily );
1288 : }
1289 :
1290 : return StringAnimationSharedPtr();
1291 : }
1292 :
1293 0 : BoolAnimationSharedPtr AnimationFactory::createBoolPropertyAnimation( const ::rtl::OUString& rAttrName,
1294 : const AnimatableShapeSharedPtr& /*rShape*/,
1295 : const ShapeManagerSharedPtr& rShapeManager,
1296 : const ::basegfx::B2DVector& /*rSlideSize*/,
1297 : int nFlags )
1298 : {
1299 : // ATTENTION: When changing this map, also the classifyAttributeName() method must
1300 : // be checked and possibly adapted in their switch statement
1301 0 : switch( mapAttributeName( rAttrName ) )
1302 : {
1303 : default:
1304 : // FALLTHROUGH intended
1305 : case ATTRIBUTE_INVALID:
1306 0 : ENSURE_OR_THROW( false,
1307 : "AnimationFactory::createBoolPropertyAnimation(): Unknown attribute" );
1308 : break;
1309 :
1310 : case ATTRIBUTE_CHAR_COLOR:
1311 : // FALLTHROUGH intended
1312 : case ATTRIBUTE_CHAR_FONT_NAME:
1313 : // FALLTHROUGH intended
1314 : case ATTRIBUTE_CHAR_HEIGHT:
1315 : // FALLTHROUGH intended
1316 : case ATTRIBUTE_CHAR_POSTURE:
1317 : // FALLTHROUGH intended
1318 : case ATTRIBUTE_CHAR_ROTATION:
1319 : // FALLTHROUGH intended
1320 : case ATTRIBUTE_CHAR_WEIGHT:
1321 : // FALLTHROUGH intended
1322 : case ATTRIBUTE_COLOR:
1323 : // FALLTHROUGH intended
1324 : case ATTRIBUTE_DIMCOLOR:
1325 : // FALLTHROUGH intended
1326 : case ATTRIBUTE_FILL_COLOR:
1327 : // FALLTHROUGH intended
1328 : case ATTRIBUTE_FILL_STYLE:
1329 : // FALLTHROUGH intended
1330 : case ATTRIBUTE_HEIGHT:
1331 : // FALLTHROUGH intended
1332 : case ATTRIBUTE_LINE_COLOR:
1333 : // FALLTHROUGH intended
1334 : case ATTRIBUTE_LINE_STYLE:
1335 : // FALLTHROUGH intended
1336 : case ATTRIBUTE_OPACITY:
1337 : // FALLTHROUGH intended
1338 : case ATTRIBUTE_ROTATE:
1339 : // FALLTHROUGH intended
1340 : case ATTRIBUTE_SKEW_X:
1341 : // FALLTHROUGH intended
1342 : case ATTRIBUTE_SKEW_Y:
1343 : // FALLTHROUGH intended
1344 : case ATTRIBUTE_WIDTH:
1345 : // FALLTHROUGH intended
1346 : case ATTRIBUTE_POS_X:
1347 : // FALLTHROUGH intended
1348 : case ATTRIBUTE_POS_Y:
1349 : // FALLTHROUGH intended
1350 : case ATTRIBUTE_CHAR_UNDERLINE:
1351 0 : ENSURE_OR_THROW( false,
1352 : "AnimationFactory::createBoolPropertyAnimation(): Attribute type mismatch" );
1353 : break;
1354 :
1355 : case ATTRIBUTE_VISIBILITY:
1356 : return makeGenericAnimation<BoolAnimation>( rShapeManager,
1357 : nFlags,
1358 : &ShapeAttributeLayer::isVisibilityValid,
1359 : // TODO(F1): Is there a corresponding shape property?
1360 : true,
1361 : &ShapeAttributeLayer::getVisibility,
1362 0 : &ShapeAttributeLayer::setVisibility );
1363 : }
1364 :
1365 : return BoolAnimationSharedPtr();
1366 : }
1367 :
1368 0 : NumberAnimationSharedPtr AnimationFactory::createPathMotionAnimation( const ::rtl::OUString& rSVGDPath,
1369 : sal_Int16 nAdditive,
1370 : const AnimatableShapeSharedPtr& /*rShape*/,
1371 : const ShapeManagerSharedPtr& rShapeManager,
1372 : const ::basegfx::B2DVector& rSlideSize,
1373 : int nFlags )
1374 : {
1375 : return NumberAnimationSharedPtr(
1376 : new PathAnimation( rSVGDPath, nAdditive,
1377 : rShapeManager,
1378 : rSlideSize,
1379 0 : nFlags ) );
1380 : }
1381 :
1382 : }
1383 : }
1384 :
1385 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|