android: Update app-specific/MIME type icons
[LibreOffice.git] / slideshow / source / engine / activities / activitiesfactory.cxx
blob90388e84bc9ffc718b973b1d5d8fb56c9a63576a
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 <comphelper/diagnose_ex.hxx>
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 <utility>
42 #include <vector>
43 #include <algorithm>
45 using namespace com::sun::star;
47 namespace slideshow::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 std::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 OptionalValueType aFrom,
145 const OptionalValueType& rTo,
146 const OptionalValueType& rBy,
147 const ActivityParameters& rParms,
148 ::std::shared_ptr< AnimationType > xAnim,
149 const Interpolator< ValueType >& rInterpolator,
150 bool bCumulative )
151 : BaseType( rParms ),
152 maFrom(std::move( aFrom )),
153 maTo( rTo ),
154 maBy( rBy ),
155 mpFormula( rParms.mpFormula ),
156 maStartValue(),
157 maEndValue(),
158 maPreviousValue(),
159 maStartInterpolationValue(),
160 mnIteration( 0 ),
161 mpAnim(std::move( xAnim )),
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;
211 maStartInterpolationValue = maStartValue;
213 else
215 maStartValue = aAnimationStartValue;
216 maStartInterpolationValue = maStartValue;
218 // By or To animation. According to SMIL spec,
219 // the To value takes precedence over the By
220 // value, if both are specified
221 if( maTo )
223 // To animation
225 // According to the SMIL spec
226 // (http://www.w3.org/TR/smil20/animation.html#animationNS-ToAnimation),
227 // the to animation interpolates between
228 // the _running_ underlying value and the to value (as the end value)
229 mbDynamicStartValue = true;
230 maPreviousValue = maStartValue;
231 maEndValue = *maTo;
233 else if( maBy )
235 // By animation
236 maStartValue = aAnimationStartValue;
237 maEndValue = maStartValue + *maBy;
242 virtual void endAnimation()
244 // end animation
245 if (mpAnim)
246 mpAnim->end();
249 /// perform override for ContinuousActivityBase
250 void perform( double nModifiedTime, sal_uInt32 nRepeatCount ) const
252 if (this->isDisposed() || !mpAnim)
253 return;
255 // According to SMIL 3.0 spec 'to' animation if no other (lower priority)
256 // animations are active or frozen then a simple interpolation is performed.
257 // That is, the start interpolation value is constant while the animation
258 // is running, and is equal to the underlying value retrieved when
259 // the animation start.
260 // However if another animation is manipulating the underlying value,
261 // the 'to' animation will initially add to the effect of the lower priority
262 // animation, and increasingly dominate it as it nears the end of the
263 // simple duration, eventually overriding it completely.
264 // That is, each time the underlying value is changed between two
265 // computations of the animation function the new underlying value is used
266 // as start value for the interpolation.
267 // See:
268 // http://www.w3.org/TR/SMIL3/smil-animation.html#animationNS-ToAnimation
269 // (Figure 6 - Effect of Additive to animation example)
270 // Moreover when a 'to' animation is repeated, at each new iteration
271 // the start interpolation value is reset to the underlying value
272 // of the animated property when the animation started,
273 // as it is shown in the example provided by the SMIL 3.0 spec.
274 // This is exactly as Firefox performs SVG 'to' animations.
275 if( mbDynamicStartValue )
277 if( mnIteration != nRepeatCount )
279 mnIteration = nRepeatCount;
280 maStartInterpolationValue = maStartValue;
282 else
284 ValueType aActualValue = mpAnim->getUnderlyingValue();
285 if( aActualValue != maPreviousValue )
286 maStartInterpolationValue = aActualValue;
290 ValueType aValue = maInterpolator( maStartInterpolationValue,
291 maEndValue, nModifiedTime );
293 // According to the SMIL spec:
294 // Because 'to' animation is defined in terms of absolute values of
295 // the target attribute, cumulative animation is not defined.
296 if( mbCumulative && !mbDynamicStartValue )
298 // aValue = this.aEndValue * nRepeatCount + aValue;
299 aValue = accumulate( maEndValue, nRepeatCount, aValue );
302 (*mpAnim)( getPresentationValue( aValue ) );
304 if( mbDynamicStartValue )
306 maPreviousValue = mpAnim->getUnderlyingValue();
311 using BaseType::perform;
313 /// perform override for DiscreteActivityBase base
314 void perform( sal_uInt32 nFrame, sal_uInt32 nRepeatCount ) const
316 if (this->isDisposed() || !mpAnim)
317 return;
318 (*mpAnim)(
319 getPresentationValue(
320 accumulate( maEndValue, mbCumulative ? nRepeatCount : 0,
321 lerp( maInterpolator,
322 (mbDynamicStartValue
323 ? mpAnim->getUnderlyingValue()
324 : maStartValue),
325 maEndValue,
326 nFrame,
327 BaseType::getNumberOfKeyTimes() ) ) ) );
330 using BaseType::isAutoReverse;
332 virtual void performEnd()
334 // xxx todo: good guess
335 if (mpAnim)
337 if (isAutoReverse())
338 (*mpAnim)( getPresentationValue( maStartValue ) );
339 else
340 (*mpAnim)( getPresentationValue( maEndValue ) );
344 /// Disposable:
345 virtual void dispose()
347 mpAnim.reset();
348 BaseType::dispose();
351 private:
352 const OptionalValueType maFrom;
353 const OptionalValueType maTo;
354 const OptionalValueType maBy;
356 std::shared_ptr<ExpressionNode> mpFormula;
358 ValueType maStartValue;
359 ValueType maEndValue;
361 mutable ValueType maPreviousValue;
362 mutable ValueType maStartInterpolationValue;
363 mutable sal_uInt32 mnIteration;
365 ::std::shared_ptr< AnimationType > mpAnim;
366 Interpolator< ValueType > maInterpolator;
367 bool mbDynamicStartValue;
368 bool mbCumulative;
372 /** Generate Activity corresponding to given FromToBy values
374 @tpl BaseType
375 BaseType to use for deriving the Activity from
377 @tpl AnimationType
378 Subtype of the Animation object (e.g. NumberAnimation)
380 template<class BaseType, typename AnimationType>
381 AnimationActivitySharedPtr createFromToByActivity(
382 const uno::Any& rFromAny,
383 const uno::Any& rToAny,
384 const uno::Any& rByAny,
385 const ActivityParameters& rParms,
386 const ::std::shared_ptr< AnimationType >& rAnim,
387 const Interpolator< typename AnimationType::ValueType >& rInterpolator,
388 bool bCumulative,
389 const ShapeSharedPtr& rShape,
390 const ::basegfx::B2DVector& rSlideBounds )
392 typedef typename AnimationType::ValueType ValueType;
393 typedef std::optional<ValueType> OptionalValueType;
395 OptionalValueType aFrom;
396 OptionalValueType aTo;
397 OptionalValueType aBy;
399 ValueType aTmpValue;
401 if( rFromAny.hasValue() )
403 ENSURE_OR_THROW(
404 extractValue( aTmpValue, rFromAny, rShape, rSlideBounds ),
405 "createFromToByActivity(): Could not extract from value" );
406 aFrom = aTmpValue;
408 if( rToAny.hasValue() )
410 ENSURE_OR_THROW(
411 extractValue( aTmpValue, rToAny, rShape, rSlideBounds ),
412 "createFromToByActivity(): Could not extract to value" );
413 aTo = aTmpValue;
415 if( rByAny.hasValue() )
417 ENSURE_OR_THROW(
418 extractValue( aTmpValue, rByAny, rShape, rSlideBounds ),
419 "createFromToByActivity(): Could not extract by value" );
420 aBy = aTmpValue;
423 return std::make_shared<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 std::shared_ptr<AnimationType> xAnim,
513 const Interpolator< ValueType >& rInterpolator,
514 bool bCumulative )
515 : BaseType( rParms ),
516 maValues( rValues ),
517 mpFormula( rParms.mpFormula ),
518 mpAnim(std::move( xAnim )),
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 slideshow::internal::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( const auto& rValue : rValues )
625 ValueType aValue;
626 ENSURE_OR_THROW(
627 extractValue( aValue, rValue, rShape, rSlideBounds ),
628 "createValueListActivity(): Could not extract values" );
629 aValueVector.push_back( aValue );
632 return std::make_shared<ValuesActivity<BaseType, AnimationType>>(
633 aValueVector,
634 rParms,
635 rAnim,
636 rInterpolator,
637 bCumulative );
640 /** Generate Activity for given XAnimate, corresponding to given Value vector
642 @tpl AnimationType
643 Subtype of the Animation object (e.g. NumberAnimation)
645 @param rParms
646 Common activity parameters
648 @param xNode
649 XAnimate node, to retrieve animation values from
651 @param rAnim
652 Actual animation to operate with (gets called with the
653 time-dependent values)
655 @param rInterpolator
656 Interpolator object to be used for lerping between
657 start and end values (need to be passed, since it
658 might contain state, e.g. interpolation direction
659 for HSL color space).
661 template<typename AnimationType>
662 AnimationActivitySharedPtr createActivity(
663 const ActivitiesFactory::CommonParameters& rParms,
664 const uno::Reference< animations::XAnimate >& xNode,
665 const ::std::shared_ptr< AnimationType >& rAnim,
666 const Interpolator< typename AnimationType::ValueType >& rInterpolator
667 = Interpolator< typename AnimationType::ValueType >() )
669 // setup common parameters
670 // =======================
672 ActivityParameters aActivityParms( rParms.mpEndEvent,
673 rParms.mrEventQueue,
674 rParms.mrActivitiesQueue,
675 rParms.mnMinDuration,
676 rParms.maRepeats,
677 rParms.mnAcceleration,
678 rParms.mnDeceleration,
679 rParms.mnMinNumberOfFrames,
680 rParms.mbAutoReverse );
682 // is a formula given?
683 const OUString& rFormulaString( xNode->getFormula() );
684 if( !rFormulaString.isEmpty() )
686 // yep, parse and pass to ActivityParameters
689 aActivityParms.mpFormula =
690 SmilFunctionParser::parseSmilFunction(
691 rFormulaString,
692 calcRelativeShapeBounds(
693 rParms.maSlideBounds,
694 rParms.mpShape->getBounds() ) );
696 catch( ParseError& )
698 // parse error, thus no formula
699 OSL_FAIL( "createActivity(): Error parsing formula string" );
703 // are key times given?
704 const uno::Sequence< double >& aKeyTimes( xNode->getKeyTimes() );
705 if( aKeyTimes.hasElements() )
707 // yes, convert them from Sequence< double >
708 aActivityParms.maDiscreteTimes.resize( aKeyTimes.getLength() );
709 comphelper::sequenceToArray(
710 aActivityParms.maDiscreteTimes.data(),
711 aKeyTimes ); // saves us some temporary vectors
714 // values sequence given?
715 const sal_Int32 nValueLen( xNode->getValues().getLength() );
716 if( nValueLen )
718 // Value list activity
719 // ===================
721 // fake keytimes, if necessary
722 if( !aKeyTimes.hasElements() )
724 // create a dummy vector of key times,
725 // with aValues.getLength equally spaced entries.
726 for( sal_Int32 i=0; i<nValueLen; ++i )
727 aActivityParms.maDiscreteTimes.push_back( double(i)/nValueLen );
730 // determine type of animation needed here:
731 // Value list activities are possible with
732 // ContinuousKeyTimeActivityBase and DiscreteActivityBase
733 // specializations
734 const sal_Int16 nCalcMode( xNode->getCalcMode() );
736 switch( nCalcMode )
738 case animations::AnimationCalcMode::DISCRETE:
740 // since DiscreteActivityBase suspends itself
741 // between the frames, create a WakeupEvent for it.
742 aActivityParms.mpWakeupEvent =
743 std::make_shared<WakeupEvent>(
744 rParms.mrEventQueue.getTimer(),
745 rParms.mrActivitiesQueue );
747 AnimationActivitySharedPtr pActivity(
748 createValueListActivity< DiscreteActivityBase >(
749 xNode->getValues(),
750 aActivityParms,
751 rAnim,
752 rInterpolator,
753 xNode->getAccumulate(),
754 rParms.mpShape,
755 rParms.maSlideBounds ) );
757 // WakeupEvent and DiscreteActivityBase need circular
758 // references to the corresponding other object.
759 aActivityParms.mpWakeupEvent->setActivity( pActivity );
761 return pActivity;
764 default:
765 OSL_FAIL( "createActivity(): unexpected case" );
766 [[fallthrough]];
767 case animations::AnimationCalcMode::PACED:
768 case animations::AnimationCalcMode::SPLINE:
769 case animations::AnimationCalcMode::LINEAR:
770 return createValueListActivity< ContinuousKeyTimeActivityBase >(
771 xNode->getValues(),
772 aActivityParms,
773 rAnim,
774 rInterpolator,
775 xNode->getAccumulate(),
776 rParms.mpShape,
777 rParms.maSlideBounds );
780 else
782 // FromToBy activity
783 // =================
785 // determine type of animation needed here:
786 // FromToBy activities are possible with
787 // ContinuousActivityBase and DiscreteActivityBase
788 // specializations
789 const sal_Int16 nCalcMode( xNode->getCalcMode() );
791 switch( nCalcMode )
793 case animations::AnimationCalcMode::DISCRETE:
795 // fake keytimes, if necessary
796 if( !aKeyTimes.hasElements() )
798 // create a dummy vector of 2 key times
799 const ::std::size_t nLen( 2 );
800 for( ::std::size_t i=0; i<nLen; ++i )
801 aActivityParms.maDiscreteTimes.push_back( double(i)/nLen );
804 // since DiscreteActivityBase suspends itself
805 // between the frames, create a WakeupEvent for it.
806 aActivityParms.mpWakeupEvent =
807 std::make_shared<WakeupEvent>(
808 rParms.mrEventQueue.getTimer(),
809 rParms.mrActivitiesQueue );
811 AnimationActivitySharedPtr pActivity(
812 createFromToByActivity< DiscreteActivityBase >(
813 xNode->getFrom(),
814 xNode->getTo(),
815 xNode->getBy(),
816 aActivityParms,
817 rAnim,
818 rInterpolator,
819 xNode->getAccumulate(),
820 rParms.mpShape,
821 rParms.maSlideBounds ) );
823 // WakeupEvent and DiscreteActivityBase need circular
824 // references to the corresponding other object.
825 aActivityParms.mpWakeupEvent->setActivity( pActivity );
827 return pActivity;
830 default:
831 OSL_FAIL( "createActivity(): unexpected case" );
832 [[fallthrough]];
833 case animations::AnimationCalcMode::PACED:
834 case animations::AnimationCalcMode::SPLINE:
835 case animations::AnimationCalcMode::LINEAR:
836 return createFromToByActivity< ContinuousActivityBase >(
837 xNode->getFrom(),
838 xNode->getTo(),
839 xNode->getBy(),
840 aActivityParms,
841 rAnim,
842 rInterpolator,
843 xNode->getAccumulate(),
844 rParms.mpShape,
845 rParms.maSlideBounds );
850 /** Simple activity for ActivitiesFactory::createSimpleActivity
852 @tpl Direction
853 Determines direction of value generator. A 1 yields a
854 forward direction, starting with 0.0 and ending with
855 1.0. A 0 yields a backward direction, starting with
856 1.0 and ending with 0.0
858 template<int Direction>
859 class SimpleActivity : public ContinuousActivityBase
861 public:
862 /** Create SimpleActivity.
864 @param rParms
865 Standard Activity parameter struct
867 SimpleActivity( const ActivityParameters& rParms,
868 NumberAnimationSharedPtr xAnim ) :
869 ContinuousActivityBase( rParms ),
870 mpAnim(std::move( xAnim ))
872 ENSURE_OR_THROW( mpAnim, "Invalid animation object" );
875 virtual void startAnimation() override
877 if (this->isDisposed() || !mpAnim)
878 return;
879 ContinuousActivityBase::startAnimation();
881 // start animation
882 mpAnim->start( getShape(),
883 getShapeAttributeLayer() );
886 virtual void endAnimation() override
888 // end animation
889 if (mpAnim)
890 mpAnim->end();
893 using SimpleContinuousActivityBase::perform;
895 /// perform override for ContinuousActivityBase
896 virtual void perform( double nModifiedTime, sal_uInt32 ) const override
898 if (this->isDisposed() || !mpAnim)
899 return;
900 // no cumulation, simple [0,1] range
901 (*mpAnim)( 1.0 - Direction + nModifiedTime*(2.0*Direction - 1.0) );
904 virtual void performEnd() override
906 // xxx todo: review
907 if (mpAnim)
908 (*mpAnim)( 1.0*Direction );
911 /// Disposable:
912 virtual void dispose() override
914 mpAnim.reset();
915 ContinuousActivityBase::dispose();
918 private:
919 NumberAnimationSharedPtr mpAnim;
922 } // anon namespace
925 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
926 const CommonParameters& rParms,
927 const NumberAnimationSharedPtr& rAnim,
928 const uno::Reference< animations::XAnimate >& xNode )
930 // forward to appropriate template instantiation
931 return createActivity( rParms, xNode, rAnim );
934 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
935 const CommonParameters& rParms,
936 const EnumAnimationSharedPtr& rAnim,
937 const uno::Reference< animations::XAnimate >& xNode )
939 // forward to appropriate template instantiation
940 return createActivity( rParms, xNode, rAnim );
943 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
944 const CommonParameters& rParms,
945 const ColorAnimationSharedPtr& rAnim,
946 const uno::Reference< animations::XAnimate >& xNode )
948 // forward to appropriate template instantiation
949 return createActivity( rParms, xNode, rAnim );
952 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
953 const CommonParameters& rParms,
954 const HSLColorAnimationSharedPtr& rAnim,
955 const uno::Reference< animations::XAnimateColor >& xNode )
957 // forward to appropriate template instantiation
958 return createActivity( rParms,
959 uno::Reference< animations::XAnimate >(
960 xNode, uno::UNO_QUERY_THROW ),
961 rAnim,
962 // Direction==true means clockwise in SMIL API
963 Interpolator< HSLColor >( !xNode->getDirection() ) );
966 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
967 const CommonParameters& rParms,
968 const PairAnimationSharedPtr& rAnim,
969 const uno::Reference< animations::XAnimate >& xNode )
971 // forward to appropriate template instantiation
972 return createActivity( rParms, xNode, rAnim );
975 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
976 const CommonParameters& rParms,
977 const StringAnimationSharedPtr& rAnim,
978 const uno::Reference< animations::XAnimate >& xNode )
980 // forward to appropriate template instantiation
981 return createActivity( rParms, xNode, rAnim );
984 AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
985 const CommonParameters& rParms,
986 const BoolAnimationSharedPtr& rAnim,
987 const uno::Reference< animations::XAnimate >& xNode )
989 // forward to appropriate template instantiation
990 return createActivity( rParms, xNode, rAnim );
993 AnimationActivitySharedPtr ActivitiesFactory::createSimpleActivity(
994 const CommonParameters& rParms,
995 const NumberAnimationSharedPtr& rAnim,
996 bool bDirectionForward )
998 ActivityParameters aActivityParms( rParms.mpEndEvent,
999 rParms.mrEventQueue,
1000 rParms.mrActivitiesQueue,
1001 rParms.mnMinDuration,
1002 rParms.maRepeats,
1003 rParms.mnAcceleration,
1004 rParms.mnDeceleration,
1005 rParms.mnMinNumberOfFrames,
1006 rParms.mbAutoReverse );
1008 if( bDirectionForward )
1009 return std::make_shared<SimpleActivity<1>>( aActivityParms, rAnim );
1010 else
1011 return std::make_shared<SimpleActivity<0>>( aActivityParms, rAnim );
1014 } // namespace presentation
1016 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */