1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <comphelper/diagnose_ex.hxx>
22 #include <sal/log.hxx>
24 #include <animationfactory.hxx>
25 #include <attributemap.hxx>
27 #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
28 #include <com/sun/star/animations/AnimationTransformType.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/drawing/FillStyle.hpp>
31 #include <com/sun/star/drawing/LineStyle.hpp>
32 #include <com/sun/star/awt/FontSlant.hpp>
34 #include <basegfx/polygon/b2dpolygon.hxx>
35 #include <basegfx/polygon/b2dpolygontools.hxx>
36 #include <basegfx/polygon/b2dpolypolygontools.hxx>
38 #include <box2dtools.hxx>
41 using namespace ::com::sun::star
;
44 namespace slideshow::internal
48 // attention, there is a similar implementation of Animation in
49 // transitions/transitionfactory.cxx
51 template< typename ValueT
> class TupleAnimation
: public PairAnimation
54 TupleAnimation( const ShapeManagerSharedPtr
& rShapeManager
,
56 bool (ShapeAttributeLayer::*pIs1stValid
)() const,
57 bool (ShapeAttributeLayer::*pIs2ndValid
)() const,
58 const ValueT
& rDefaultValue
,
59 const ::basegfx::B2DSize
& rReferenceSize
,
60 double (ShapeAttributeLayer::*pGet1stValue
)() const,
61 double (ShapeAttributeLayer::*pGet2ndValue
)() const,
62 void (ShapeAttributeLayer::*pSetValue
)( const ValueT
& ) ) :
65 mpShapeManager( rShapeManager
),
66 mpIs1stValidFunc(pIs1stValid
),
67 mpIs2ndValidFunc(pIs2ndValid
),
68 mpGet1stValueFunc(pGet1stValue
),
69 mpGet2ndValueFunc(pGet2ndValue
),
70 mpSetValueFunc(pSetValue
),
72 maReferenceSize( rReferenceSize
),
73 maDefaultValue( rDefaultValue
),
74 mbAnimationStarted( false )
76 ENSURE_OR_THROW( rShapeManager
,
77 "TupleAnimation::TupleAnimation(): Invalid ShapeManager" );
78 ENSURE_OR_THROW( pIs1stValid
&& pIs2ndValid
&& pGet1stValue
&& pGet2ndValue
&& pSetValue
,
79 "TupleAnimation::TupleAnimation(): One of the method pointers is NULL" );
82 virtual ~TupleAnimation() override
87 // Animation interface
89 virtual void prefetch() override
92 virtual void start( const AnimatableShapeSharedPtr
& rShape
,
93 const ShapeAttributeLayerSharedPtr
& rAttrLayer
) override
96 "TupleAnimation::start(): Shape already set" );
97 OSL_ENSURE( !mpAttrLayer
,
98 "TupleAnimation::start(): Attribute layer already set" );
101 mpAttrLayer
= rAttrLayer
;
103 ENSURE_OR_THROW( rShape
,
104 "TupleAnimation::start(): Invalid shape" );
105 ENSURE_OR_THROW( rAttrLayer
,
106 "TupleAnimation::start(): Invalid attribute layer" );
108 if( !mbAnimationStarted
)
110 mbAnimationStarted
= true;
112 if( !(mnFlags
& AnimationFactory::FLAG_NO_SPRITE
) )
113 mpShapeManager
->enterAnimationMode( mpShape
);
117 virtual void end() override
{ end_(); }
120 if( mbAnimationStarted
)
122 mbAnimationStarted
= false;
124 if( !(mnFlags
& AnimationFactory::FLAG_NO_SPRITE
) )
125 mpShapeManager
->leaveAnimationMode( mpShape
);
127 if( mpShape
->isContentChanged() )
128 mpShapeManager
->notifyShapeUpdate( mpShape
);
132 // PairAnimation interface
135 virtual bool operator()( const ::basegfx::B2DTuple
& rValue
) override
137 ENSURE_OR_RETURN_FALSE( mpAttrLayer
&& mpShape
,
138 "TupleAnimation::operator(): Invalid ShapeAttributeLayer" );
140 ValueT
aValue(rValue
.getX(), rValue
.getY());
142 // Activities get values from the expression parser,
143 // which returns _relative_ sizes/positions.
144 // Convert back relative to reference coordinate system
145 aValue
*= basegfx::B2DPoint(maReferenceSize
);
147 ((*mpAttrLayer
).*mpSetValueFunc
)( aValue
);
149 if( mpShape
->isContentChanged() )
150 mpShapeManager
->notifyShapeUpdate( mpShape
);
155 virtual ::basegfx::B2DTuple
getUnderlyingValue() const override
157 ENSURE_OR_THROW( mpAttrLayer
,
158 "TupleAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
160 ::basegfx::B2DTuple aRetVal
;
162 // deviated from the (*shared_ptr).*mpFuncPtr
163 // notation here, since gcc does not seem to parse
164 // that as a member function call anymore.
165 basegfx::B2DPoint
aPoint(maDefaultValue
);
166 aRetVal
.setX( (mpAttrLayer
.get()->*mpIs1stValidFunc
)() ?
167 (mpAttrLayer
.get()->*mpGet1stValueFunc
)() :
169 aRetVal
.setY( (mpAttrLayer
.get()->*mpIs2ndValidFunc
)() ?
170 (mpAttrLayer
.get()->*mpGet2ndValueFunc
)() :
173 // Activities get values from the expression
174 // parser, which returns _relative_
175 // sizes/positions. Convert start value to the
176 // same coordinate space (i.e. relative to given
178 aRetVal
/= basegfx::B2DPoint(maReferenceSize
);
184 AnimatableShapeSharedPtr mpShape
;
185 ShapeAttributeLayerSharedPtr mpAttrLayer
;
186 ShapeManagerSharedPtr mpShapeManager
;
187 bool (ShapeAttributeLayer::*mpIs1stValidFunc
)() const;
188 bool (ShapeAttributeLayer::*mpIs2ndValidFunc
)() const;
189 double (ShapeAttributeLayer::*mpGet1stValueFunc
)() const;
190 double (ShapeAttributeLayer::*mpGet2ndValueFunc
)() const;
191 void (ShapeAttributeLayer::*mpSetValueFunc
)( const ValueT
& );
195 const ::basegfx::B2DSize maReferenceSize
;
196 const ValueT maDefaultValue
;
197 bool mbAnimationStarted
;
201 class PathAnimation
: public NumberAnimation
204 PathAnimation( std::u16string_view rSVGDPath
,
206 const ShapeManagerSharedPtr
& rShapeManager
,
207 const ::basegfx::B2DVector
& rSlideSize
,
209 box2d::utils::Box2DWorldSharedPtr pBox2DWorld
) :
213 mpShapeManager( rShapeManager
),
214 maPageSize( rSlideSize
.getX(), rSlideSize
.getY() ),
217 mbAnimationStarted( false ),
218 mbAnimationFirstUpdate( true ),
219 mnAdditive( nAdditive
),
220 mpBox2DWorld(std::move( pBox2DWorld
))
222 ENSURE_OR_THROW( rShapeManager
,
223 "PathAnimation::PathAnimation(): Invalid ShapeManager" );
225 ::basegfx::B2DPolyPolygon aPolyPoly
;
227 ENSURE_OR_THROW( ::basegfx::utils::importFromSvgD( aPolyPoly
, rSVGDPath
, false, nullptr ),
228 "PathAnimation::PathAnimation(): failed to parse SVG:d path" );
229 ENSURE_OR_THROW( aPolyPoly
.count() == 1,
230 "PathAnimation::PathAnimation(): motion path consists of multiple/zero polygon(s)" );
232 maPathPoly
= aPolyPoly
.getB2DPolygon(0);
235 virtual ~PathAnimation() override
240 // Animation interface
242 virtual void prefetch() override
245 virtual void start( const AnimatableShapeSharedPtr
& rShape
,
246 const ShapeAttributeLayerSharedPtr
& rAttrLayer
) override
248 OSL_ENSURE( !mpShape
,
249 "PathAnimation::start(): Shape already set" );
250 OSL_ENSURE( !mpAttrLayer
,
251 "PathAnimation::start(): Attribute layer already set" );
254 mpAttrLayer
= rAttrLayer
;
256 ENSURE_OR_THROW( rShape
,
257 "PathAnimation::start(): Invalid shape" );
258 ENSURE_OR_THROW( rAttrLayer
,
259 "PathAnimation::start(): Invalid attribute layer" );
261 // TODO(F1): Check whether _shape_ bounds are correct here.
262 // Theoretically, our AttrLayer is way down the stack, and
263 // we only have to consider _that_ value, not the one from
264 // the top of the stack as returned by Shape::getBounds()
265 if( mnAdditive
== animations::AnimationAdditiveMode::SUM
)
266 maShapeOrig
= mpShape
->getBounds().getCenter();
268 maShapeOrig
= mpShape
->getDomBounds().getCenter();
270 if( !mbAnimationStarted
)
272 mbAnimationStarted
= true;
274 if( !(mnFlags
& AnimationFactory::FLAG_NO_SPRITE
) )
275 mpShapeManager
->enterAnimationMode( mpShape
);
279 virtual void end() override
{ end_(); }
282 if( !mbAnimationStarted
)
285 mbAnimationStarted
= false;
287 if( !(mnFlags
& AnimationFactory::FLAG_NO_SPRITE
) )
288 mpShapeManager
->leaveAnimationMode( mpShape
);
290 if( mpShape
->isContentChanged() )
291 mpShapeManager
->notifyShapeUpdate( mpShape
);
293 // if there is a physics animation going on report the animation ending
294 // and zero out the velocity of the shape
295 if( mpBox2DWorld
->isInitialized() )
296 mpBox2DWorld
->queueLinearVelocityUpdate( mpShape
->getXShape(), {0,0});
299 // NumberAnimation interface
302 virtual bool operator()( double nValue
) override
304 ENSURE_OR_RETURN_FALSE( mpAttrLayer
&& mpShape
,
305 "PathAnimation::operator(): Invalid ShapeAttributeLayer" );
307 ::basegfx::B2DPoint rOutPos
= ::basegfx::utils::getPositionRelative( maPathPoly
,
310 // TODO(F1): Determine whether the path is
311 // absolute, or shape-relative.
313 // interpret path as page-relative. Scale up with page size
314 rOutPos
*= basegfx::B2DPoint(maPageSize
);
316 // TODO(F1): Determine whether the path origin is
317 // absolute, or shape-relative.
319 // interpret path as shape-originated. Offset to shape position
321 rOutPos
+= maShapeOrig
;
323 mpAttrLayer
->setPosition( rOutPos
);
325 if( mpShape
->isContentChanged() )
327 mpShapeManager
->notifyShapeUpdate( mpShape
);
329 // if there's a physics animation going on report the change to it
330 if ( mpBox2DWorld
->isInitialized() )
332 mpBox2DWorld
->queueShapePathAnimationUpdate( mpShape
->getXShape(),
334 mbAnimationFirstUpdate
);
338 if( mbAnimationFirstUpdate
) mbAnimationFirstUpdate
= false;
343 virtual double getUnderlyingValue() const override
345 ENSURE_OR_THROW( mpAttrLayer
,
346 "PathAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
348 return 0.0; // though this should be used in concert with
349 // ActivitiesFactory::createSimpleActivity, better
350 // explicitly name our start value.
351 // Permissible range for operator() above is [0,1]
355 ::basegfx::B2DPolygon maPathPoly
;
356 AnimatableShapeSharedPtr mpShape
;
357 ShapeAttributeLayerSharedPtr mpAttrLayer
;
358 ShapeManagerSharedPtr mpShapeManager
;
359 const ::basegfx::B2DSize maPageSize
;
360 ::basegfx::B2DPoint maShapeOrig
;
362 bool mbAnimationStarted
;
363 bool mbAnimationFirstUpdate
;
364 sal_Int16 mnAdditive
;
365 box2d::utils::Box2DWorldSharedPtr mpBox2DWorld
;
368 class PhysicsAnimation
: public NumberAnimation
371 PhysicsAnimation( ::box2d::utils::Box2DWorldSharedPtr pBox2DWorld
,
372 const double fDuration
,
373 const ShapeManagerSharedPtr
& rShapeManager
,
374 const ::basegfx::B2DVector
& rSlideSize
,
375 const ::basegfx::B2DVector
& rStartVelocity
,
376 const double fDensity
,
377 const double fBounciness
,
381 mpShapeManager( rShapeManager
),
382 maPageSize( rSlideSize
),
384 mbAnimationStarted( false ),
386 mpBox2DWorld(std::move( pBox2DWorld
)),
387 mfDuration(fDuration
),
388 maStartVelocity(rStartVelocity
),
390 mfBounciness(fBounciness
),
391 mfPreviousElapsedTime(0.00f
),
392 mbIsBox2dWorldStepper(false)
394 ENSURE_OR_THROW( rShapeManager
,
395 "PhysicsAnimation::PhysicsAnimation(): Invalid ShapeManager" );
398 virtual ~PhysicsAnimation() override
403 // Animation interface
405 virtual void prefetch() override
408 virtual void start( const AnimatableShapeSharedPtr
& rShape
,
409 const ShapeAttributeLayerSharedPtr
& rAttrLayer
) override
411 OSL_ENSURE( !mpShape
,
412 "PhysicsAnimation::start(): Shape already set" );
413 OSL_ENSURE( !mpAttrLayer
,
414 "PhysicsAnimation::start(): Attribute layer already set" );
417 mpAttrLayer
= rAttrLayer
;
419 ENSURE_OR_THROW( rShape
,
420 "PhysicsAnimation::start(): Invalid shape" );
421 ENSURE_OR_THROW( rAttrLayer
,
422 "PhysicsAnimation::start(): Invalid attribute layer" );
424 if( !mbAnimationStarted
)
426 mbAnimationStarted
= true;
428 mpBox2DWorld
->alertPhysicsAnimationStart(basegfx::B2DVector(maPageSize
.getWidth(), maPageSize
.getHeight()), mpShapeManager
);
429 mpBox2DBody
= mpBox2DWorld
->makeShapeDynamic( mpShape
->getXShape(), maStartVelocity
, mfDensity
, mfBounciness
);
431 if( !(mnFlags
& AnimationFactory::FLAG_NO_SPRITE
) )
432 mpShapeManager
->enterAnimationMode( mpShape
);
436 virtual void end() override
{ end_(); }
439 if( mbIsBox2dWorldStepper
)
441 mbIsBox2dWorldStepper
= false;
442 mpBox2DWorld
->setHasWorldStepper(false);
445 if( !mbAnimationStarted
)
448 mbAnimationStarted
= false;
450 if( !(mnFlags
& AnimationFactory::FLAG_NO_SPRITE
) )
451 mpShapeManager
->leaveAnimationMode( mpShape
);
453 if( mpShape
->isContentChanged() )
454 mpShapeManager
->notifyShapeUpdate( mpShape
);
456 mpBox2DWorld
->alertPhysicsAnimationEnd(mpShape
);
457 // if this was the only physics animation effect going on
458 // all box2d bodies were destroyed on alertPhysicsAnimationEnd
459 // except the one owned by the animation.
460 // Try to destroy the remaining body - if it is unique
461 // (it being unique means all physics animation effects have ended
462 // since otherwise mpBox2DWorld would own a copy of the shared_ptr )
467 // NumberAnimation interface
470 virtual bool operator()( double nValue
) override
472 ENSURE_OR_RETURN_FALSE( mpAttrLayer
&& mpShape
,
473 "PhysicsAnimation::operator(): Invalid ShapeAttributeLayer" );
475 // if there are multiple physics animations going in parallel
476 // Only one of them should step the box2d world
477 if( !mpBox2DWorld
->hasWorldStepper() )
479 mbIsBox2dWorldStepper
= true;
480 mpBox2DWorld
->setHasWorldStepper(true);
483 if( mbIsBox2dWorldStepper
)
485 double fPassedTime
= (mfDuration
* nValue
) - mfPreviousElapsedTime
;
486 mfPreviousElapsedTime
+= mpBox2DWorld
->stepAmount( fPassedTime
);
489 mpAttrLayer
->setPosition( mpBox2DBody
->getPosition() );
490 mpAttrLayer
->setRotationAngle( mpBox2DBody
->getAngle() );
492 if( mpShape
->isContentChanged() )
493 mpShapeManager
->notifyShapeUpdate( mpShape
);
498 virtual double getUnderlyingValue() const override
500 ENSURE_OR_THROW( mpAttrLayer
,
501 "PhysicsAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
507 AnimatableShapeSharedPtr mpShape
;
508 ShapeAttributeLayerSharedPtr mpAttrLayer
;
509 ShapeManagerSharedPtr mpShapeManager
;
510 const ::basegfx::B2DSize maPageSize
;
512 bool mbAnimationStarted
;
513 box2d::utils::Box2DBodySharedPtr mpBox2DBody
;
514 box2d::utils::Box2DWorldSharedPtr mpBox2DWorld
;
516 const ::basegfx::B2DVector maStartVelocity
;
517 const double mfDensity
;
518 const double mfBounciness
;
519 double mfPreviousElapsedTime
;
520 bool mbIsBox2dWorldStepper
;
523 /** GenericAnimation template
525 This template makes heavy use of SFINAE, only one of
526 the operator()() methods will compile for each of the
529 Note that we omit the virtual keyword on the
530 operator()() overrides and getUnderlyingValue() methods on
531 purpose; those that actually do override baseclass
532 virtual methods inherit the property, and the others
533 won't increase our vtable. What's more, having all
534 those methods in the vtable actually creates POIs for
535 them, which breaks the whole SFINAE concept (IOW, this
536 template won't compile any longer).
539 Type of animation to generate (determines the
540 interface GenericAnimation will implement). Must be
541 one of NumberAnimation, ColorAnimation,
542 StringAnimation, PairAnimation or BoolAnimation.
545 Type of a functor object, which can optionally be used to
546 modify the getter/setter values.
548 template< typename AnimationBase
, typename ModifierFunctor
> class GenericAnimation
: public AnimationBase
551 typedef typename
AnimationBase::ValueType ValueT
;
553 /** Create generic animation
556 Function pointer to one of the is*Valid
557 methods. Used to either take the given getter
558 method, or the given default value for the start value.
561 Default value, to take as the start value if
562 is*Valid returns false.
565 Getter method, to fetch start value if valid.
568 Setter method. This one puts the current animation
569 value to the ShapeAttributeLayer.
571 @param rGetterModifier
572 Modifies up values retrieved from the pGetValue method.
573 Must provide operator()( const ValueT& ) method.
575 @param rSetterModifier
576 Modifies up values before passing them to the pSetValue method.
577 Must provide operator()( const ValueT& ) method.
579 GenericAnimation( const ShapeManagerSharedPtr
& rShapeManager
,
581 bool (ShapeAttributeLayer::*pIsValid
)() const,
582 ValueT aDefaultValue
,
583 ValueT (ShapeAttributeLayer::*pGetValue
)() const,
584 void (ShapeAttributeLayer::*pSetValue
)( const ValueT
& ),
585 const ModifierFunctor
& rGetterModifier
,
586 const ModifierFunctor
& rSetterModifier
,
587 const AttributeType eAttrType
,
588 box2d::utils::Box2DWorldSharedPtr pBox2DWorld
) :
591 mpShapeManager( rShapeManager
),
592 mpIsValidFunc(pIsValid
),
593 mpGetValueFunc(pGetValue
),
594 mpSetValueFunc(pSetValue
),
595 maGetterModifier( rGetterModifier
),
596 maSetterModifier( rSetterModifier
),
598 maDefaultValue(std::move(aDefaultValue
)),
599 mbAnimationStarted( false ),
600 mbAnimationFirstUpdate( true ),
601 meAttrType( eAttrType
),
602 mpBox2DWorld (std::move( pBox2DWorld
))
604 ENSURE_OR_THROW( rShapeManager
,
605 "GenericAnimation::GenericAnimation(): Invalid ShapeManager" );
606 ENSURE_OR_THROW( pIsValid
&& pGetValue
&& pSetValue
,
607 "GenericAnimation::GenericAnimation(): One of the method pointers is NULL" );
615 // Animation interface
617 virtual void prefetch()
620 virtual void start( const AnimatableShapeSharedPtr
& rShape
,
621 const ShapeAttributeLayerSharedPtr
& rAttrLayer
)
623 OSL_ENSURE( !mpShape
,
624 "GenericAnimation::start(): Shape already set" );
625 OSL_ENSURE( !mpAttrLayer
,
626 "GenericAnimation::start(): Attribute layer already set" );
629 mpAttrLayer
= rAttrLayer
;
631 ENSURE_OR_THROW( rShape
,
632 "GenericAnimation::start(): Invalid shape" );
633 ENSURE_OR_THROW( rAttrLayer
,
634 "GenericAnimation::start(): Invalid attribute layer" );
636 // only start animation once per repeated start() call,
637 // and only if sprites should be used for display
638 if( !mbAnimationStarted
)
640 mbAnimationStarted
= true;
642 if( !(mnFlags
& AnimationFactory::FLAG_NO_SPRITE
) )
643 mpShapeManager
->enterAnimationMode( mpShape
);
649 // TODO(Q2): Factor out common code (most
650 // prominently start() and end()) into base class
652 // only stop animation once per repeated end() call,
653 // and only if sprites are used for display
654 if( !mbAnimationStarted
)
657 mbAnimationStarted
= false;
659 if( mpBox2DWorld
&& mpBox2DWorld
->isInitialized() )
661 // if there's a physics animation going on report the animation ending to it
662 mpBox2DWorld
->queueShapeAnimationEndUpdate( mpShape
->getXShape(), meAttrType
);
665 if( !(mnFlags
& AnimationFactory::FLAG_NO_SPRITE
) )
666 mpShapeManager
->leaveAnimationMode( mpShape
);
668 // Attention, this notifyShapeUpdate() is
669 // somewhat delicate here. Calling it
670 // unconditional (i.e. not guarded by
671 // mbAnimationStarted) will lead to shapes
672 // snapping back to their original state just
673 // before the slide ends. Not calling it at
674 // all might swallow final animation
675 // states. The current implementation relies
676 // on the fact that end() is either called by
677 // the Activity (then, the last animation
678 // state has been set, and corresponds to the
679 // shape's hold state), or by the animation
680 // node (then, it's a forced end, and we
681 // _have_ to snap back).
683 // To reiterate: normally, we're called from
684 // the Activity first, thus the
685 // notifyShapeUpdate() below will update to
686 // the last activity value.
688 // force shape update, activity might have changed
689 // state in the last round.
690 if( mpShape
->isContentChanged() )
691 mpShapeManager
->notifyShapeUpdate( mpShape
);
694 // Derived Animation interface
697 /** For by-reference interfaces (B2DTuple, OUString)
699 bool operator()( const ValueT
& x
)
701 ENSURE_OR_RETURN_FALSE( mpAttrLayer
&& mpShape
,
702 "GenericAnimation::operator(): Invalid ShapeAttributeLayer" );
704 ((*mpAttrLayer
).*mpSetValueFunc
)( maSetterModifier( x
) );
706 if( mpShape
->isContentChanged() )
707 mpShapeManager
->notifyShapeUpdate( mpShape
);
709 if( mbAnimationFirstUpdate
) mbAnimationFirstUpdate
= false;
714 /** For by-value interfaces (bool, double)
716 bool operator()( ValueT x
)
718 ENSURE_OR_RETURN_FALSE( mpAttrLayer
&& mpShape
,
719 "GenericAnimation::operator(): Invalid ShapeAttributeLayer" );
721 ((*mpAttrLayer
).*mpSetValueFunc
)( maSetterModifier( x
) );
723 if( mpBox2DWorld
&& mpBox2DWorld
->isInitialized() )
725 // if there's a physics animation going on report the change to it
726 mpBox2DWorld
->queueShapeAnimationUpdate( mpShape
->getXShape(), mpAttrLayer
, meAttrType
, mbAnimationFirstUpdate
);
729 if( mpShape
->isContentChanged() )
730 mpShapeManager
->notifyShapeUpdate( mpShape
);
732 if( mbAnimationFirstUpdate
) mbAnimationFirstUpdate
= false;
737 ValueT
getUnderlyingValue() const
739 ENSURE_OR_THROW( mpAttrLayer
,
740 "GenericAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
742 // deviated from the (*shared_ptr).*mpFuncPtr
743 // notation here, since gcc does not seem to parse
744 // that as a member function call anymore.
745 if( (mpAttrLayer
.get()->*mpIsValidFunc
)() )
746 return maGetterModifier( ((*mpAttrLayer
).*mpGetValueFunc
)() );
748 return maDefaultValue
;
752 AnimatableShapeSharedPtr mpShape
;
753 ShapeAttributeLayerSharedPtr mpAttrLayer
;
754 ShapeManagerSharedPtr mpShapeManager
;
755 bool (ShapeAttributeLayer::*mpIsValidFunc
)() const;
756 ValueT (ShapeAttributeLayer::*mpGetValueFunc
)() const;
757 void (ShapeAttributeLayer::*mpSetValueFunc
)( const ValueT
& );
759 ModifierFunctor maGetterModifier
;
760 ModifierFunctor maSetterModifier
;
764 const ValueT maDefaultValue
;
765 bool mbAnimationStarted
;
766 bool mbAnimationFirstUpdate
;
768 const AttributeType meAttrType
;
769 const box2d::utils::Box2DWorldSharedPtr mpBox2DWorld
;
772 //Current c++0x draft (apparently) has std::identity, but not operator()
773 template<typename T
> struct SGI_identity
775 T
& operator()(T
& x
) const { return x
; }
776 const T
& operator()(const T
& x
) const { return x
; }
779 /** Function template wrapper around GenericAnimation template
782 Type of animation to generate (determines the
783 interface GenericAnimation will implement).
785 template< typename AnimationBase
> ::std::shared_ptr
< AnimationBase
>
786 makeGenericAnimation( const ShapeManagerSharedPtr
& rShapeManager
,
788 bool (ShapeAttributeLayer::*pIsValid
)() const,
789 const typename
AnimationBase::ValueType
& rDefaultValue
,
790 typename
AnimationBase::ValueType (ShapeAttributeLayer::*pGetValue
)() const,
791 void (ShapeAttributeLayer::*pSetValue
)( const typename
AnimationBase::ValueType
& ),
792 const AttributeType eAttrType
,
793 const box2d::utils::Box2DWorldSharedPtr
& pBox2DWorld
)
795 return std::make_shared
<GenericAnimation
< AnimationBase
,
796 SGI_identity
< typename
AnimationBase::ValueType
> >>(
803 // no modification necessary, use identity functor here
804 SGI_identity
< typename
AnimationBase::ValueType
>(),
805 SGI_identity
< typename
AnimationBase::ValueType
>(),
813 explicit Scaler( double nScale
) :
818 double operator()( double nVal
) const
820 return mnScale
* nVal
;
827 /** Overload for NumberAnimations which need scaling (width,height,x,y currently)
829 NumberAnimationSharedPtr
makeGenericAnimation( const ShapeManagerSharedPtr
& rShapeManager
,
831 bool (ShapeAttributeLayer::*pIsValid
)() const,
832 double nDefaultValue
,
833 double (ShapeAttributeLayer::*pGetValue
)() const,
834 void (ShapeAttributeLayer::*pSetValue
)( const double& ),
836 const AttributeType eAttrType
,
837 const box2d::utils::Box2DWorldSharedPtr
& pBox2DWorld
)
839 return std::make_shared
<GenericAnimation
< NumberAnimation
, Scaler
>>( rShapeManager
,
842 nDefaultValue
/ nScaleValue
,
845 Scaler( 1.0/nScaleValue
),
846 Scaler( nScaleValue
),
852 uno::Any
getShapeDefault( const AnimatableShapeSharedPtr
& rShape
,
853 const OUString
& rPropertyName
)
855 uno::Reference
< drawing::XShape
> xShape( rShape
->getXShape() );
858 return uno::Any(); // no regular shape, no defaults available
861 // extract relevant value from XShape's PropertySet
862 uno::Reference
< beans::XPropertySet
> xPropSet( xShape
,
865 ENSURE_OR_THROW( xPropSet
.is(),
866 "getShapeDefault(): Cannot query property set from shape" );
868 return xPropSet
->getPropertyValue( rPropertyName
);
871 template< typename ValueType
> ValueType
getDefault( const AnimatableShapeSharedPtr
& rShape
,
872 const OUString
& rPropertyName
)
874 const uno::Any
& rAny( getShapeDefault( rShape
,
877 if( !rAny
.hasValue() )
879 SAL_WARN("slideshow", "getDefault(): cannot get shape property " << rPropertyName
);
884 ValueType aValue
= ValueType();
886 if( !(rAny
>>= aValue
) )
888 SAL_WARN("slideshow", "getDefault(): cannot extract shape property " << rPropertyName
);
896 template<> RGBColor getDefault
< RGBColor
>( const AnimatableShapeSharedPtr
& rShape
,
897 const OUString
& rPropertyName
)
899 const uno::Any
& rAny( getShapeDefault( rShape
,
902 if( !rAny
.hasValue() )
904 SAL_WARN("slideshow", "getDefault(): cannot get shape color property " << rPropertyName
);
909 sal_Int32 nValue
= 0;
911 if( !(rAny
>>= nValue
) )
913 SAL_INFO("slideshow", "getDefault(): cannot extract shape color property " << rPropertyName
);
917 // convert from 0xAARRGGBB API color to 0xRRGGBB00
919 return RGBColor( (nValue
<< 8U) & 0xFFFFFF00U
);
924 AnimationFactory::AttributeClass
AnimationFactory::classifyAttributeName( const OUString
& rAttrName
)
926 // ATTENTION: When changing this map, also the create*PropertyAnimation() methods must
927 // be checked and possibly adapted in their switch statements
929 // TODO(Q2): Since this map must be coherent with the various switch statements
930 // in the create*PropertyAnimation methods, try to unify into a single method or table
931 switch( mapAttributeName( rAttrName
) )
934 case AttributeType::Invalid
:
935 return CLASS_UNKNOWN_PROPERTY
;
937 case AttributeType::CharColor
:
938 case AttributeType::Color
:
939 case AttributeType::DimColor
:
940 case AttributeType::FillColor
:
941 case AttributeType::LineColor
:
942 return CLASS_COLOR_PROPERTY
;
944 case AttributeType::CharFontName
:
945 return CLASS_STRING_PROPERTY
;
947 case AttributeType::Visibility
:
948 return CLASS_BOOL_PROPERTY
;
950 case AttributeType::CharHeight
:
951 case AttributeType::CharWeight
:
952 case AttributeType::Height
:
953 case AttributeType::Opacity
:
954 case AttributeType::Rotate
:
955 case AttributeType::SkewX
:
956 case AttributeType::SkewY
:
957 case AttributeType::Width
:
958 case AttributeType::PosX
:
959 case AttributeType::PosY
:
960 return CLASS_NUMBER_PROPERTY
;
962 case AttributeType::CharUnderline
:
963 case AttributeType::FillStyle
:
964 case AttributeType::LineStyle
:
965 case AttributeType::CharPosture
:
966 return CLASS_ENUM_PROPERTY
;
970 NumberAnimationSharedPtr
AnimationFactory::createNumberPropertyAnimation( const OUString
& rAttrName
,
971 const AnimatableShapeSharedPtr
& rShape
,
972 const ShapeManagerSharedPtr
& rShapeManager
,
973 const ::basegfx::B2DVector
& rSlideSize
,
974 const box2d::utils::Box2DWorldSharedPtr
& pBox2DWorld
,
977 // ATTENTION: When changing this map, also the classifyAttributeName() method must
978 // be checked and possibly adapted in their switch statement
979 AttributeType eAttrType
= mapAttributeName(rAttrName
);
983 case AttributeType::Invalid
:
984 ENSURE_OR_THROW( false,
985 "AnimationFactory::createNumberPropertyAnimation(): Unknown attribute" );
988 case AttributeType::CharColor
:
989 case AttributeType::CharFontName
:
990 case AttributeType::CharPosture
:
991 case AttributeType::CharUnderline
:
992 case AttributeType::Color
:
993 case AttributeType::DimColor
:
994 case AttributeType::FillColor
:
995 case AttributeType::FillStyle
:
996 case AttributeType::LineColor
:
997 case AttributeType::LineStyle
:
998 case AttributeType::Visibility
:
999 ENSURE_OR_THROW( false,
1000 "AnimationFactory::createNumberPropertyAnimation(): Attribute type mismatch" );
1003 case AttributeType::CharHeight
:
1004 return makeGenericAnimation
<NumberAnimation
>( rShapeManager
,
1006 &ShapeAttributeLayer::isCharScaleValid
,
1007 1.0, // CharHeight is a relative attribute, thus
1009 &ShapeAttributeLayer::getCharScale
,
1010 &ShapeAttributeLayer::setCharScale
,
1014 case AttributeType::CharWeight
:
1015 return makeGenericAnimation
<NumberAnimation
>( rShapeManager
,
1017 &ShapeAttributeLayer::isCharWeightValid
,
1018 getDefault
<double>( rShape
, rAttrName
),
1019 &ShapeAttributeLayer::getCharWeight
,
1020 &ShapeAttributeLayer::setCharWeight
,
1024 case AttributeType::Height
:
1025 return makeGenericAnimation( rShapeManager
,
1027 &ShapeAttributeLayer::isHeightValid
,
1028 // TODO(F1): Check whether _shape_ bounds are correct here.
1029 // Theoretically, our AttrLayer is way down the stack, and
1030 // we only have to consider _that_ value, not the one from
1031 // the top of the stack as returned by Shape::getBounds()
1032 rShape
->getBounds().getHeight(),
1033 &ShapeAttributeLayer::getHeight
,
1034 &ShapeAttributeLayer::setHeight
,
1035 // convert expression parser value from relative page size
1040 case AttributeType::Opacity
:
1041 return makeGenericAnimation
<NumberAnimation
>( rShapeManager
,
1043 &ShapeAttributeLayer::isAlphaValid
,
1044 // TODO(F1): Provide shape default here (FillTransparency?)
1046 &ShapeAttributeLayer::getAlpha
,
1047 &ShapeAttributeLayer::setAlpha
,
1051 case AttributeType::Rotate
:
1052 return makeGenericAnimation
<NumberAnimation
>( rShapeManager
,
1054 &ShapeAttributeLayer::isRotationAngleValid
,
1055 // NOTE: Since we paint the shape as-is from metafile,
1056 // rotation angle is always 0.0, even for rotated shapes
1058 &ShapeAttributeLayer::getRotationAngle
,
1059 &ShapeAttributeLayer::setRotationAngle
,
1063 case AttributeType::SkewX
:
1064 return makeGenericAnimation
<NumberAnimation
>( rShapeManager
,
1066 &ShapeAttributeLayer::isShearXAngleValid
,
1067 // TODO(F1): Is there any shape property for skew?
1069 &ShapeAttributeLayer::getShearXAngle
,
1070 &ShapeAttributeLayer::setShearXAngle
,
1074 case AttributeType::SkewY
:
1075 return makeGenericAnimation
<NumberAnimation
>( rShapeManager
,
1077 &ShapeAttributeLayer::isShearYAngleValid
,
1078 // TODO(F1): Is there any shape property for skew?
1080 &ShapeAttributeLayer::getShearYAngle
,
1081 &ShapeAttributeLayer::setShearYAngle
,
1085 case AttributeType::Width
:
1086 return makeGenericAnimation( rShapeManager
,
1088 &ShapeAttributeLayer::isWidthValid
,
1089 // TODO(F1): Check whether _shape_ bounds are correct here.
1090 // Theoretically, our AttrLayer is way down the stack, and
1091 // we only have to consider _that_ value, not the one from
1092 // the top of the stack as returned by Shape::getBounds()
1093 rShape
->getBounds().getWidth(),
1094 &ShapeAttributeLayer::getWidth
,
1095 &ShapeAttributeLayer::setWidth
,
1096 // convert expression parser value from relative page size
1101 case AttributeType::PosX
:
1102 return makeGenericAnimation( rShapeManager
,
1104 &ShapeAttributeLayer::isPosXValid
,
1105 // TODO(F1): Check whether _shape_ bounds are correct here.
1106 // Theoretically, our AttrLayer is way down the stack, and
1107 // we only have to consider _that_ value, not the one from
1108 // the top of the stack as returned by Shape::getBounds()
1109 rShape
->getBounds().getCenterX(),
1110 &ShapeAttributeLayer::getPosX
,
1111 &ShapeAttributeLayer::setPosX
,
1112 // convert expression parser value from relative page size
1117 case AttributeType::PosY
:
1118 return makeGenericAnimation( rShapeManager
,
1120 &ShapeAttributeLayer::isPosYValid
,
1121 // TODO(F1): Check whether _shape_ bounds are correct here.
1122 // Theoretically, our AttrLayer is way down the stack, and
1123 // we only have to consider _that_ value, not the one from
1124 // the top of the stack as returned by Shape::getBounds()
1125 rShape
->getBounds().getCenterY(),
1126 &ShapeAttributeLayer::getPosY
,
1127 &ShapeAttributeLayer::setPosY
,
1128 // convert expression parser value from relative page size
1134 return NumberAnimationSharedPtr();
1137 EnumAnimationSharedPtr
AnimationFactory::createEnumPropertyAnimation( const OUString
& rAttrName
,
1138 const AnimatableShapeSharedPtr
& rShape
,
1139 const ShapeManagerSharedPtr
& rShapeManager
,
1140 const ::basegfx::B2DVector
& /*rSlideSize*/,
1141 const box2d::utils::Box2DWorldSharedPtr
& pBox2DWorld
,
1144 // ATTENTION: When changing this map, also the classifyAttributeName() method must
1145 // be checked and possibly adapted in their switch statement
1146 AttributeType eAttrType
= mapAttributeName( rAttrName
);
1150 case AttributeType::Invalid
:
1151 ENSURE_OR_THROW( false,
1152 "AnimationFactory::createEnumPropertyAnimation(): Unknown attribute" );
1155 case AttributeType::CharColor
:
1156 case AttributeType::CharFontName
:
1157 case AttributeType::Color
:
1158 case AttributeType::DimColor
:
1159 case AttributeType::FillColor
:
1160 case AttributeType::LineColor
:
1161 case AttributeType::Visibility
:
1162 case AttributeType::CharHeight
:
1163 case AttributeType::CharWeight
:
1164 case AttributeType::Height
:
1165 case AttributeType::Opacity
:
1166 case AttributeType::Rotate
:
1167 case AttributeType::SkewX
:
1168 case AttributeType::SkewY
:
1169 case AttributeType::Width
:
1170 case AttributeType::PosX
:
1171 case AttributeType::PosY
:
1172 ENSURE_OR_THROW( false,
1173 "AnimationFactory::createEnumPropertyAnimation(): Attribute type mismatch" );
1177 case AttributeType::FillStyle
:
1178 return makeGenericAnimation
<EnumAnimation
>( rShapeManager
,
1180 &ShapeAttributeLayer::isFillStyleValid
,
1181 sal::static_int_cast
<sal_Int16
>(
1182 getDefault
<drawing::FillStyle
>( rShape
, rAttrName
)),
1183 &ShapeAttributeLayer::getFillStyle
,
1184 &ShapeAttributeLayer::setFillStyle
,
1188 case AttributeType::LineStyle
:
1189 return makeGenericAnimation
<EnumAnimation
>( rShapeManager
,
1191 &ShapeAttributeLayer::isLineStyleValid
,
1192 sal::static_int_cast
<sal_Int16
>(
1193 getDefault
<drawing::LineStyle
>( rShape
, rAttrName
)),
1194 &ShapeAttributeLayer::getLineStyle
,
1195 &ShapeAttributeLayer::setLineStyle
,
1199 case AttributeType::CharPosture
:
1200 return makeGenericAnimation
<EnumAnimation
>( rShapeManager
,
1202 &ShapeAttributeLayer::isCharPostureValid
,
1203 sal::static_int_cast
<sal_Int16
>(
1204 getDefault
<awt::FontSlant
>( rShape
, rAttrName
)),
1205 &ShapeAttributeLayer::getCharPosture
,
1206 &ShapeAttributeLayer::setCharPosture
,
1210 case AttributeType::CharUnderline
:
1211 return makeGenericAnimation
<EnumAnimation
>( rShapeManager
,
1213 &ShapeAttributeLayer::isUnderlineModeValid
,
1214 getDefault
<sal_Int16
>( rShape
, rAttrName
),
1215 &ShapeAttributeLayer::getUnderlineMode
,
1216 &ShapeAttributeLayer::setUnderlineMode
,
1221 return EnumAnimationSharedPtr();
1224 ColorAnimationSharedPtr
AnimationFactory::createColorPropertyAnimation( const OUString
& rAttrName
,
1225 const AnimatableShapeSharedPtr
& rShape
,
1226 const ShapeManagerSharedPtr
& rShapeManager
,
1227 const ::basegfx::B2DVector
& /*rSlideSize*/,
1228 const box2d::utils::Box2DWorldSharedPtr
& pBox2DWorld
,
1231 // ATTENTION: When changing this map, also the classifyAttributeName() method must
1232 // be checked and possibly adapted in their switch statement
1233 AttributeType eAttrType
= mapAttributeName(rAttrName
);
1237 case AttributeType::Invalid
:
1238 ENSURE_OR_THROW( false,
1239 "AnimationFactory::createColorPropertyAnimation(): Unknown attribute" );
1242 case AttributeType::CharFontName
:
1243 case AttributeType::CharHeight
:
1244 case AttributeType::CharPosture
:
1245 case AttributeType::CharUnderline
:
1246 case AttributeType::CharWeight
:
1247 case AttributeType::FillStyle
:
1248 case AttributeType::Height
:
1249 case AttributeType::LineStyle
:
1250 case AttributeType::Opacity
:
1251 case AttributeType::Rotate
:
1252 case AttributeType::SkewX
:
1253 case AttributeType::SkewY
:
1254 case AttributeType::Visibility
:
1255 case AttributeType::Width
:
1256 case AttributeType::PosX
:
1257 case AttributeType::PosY
:
1258 ENSURE_OR_THROW( false,
1259 "AnimationFactory::createColorPropertyAnimation(): Attribute type mismatch" );
1262 case AttributeType::CharColor
:
1263 return makeGenericAnimation
<ColorAnimation
>( rShapeManager
,
1265 &ShapeAttributeLayer::isCharColorValid
,
1266 getDefault
<RGBColor
>( rShape
, rAttrName
),
1267 &ShapeAttributeLayer::getCharColor
,
1268 &ShapeAttributeLayer::setCharColor
,
1272 case AttributeType::Color
:
1273 // TODO(F2): This is just mapped to fill color to make it work
1274 return makeGenericAnimation
<ColorAnimation
>( rShapeManager
,
1276 &ShapeAttributeLayer::isFillColorValid
,
1277 getDefault
<RGBColor
>( rShape
, rAttrName
),
1278 &ShapeAttributeLayer::getFillColor
,
1279 &ShapeAttributeLayer::setFillColor
,
1283 case AttributeType::DimColor
:
1284 return makeGenericAnimation
<ColorAnimation
>( rShapeManager
,
1286 &ShapeAttributeLayer::isDimColorValid
,
1287 getDefault
<RGBColor
>( rShape
, rAttrName
),
1288 &ShapeAttributeLayer::getDimColor
,
1289 &ShapeAttributeLayer::setDimColor
,
1293 case AttributeType::FillColor
:
1294 return makeGenericAnimation
<ColorAnimation
>( rShapeManager
,
1296 &ShapeAttributeLayer::isFillColorValid
,
1297 getDefault
<RGBColor
>( rShape
, rAttrName
),
1298 &ShapeAttributeLayer::getFillColor
,
1299 &ShapeAttributeLayer::setFillColor
,
1303 case AttributeType::LineColor
:
1304 return makeGenericAnimation
<ColorAnimation
>( rShapeManager
,
1306 &ShapeAttributeLayer::isLineColorValid
,
1307 getDefault
<RGBColor
>( rShape
, rAttrName
),
1308 &ShapeAttributeLayer::getLineColor
,
1309 &ShapeAttributeLayer::setLineColor
,
1314 return ColorAnimationSharedPtr();
1317 PairAnimationSharedPtr
AnimationFactory::createPairPropertyAnimation( const AnimatableShapeSharedPtr
& rShape
,
1318 const ShapeManagerSharedPtr
& rShapeManager
,
1319 const ::basegfx::B2DVector
& rSlideSize
,
1320 sal_Int16 nTransformType
,
1323 const ::basegfx::B2DRectangle
& rBounds( rShape
->getBounds() );
1325 switch( nTransformType
)
1327 case animations::AnimationTransformType::SCALE
:
1328 return std::make_shared
<TupleAnimation
< ::basegfx::B2DSize
>>(
1331 &ShapeAttributeLayer::isWidthValid
,
1332 &ShapeAttributeLayer::isHeightValid
,
1333 // TODO(F1): Check whether _shape_ bounds are correct here.
1334 // Theoretically, our AttrLayer is way down the stack, and
1335 // we only have to consider _that_ value, not the one from
1336 // the top of the stack as returned by Shape::getBounds()
1337 basegfx::B2DSize(rBounds
.getRange().getX(), rBounds
.getRange().getY()),
1338 basegfx::B2DSize(rBounds
.getRange().getX(), rBounds
.getRange().getY()),
1339 &ShapeAttributeLayer::getWidth
,
1340 &ShapeAttributeLayer::getHeight
,
1341 &ShapeAttributeLayer::setSize
);
1343 case animations::AnimationTransformType::TRANSLATE
:
1344 return std::make_shared
<TupleAnimation
< ::basegfx::B2DPoint
>>(
1347 &ShapeAttributeLayer::isPosXValid
,
1348 &ShapeAttributeLayer::isPosYValid
,
1349 // TODO(F1): Check whether _shape_ bounds are correct here.
1350 // Theoretically, our AttrLayer is way down the stack, and
1351 // we only have to consider _that_ value, not the one from
1352 // the top of the stack as returned by Shape::getBounds()
1353 rBounds
.getCenter(),
1354 basegfx::B2DSize(rSlideSize
.getX(), rSlideSize
.getY()),
1355 &ShapeAttributeLayer::getPosX
,
1356 &ShapeAttributeLayer::getPosY
,
1357 &ShapeAttributeLayer::setPosition
);
1360 ENSURE_OR_THROW( false,
1361 "AnimationFactory::createPairPropertyAnimation(): Attribute type mismatch" );
1365 return PairAnimationSharedPtr();
1368 StringAnimationSharedPtr
AnimationFactory::createStringPropertyAnimation( const OUString
& rAttrName
,
1369 const AnimatableShapeSharedPtr
& rShape
,
1370 const ShapeManagerSharedPtr
& rShapeManager
,
1371 const ::basegfx::B2DVector
& /*rSlideSize*/,
1372 const box2d::utils::Box2DWorldSharedPtr
& pBox2DWorld
,
1375 // ATTENTION: When changing this map, also the classifyAttributeName() method must
1376 // be checked and possibly adapted in their switch statement
1377 AttributeType eAttrType
= mapAttributeName(rAttrName
);
1381 case AttributeType::Invalid
:
1382 ENSURE_OR_THROW( false,
1383 "AnimationFactory::createStringPropertyAnimation(): Unknown attribute" );
1386 case AttributeType::CharColor
:
1387 case AttributeType::CharHeight
:
1388 case AttributeType::CharUnderline
:
1389 case AttributeType::Color
:
1390 case AttributeType::DimColor
:
1391 case AttributeType::FillColor
:
1392 case AttributeType::Height
:
1393 case AttributeType::LineColor
:
1394 case AttributeType::Opacity
:
1395 case AttributeType::Rotate
:
1396 case AttributeType::SkewX
:
1397 case AttributeType::SkewY
:
1398 case AttributeType::Visibility
:
1399 case AttributeType::Width
:
1400 case AttributeType::PosX
:
1401 case AttributeType::PosY
:
1402 case AttributeType::CharPosture
:
1403 case AttributeType::CharWeight
:
1404 case AttributeType::FillStyle
:
1405 case AttributeType::LineStyle
:
1406 ENSURE_OR_THROW( false,
1407 "AnimationFactory::createStringPropertyAnimation(): Attribute type mismatch" );
1410 case AttributeType::CharFontName
:
1411 return makeGenericAnimation
<StringAnimation
>( rShapeManager
,
1413 &ShapeAttributeLayer::isFontFamilyValid
,
1414 getDefault
< OUString
>( rShape
, rAttrName
),
1415 &ShapeAttributeLayer::getFontFamily
,
1416 &ShapeAttributeLayer::setFontFamily
,
1421 return StringAnimationSharedPtr();
1424 BoolAnimationSharedPtr
AnimationFactory::createBoolPropertyAnimation( const OUString
& rAttrName
,
1425 const AnimatableShapeSharedPtr
& /*rShape*/,
1426 const ShapeManagerSharedPtr
& rShapeManager
,
1427 const ::basegfx::B2DVector
& /*rSlideSize*/,
1428 const box2d::utils::Box2DWorldSharedPtr
& pBox2DWorld
,
1431 // ATTENTION: When changing this map, also the classifyAttributeName() method must
1432 // be checked and possibly adapted in their switch statement
1433 AttributeType eAttrType
= mapAttributeName(rAttrName
);
1437 case AttributeType::Invalid
:
1438 ENSURE_OR_THROW( false,
1439 "AnimationFactory::createBoolPropertyAnimation(): Unknown attribute" );
1442 case AttributeType::CharColor
:
1443 case AttributeType::CharFontName
:
1444 case AttributeType::CharHeight
:
1445 case AttributeType::CharPosture
:
1446 case AttributeType::CharWeight
:
1447 case AttributeType::Color
:
1448 case AttributeType::DimColor
:
1449 case AttributeType::FillColor
:
1450 case AttributeType::FillStyle
:
1451 case AttributeType::Height
:
1452 case AttributeType::LineColor
:
1453 case AttributeType::LineStyle
:
1454 case AttributeType::Opacity
:
1455 case AttributeType::Rotate
:
1456 case AttributeType::SkewX
:
1457 case AttributeType::SkewY
:
1458 case AttributeType::Width
:
1459 case AttributeType::PosX
:
1460 case AttributeType::PosY
:
1461 case AttributeType::CharUnderline
:
1462 ENSURE_OR_THROW( false,
1463 "AnimationFactory::createBoolPropertyAnimation(): Attribute type mismatch" );
1466 case AttributeType::Visibility
:
1467 return makeGenericAnimation
<BoolAnimation
>( rShapeManager
,
1469 &ShapeAttributeLayer::isVisibilityValid
,
1470 // TODO(F1): Is there a corresponding shape property?
1472 &ShapeAttributeLayer::getVisibility
,
1473 &ShapeAttributeLayer::setVisibility
,
1478 return BoolAnimationSharedPtr();
1481 NumberAnimationSharedPtr
AnimationFactory::createPathMotionAnimation( const OUString
& rSVGDPath
,
1482 sal_Int16 nAdditive
,
1483 const AnimatableShapeSharedPtr
& /*rShape*/,
1484 const ShapeManagerSharedPtr
& rShapeManager
,
1485 const ::basegfx::B2DVector
& rSlideSize
,
1486 const box2d::utils::Box2DWorldSharedPtr
& pBox2DWorld
,
1489 return std::make_shared
<PathAnimation
>( rSVGDPath
, nAdditive
,
1496 NumberAnimationSharedPtr
AnimationFactory::createPhysicsAnimation( const box2d::utils::Box2DWorldSharedPtr
& pBox2DWorld
,
1497 const double fDuration
,
1498 const ShapeManagerSharedPtr
& rShapeManager
,
1499 const ::basegfx::B2DVector
& rSlideSize
,
1500 const ::basegfx::B2DVector
& rStartVelocity
,
1501 const double fDensity
,
1502 const double fBounciness
,
1505 return std::make_shared
<PhysicsAnimation
>( pBox2DWorld
, fDuration
,
1516 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */