Use o3tl::convert in Math
[LibreOffice.git] / slideshow / source / engine / activities / activitiesfactory.cxx
blob2dadfea49e1c1b1f0ac773af19b92b96b4e58d36
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 <slideshowexceptions.hxx>
28 #include <smilfunctionparser.hxx>
29 #include "accumulation.hxx"
30 #include "activityparameters.hxx"
31 #include "interpolation.hxx"
32 #include <tools.hxx>
33 #include "simplecontinuousactivitybase.hxx"
34 #include "discreteactivitybase.hxx"
35 #include "continuousactivitybase.hxx"
36 #include "continuouskeytimeactivitybase.hxx"
38 #include <optional>
40 #include <memory>
41 #include <vector>
42 #include <algorithm>
44 using namespace com::sun::star;
46 namespace slideshow::internal {
48 namespace {
50 /** Traits template, to take formula application only for ValueType = double
52 template<typename ValueType> struct FormulaTraits
54 static ValueType getPresentationValue(
55 const ValueType& rVal, const std::shared_ptr<ExpressionNode>& )
57 return rVal;
61 /// Specialization for ValueType = double
62 template<> struct FormulaTraits<double>
64 static double getPresentationValue(
65 double const& rVal, std::shared_ptr<ExpressionNode> const& rFormula )
67 return rFormula ? (*rFormula)(rVal) : rVal;
71 // Various ActivityBase specializations for different animator types
72 // =================================================================
74 /** FromToBy handler
76 Provides the Activity specializations for FromToBy
77 animations (e.g. those without a values list).
79 This template makes heavy use of SFINAE, only one of
80 the perform*() methods will compile for each of the
81 base classes.
83 Note that we omit the virtual keyword on the perform()
84 overrides on purpose; those that actually do override
85 baseclass virtual methods inherit the property, and
86 the others won't increase our vtable. What's more,
87 having all perform() method in the vtable actually
88 creates POIs for them, which breaks the whole SFINAE
89 concept (IOW, this template won't compile any longer).
91 @tpl BaseType
92 Base class to use for this activity. Only
93 ContinuousActivityBase and DiscreteActivityBase are
94 supported here.
96 @tpl AnimationType
97 Type of the Animation to call.
99 template<class BaseType, typename AnimationType>
100 class FromToByActivity : public BaseType
102 public:
103 typedef typename AnimationType::ValueType ValueType;
104 typedef std::optional<ValueType> OptionalValueType;
106 private:
107 // some compilers don't inline whose definition they haven't
108 // seen before the call site...
109 ValueType getPresentationValue( const ValueType& rVal ) const
111 return FormulaTraits<ValueType>::getPresentationValue( rVal, mpFormula);
114 public:
115 /** Create FromToByActivity.
117 @param rFrom
118 From this value, the animation starts
120 @param rTo
121 With this value, the animation ends
123 @param rBy
124 With this value, the animation increments the start value
126 @param rParms
127 Standard Activity parameter struct
129 @param rAnim
130 Shared ptr to AnimationType
132 @param rInterpolator
133 Interpolator object to be used for lerping between
134 start and end value (need to be passed, since it
135 might contain state, e.g. interpolation direction
136 for HSL color space).
138 @param bCumulative
139 Whether repeated animations should cumulate the
140 value, or start fresh each time.
142 FromToByActivity(
143 const OptionalValueType& rFrom,
144 const OptionalValueType& rTo,
145 const OptionalValueType& rBy,
146 const ActivityParameters& rParms,
147 const ::std::shared_ptr< AnimationType >& rAnim,
148 const Interpolator< ValueType >& rInterpolator,
149 bool bCumulative )
150 : BaseType( rParms ),
151 maFrom( rFrom ),
152 maTo( rTo ),
153 maBy( rBy ),
154 mpFormula( rParms.mpFormula ),
155 maStartValue(),
156 maEndValue(),
157 maPreviousValue(),
158 maStartInterpolationValue(),
159 mnIteration( 0 ),
160 mpAnim( rAnim ),
161 maInterpolator( rInterpolator ),
162 mbDynamicStartValue( false ),
163 mbCumulative( bCumulative )
165 ENSURE_OR_THROW( mpAnim, "Invalid animation object" );
167 ENSURE_OR_THROW(
168 rTo || rBy,
169 "From and one of To or By, or To or By alone must be valid" );
172 virtual void startAnimation()
174 if (this->isDisposed() || !mpAnim)
175 return;
176 BaseType::startAnimation();
178 // start animation
179 mpAnim->start( BaseType::getShape(),
180 BaseType::getShapeAttributeLayer() );
182 // setup start and end value. Determine animation
183 // start value only when animation actually
184 // started up (this order is part of the Animation
185 // interface contract)
186 const ValueType aAnimationStartValue( mpAnim->getUnderlyingValue() );
188 // first of all, determine general type of
189 // animation, by inspecting which of the FromToBy values
190 // are actually valid.
191 // See http://www.w3.org/TR/smil20/animation.html#AnimationNS-FromToBy
192 // for a definition
193 if( maFrom )
195 // From-to or From-by animation. According to
196 // SMIL spec, the To value takes precedence
197 // over the By value, if both are specified
198 if( maTo )
200 // From-To animation
201 maStartValue = *maFrom;
202 maEndValue = *maTo;
204 else if( maBy )
206 // From-By animation
207 maStartValue = *maFrom;
208 maEndValue = maStartValue + *maBy;
210 maStartInterpolationValue = maStartValue;
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 std::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 = aTmpValue;
407 if( rToAny.hasValue() )
409 ENSURE_OR_THROW(
410 extractValue( aTmpValue, rToAny, rShape, rSlideBounds ),
411 "createFromToByActivity(): Could not extract to value" );
412 aTo = aTmpValue;
414 if( rByAny.hasValue() )
416 ENSURE_OR_THROW(
417 extractValue( aTmpValue, rByAny, rShape, rSlideBounds ),
418 "createFromToByActivity(): Could not extract by value" );
419 aBy = aTmpValue;
422 return std::make_shared<FromToByActivity<BaseType, AnimationType>>(
423 aFrom,
424 aTo,
425 aBy,
426 rParms,
427 rAnim,
428 rInterpolator,
429 bCumulative );
432 /* The following table shows which animator combines with
433 which Activity type:
435 NumberAnimator: all
436 PairAnimation: all
437 ColorAnimation: all
438 StringAnimation: DiscreteActivityBase
439 BoolAnimation: DiscreteActivityBase
442 /** Values handler
444 Provides the Activity specializations for value lists
445 animations.
447 This template makes heavy use of SFINAE, only one of
448 the perform*() methods will compile for each of the
449 base classes.
451 Note that we omit the virtual keyword on the perform()
452 overrides on purpose; those that actually do override
453 baseclass virtual methods inherit the property, and
454 the others won't increase our vtable. What's more,
455 having all perform() method in the vtable actually
456 creates POIs for them, which breaks the whole SFINAE
457 concept (IOW, this template won't compile any longer).
459 @tpl BaseType
460 Base class to use for this activity. Only
461 ContinuousKeyTimeActivityBase and DiscreteActivityBase
462 are supported here. For values animation without key
463 times, the client must emulate key times by providing
464 a vector of equally spaced values between 0 and 1,
465 with the same number of entries as the values vector.
467 @tpl AnimationType
468 Type of the Animation to call.
470 template<class BaseType, typename AnimationType>
471 class ValuesActivity : public BaseType
473 public:
474 typedef typename AnimationType::ValueType ValueType;
475 typedef std::vector<ValueType> ValueVectorType;
477 private:
478 // some compilers don't inline methods whose definition they haven't
479 // seen before the call site...
480 ValueType getPresentationValue( const ValueType& rVal ) const
482 return FormulaTraits<ValueType>::getPresentationValue(
483 rVal, mpFormula );
486 public:
487 /** Create ValuesActivity.
489 @param rValues
490 Value vector to cycle animation through
492 @param rParms
493 Standard Activity parameter struct
495 @param rAnim
496 Shared ptr to AnimationType
498 @param rInterpolator
499 Interpolator object to be used for lerping between
500 start and end value (need to be passed, since it
501 might contain state, e.g. interpolation direction
502 for HSL color space).
504 @param bCumulative
505 Whether repeated animations should cumulate the
506 value, or start afresh each time.
508 ValuesActivity(
509 const ValueVectorType& rValues,
510 const ActivityParameters& rParms,
511 const std::shared_ptr<AnimationType>& rAnim,
512 const Interpolator< ValueType >& rInterpolator,
513 bool bCumulative )
514 : BaseType( rParms ),
515 maValues( rValues ),
516 mpFormula( rParms.mpFormula ),
517 mpAnim( rAnim ),
518 maInterpolator( rInterpolator ),
519 mbCumulative( bCumulative )
521 ENSURE_OR_THROW( mpAnim, "Invalid animation object" );
522 ENSURE_OR_THROW( !rValues.empty(), "Empty value vector" );
525 virtual void startAnimation()
527 if (this->isDisposed() || !mpAnim)
528 return;
529 BaseType::startAnimation();
531 // start animation
532 mpAnim->start( BaseType::getShape(),
533 BaseType::getShapeAttributeLayer() );
536 virtual void endAnimation()
538 // end animation
539 if (mpAnim)
540 mpAnim->end();
543 /// perform override for ContinuousKeyTimeActivityBase base
544 void perform( sal_uInt32 nIndex,
545 double nFractionalIndex,
546 sal_uInt32 nRepeatCount ) const
548 if (this->isDisposed() || !mpAnim)
549 return;
550 ENSURE_OR_THROW( nIndex+1 < maValues.size(),
551 "ValuesActivity::perform(): index out of range" );
553 // interpolate between nIndex and nIndex+1 values
554 (*mpAnim)(
555 getPresentationValue(
556 accumulate<ValueType>( maValues.back(),
557 mbCumulative ? nRepeatCount : 0,
558 maInterpolator( maValues[ nIndex ],
559 maValues[ nIndex+1 ],
560 nFractionalIndex ) ) ) );
563 using BaseType::perform;
565 /// perform override for DiscreteActivityBase base
566 void perform( sal_uInt32 nFrame, sal_uInt32 nRepeatCount ) const
568 if (this->isDisposed() || !mpAnim)
569 return;
570 ENSURE_OR_THROW( nFrame < maValues.size(),
571 "ValuesActivity::perform(): index out of range" );
573 // this is discrete, thus no lerp here.
574 (*mpAnim)(
575 getPresentationValue(
576 slideshow::internal::accumulate<ValueType>( maValues.back(),
577 mbCumulative ? nRepeatCount : 0,
578 maValues[ nFrame ] ) ) );
581 virtual void performEnd()
583 // xxx todo: good guess
584 if (mpAnim)
585 (*mpAnim)( getPresentationValue( maValues.back() ) );
588 private:
589 ValueVectorType maValues;
591 std::shared_ptr<ExpressionNode> mpFormula;
593 std::shared_ptr<AnimationType> mpAnim;
594 Interpolator< ValueType > maInterpolator;
595 bool mbCumulative;
598 /** Generate Activity corresponding to given Value vector
600 @tpl BaseType
601 BaseType to use for deriving the Activity from
603 @tpl AnimationType
604 Subtype of the Animation object (e.g. NumberAnimation)
606 template<class BaseType, typename AnimationType>
607 AnimationActivitySharedPtr createValueListActivity(
608 const uno::Sequence<uno::Any>& rValues,
609 const ActivityParameters& rParms,
610 const std::shared_ptr<AnimationType>& rAnim,
611 const Interpolator<typename AnimationType::ValueType>& rInterpolator,
612 bool bCumulative,
613 const ShapeSharedPtr& rShape,
614 const ::basegfx::B2DVector& rSlideBounds )
616 typedef typename AnimationType::ValueType ValueType;
617 typedef std::vector<ValueType> ValueVectorType;
619 ValueVectorType aValueVector;
620 aValueVector.reserve( rValues.getLength() );
622 for( const auto& rValue : rValues )
624 ValueType aValue;
625 ENSURE_OR_THROW(
626 extractValue( aValue, rValue, rShape, rSlideBounds ),
627 "createValueListActivity(): Could not extract values" );
628 aValueVector.push_back( aValue );
631 return std::make_shared<ValuesActivity<BaseType, AnimationType>>(
632 aValueVector,
633 rParms,
634 rAnim,
635 rInterpolator,
636 bCumulative );
639 /** Generate Activity for given XAnimate, corresponding to given Value vector
641 @tpl AnimationType
642 Subtype of the Animation object (e.g. NumberAnimation)
644 @param rParms
645 Common activity parameters
647 @param xNode
648 XAnimate node, to retrieve animation values from
650 @param rAnim
651 Actual animation to operate with (gets called with the
652 time-dependent values)
654 @param rInterpolator
655 Interpolator object to be used for lerping between
656 start and end values (need to be passed, since it
657 might contain state, e.g. interpolation direction
658 for HSL color space).
660 template<typename AnimationType>
661 AnimationActivitySharedPtr createActivity(
662 const ActivitiesFactory::CommonParameters& rParms,
663 const uno::Reference< animations::XAnimate >& xNode,
664 const ::std::shared_ptr< AnimationType >& rAnim,
665 const Interpolator< typename AnimationType::ValueType >& rInterpolator
666 = Interpolator< typename AnimationType::ValueType >() )
668 // setup common parameters
669 // =======================
671 ActivityParameters aActivityParms( rParms.mpEndEvent,
672 rParms.mrEventQueue,
673 rParms.mrActivitiesQueue,
674 rParms.mnMinDuration,
675 rParms.maRepeats,
676 rParms.mnAcceleration,
677 rParms.mnDeceleration,
678 rParms.mnMinNumberOfFrames,
679 rParms.mbAutoReverse );
681 // is a formula given?
682 const OUString& rFormulaString( xNode->getFormula() );
683 if( !rFormulaString.isEmpty() )
685 // yep, parse and pass to ActivityParameters
688 aActivityParms.mpFormula =
689 SmilFunctionParser::parseSmilFunction(
690 rFormulaString,
691 calcRelativeShapeBounds(
692 rParms.maSlideBounds,
693 rParms.mpShape->getBounds() ) );
695 catch( ParseError& )
697 // parse error, thus no formula
698 OSL_FAIL( "createActivity(): Error parsing formula string" );
702 // are key times given?
703 const uno::Sequence< double >& aKeyTimes( xNode->getKeyTimes() );
704 if( aKeyTimes.hasElements() )
706 // yes, convert them from Sequence< double >
707 aActivityParms.maDiscreteTimes.resize( aKeyTimes.getLength() );
708 comphelper::sequenceToArray(
709 aActivityParms.maDiscreteTimes.data(),
710 aKeyTimes ); // saves us some temporary vectors
713 // values sequence given?
714 const sal_Int32 nValueLen( xNode->getValues().getLength() );
715 if( nValueLen )
717 // Value list activity
718 // ===================
720 // fake keytimes, if necessary
721 if( !aKeyTimes.hasElements() )
723 // create a dummy vector of key times,
724 // with aValues.getLength equally spaced entries.
725 for( sal_Int32 i=0; i<nValueLen; ++i )
726 aActivityParms.maDiscreteTimes.push_back( double(i)/nValueLen );
729 // determine type of animation needed here:
730 // Value list activities are possible with
731 // ContinuousKeyTimeActivityBase and DiscreteActivityBase
732 // specializations
733 const sal_Int16 nCalcMode( xNode->getCalcMode() );
735 switch( nCalcMode )
737 case animations::AnimationCalcMode::DISCRETE:
739 // since DiscreteActivityBase suspends itself
740 // between the frames, create a WakeupEvent for it.
741 aActivityParms.mpWakeupEvent =
742 std::make_shared<WakeupEvent>(
743 rParms.mrEventQueue.getTimer(),
744 rParms.mrActivitiesQueue );
746 AnimationActivitySharedPtr pActivity(
747 createValueListActivity< DiscreteActivityBase >(
748 xNode->getValues(),
749 aActivityParms,
750 rAnim,
751 rInterpolator,
752 xNode->getAccumulate(),
753 rParms.mpShape,
754 rParms.maSlideBounds ) );
756 // WakeupEvent and DiscreteActivityBase need circular
757 // references to the corresponding other object.
758 aActivityParms.mpWakeupEvent->setActivity( pActivity );
760 return pActivity;
763 default:
764 OSL_FAIL( "createActivity(): unexpected case" );
765 [[fallthrough]];
766 case animations::AnimationCalcMode::PACED:
767 case animations::AnimationCalcMode::SPLINE:
768 case animations::AnimationCalcMode::LINEAR:
769 return createValueListActivity< ContinuousKeyTimeActivityBase >(
770 xNode->getValues(),
771 aActivityParms,
772 rAnim,
773 rInterpolator,
774 xNode->getAccumulate(),
775 rParms.mpShape,
776 rParms.maSlideBounds );
779 else
781 // FromToBy activity
782 // =================
784 // determine type of animation needed here:
785 // FromToBy activities are possible with
786 // ContinuousActivityBase and DiscreteActivityBase
787 // specializations
788 const sal_Int16 nCalcMode( xNode->getCalcMode() );
790 switch( nCalcMode )
792 case animations::AnimationCalcMode::DISCRETE:
794 // fake keytimes, if necessary
795 if( !aKeyTimes.hasElements() )
797 // create a dummy vector of 2 key times
798 const ::std::size_t nLen( 2 );
799 for( ::std::size_t i=0; i<nLen; ++i )
800 aActivityParms.maDiscreteTimes.push_back( double(i)/nLen );
803 // since DiscreteActivityBase suspends itself
804 // between the frames, create a WakeupEvent for it.
805 aActivityParms.mpWakeupEvent =
806 std::make_shared<WakeupEvent>(
807 rParms.mrEventQueue.getTimer(),
808 rParms.mrActivitiesQueue );
810 AnimationActivitySharedPtr pActivity(
811 createFromToByActivity< DiscreteActivityBase >(
812 xNode->getFrom(),
813 xNode->getTo(),
814 xNode->getBy(),
815 aActivityParms,
816 rAnim,
817 rInterpolator,
818 xNode->getAccumulate(),
819 rParms.mpShape,
820 rParms.maSlideBounds ) );
822 // WakeupEvent and DiscreteActivityBase need circular
823 // references to the corresponding other object.
824 aActivityParms.mpWakeupEvent->setActivity( pActivity );
826 return pActivity;
829 default:
830 OSL_FAIL( "createActivity(): unexpected case" );
831 [[fallthrough]];
832 case animations::AnimationCalcMode::PACED:
833 case animations::AnimationCalcMode::SPLINE:
834 case animations::AnimationCalcMode::LINEAR:
835 return createFromToByActivity< ContinuousActivityBase >(
836 xNode->getFrom(),
837 xNode->getTo(),
838 xNode->getBy(),
839 aActivityParms,
840 rAnim,
841 rInterpolator,
842 xNode->getAccumulate(),
843 rParms.mpShape,
844 rParms.maSlideBounds );
849 /** Simple activity for ActivitiesFactory::createSimpleActivity
851 @tpl Direction
852 Determines direction of value generator. A 1 yields a
853 forward direction, starting with 0.0 and ending with
854 1.0. A 0 yields a backward direction, starting with
855 1.0 and ending with 0.0
857 template<int Direction>
858 class SimpleActivity : public ContinuousActivityBase
860 public:
861 /** Create SimpleActivity.
863 @param rParms
864 Standard Activity parameter struct
866 SimpleActivity( const ActivityParameters& rParms,
867 const NumberAnimationSharedPtr& rAnim ) :
868 ContinuousActivityBase( rParms ),
869 mpAnim( rAnim )
871 ENSURE_OR_THROW( mpAnim, "Invalid animation object" );
874 virtual void startAnimation() override
876 if (this->isDisposed() || !mpAnim)
877 return;
878 ContinuousActivityBase::startAnimation();
880 // start animation
881 mpAnim->start( getShape(),
882 getShapeAttributeLayer() );
885 virtual void endAnimation() override
887 // end animation
888 if (mpAnim)
889 mpAnim->end();
892 using SimpleContinuousActivityBase::perform;
894 /// perform override for ContinuousActivityBase
895 virtual void perform( double nModifiedTime, sal_uInt32 ) const override
897 if (this->isDisposed() || !mpAnim)
898 return;
899 // no cumulation, simple [0,1] range
900 (*mpAnim)( 1.0 - Direction + nModifiedTime*(2.0*Direction - 1.0) );
903 virtual void performEnd() override
905 // xxx todo: review
906 if (mpAnim)
907 (*mpAnim)( 1.0*Direction );
910 /// Disposable:
911 virtual void dispose() override
913 mpAnim.reset();
914 ContinuousActivityBase::dispose();
917 private:
918 NumberAnimationSharedPtr mpAnim;
921 } // anon namespace
924 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
925 const CommonParameters& rParms,
926 const NumberAnimationSharedPtr& rAnim,
927 const uno::Reference< animations::XAnimate >& xNode )
929 // forward to appropriate template instantiation
930 return createActivity( rParms, xNode, rAnim );
933 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
934 const CommonParameters& rParms,
935 const EnumAnimationSharedPtr& rAnim,
936 const uno::Reference< animations::XAnimate >& xNode )
938 // forward to appropriate template instantiation
939 return createActivity( rParms, xNode, rAnim );
942 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
943 const CommonParameters& rParms,
944 const ColorAnimationSharedPtr& rAnim,
945 const uno::Reference< animations::XAnimate >& xNode )
947 // forward to appropriate template instantiation
948 return createActivity( rParms, xNode, rAnim );
951 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
952 const CommonParameters& rParms,
953 const HSLColorAnimationSharedPtr& rAnim,
954 const uno::Reference< animations::XAnimateColor >& xNode )
956 // forward to appropriate template instantiation
957 return createActivity( rParms,
958 uno::Reference< animations::XAnimate >(
959 xNode, uno::UNO_QUERY_THROW ),
960 rAnim,
961 // Direction==true means clockwise in SMIL API
962 Interpolator< HSLColor >( !xNode->getDirection() ) );
965 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
966 const CommonParameters& rParms,
967 const PairAnimationSharedPtr& rAnim,
968 const uno::Reference< animations::XAnimate >& xNode )
970 // forward to appropriate template instantiation
971 return createActivity( rParms, xNode, rAnim );
974 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
975 const CommonParameters& rParms,
976 const StringAnimationSharedPtr& rAnim,
977 const uno::Reference< animations::XAnimate >& xNode )
979 // forward to appropriate template instantiation
980 return createActivity( rParms, xNode, rAnim );
983 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
984 const CommonParameters& rParms,
985 const BoolAnimationSharedPtr& rAnim,
986 const uno::Reference< animations::XAnimate >& xNode )
988 // forward to appropriate template instantiation
989 return createActivity( rParms, xNode, rAnim );
992 AnimationActivitySharedPtr ActivitiesFactory::createSimpleActivity(
993 const CommonParameters& rParms,
994 const NumberAnimationSharedPtr& rAnim,
995 bool bDirectionForward )
997 ActivityParameters aActivityParms( rParms.mpEndEvent,
998 rParms.mrEventQueue,
999 rParms.mrActivitiesQueue,
1000 rParms.mnMinDuration,
1001 rParms.maRepeats,
1002 rParms.mnAcceleration,
1003 rParms.mnDeceleration,
1004 rParms.mnMinNumberOfFrames,
1005 rParms.mbAutoReverse );
1007 if( bDirectionForward )
1008 return std::make_shared<SimpleActivity<1>>( aActivityParms, rAnim );
1009 else
1010 return std::make_shared<SimpleActivity<0>>( aActivityParms, rAnim );
1013 } // namespace presentation
1015 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */