Bump version to 6.0-36
[LibreOffice.git] / slideshow / source / engine / activities / activitiesfactory.cxx
blobdadd590257e0854823dd1b690c7ec0562238b5da
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <tools/diagnose_ex.h>
23 #include <com/sun/star/animations/AnimationCalcMode.hpp>
24 #include <comphelper/sequence.hxx>
26 #include <activitiesfactory.hxx>
27 #include <smilfunctionparser.hxx>
28 #include "accumulation.hxx"
29 #include "activityparameters.hxx"
30 #include "interpolation.hxx"
31 #include <tools.hxx>
32 #include "simplecontinuousactivitybase.hxx"
33 #include "discreteactivitybase.hxx"
34 #include "continuousactivitybase.hxx"
35 #include "continuouskeytimeactivitybase.hxx"
37 #include <boost/optional.hpp>
39 #include <memory>
40 #include <cmath>
41 #include <vector>
42 #include <algorithm>
44 using namespace com::sun::star;
46 namespace slideshow {
47 namespace internal {
49 namespace {
51 /** Traits template, to take formula application only for ValueType = double
53 template<typename ValueType> struct FormulaTraits
55 static ValueType getPresentationValue(
56 const ValueType& rVal, const std::shared_ptr<ExpressionNode>& )
58 return rVal;
62 /// Specialization for ValueType = double
63 template<> struct FormulaTraits<double>
65 static double getPresentationValue(
66 double const& rVal, std::shared_ptr<ExpressionNode> const& rFormula )
68 return rFormula ? (*rFormula)(rVal) : rVal;
72 // Various ActivityBase specializations for different animator types
73 // =================================================================
75 /** FromToBy handler
77 Provides the Activity specializations for FromToBy
78 animations (e.g. those without a values list).
80 This template makes heavy use of SFINAE, only one of
81 the perform*() methods will compile for each of the
82 base classes.
84 Note that we omit the virtual keyword on the perform()
85 overrides on purpose; those that actually do override
86 baseclass virtual methods inherit the property, and
87 the others won't increase our vtable. What's more,
88 having all perform() method in the vtable actually
89 creates POIs for them, which breaks the whole SFINAE
90 concept (IOW, this template won't compile any longer).
92 @tpl BaseType
93 Base class to use for this activity. Only
94 ContinuousActivityBase and DiscreteActivityBase are
95 supported here.
97 @tpl AnimationType
98 Type of the Animation to call.
100 template<class BaseType, typename AnimationType>
101 class FromToByActivity : public BaseType
103 public:
104 typedef typename AnimationType::ValueType ValueType;
105 typedef boost::optional<ValueType> OptionalValueType;
107 private:
108 // some compilers don't inline whose definition they haven't
109 // seen before the call site...
110 ValueType getPresentationValue( const ValueType& rVal ) const
112 return FormulaTraits<ValueType>::getPresentationValue( rVal, mpFormula);
115 public:
116 /** Create FromToByActivity.
118 @param rFrom
119 From this value, the animation starts
121 @param rTo
122 With this value, the animation ends
124 @param rBy
125 With this value, the animation increments the start value
127 @param rParms
128 Standard Activity parameter struct
130 @param rAnim
131 Shared ptr to AnimationType
133 @param rInterpolator
134 Interpolator object to be used for lerping between
135 start and end value (need to be passed, since it
136 might contain state, e.g. interpolation direction
137 for HSL color space).
139 @param bCumulative
140 Whether repeated animations should cumulate the
141 value, or start fresh each time.
143 FromToByActivity(
144 const OptionalValueType& rFrom,
145 const OptionalValueType& rTo,
146 const OptionalValueType& rBy,
147 const ActivityParameters& rParms,
148 const ::std::shared_ptr< AnimationType >& rAnim,
149 const Interpolator< ValueType >& rInterpolator,
150 bool bCumulative )
151 : BaseType( rParms ),
152 maFrom( rFrom ),
153 maTo( rTo ),
154 maBy( rBy ),
155 mpFormula( rParms.mpFormula ),
156 maStartValue(),
157 maEndValue(),
158 maPreviousValue(),
159 maStartInterpolationValue(),
160 mnIteration( 0 ),
161 mpAnim( rAnim ),
162 maInterpolator( rInterpolator ),
163 mbDynamicStartValue( false ),
164 mbCumulative( bCumulative )
166 ENSURE_OR_THROW( mpAnim, "Invalid animation object" );
168 ENSURE_OR_THROW(
169 rTo || rBy,
170 "From and one of To or By, or To or By alone must be valid" );
173 virtual void startAnimation()
175 if (this->isDisposed() || !mpAnim)
176 return;
177 BaseType::startAnimation();
179 // start animation
180 mpAnim->start( BaseType::getShape(),
181 BaseType::getShapeAttributeLayer() );
183 // setup start and end value. Determine animation
184 // start value only when animation actually
185 // started up (this order is part of the Animation
186 // interface contract)
187 const ValueType aAnimationStartValue( mpAnim->getUnderlyingValue() );
189 // first of all, determine general type of
190 // animation, by inspecting which of the FromToBy values
191 // are actually valid.
192 // See http://www.w3.org/TR/smil20/animation.html#AnimationNS-FromToBy
193 // for a definition
194 if( maFrom )
196 // From-to or From-by animation. According to
197 // SMIL spec, the To value takes precedence
198 // over the By value, if both are specified
199 if( maTo )
201 // From-To animation
202 maStartValue = *maFrom;
203 maEndValue = *maTo;
205 else if( maBy )
207 // From-By animation
208 maStartValue = *maFrom;
209 maEndValue = maStartValue + *maBy;
212 else
214 maStartValue = aAnimationStartValue;
215 maStartInterpolationValue = maStartValue;
217 // By or To animation. According to SMIL spec,
218 // the To value takes precedence over the By
219 // value, if both are specified
220 if( maTo )
222 // To animation
224 // According to the SMIL spec
225 // (http://www.w3.org/TR/smil20/animation.html#animationNS-ToAnimation),
226 // the to animation interpolates between
227 // the _running_ underlying value and the to value (as the end value)
228 mbDynamicStartValue = true;
229 maPreviousValue = maStartValue;
230 maEndValue = *maTo;
232 else if( maBy )
234 // By animation
235 maStartValue = aAnimationStartValue;
236 maEndValue = maStartValue + *maBy;
241 virtual void endAnimation()
243 // end animation
244 if (mpAnim)
245 mpAnim->end();
248 /// perform override for ContinuousActivityBase
249 void perform( double nModifiedTime, sal_uInt32 nRepeatCount ) const
251 if (this->isDisposed() || !mpAnim)
252 return;
254 // According to SMIL 3.0 spec 'to' animation if no other (lower priority)
255 // animations are active or frozen then a simple interpolation is performed.
256 // That is, the start interpolation value is constant while the animation
257 // is running, and is equal to the underlying value retrieved when
258 // the animation start.
259 // However if another animation is manipulating the underlying value,
260 // the 'to' animation will initially add to the effect of the lower priority
261 // animation, and increasingly dominate it as it nears the end of the
262 // simple duration, eventually overriding it completely.
263 // That is, each time the underlying value is changed between two
264 // computations of the animation function the new underlying value is used
265 // as start value for the interpolation.
266 // See:
267 // http://www.w3.org/TR/SMIL3/smil-animation.html#animationNS-ToAnimation
268 // (Figure 6 - Effect of Additive to animation example)
269 // Moreover when a 'to' animation is repeated, at each new iteration
270 // the start interpolation value is reset to the underlying value
271 // of the animated property when the animation started,
272 // as it is shown in the example provided by the SMIL 3.0 spec.
273 // This is exactly as Firefox performs SVG 'to' animations.
274 if( mbDynamicStartValue )
276 if( mnIteration != nRepeatCount )
278 mnIteration = nRepeatCount;
279 maStartInterpolationValue = maStartValue;
281 else
283 ValueType aActualValue = mpAnim->getUnderlyingValue();
284 if( aActualValue != maPreviousValue )
285 maStartInterpolationValue = aActualValue;
289 ValueType aValue = maInterpolator( maStartInterpolationValue,
290 maEndValue, nModifiedTime );
292 // According to the SMIL spec:
293 // Because 'to' animation is defined in terms of absolute values of
294 // the target attribute, cumulative animation is not defined.
295 if( mbCumulative && !mbDynamicStartValue )
297 // aValue = this.aEndValue * nRepeatCount + aValue;
298 aValue = accumulate( maEndValue, nRepeatCount, aValue );
301 (*mpAnim)( getPresentationValue( aValue ) );
303 if( mbDynamicStartValue )
305 maPreviousValue = mpAnim->getUnderlyingValue();
310 using BaseType::perform;
312 /// perform override for DiscreteActivityBase base
313 void perform( sal_uInt32 nFrame, sal_uInt32 nRepeatCount ) const
315 if (this->isDisposed() || !mpAnim)
316 return;
317 (*mpAnim)(
318 getPresentationValue(
319 accumulate( maEndValue, mbCumulative ? nRepeatCount : 0,
320 lerp( maInterpolator,
321 (mbDynamicStartValue
322 ? mpAnim->getUnderlyingValue()
323 : maStartValue),
324 maEndValue,
325 nFrame,
326 BaseType::getNumberOfKeyTimes() ) ) ) );
329 using BaseType::isAutoReverse;
331 virtual void performEnd()
333 // xxx todo: good guess
334 if (mpAnim)
336 if (isAutoReverse())
337 (*mpAnim)( getPresentationValue( maStartValue ) );
338 else
339 (*mpAnim)( getPresentationValue( maEndValue ) );
343 /// Disposable:
344 virtual void dispose()
346 mpAnim.reset();
347 BaseType::dispose();
350 private:
351 const OptionalValueType maFrom;
352 const OptionalValueType maTo;
353 const OptionalValueType maBy;
355 std::shared_ptr<ExpressionNode> mpFormula;
357 ValueType maStartValue;
358 ValueType maEndValue;
360 mutable ValueType maPreviousValue;
361 mutable ValueType maStartInterpolationValue;
362 mutable sal_uInt32 mnIteration;
364 ::std::shared_ptr< AnimationType > mpAnim;
365 Interpolator< ValueType > maInterpolator;
366 bool mbDynamicStartValue;
367 bool mbCumulative;
371 /** Generate Activity corresponding to given FromToBy values
373 @tpl BaseType
374 BaseType to use for deriving the Activity from
376 @tpl AnimationType
377 Subtype of the Animation object (e.g. NumberAnimation)
379 template<class BaseType, typename AnimationType>
380 AnimationActivitySharedPtr createFromToByActivity(
381 const uno::Any& rFromAny,
382 const uno::Any& rToAny,
383 const uno::Any& rByAny,
384 const ActivityParameters& rParms,
385 const ::std::shared_ptr< AnimationType >& rAnim,
386 const Interpolator< typename AnimationType::ValueType >& rInterpolator,
387 bool bCumulative,
388 const ShapeSharedPtr& rShape,
389 const ::basegfx::B2DVector& rSlideBounds )
391 typedef typename AnimationType::ValueType ValueType;
392 typedef boost::optional<ValueType> OptionalValueType;
394 OptionalValueType aFrom;
395 OptionalValueType aTo;
396 OptionalValueType aBy;
398 ValueType aTmpValue;
400 if( rFromAny.hasValue() )
402 ENSURE_OR_THROW(
403 extractValue( aTmpValue, rFromAny, rShape, rSlideBounds ),
404 "createFromToByActivity(): Could not extract from value" );
405 aFrom.reset(aTmpValue);
407 if( rToAny.hasValue() )
409 ENSURE_OR_THROW(
410 extractValue( aTmpValue, rToAny, rShape, rSlideBounds ),
411 "createFromToByActivity(): Could not extract to value" );
412 aTo.reset(aTmpValue);
414 if( rByAny.hasValue() )
416 ENSURE_OR_THROW(
417 extractValue( aTmpValue, rByAny, rShape, rSlideBounds ),
418 "createFromToByActivity(): Could not extract by value" );
419 aBy.reset(aTmpValue);
422 return AnimationActivitySharedPtr(
423 new FromToByActivity<BaseType, AnimationType>(
424 aFrom,
425 aTo,
426 aBy,
427 rParms,
428 rAnim,
429 rInterpolator,
430 bCumulative ) );
433 /* The following table shows which animator combines with
434 which Activity type:
436 NumberAnimator: all
437 PairAnimation: all
438 ColorAnimation: all
439 StringAnimation: DiscreteActivityBase
440 BoolAnimation: DiscreteActivityBase
443 /** Values handler
445 Provides the Activity specializations for value lists
446 animations.
448 This template makes heavy use of SFINAE, only one of
449 the perform*() methods will compile for each of the
450 base classes.
452 Note that we omit the virtual keyword on the perform()
453 overrides on purpose; those that actually do override
454 baseclass virtual methods inherit the property, and
455 the others won't increase our vtable. What's more,
456 having all perform() method in the vtable actually
457 creates POIs for them, which breaks the whole SFINAE
458 concept (IOW, this template won't compile any longer).
460 @tpl BaseType
461 Base class to use for this activity. Only
462 ContinuousKeyTimeActivityBase and DiscreteActivityBase
463 are supported here. For values animation without key
464 times, the client must emulate key times by providing
465 a vector of equally spaced values between 0 and 1,
466 with the same number of entries as the values vector.
468 @tpl AnimationType
469 Type of the Animation to call.
471 template<class BaseType, typename AnimationType>
472 class ValuesActivity : public BaseType
474 public:
475 typedef typename AnimationType::ValueType ValueType;
476 typedef std::vector<ValueType> ValueVectorType;
478 private:
479 // some compilers don't inline methods whose definition they haven't
480 // seen before the call site...
481 ValueType getPresentationValue( const ValueType& rVal ) const
483 return FormulaTraits<ValueType>::getPresentationValue(
484 rVal, mpFormula );
487 public:
488 /** Create ValuesActivity.
490 @param rValues
491 Value vector to cycle animation through
493 @param rParms
494 Standard Activity parameter struct
496 @param rAnim
497 Shared ptr to AnimationType
499 @param rInterpolator
500 Interpolator object to be used for lerping between
501 start and end value (need to be passed, since it
502 might contain state, e.g. interpolation direction
503 for HSL color space).
505 @param bCumulative
506 Whether repeated animations should cumulate the
507 value, or start afresh each time.
509 ValuesActivity(
510 const ValueVectorType& rValues,
511 const ActivityParameters& rParms,
512 const std::shared_ptr<AnimationType>& rAnim,
513 const Interpolator< ValueType >& rInterpolator,
514 bool bCumulative )
515 : BaseType( rParms ),
516 maValues( rValues ),
517 mpFormula( rParms.mpFormula ),
518 mpAnim( rAnim ),
519 maInterpolator( rInterpolator ),
520 mbCumulative( bCumulative )
522 ENSURE_OR_THROW( mpAnim, "Invalid animation object" );
523 ENSURE_OR_THROW( !rValues.empty(), "Empty value vector" );
526 virtual void startAnimation()
528 if (this->isDisposed() || !mpAnim)
529 return;
530 BaseType::startAnimation();
532 // start animation
533 mpAnim->start( BaseType::getShape(),
534 BaseType::getShapeAttributeLayer() );
537 virtual void endAnimation()
539 // end animation
540 if (mpAnim)
541 mpAnim->end();
544 /// perform override for ContinuousKeyTimeActivityBase base
545 void perform( sal_uInt32 nIndex,
546 double nFractionalIndex,
547 sal_uInt32 nRepeatCount ) const
549 if (this->isDisposed() || !mpAnim)
550 return;
551 ENSURE_OR_THROW( nIndex+1 < maValues.size(),
552 "ValuesActivity::perform(): index out of range" );
554 // interpolate between nIndex and nIndex+1 values
555 (*mpAnim)(
556 getPresentationValue(
557 accumulate<ValueType>( maValues.back(),
558 mbCumulative ? nRepeatCount : 0,
559 maInterpolator( maValues[ nIndex ],
560 maValues[ nIndex+1 ],
561 nFractionalIndex ) ) ) );
564 using BaseType::perform;
566 /// perform override for DiscreteActivityBase base
567 void perform( sal_uInt32 nFrame, sal_uInt32 nRepeatCount ) const
569 if (this->isDisposed() || !mpAnim)
570 return;
571 ENSURE_OR_THROW( nFrame < maValues.size(),
572 "ValuesActivity::perform(): index out of range" );
574 // this is discrete, thus no lerp here.
575 (*mpAnim)(
576 getPresentationValue(
577 accumulate<ValueType>( maValues.back(),
578 mbCumulative ? nRepeatCount : 0,
579 maValues[ nFrame ] ) ) );
582 virtual void performEnd()
584 // xxx todo: good guess
585 if (mpAnim)
586 (*mpAnim)( getPresentationValue( maValues.back() ) );
589 private:
590 ValueVectorType maValues;
592 std::shared_ptr<ExpressionNode> mpFormula;
594 std::shared_ptr<AnimationType> mpAnim;
595 Interpolator< ValueType > maInterpolator;
596 bool mbCumulative;
599 /** Generate Activity corresponding to given Value vector
601 @tpl BaseType
602 BaseType to use for deriving the Activity from
604 @tpl AnimationType
605 Subtype of the Animation object (e.g. NumberAnimation)
607 template<class BaseType, typename AnimationType>
608 AnimationActivitySharedPtr createValueListActivity(
609 const uno::Sequence<uno::Any>& rValues,
610 const ActivityParameters& rParms,
611 const std::shared_ptr<AnimationType>& rAnim,
612 const Interpolator<typename AnimationType::ValueType>& rInterpolator,
613 bool bCumulative,
614 const ShapeSharedPtr& rShape,
615 const ::basegfx::B2DVector& rSlideBounds )
617 typedef typename AnimationType::ValueType ValueType;
618 typedef std::vector<ValueType> ValueVectorType;
620 ValueVectorType aValueVector;
621 aValueVector.reserve( rValues.getLength() );
623 for( ::std::size_t i=0, nLen=rValues.getLength(); i<nLen; ++i )
625 ValueType aValue;
626 ENSURE_OR_THROW(
627 extractValue( aValue, rValues[i], rShape, rSlideBounds ),
628 "createValueListActivity(): Could not extract values" );
629 aValueVector.push_back( aValue );
632 return AnimationActivitySharedPtr(
633 new ValuesActivity<BaseType, AnimationType>(
634 aValueVector,
635 rParms,
636 rAnim,
637 rInterpolator,
638 bCumulative ) );
641 /** Generate Activity for given XAnimate, corresponding to given Value vector
643 @tpl AnimationType
644 Subtype of the Animation object (e.g. NumberAnimation)
646 @param rParms
647 Common activity parameters
649 @param xNode
650 XAnimate node, to retrieve animation values from
652 @param rAnim
653 Actual animation to operate with (gets called with the
654 time-dependent values)
656 @param rInterpolator
657 Interpolator object to be used for lerping between
658 start and end values (need to be passed, since it
659 might contain state, e.g. interpolation direction
660 for HSL color space).
662 template<typename AnimationType>
663 AnimationActivitySharedPtr createActivity(
664 const ActivitiesFactory::CommonParameters& rParms,
665 const uno::Reference< animations::XAnimate >& xNode,
666 const ::std::shared_ptr< AnimationType >& rAnim,
667 const Interpolator< typename AnimationType::ValueType >& rInterpolator
668 = Interpolator< typename AnimationType::ValueType >() )
670 // setup common parameters
671 // =======================
673 ActivityParameters aActivityParms( rParms.mpEndEvent,
674 rParms.mrEventQueue,
675 rParms.mrActivitiesQueue,
676 rParms.mnMinDuration,
677 rParms.maRepeats,
678 rParms.mnAcceleration,
679 rParms.mnDeceleration,
680 rParms.mnMinNumberOfFrames,
681 rParms.mbAutoReverse );
683 // is a formula given?
684 const OUString& rFormulaString( xNode->getFormula() );
685 if( !rFormulaString.isEmpty() )
687 // yep, parse and pass to ActivityParameters
690 aActivityParms.mpFormula =
691 SmilFunctionParser::parseSmilFunction(
692 rFormulaString,
693 calcRelativeShapeBounds(
694 rParms.maSlideBounds,
695 rParms.mpShape->getBounds() ) );
697 catch( ParseError& )
699 // parse error, thus no formula
700 OSL_FAIL( "createActivity(): Error parsing formula string" );
704 // are key times given?
705 const uno::Sequence< double >& aKeyTimes( xNode->getKeyTimes() );
706 if( aKeyTimes.hasElements() )
708 // yes, convert them from Sequence< double >
709 aActivityParms.maDiscreteTimes.resize( aKeyTimes.getLength() );
710 comphelper::sequenceToArray(
711 &aActivityParms.maDiscreteTimes[0],
712 aKeyTimes ); // saves us some temporary vectors
715 // values sequence given?
716 const sal_Int32 nValueLen( xNode->getValues().getLength() );
717 if( nValueLen )
719 // Value list activity
720 // ===================
722 // fake keytimes, if necessary
723 if( !aKeyTimes.hasElements() )
725 // create a dummy vector of key times,
726 // with aValues.getLength equally spaced entries.
727 for( sal_Int32 i=0; i<nValueLen; ++i )
728 aActivityParms.maDiscreteTimes.push_back( double(i)/nValueLen );
731 // determine type of animation needed here:
732 // Value list activities are possible with
733 // ContinuousKeyTimeActivityBase and DiscreteActivityBase
734 // specializations
735 const sal_Int16 nCalcMode( xNode->getCalcMode() );
737 switch( nCalcMode )
739 case animations::AnimationCalcMode::DISCRETE:
741 // since DiscreteActivityBase suspends itself
742 // between the frames, create a WakeupEvent for it.
743 aActivityParms.mpWakeupEvent.reset(
744 new WakeupEvent(
745 rParms.mrEventQueue.getTimer(),
746 rParms.mrActivitiesQueue ) );
748 AnimationActivitySharedPtr pActivity(
749 createValueListActivity< DiscreteActivityBase >(
750 xNode->getValues(),
751 aActivityParms,
752 rAnim,
753 rInterpolator,
754 xNode->getAccumulate(),
755 rParms.mpShape,
756 rParms.maSlideBounds ) );
758 // WakeupEvent and DiscreteActivityBase need circular
759 // references to the corresponding other object.
760 aActivityParms.mpWakeupEvent->setActivity( pActivity );
762 return pActivity;
765 default:
766 OSL_FAIL( "createActivity(): unexpected case" );
767 SAL_FALLTHROUGH;
768 case animations::AnimationCalcMode::PACED:
769 case animations::AnimationCalcMode::SPLINE:
770 case animations::AnimationCalcMode::LINEAR:
771 return createValueListActivity< ContinuousKeyTimeActivityBase >(
772 xNode->getValues(),
773 aActivityParms,
774 rAnim,
775 rInterpolator,
776 xNode->getAccumulate(),
777 rParms.mpShape,
778 rParms.maSlideBounds );
781 else
783 // FromToBy activity
784 // =================
786 // determine type of animation needed here:
787 // FromToBy activities are possible with
788 // ContinuousActivityBase and DiscreteActivityBase
789 // specializations
790 const sal_Int16 nCalcMode( xNode->getCalcMode() );
792 switch( nCalcMode )
794 case animations::AnimationCalcMode::DISCRETE:
796 // fake keytimes, if necessary
797 if( !aKeyTimes.hasElements() )
799 // create a dummy vector of 2 key times
800 const ::std::size_t nLen( 2 );
801 for( ::std::size_t i=0; i<nLen; ++i )
802 aActivityParms.maDiscreteTimes.push_back( double(i)/nLen );
805 // since DiscreteActivityBase suspends itself
806 // between the frames, create a WakeupEvent for it.
807 aActivityParms.mpWakeupEvent.reset(
808 new WakeupEvent(
809 rParms.mrEventQueue.getTimer(),
810 rParms.mrActivitiesQueue ) );
812 AnimationActivitySharedPtr pActivity(
813 createFromToByActivity< DiscreteActivityBase >(
814 xNode->getFrom(),
815 xNode->getTo(),
816 xNode->getBy(),
817 aActivityParms,
818 rAnim,
819 rInterpolator,
820 xNode->getAccumulate(),
821 rParms.mpShape,
822 rParms.maSlideBounds ) );
824 // WakeupEvent and DiscreteActivityBase need circular
825 // references to the corresponding other object.
826 aActivityParms.mpWakeupEvent->setActivity( pActivity );
828 return pActivity;
831 default:
832 OSL_FAIL( "createActivity(): unexpected case" );
833 SAL_FALLTHROUGH;
834 case animations::AnimationCalcMode::PACED:
835 case animations::AnimationCalcMode::SPLINE:
836 case animations::AnimationCalcMode::LINEAR:
837 return createFromToByActivity< ContinuousActivityBase >(
838 xNode->getFrom(),
839 xNode->getTo(),
840 xNode->getBy(),
841 aActivityParms,
842 rAnim,
843 rInterpolator,
844 xNode->getAccumulate(),
845 rParms.mpShape,
846 rParms.maSlideBounds );
851 /** Simple activity for ActivitiesFactory::createSimpleActivity
853 @tpl Direction
854 Determines direction of value generator. A 1 yields a
855 forward direction, starting with 0.0 and ending with
856 1.0. A 0 yields a backward direction, starting with
857 1.0 and ending with 0.0
859 template<int Direction>
860 class SimpleActivity : public ContinuousActivityBase
862 public:
863 /** Create SimpleActivity.
865 @param rParms
866 Standard Activity parameter struct
868 SimpleActivity( const ActivityParameters& rParms,
869 const NumberAnimationSharedPtr& rAnim ) :
870 ContinuousActivityBase( rParms ),
871 mpAnim( rAnim )
873 ENSURE_OR_THROW( mpAnim, "Invalid animation object" );
876 virtual void startAnimation() override
878 if (this->isDisposed() || !mpAnim)
879 return;
880 ContinuousActivityBase::startAnimation();
882 // start animation
883 mpAnim->start( getShape(),
884 getShapeAttributeLayer() );
887 virtual void endAnimation() override
889 // end animation
890 if (mpAnim)
891 mpAnim->end();
894 using SimpleContinuousActivityBase::perform;
896 /// perform override for ContinuousActivityBase
897 virtual void perform( double nModifiedTime, sal_uInt32 ) const override
899 if (this->isDisposed() || !mpAnim)
900 return;
901 // no cumulation, simple [0,1] range
902 (*mpAnim)( 1.0 - Direction + nModifiedTime*(2.0*Direction - 1.0) );
905 virtual void performEnd() override
907 // xxx todo: review
908 if (mpAnim)
909 (*mpAnim)( 1.0*Direction );
912 /// Disposable:
913 virtual void dispose() override
915 mpAnim.reset();
916 ContinuousActivityBase::dispose();
919 private:
920 NumberAnimationSharedPtr mpAnim;
923 } // anon namespace
926 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
927 const CommonParameters& rParms,
928 const NumberAnimationSharedPtr& rAnim,
929 const uno::Reference< animations::XAnimate >& xNode )
931 // forward to appropriate template instantiation
932 return createActivity( rParms, xNode, rAnim );
935 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
936 const CommonParameters& rParms,
937 const EnumAnimationSharedPtr& rAnim,
938 const uno::Reference< animations::XAnimate >& xNode )
940 // forward to appropriate template instantiation
941 return createActivity( rParms, xNode, rAnim );
944 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
945 const CommonParameters& rParms,
946 const ColorAnimationSharedPtr& rAnim,
947 const uno::Reference< animations::XAnimate >& xNode )
949 // forward to appropriate template instantiation
950 return createActivity( rParms, xNode, rAnim );
953 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
954 const CommonParameters& rParms,
955 const HSLColorAnimationSharedPtr& rAnim,
956 const uno::Reference< animations::XAnimateColor >& xNode )
958 // forward to appropriate template instantiation
959 return createActivity( rParms,
960 uno::Reference< animations::XAnimate >(
961 xNode, uno::UNO_QUERY_THROW ),
962 rAnim,
963 // Direction==true means clockwise in SMIL API
964 Interpolator< HSLColor >( !xNode->getDirection() ) );
967 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
968 const CommonParameters& rParms,
969 const PairAnimationSharedPtr& rAnim,
970 const uno::Reference< animations::XAnimate >& xNode )
972 // forward to appropriate template instantiation
973 return createActivity( rParms, xNode, rAnim );
976 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
977 const CommonParameters& rParms,
978 const StringAnimationSharedPtr& rAnim,
979 const uno::Reference< animations::XAnimate >& xNode )
981 // forward to appropriate template instantiation
982 return createActivity( rParms, xNode, rAnim );
985 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
986 const CommonParameters& rParms,
987 const BoolAnimationSharedPtr& rAnim,
988 const uno::Reference< animations::XAnimate >& xNode )
990 // forward to appropriate template instantiation
991 return createActivity( rParms, xNode, rAnim );
994 AnimationActivitySharedPtr ActivitiesFactory::createSimpleActivity(
995 const CommonParameters& rParms,
996 const NumberAnimationSharedPtr& rAnim,
997 bool bDirectionForward )
999 ActivityParameters aActivityParms( rParms.mpEndEvent,
1000 rParms.mrEventQueue,
1001 rParms.mrActivitiesQueue,
1002 rParms.mnMinDuration,
1003 rParms.maRepeats,
1004 rParms.mnAcceleration,
1005 rParms.mnDeceleration,
1006 rParms.mnMinNumberOfFrames,
1007 rParms.mbAutoReverse );
1009 if( bDirectionForward )
1010 return AnimationActivitySharedPtr(
1011 new SimpleActivity<1>( aActivityParms, rAnim ) );
1012 else
1013 return AnimationActivitySharedPtr(
1014 new SimpleActivity<0>( aActivityParms, rAnim ) );
1017 } // namespace internal
1018 } // namespace presentation
1020 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */