170f497fbSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
370f497fbSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
470f497fbSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
570f497fbSAndrew Rist  * distributed with this work for additional information
670f497fbSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
770f497fbSAndrew Rist  * to you under the Apache License, Version 2.0 (the
870f497fbSAndrew Rist  * "License"); you may not use this file except in compliance
970f497fbSAndrew Rist  * with the License.  You may obtain a copy of the License at
1070f497fbSAndrew Rist  *
1170f497fbSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1270f497fbSAndrew Rist  *
1370f497fbSAndrew Rist  * Unless required by applicable law or agreed to in writing,
1470f497fbSAndrew Rist  * software distributed under the License is distributed on an
1570f497fbSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1670f497fbSAndrew Rist  * KIND, either express or implied.  See the License for the
1770f497fbSAndrew Rist  * specific language governing permissions and limitations
1870f497fbSAndrew Rist  * under the License.
1970f497fbSAndrew Rist  *
2070f497fbSAndrew Rist  *************************************************************/
2170f497fbSAndrew Rist 
2270f497fbSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_slideshow.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir // must be first
28cdf0e10cSrcweir #include <canvas/debug.hxx>
29cdf0e10cSrcweir #include <tools/diagnose_ex.h>
30cdf0e10cSrcweir #include <canvas/verbosetrace.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <com/sun/star/animations/AnimationCalcMode.hpp>
33cdf0e10cSrcweir #include <comphelper/sequence.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include "activitiesfactory.hxx"
36cdf0e10cSrcweir #include "smilfunctionparser.hxx"
37cdf0e10cSrcweir #include "accumulation.hxx"
38cdf0e10cSrcweir #include "activityparameters.hxx"
39cdf0e10cSrcweir #include "interpolation.hxx"
40cdf0e10cSrcweir #include "tools.hxx"
41cdf0e10cSrcweir #include "simplecontinuousactivitybase.hxx"
42cdf0e10cSrcweir #include "discreteactivitybase.hxx"
43cdf0e10cSrcweir #include "continuousactivitybase.hxx"
44cdf0e10cSrcweir #include "continuouskeytimeactivitybase.hxx"
45cdf0e10cSrcweir 
46cdf0e10cSrcweir #include <boost/bind.hpp>
47cdf0e10cSrcweir #include <boost/optional.hpp>
48cdf0e10cSrcweir 
49cdf0e10cSrcweir #include <cmath> // for modf
50cdf0e10cSrcweir #include <vector>
51cdf0e10cSrcweir #include <algorithm>
52cdf0e10cSrcweir 
53cdf0e10cSrcweir using namespace com::sun::star;
54cdf0e10cSrcweir 
55cdf0e10cSrcweir namespace slideshow {
56cdf0e10cSrcweir namespace internal {
57cdf0e10cSrcweir 
58cdf0e10cSrcweir namespace {
59cdf0e10cSrcweir 
60cdf0e10cSrcweir /** Traits template, to take formula application only for ValueType = double
61cdf0e10cSrcweir  */
62cdf0e10cSrcweir template<typename ValueType> struct FormulaTraits
63cdf0e10cSrcweir {
getPresentationValueslideshow::internal::__anon5e43dbaf0111::FormulaTraits64cdf0e10cSrcweir     static ValueType getPresentationValue(
65cdf0e10cSrcweir         const ValueType& rVal, const ExpressionNodeSharedPtr& )
66cdf0e10cSrcweir     {
67cdf0e10cSrcweir         return rVal;
68cdf0e10cSrcweir     }
69cdf0e10cSrcweir };
70cdf0e10cSrcweir 
71cdf0e10cSrcweir /// Specialization for ValueType = double
72cdf0e10cSrcweir template<> struct FormulaTraits<double>
73cdf0e10cSrcweir {
getPresentationValueslideshow::internal::__anon5e43dbaf0111::FormulaTraits74cdf0e10cSrcweir     static double getPresentationValue(
75cdf0e10cSrcweir         double const& rVal, ExpressionNodeSharedPtr const& rFormula )
76cdf0e10cSrcweir     {
77cdf0e10cSrcweir         return rFormula ? (*rFormula)(rVal) : rVal;
78cdf0e10cSrcweir     }
79cdf0e10cSrcweir };
80cdf0e10cSrcweir 
81cdf0e10cSrcweir // Various ActivityBase specializations for different animator types
82cdf0e10cSrcweir // =================================================================
83cdf0e10cSrcweir 
84cdf0e10cSrcweir /** FromToBy handler
85cdf0e10cSrcweir 
86cdf0e10cSrcweir     Provides the Activity specializations for FromToBy
87cdf0e10cSrcweir     animations (e.g. those without a values list).
88cdf0e10cSrcweir 
89cdf0e10cSrcweir     This template makes heavy use of SFINAE, only one of
90cdf0e10cSrcweir     the perform*() methods will compile for each of the
91cdf0e10cSrcweir     base classes.
92cdf0e10cSrcweir 
93cdf0e10cSrcweir     Note that we omit the virtual keyword on the perform()
94cdf0e10cSrcweir     overrides on purpose; those that actually do override
95cdf0e10cSrcweir     baseclass virtual methods inherit the property, and
96cdf0e10cSrcweir     the others won't increase our vtable. What's more,
97cdf0e10cSrcweir     having all perform() method in the vtable actually
98cdf0e10cSrcweir     creates POIs for them, which breaks the whole SFINAE
99cdf0e10cSrcweir     concept (IOW, this template won't compile any longer).
100cdf0e10cSrcweir 
101cdf0e10cSrcweir     @tpl BaseType
102cdf0e10cSrcweir     Base class to use for this activity. Only
103cdf0e10cSrcweir     ContinuousActivityBase and DiscreteActivityBase are
104cdf0e10cSrcweir     supported here.
105cdf0e10cSrcweir 
106cdf0e10cSrcweir     @tpl AnimationType
107cdf0e10cSrcweir     Type of the Animation to call.
108cdf0e10cSrcweir */
109cdf0e10cSrcweir template<class BaseType, typename AnimationType>
110cdf0e10cSrcweir class FromToByActivity : public BaseType
111cdf0e10cSrcweir {
112cdf0e10cSrcweir public:
113cdf0e10cSrcweir     typedef typename AnimationType::ValueType           ValueType;
114cdf0e10cSrcweir     typedef boost::optional<ValueType>                  OptionalValueType;
115cdf0e10cSrcweir 
116cdf0e10cSrcweir private:
117cdf0e10cSrcweir     // some compilers don't inline whose definition they haven't
118cdf0e10cSrcweir     // seen before the call site...
getPresentationValue(const ValueType & rVal) const119cdf0e10cSrcweir     ValueType getPresentationValue( const ValueType& rVal ) const
120cdf0e10cSrcweir     {
121cdf0e10cSrcweir         return FormulaTraits<ValueType>::getPresentationValue( rVal, mpFormula);
122cdf0e10cSrcweir     }
123cdf0e10cSrcweir 
124cdf0e10cSrcweir public:
125cdf0e10cSrcweir     /** Create FromToByActivity.
126cdf0e10cSrcweir 
127cdf0e10cSrcweir         @param rFrom
128cdf0e10cSrcweir         From this value, the animation starts
129cdf0e10cSrcweir 
130cdf0e10cSrcweir         @param rTo
131cdf0e10cSrcweir         With this value, the animation ends
132cdf0e10cSrcweir 
133cdf0e10cSrcweir         @param rBy
134cdf0e10cSrcweir         With this value, the animation increments the start value
135cdf0e10cSrcweir 
136cdf0e10cSrcweir         @param rParms
137cdf0e10cSrcweir         Standard Activity parameter struct
138cdf0e10cSrcweir 
139cdf0e10cSrcweir         @param rAnim
140cdf0e10cSrcweir         Shared ptr to AnimationType
141cdf0e10cSrcweir 
142cdf0e10cSrcweir         @param rInterpolator
143cdf0e10cSrcweir         Interpolator object to be used for lerping between
144cdf0e10cSrcweir         start and end value (need to be passed, since it
145cdf0e10cSrcweir         might contain state, e.g. interpolation direction
146cdf0e10cSrcweir         for HSL color space).
147cdf0e10cSrcweir 
148cdf0e10cSrcweir         @param bCumulative
149cdf0e10cSrcweir         Whether repeated animations should cumulate the
150cdf0e10cSrcweir         value, or start fresh each time.
151cdf0e10cSrcweir     */
FromToByActivity(const OptionalValueType & rFrom,const OptionalValueType & rTo,const OptionalValueType & rBy,const ActivityParameters & rParms,const::boost::shared_ptr<AnimationType> & rAnim,const Interpolator<ValueType> & rInterpolator,bool bCumulative)152cdf0e10cSrcweir     FromToByActivity(
153cdf0e10cSrcweir         const OptionalValueType&                      rFrom,
154cdf0e10cSrcweir         const OptionalValueType&                      rTo,
155cdf0e10cSrcweir         const OptionalValueType&                      rBy,
156cdf0e10cSrcweir         const ActivityParameters&                     rParms,
157cdf0e10cSrcweir         const ::boost::shared_ptr< AnimationType >&   rAnim,
158cdf0e10cSrcweir         const Interpolator< ValueType >&              rInterpolator,
159cdf0e10cSrcweir         bool                                          bCumulative )
160cdf0e10cSrcweir         : BaseType( rParms ),
161cdf0e10cSrcweir           maFrom( rFrom ),
162cdf0e10cSrcweir           maTo( rTo ),
163cdf0e10cSrcweir           maBy( rBy ),
164cdf0e10cSrcweir           mpFormula( rParms.mpFormula ),
165cdf0e10cSrcweir           maStartValue(),
166cdf0e10cSrcweir           maEndValue(),
167cdf0e10cSrcweir           mpAnim( rAnim ),
168cdf0e10cSrcweir           maInterpolator( rInterpolator ),
169cdf0e10cSrcweir           mbCumulative( bCumulative )
170cdf0e10cSrcweir     {
171cdf0e10cSrcweir         ENSURE_OR_THROW( mpAnim, "Invalid animation object" );
172cdf0e10cSrcweir 
173cdf0e10cSrcweir         ENSURE_OR_THROW(
174cdf0e10cSrcweir             rTo || rBy,
175cdf0e10cSrcweir             "From and one of To or By, or To or By alone must be valid" );
176cdf0e10cSrcweir     }
177cdf0e10cSrcweir 
startAnimation()178cdf0e10cSrcweir     virtual void startAnimation()
179cdf0e10cSrcweir     {
180cdf0e10cSrcweir         if (this->isDisposed() || !mpAnim)
181cdf0e10cSrcweir             return;
182cdf0e10cSrcweir         BaseType::startAnimation();
183cdf0e10cSrcweir 
184cdf0e10cSrcweir         // start animation
185cdf0e10cSrcweir         mpAnim->start( BaseType::getShape(),
186cdf0e10cSrcweir                        BaseType::getShapeAttributeLayer() );
187cdf0e10cSrcweir 
188cdf0e10cSrcweir         // setup start and end value. Determine animation
189cdf0e10cSrcweir         // start value only when animation actually
190cdf0e10cSrcweir         // started up (this order is part of the Animation
191cdf0e10cSrcweir         // interface contract)
192cdf0e10cSrcweir         const ValueType aAnimationStartValue( mpAnim->getUnderlyingValue() );
193cdf0e10cSrcweir 
194cdf0e10cSrcweir         // first of all, determine general type of
195cdf0e10cSrcweir         // animation, by inspecting which of the FromToBy values
196cdf0e10cSrcweir         // are actually valid.
197cdf0e10cSrcweir         // See http://www.w3.org/TR/smil20/animation.html#AnimationNS-FromToBy
198cdf0e10cSrcweir         // for a definition
199cdf0e10cSrcweir         if( maFrom )
200cdf0e10cSrcweir         {
201cdf0e10cSrcweir             // From-to or From-by animation. According to
202cdf0e10cSrcweir             // SMIL spec, the To value takes precedence
203cdf0e10cSrcweir             // over the By value, if both are specified
204cdf0e10cSrcweir             if( maTo )
205cdf0e10cSrcweir             {
206cdf0e10cSrcweir                 // From-To animation
207cdf0e10cSrcweir                 maStartValue = *maFrom;
208cdf0e10cSrcweir                 maEndValue = *maTo;
209cdf0e10cSrcweir             }
210cdf0e10cSrcweir             else if( maBy )
211cdf0e10cSrcweir             {
212cdf0e10cSrcweir                 // From-By animation
213cdf0e10cSrcweir                 maStartValue = *maFrom;
214cdf0e10cSrcweir                 maEndValue = maStartValue + *maBy;
215cdf0e10cSrcweir             }
216cdf0e10cSrcweir         }
217cdf0e10cSrcweir         else
218cdf0e10cSrcweir         {
219cdf0e10cSrcweir             // By or To animation. According to SMIL spec,
220cdf0e10cSrcweir             // the To value takes precedence over the By
221cdf0e10cSrcweir             // value, if both are specified
222cdf0e10cSrcweir             if( maTo )
223cdf0e10cSrcweir             {
224cdf0e10cSrcweir                 // To animation
225e630ada4SAndre Fischer                 maStartValue = aAnimationStartValue;
226cdf0e10cSrcweir                 maEndValue = *maTo;
227cdf0e10cSrcweir             }
228cdf0e10cSrcweir             else if( maBy )
229cdf0e10cSrcweir             {
230cdf0e10cSrcweir                 // By animation
231cdf0e10cSrcweir                 maStartValue = aAnimationStartValue;
232cdf0e10cSrcweir                 maEndValue = maStartValue + *maBy;
233cdf0e10cSrcweir             }
234cdf0e10cSrcweir         }
235cdf0e10cSrcweir     }
236cdf0e10cSrcweir 
endAnimation()237cdf0e10cSrcweir     virtual void endAnimation()
238cdf0e10cSrcweir     {
239cdf0e10cSrcweir         // end animation
240cdf0e10cSrcweir         if (mpAnim)
241cdf0e10cSrcweir             mpAnim->end();
242cdf0e10cSrcweir     }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir     /// perform override for ContinuousActivityBase
perform(double nModifiedTime,sal_uInt32 nRepeatCount) const245cdf0e10cSrcweir     void perform( double nModifiedTime, sal_uInt32 nRepeatCount ) const
246cdf0e10cSrcweir     {
247cdf0e10cSrcweir         if (this->isDisposed() || !mpAnim)
248cdf0e10cSrcweir             return;
249cdf0e10cSrcweir         (*mpAnim)(
250cdf0e10cSrcweir             getPresentationValue(
251cdf0e10cSrcweir                 accumulate( maEndValue,
252cdf0e10cSrcweir                             mbCumulative * nRepeatCount, // means: mbCumulative ? nRepeatCount : 0,
253e630ada4SAndre Fischer                             maInterpolator( maStartValue,
254cdf0e10cSrcweir                                             maEndValue,
255cdf0e10cSrcweir                                             nModifiedTime ) ) ) );
256cdf0e10cSrcweir     }
257cdf0e10cSrcweir 
258cdf0e10cSrcweir     using BaseType::perform;
259cdf0e10cSrcweir 
260cdf0e10cSrcweir     /// perform override for DiscreteActivityBase base
perform(sal_uInt32 nFrame,sal_uInt32 nRepeatCount) const261cdf0e10cSrcweir     void perform( sal_uInt32 nFrame, sal_uInt32 nRepeatCount ) const
262cdf0e10cSrcweir     {
263cdf0e10cSrcweir         if (this->isDisposed() || !mpAnim)
264cdf0e10cSrcweir             return;
265cdf0e10cSrcweir         (*mpAnim)(
266cdf0e10cSrcweir             getPresentationValue(
267cdf0e10cSrcweir                 accumulate( maEndValue, mbCumulative ? nRepeatCount : 0,
268cdf0e10cSrcweir                             lerp( maInterpolator,
269e630ada4SAndre Fischer                                   maStartValue,
270cdf0e10cSrcweir                                   maEndValue,
271cdf0e10cSrcweir                                   nFrame,
272cdf0e10cSrcweir                                   BaseType::getNumberOfKeyTimes() ) ) ) );
273cdf0e10cSrcweir     }
274cdf0e10cSrcweir 
275cdf0e10cSrcweir     using BaseType::isAutoReverse;
276cdf0e10cSrcweir 
performEnd()277cdf0e10cSrcweir     virtual void performEnd()
278cdf0e10cSrcweir     {
279cdf0e10cSrcweir         // xxx todo: good guess
280cdf0e10cSrcweir         if (mpAnim)
281cdf0e10cSrcweir         {
282cdf0e10cSrcweir             if (isAutoReverse())
283cdf0e10cSrcweir                 (*mpAnim)( getPresentationValue( maStartValue ) );
284cdf0e10cSrcweir             else
285cdf0e10cSrcweir                 (*mpAnim)( getPresentationValue( maEndValue ) );
286cdf0e10cSrcweir         }
287cdf0e10cSrcweir     }
288cdf0e10cSrcweir 
289cdf0e10cSrcweir     /// Disposable:
dispose()290cdf0e10cSrcweir     virtual void dispose()
291cdf0e10cSrcweir     {
292cdf0e10cSrcweir         mpAnim.reset();
293cdf0e10cSrcweir         BaseType::dispose();
294cdf0e10cSrcweir     }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir private:
297cdf0e10cSrcweir     const OptionalValueType                 maFrom;
298cdf0e10cSrcweir     const OptionalValueType                 maTo;
299cdf0e10cSrcweir     const OptionalValueType                 maBy;
300cdf0e10cSrcweir 
301cdf0e10cSrcweir     ExpressionNodeSharedPtr                 mpFormula;
302cdf0e10cSrcweir 
303cdf0e10cSrcweir     ValueType                               maStartValue;
304cdf0e10cSrcweir     ValueType                               maEndValue;
305cdf0e10cSrcweir 
306cdf0e10cSrcweir     ::boost::shared_ptr< AnimationType >    mpAnim;
307cdf0e10cSrcweir     Interpolator< ValueType >               maInterpolator;
308cdf0e10cSrcweir     bool                                    mbCumulative;
309cdf0e10cSrcweir };
310cdf0e10cSrcweir 
311cdf0e10cSrcweir 
312cdf0e10cSrcweir /** Generate Activity corresponding to given FromToBy values
313cdf0e10cSrcweir 
314cdf0e10cSrcweir     @tpl BaseType
315cdf0e10cSrcweir     BaseType to use for deriving the Activity from
316cdf0e10cSrcweir 
317cdf0e10cSrcweir     @tpl AnimationType
318cdf0e10cSrcweir     Subtype of the Animation object (e.g. NumberAnimation)
319cdf0e10cSrcweir */
320cdf0e10cSrcweir template<class BaseType, typename AnimationType>
createFromToByActivity(const uno::Any & rFromAny,const uno::Any & rToAny,const uno::Any & rByAny,const ActivityParameters & rParms,const::boost::shared_ptr<AnimationType> & rAnim,const Interpolator<typename AnimationType::ValueType> & rInterpolator,bool bCumulative,const ShapeSharedPtr & rShape,const::basegfx::B2DVector & rSlideBounds)321cdf0e10cSrcweir AnimationActivitySharedPtr createFromToByActivity(
322cdf0e10cSrcweir     const uno::Any&                                          rFromAny,
323cdf0e10cSrcweir     const uno::Any&                                          rToAny,
324cdf0e10cSrcweir     const uno::Any&                                          rByAny,
325cdf0e10cSrcweir     const ActivityParameters&                                rParms,
326cdf0e10cSrcweir     const ::boost::shared_ptr< AnimationType >&              rAnim,
327cdf0e10cSrcweir     const Interpolator< typename AnimationType::ValueType >& rInterpolator,
328cdf0e10cSrcweir     bool                                                     bCumulative,
329cdf0e10cSrcweir     const ShapeSharedPtr&                                    rShape,
330cdf0e10cSrcweir     const ::basegfx::B2DVector&                              rSlideBounds )
331cdf0e10cSrcweir {
332cdf0e10cSrcweir     typedef typename AnimationType::ValueType           ValueType;
333cdf0e10cSrcweir     typedef boost::optional<ValueType>                  OptionalValueType;
334cdf0e10cSrcweir 
335cdf0e10cSrcweir     OptionalValueType aFrom;
336cdf0e10cSrcweir     OptionalValueType aTo;
337cdf0e10cSrcweir     OptionalValueType aBy;
338cdf0e10cSrcweir 
339cdf0e10cSrcweir     ValueType aTmpValue;
340cdf0e10cSrcweir 
341cdf0e10cSrcweir     if( rFromAny.hasValue() )
342cdf0e10cSrcweir     {
343cdf0e10cSrcweir         ENSURE_OR_THROW(
344cdf0e10cSrcweir             extractValue( aTmpValue, rFromAny, rShape, rSlideBounds ),
345cdf0e10cSrcweir             "createFromToByActivity(): Could not extract from value" );
346cdf0e10cSrcweir         aFrom.reset(aTmpValue);
347cdf0e10cSrcweir     }
348cdf0e10cSrcweir     if( rToAny.hasValue() )
349cdf0e10cSrcweir     {
350cdf0e10cSrcweir         ENSURE_OR_THROW(
351cdf0e10cSrcweir             extractValue( aTmpValue, rToAny, rShape, rSlideBounds ),
352cdf0e10cSrcweir             "createFromToByActivity(): Could not extract to value" );
353cdf0e10cSrcweir         aTo.reset(aTmpValue);
354cdf0e10cSrcweir     }
355cdf0e10cSrcweir     if( rByAny.hasValue() )
356cdf0e10cSrcweir     {
357cdf0e10cSrcweir         ENSURE_OR_THROW(
358cdf0e10cSrcweir             extractValue( aTmpValue, rByAny, rShape, rSlideBounds ),
359cdf0e10cSrcweir             "createFromToByActivity(): Could not extract by value" );
360cdf0e10cSrcweir         aBy.reset(aTmpValue);
361cdf0e10cSrcweir     }
362cdf0e10cSrcweir 
363cdf0e10cSrcweir     return AnimationActivitySharedPtr(
364cdf0e10cSrcweir         new FromToByActivity<BaseType, AnimationType>(
365cdf0e10cSrcweir             aFrom,
366cdf0e10cSrcweir             aTo,
367cdf0e10cSrcweir             aBy,
368cdf0e10cSrcweir             rParms,
369cdf0e10cSrcweir             rAnim,
370cdf0e10cSrcweir             rInterpolator,
371cdf0e10cSrcweir             bCumulative ) );
372cdf0e10cSrcweir }
373cdf0e10cSrcweir 
374cdf0e10cSrcweir /* The following table shows which animator combines with
375cdf0e10cSrcweir    which Activity type:
376cdf0e10cSrcweir 
377cdf0e10cSrcweir    NumberAnimator:  all
378cdf0e10cSrcweir    PairAnimation:   all
379cdf0e10cSrcweir    ColorAnimation:  all
380cdf0e10cSrcweir    StringAnimation: DiscreteActivityBase
381cdf0e10cSrcweir    BoolAnimation:   DiscreteActivityBase
382cdf0e10cSrcweir */
383cdf0e10cSrcweir 
384cdf0e10cSrcweir /** Values handler
385cdf0e10cSrcweir 
386cdf0e10cSrcweir     Provides the Activity specializations for value lists
387cdf0e10cSrcweir     animations.
388cdf0e10cSrcweir 
389cdf0e10cSrcweir     This template makes heavy use of SFINAE, only one of
390cdf0e10cSrcweir     the perform*() methods will compile for each of the
391cdf0e10cSrcweir     base classes.
392cdf0e10cSrcweir 
393cdf0e10cSrcweir     Note that we omit the virtual keyword on the perform()
394cdf0e10cSrcweir     overrides on purpose; those that actually do override
395cdf0e10cSrcweir     baseclass virtual methods inherit the property, and
396cdf0e10cSrcweir     the others won't increase our vtable. What's more,
397cdf0e10cSrcweir     having all perform() method in the vtable actually
398cdf0e10cSrcweir     creates POIs for them, which breaks the whole SFINAE
399cdf0e10cSrcweir     concept (IOW, this template won't compile any longer).
400cdf0e10cSrcweir 
401cdf0e10cSrcweir     @tpl BaseType
402cdf0e10cSrcweir     Base class to use for this activity. Only
403cdf0e10cSrcweir     ContinuousKeyTimeActivityBase and DiscreteActivityBase
404cdf0e10cSrcweir     are supported here. For values animation without key
405cdf0e10cSrcweir     times, the client must emulate key times by providing
406cdf0e10cSrcweir     a vector of equally spaced values between 0 and 1,
407cdf0e10cSrcweir     with the same number of entries as the values vector.
408cdf0e10cSrcweir 
409cdf0e10cSrcweir     @tpl AnimationType
410cdf0e10cSrcweir     Type of the Animation to call.
411cdf0e10cSrcweir */
412cdf0e10cSrcweir template<class BaseType, typename AnimationType>
413cdf0e10cSrcweir class ValuesActivity : public BaseType
414cdf0e10cSrcweir {
415cdf0e10cSrcweir public:
416cdf0e10cSrcweir     typedef typename AnimationType::ValueType   ValueType;
417cdf0e10cSrcweir     typedef std::vector<ValueType>              ValueVectorType;
418cdf0e10cSrcweir 
419cdf0e10cSrcweir private:
420cdf0e10cSrcweir     // some compilers don't inline methods whose definition they haven't
421cdf0e10cSrcweir     // seen before the call site...
getPresentationValue(const ValueType & rVal) const422cdf0e10cSrcweir     ValueType getPresentationValue( const ValueType& rVal ) const
423cdf0e10cSrcweir     {
424cdf0e10cSrcweir         return FormulaTraits<ValueType>::getPresentationValue(
425cdf0e10cSrcweir             rVal, mpFormula );
426cdf0e10cSrcweir     }
427cdf0e10cSrcweir 
428cdf0e10cSrcweir public:
429cdf0e10cSrcweir     /** Create ValuesActivity.
430cdf0e10cSrcweir 
431cdf0e10cSrcweir         @param rValues
432cdf0e10cSrcweir         Value vector to cycle animation through
433cdf0e10cSrcweir 
434cdf0e10cSrcweir         @param rParms
435cdf0e10cSrcweir         Standard Activity parameter struct
436cdf0e10cSrcweir 
437cdf0e10cSrcweir         @param rAnim
438cdf0e10cSrcweir         Shared ptr to AnimationType
439cdf0e10cSrcweir 
440cdf0e10cSrcweir         @param rInterpolator
441cdf0e10cSrcweir         Interpolator object to be used for lerping between
442cdf0e10cSrcweir         start and end value (need to be passed, since it
443cdf0e10cSrcweir         might contain state, e.g. interpolation direction
444cdf0e10cSrcweir         for HSL color space).
445cdf0e10cSrcweir 
446cdf0e10cSrcweir         @param bCumulative
447cdf0e10cSrcweir         Whether repeated animations should cumulate the
448cdf0e10cSrcweir         value, or start afresh each time.
449cdf0e10cSrcweir     */
ValuesActivity(const ValueVectorType & rValues,const ActivityParameters & rParms,const boost::shared_ptr<AnimationType> & rAnim,const Interpolator<ValueType> & rInterpolator,bool bCumulative)450cdf0e10cSrcweir     ValuesActivity(
451cdf0e10cSrcweir         const ValueVectorType&                      rValues,
452cdf0e10cSrcweir         const ActivityParameters&                   rParms,
453cdf0e10cSrcweir         const boost::shared_ptr<AnimationType>&     rAnim,
454cdf0e10cSrcweir         const Interpolator< ValueType >&            rInterpolator,
455cdf0e10cSrcweir         bool                                        bCumulative )
456cdf0e10cSrcweir         : BaseType( rParms ),
457cdf0e10cSrcweir           maValues( rValues ),
458cdf0e10cSrcweir           mpFormula( rParms.mpFormula ),
459cdf0e10cSrcweir           mpAnim( rAnim ),
460cdf0e10cSrcweir           maInterpolator( rInterpolator ),
461cdf0e10cSrcweir           mbCumulative( bCumulative )
462cdf0e10cSrcweir     {
463cdf0e10cSrcweir         ENSURE_OR_THROW( mpAnim, "Invalid animation object" );
464cdf0e10cSrcweir         ENSURE_OR_THROW( !rValues.empty(), "Empty value vector" );
465cdf0e10cSrcweir     }
466cdf0e10cSrcweir 
startAnimation()467cdf0e10cSrcweir     virtual void startAnimation()
468cdf0e10cSrcweir     {
469cdf0e10cSrcweir         if (this->isDisposed() || !mpAnim)
470cdf0e10cSrcweir             return;
471cdf0e10cSrcweir         BaseType::startAnimation();
472cdf0e10cSrcweir 
473cdf0e10cSrcweir         // start animation
474cdf0e10cSrcweir         mpAnim->start( BaseType::getShape(),
475cdf0e10cSrcweir                        BaseType::getShapeAttributeLayer() );
476cdf0e10cSrcweir     }
477cdf0e10cSrcweir 
endAnimation()478cdf0e10cSrcweir     virtual void endAnimation()
479cdf0e10cSrcweir     {
480cdf0e10cSrcweir         // end animation
481cdf0e10cSrcweir         if (mpAnim)
482cdf0e10cSrcweir             mpAnim->end();
483cdf0e10cSrcweir     }
484cdf0e10cSrcweir 
485cdf0e10cSrcweir     /// perform override for ContinuousKeyTimeActivityBase base
perform(sal_uInt32 nIndex,double nFractionalIndex,sal_uInt32 nRepeatCount) const486cdf0e10cSrcweir     void perform( sal_uInt32    nIndex,
487cdf0e10cSrcweir                   double        nFractionalIndex,
488cdf0e10cSrcweir                   sal_uInt32    nRepeatCount ) const
489cdf0e10cSrcweir     {
490cdf0e10cSrcweir         if (this->isDisposed() || !mpAnim)
491cdf0e10cSrcweir             return;
492cdf0e10cSrcweir         ENSURE_OR_THROW( nIndex+1 < maValues.size(),
493cdf0e10cSrcweir                           "ValuesActivity::perform(): index out of range" );
494cdf0e10cSrcweir 
495cdf0e10cSrcweir         // interpolate between nIndex and nIndex+1 values
496cdf0e10cSrcweir         (*mpAnim)(
497cdf0e10cSrcweir             getPresentationValue(
498*591a3969SHerbert Dürr                 accumulate<ValueType>( maValues.back(),
499cdf0e10cSrcweir                             mbCumulative ? nRepeatCount : 0,
500cdf0e10cSrcweir                             maInterpolator( maValues[ nIndex ],
501cdf0e10cSrcweir                                             maValues[ nIndex+1 ],
502cdf0e10cSrcweir                                             nFractionalIndex ) ) ) );
503cdf0e10cSrcweir     }
504cdf0e10cSrcweir 
505cdf0e10cSrcweir     using BaseType::perform;
506cdf0e10cSrcweir 
507cdf0e10cSrcweir     /// perform override for DiscreteActivityBase base
perform(sal_uInt32 nFrame,sal_uInt32 nRepeatCount) const508cdf0e10cSrcweir     void perform( sal_uInt32 nFrame, sal_uInt32 nRepeatCount ) const
509cdf0e10cSrcweir     {
510cdf0e10cSrcweir         if (this->isDisposed() || !mpAnim)
511cdf0e10cSrcweir             return;
512cdf0e10cSrcweir         ENSURE_OR_THROW( nFrame < maValues.size(),
513cdf0e10cSrcweir                           "ValuesActivity::perform(): index out of range" );
514cdf0e10cSrcweir 
515cdf0e10cSrcweir         // this is discrete, thus no lerp here.
516cdf0e10cSrcweir         (*mpAnim)(
517cdf0e10cSrcweir             getPresentationValue(
518*591a3969SHerbert Dürr                 accumulate<ValueType>( maValues.back(),
519cdf0e10cSrcweir                             mbCumulative ? nRepeatCount : 0,
520cdf0e10cSrcweir                             maValues[ nFrame ] ) ) );
521cdf0e10cSrcweir     }
522cdf0e10cSrcweir 
performEnd()523cdf0e10cSrcweir     virtual void performEnd()
524cdf0e10cSrcweir     {
525cdf0e10cSrcweir         // xxx todo: good guess
526cdf0e10cSrcweir         if (mpAnim)
527cdf0e10cSrcweir             (*mpAnim)( getPresentationValue( maValues.back() ) );
528cdf0e10cSrcweir     }
529cdf0e10cSrcweir 
530cdf0e10cSrcweir     /// Disposable:
dispose()531cdf0e10cSrcweir     virtual void dispose()
532cdf0e10cSrcweir     {
533cdf0e10cSrcweir         mpAnim.reset();
534cdf0e10cSrcweir         BaseType::dispose();
535cdf0e10cSrcweir     }
536cdf0e10cSrcweir 
537cdf0e10cSrcweir private:
538cdf0e10cSrcweir     ValueVectorType                         maValues;
539cdf0e10cSrcweir 
540cdf0e10cSrcweir     ExpressionNodeSharedPtr                 mpFormula;
541cdf0e10cSrcweir 
542cdf0e10cSrcweir     boost::shared_ptr<AnimationType>        mpAnim;
543cdf0e10cSrcweir     Interpolator< ValueType >               maInterpolator;
544cdf0e10cSrcweir     bool                                    mbCumulative;
545cdf0e10cSrcweir };
546cdf0e10cSrcweir 
547cdf0e10cSrcweir /** Generate Activity corresponding to given Value vector
548cdf0e10cSrcweir 
549cdf0e10cSrcweir     @tpl BaseType
550cdf0e10cSrcweir     BaseType to use for deriving the Activity from
551cdf0e10cSrcweir 
552cdf0e10cSrcweir     @tpl AnimationType
553cdf0e10cSrcweir     Subtype of the Animation object (e.g. NumberAnimation)
554cdf0e10cSrcweir */
555cdf0e10cSrcweir template<class BaseType, typename AnimationType>
createValueListActivity(const uno::Sequence<uno::Any> & rValues,const ActivityParameters & rParms,const boost::shared_ptr<AnimationType> & rAnim,const Interpolator<typename AnimationType::ValueType> & rInterpolator,bool bCumulative,const ShapeSharedPtr & rShape,const::basegfx::B2DVector & rSlideBounds)556cdf0e10cSrcweir AnimationActivitySharedPtr createValueListActivity(
557cdf0e10cSrcweir     const uno::Sequence<uno::Any>&                            rValues,
558cdf0e10cSrcweir     const ActivityParameters&                                 rParms,
559cdf0e10cSrcweir     const boost::shared_ptr<AnimationType>&                   rAnim,
560cdf0e10cSrcweir     const Interpolator<typename AnimationType::ValueType>&    rInterpolator,
561cdf0e10cSrcweir     bool                                                      bCumulative,
562cdf0e10cSrcweir     const ShapeSharedPtr&                                     rShape,
563cdf0e10cSrcweir     const ::basegfx::B2DVector&                               rSlideBounds )
564cdf0e10cSrcweir {
565cdf0e10cSrcweir     typedef typename AnimationType::ValueType   ValueType;
566cdf0e10cSrcweir     typedef std::vector<ValueType>              ValueVectorType;
567cdf0e10cSrcweir 
568cdf0e10cSrcweir     ValueVectorType aValueVector;
569cdf0e10cSrcweir     aValueVector.reserve( rValues.getLength() );
570cdf0e10cSrcweir 
571cdf0e10cSrcweir     for( ::std::size_t i=0, nLen=rValues.getLength(); i<nLen; ++i )
572cdf0e10cSrcweir     {
573cdf0e10cSrcweir         ValueType aValue;
574cdf0e10cSrcweir         ENSURE_OR_THROW(
575cdf0e10cSrcweir             extractValue( aValue, rValues[i], rShape, rSlideBounds ),
576cdf0e10cSrcweir             "createValueListActivity(): Could not extract values" );
577cdf0e10cSrcweir         aValueVector.push_back( aValue );
578cdf0e10cSrcweir     }
579cdf0e10cSrcweir 
580cdf0e10cSrcweir     return AnimationActivitySharedPtr(
581cdf0e10cSrcweir         new ValuesActivity<BaseType, AnimationType>(
582cdf0e10cSrcweir             aValueVector,
583cdf0e10cSrcweir             rParms,
584cdf0e10cSrcweir             rAnim,
585cdf0e10cSrcweir             rInterpolator,
586cdf0e10cSrcweir             bCumulative ) );
587cdf0e10cSrcweir }
588cdf0e10cSrcweir 
589cdf0e10cSrcweir /** Generate Activity for given XAnimate, corresponding to given Value vector
590cdf0e10cSrcweir 
591cdf0e10cSrcweir     @tpl AnimationType
592cdf0e10cSrcweir     Subtype of the Animation object (e.g. NumberAnimation)
593cdf0e10cSrcweir 
594cdf0e10cSrcweir     @param rParms
595cdf0e10cSrcweir     Common activity parameters
596cdf0e10cSrcweir 
597cdf0e10cSrcweir     @param xNode
598cdf0e10cSrcweir     XAnimate node, to retrieve animation values from
599cdf0e10cSrcweir 
600cdf0e10cSrcweir     @param rAnim
601cdf0e10cSrcweir     Actual animation to operate with (gets called with the
602cdf0e10cSrcweir     time-dependent values)
603cdf0e10cSrcweir 
604cdf0e10cSrcweir     @param rInterpolator
605cdf0e10cSrcweir     Interpolator object to be used for lerping between
606cdf0e10cSrcweir     start and end values (need to be passed, since it
607cdf0e10cSrcweir     might contain state, e.g. interpolation direction
608cdf0e10cSrcweir     for HSL color space).
609cdf0e10cSrcweir */
610cdf0e10cSrcweir template<typename AnimationType>
createActivity(const ActivitiesFactory::CommonParameters & rParms,const uno::Reference<animations::XAnimate> & xNode,const::boost::shared_ptr<AnimationType> & rAnim,const Interpolator<typename AnimationType::ValueType> & rInterpolator=Interpolator<typename AnimationType::ValueType> ())611cdf0e10cSrcweir AnimationActivitySharedPtr createActivity(
612cdf0e10cSrcweir     const ActivitiesFactory::CommonParameters&               rParms,
613cdf0e10cSrcweir     const uno::Reference< animations::XAnimate >&            xNode,
614cdf0e10cSrcweir     const ::boost::shared_ptr< AnimationType >&              rAnim,
615cdf0e10cSrcweir     const Interpolator< typename AnimationType::ValueType >& rInterpolator
616cdf0e10cSrcweir     = Interpolator< typename AnimationType::ValueType >() )
617cdf0e10cSrcweir {
618cdf0e10cSrcweir     // setup common parameters
619cdf0e10cSrcweir     // =======================
620cdf0e10cSrcweir 
621cdf0e10cSrcweir     ActivityParameters aActivityParms( rParms.mpEndEvent,
622cdf0e10cSrcweir                                        rParms.mrEventQueue,
623cdf0e10cSrcweir                                        rParms.mrActivitiesQueue,
624cdf0e10cSrcweir                                        rParms.mnMinDuration,
625cdf0e10cSrcweir                                        rParms.maRepeats,
626cdf0e10cSrcweir                                        rParms.mnAcceleration,
627cdf0e10cSrcweir                                        rParms.mnDeceleration,
628cdf0e10cSrcweir                                        rParms.mnMinNumberOfFrames,
629cdf0e10cSrcweir                                        rParms.mbAutoReverse );
630cdf0e10cSrcweir 
631cdf0e10cSrcweir     // is a formula given?
632cdf0e10cSrcweir     const ::rtl::OUString& rFormulaString( xNode->getFormula() );
633cdf0e10cSrcweir     if( rFormulaString.getLength() )
634cdf0e10cSrcweir     {
635cdf0e10cSrcweir         // yep, parse and pass to ActivityParameters
636cdf0e10cSrcweir         try
637cdf0e10cSrcweir         {
638cdf0e10cSrcweir             aActivityParms.mpFormula =
639cdf0e10cSrcweir                 SmilFunctionParser::parseSmilFunction(
640cdf0e10cSrcweir                     rFormulaString,
641cdf0e10cSrcweir                     calcRelativeShapeBounds(
642cdf0e10cSrcweir                         rParms.maSlideBounds,
643cdf0e10cSrcweir                         rParms.mpShape->getBounds() ) );
644cdf0e10cSrcweir         }
645cdf0e10cSrcweir         catch( ParseError& )
646cdf0e10cSrcweir         {
647cdf0e10cSrcweir             // parse error, thus no formula
648cdf0e10cSrcweir             OSL_ENSURE( false,
649cdf0e10cSrcweir                         "createActivity(): Error parsing formula string" );
650cdf0e10cSrcweir         }
651cdf0e10cSrcweir     }
652cdf0e10cSrcweir 
653cdf0e10cSrcweir     // are key times given?
654cdf0e10cSrcweir     const uno::Sequence< double >& aKeyTimes( xNode->getKeyTimes() );
655cdf0e10cSrcweir     if( aKeyTimes.hasElements() )
656cdf0e10cSrcweir     {
657cdf0e10cSrcweir         // yes, convert them from Sequence< double >
658cdf0e10cSrcweir         aActivityParms.maDiscreteTimes.resize( aKeyTimes.getLength() );
659cdf0e10cSrcweir         comphelper::sequenceToArray(
660cdf0e10cSrcweir             &aActivityParms.maDiscreteTimes[0],
661cdf0e10cSrcweir             aKeyTimes ); // saves us some temporary vectors
662cdf0e10cSrcweir     }
663cdf0e10cSrcweir 
664cdf0e10cSrcweir     // values sequence given?
665cdf0e10cSrcweir     const sal_Int32 nValueLen( xNode->getValues().getLength() );
666cdf0e10cSrcweir     if( nValueLen )
667cdf0e10cSrcweir     {
668cdf0e10cSrcweir         // Value list activity
669cdf0e10cSrcweir         // ===================
670cdf0e10cSrcweir 
671cdf0e10cSrcweir         // fake keytimes, if necessary
672cdf0e10cSrcweir         if( !aKeyTimes.hasElements() )
673cdf0e10cSrcweir         {
674cdf0e10cSrcweir             // create a dummy vector of key times,
675cdf0e10cSrcweir             // with aValues.getLength equally spaced entries.
676cdf0e10cSrcweir             for( sal_Int32 i=0; i<nValueLen; ++i )
677cdf0e10cSrcweir                 aActivityParms.maDiscreteTimes.push_back( double(i)/nValueLen );
678cdf0e10cSrcweir         }
679cdf0e10cSrcweir 
680cdf0e10cSrcweir         // determine type of animation needed here:
681cdf0e10cSrcweir         // Value list activities are possible with
682cdf0e10cSrcweir         // ContinuousKeyTimeActivityBase and DiscreteActivityBase
683cdf0e10cSrcweir         // specializations
684cdf0e10cSrcweir         const sal_Int16 nCalcMode( xNode->getCalcMode() );
685cdf0e10cSrcweir 
686cdf0e10cSrcweir         switch( nCalcMode )
687cdf0e10cSrcweir         {
688cdf0e10cSrcweir             case animations::AnimationCalcMode::DISCRETE:
689cdf0e10cSrcweir             {
690cdf0e10cSrcweir                 // since DiscreteActivityBase suspends itself
691cdf0e10cSrcweir                 // between the frames, create a WakeupEvent for it.
692cdf0e10cSrcweir                 aActivityParms.mpWakeupEvent.reset(
693cdf0e10cSrcweir                     new WakeupEvent(
694cdf0e10cSrcweir                         rParms.mrEventQueue.getTimer(),
695cdf0e10cSrcweir                         rParms.mrActivitiesQueue ) );
696cdf0e10cSrcweir 
697cdf0e10cSrcweir                 AnimationActivitySharedPtr pActivity(
698cdf0e10cSrcweir                     createValueListActivity< DiscreteActivityBase >(
699cdf0e10cSrcweir                         xNode->getValues(),
700cdf0e10cSrcweir                         aActivityParms,
701cdf0e10cSrcweir                         rAnim,
702cdf0e10cSrcweir                         rInterpolator,
703cdf0e10cSrcweir                         xNode->getAccumulate(),
704cdf0e10cSrcweir                         rParms.mpShape,
705cdf0e10cSrcweir                         rParms.maSlideBounds ) );
706cdf0e10cSrcweir 
707cdf0e10cSrcweir                 // WakeupEvent and DiscreteActivityBase need circular
708cdf0e10cSrcweir                 // references to the corresponding other object.
709cdf0e10cSrcweir                 aActivityParms.mpWakeupEvent->setActivity( pActivity );
710cdf0e10cSrcweir 
711cdf0e10cSrcweir                 return pActivity;
712cdf0e10cSrcweir             }
713cdf0e10cSrcweir 
714cdf0e10cSrcweir             default:
715cdf0e10cSrcweir                 OSL_ENSURE( false, "createActivity(): unexpected case" );
716cdf0e10cSrcweir                 // FALLTHROUGH intended
717cdf0e10cSrcweir             case animations::AnimationCalcMode::PACED:
718cdf0e10cSrcweir                 // FALLTHROUGH intended
719cdf0e10cSrcweir             case animations::AnimationCalcMode::SPLINE:
720cdf0e10cSrcweir                 // FALLTHROUGH intended
721cdf0e10cSrcweir             case animations::AnimationCalcMode::LINEAR:
722cdf0e10cSrcweir                 return createValueListActivity< ContinuousKeyTimeActivityBase >(
723cdf0e10cSrcweir                     xNode->getValues(),
724cdf0e10cSrcweir                     aActivityParms,
725cdf0e10cSrcweir                     rAnim,
726cdf0e10cSrcweir                     rInterpolator,
727cdf0e10cSrcweir                     xNode->getAccumulate(),
728cdf0e10cSrcweir                     rParms.mpShape,
729cdf0e10cSrcweir                     rParms.maSlideBounds );
730cdf0e10cSrcweir         }
731cdf0e10cSrcweir     }
732cdf0e10cSrcweir     else
733cdf0e10cSrcweir     {
734cdf0e10cSrcweir         // FromToBy activity
735cdf0e10cSrcweir         // =================
736cdf0e10cSrcweir 
737cdf0e10cSrcweir         // determine type of animation needed here:
738cdf0e10cSrcweir         // FromToBy activities are possible with
739cdf0e10cSrcweir         // ContinuousActivityBase and DiscreteActivityBase
740cdf0e10cSrcweir         // specializations
741cdf0e10cSrcweir         const sal_Int16 nCalcMode( xNode->getCalcMode() );
742cdf0e10cSrcweir 
743cdf0e10cSrcweir         switch( nCalcMode )
744cdf0e10cSrcweir         {
745cdf0e10cSrcweir             case animations::AnimationCalcMode::DISCRETE:
746cdf0e10cSrcweir             {
747cdf0e10cSrcweir                 // fake keytimes, if necessary
748cdf0e10cSrcweir                 if( !aKeyTimes.hasElements() )
749cdf0e10cSrcweir                 {
750cdf0e10cSrcweir                     // create a dummy vector of 2 key times
751cdf0e10cSrcweir                     const ::std::size_t nLen( 2 );
752cdf0e10cSrcweir                     for( ::std::size_t i=0; i<nLen; ++i )
753cdf0e10cSrcweir                         aActivityParms.maDiscreteTimes.push_back( double(i)/nLen );
754cdf0e10cSrcweir                 }
755cdf0e10cSrcweir 
756cdf0e10cSrcweir                 // since DiscreteActivityBase suspends itself
757cdf0e10cSrcweir                 // between the frames, create a WakeupEvent for it.
758cdf0e10cSrcweir                 aActivityParms.mpWakeupEvent.reset(
759cdf0e10cSrcweir                     new WakeupEvent(
760cdf0e10cSrcweir                         rParms.mrEventQueue.getTimer(),
761cdf0e10cSrcweir                         rParms.mrActivitiesQueue ) );
762cdf0e10cSrcweir 
763cdf0e10cSrcweir                 AnimationActivitySharedPtr pActivity(
764cdf0e10cSrcweir                     createFromToByActivity< DiscreteActivityBase >(
765cdf0e10cSrcweir                         xNode->getFrom(),
766cdf0e10cSrcweir                         xNode->getTo(),
767cdf0e10cSrcweir                         xNode->getBy(),
768cdf0e10cSrcweir                         aActivityParms,
769cdf0e10cSrcweir                         rAnim,
770cdf0e10cSrcweir                         rInterpolator,
771cdf0e10cSrcweir                         xNode->getAccumulate(),
772cdf0e10cSrcweir                         rParms.mpShape,
773cdf0e10cSrcweir                         rParms.maSlideBounds ) );
774cdf0e10cSrcweir 
775cdf0e10cSrcweir                 // WakeupEvent and DiscreteActivityBase need circular
776cdf0e10cSrcweir                 // references to the corresponding other object.
777cdf0e10cSrcweir                 aActivityParms.mpWakeupEvent->setActivity( pActivity );
778cdf0e10cSrcweir 
779cdf0e10cSrcweir                 return pActivity;
780cdf0e10cSrcweir             }
781cdf0e10cSrcweir 
782cdf0e10cSrcweir             default:
783cdf0e10cSrcweir                 OSL_ENSURE( false, "createActivity(): unexpected case" );
784cdf0e10cSrcweir                 // FALLTHROUGH intended
785cdf0e10cSrcweir             case animations::AnimationCalcMode::PACED:
786cdf0e10cSrcweir                 // FALLTHROUGH intended
787cdf0e10cSrcweir             case animations::AnimationCalcMode::SPLINE:
788cdf0e10cSrcweir                 // FALLTHROUGH intended
789cdf0e10cSrcweir             case animations::AnimationCalcMode::LINEAR:
790cdf0e10cSrcweir                 return createFromToByActivity< ContinuousActivityBase >(
791cdf0e10cSrcweir                     xNode->getFrom(),
792cdf0e10cSrcweir                     xNode->getTo(),
793cdf0e10cSrcweir                     xNode->getBy(),
794cdf0e10cSrcweir                     aActivityParms,
795cdf0e10cSrcweir                     rAnim,
796cdf0e10cSrcweir                     rInterpolator,
797cdf0e10cSrcweir                     xNode->getAccumulate(),
798cdf0e10cSrcweir                     rParms.mpShape,
799cdf0e10cSrcweir                     rParms.maSlideBounds );
800cdf0e10cSrcweir         }
801cdf0e10cSrcweir     }
802cdf0e10cSrcweir }
803cdf0e10cSrcweir 
804cdf0e10cSrcweir /** Simple activity for ActivitiesFactory::createSimpleActivity
805cdf0e10cSrcweir 
806cdf0e10cSrcweir     @tpl Direction
807cdf0e10cSrcweir     Determines direction of value generator. A 1 yields a
808cdf0e10cSrcweir     forward direction, starting with 0.0 and ending with
809cdf0e10cSrcweir     1.0. A 0 yields a backward direction, starting with
810cdf0e10cSrcweir     1.0 and ending with 0.0
811cdf0e10cSrcweir */
812cdf0e10cSrcweir template<int Direction>
813cdf0e10cSrcweir class SimpleActivity : public ContinuousActivityBase
814cdf0e10cSrcweir {
815cdf0e10cSrcweir public:
816cdf0e10cSrcweir     /** Create SimpleActivity.
817cdf0e10cSrcweir 
818cdf0e10cSrcweir         @param rParms
819cdf0e10cSrcweir         Standard Activity parameter struct
820cdf0e10cSrcweir     */
SimpleActivity(const ActivityParameters & rParms,const NumberAnimationSharedPtr & rAnim)821cdf0e10cSrcweir     SimpleActivity( const ActivityParameters&       rParms,
822cdf0e10cSrcweir                     const NumberAnimationSharedPtr& rAnim ) :
823cdf0e10cSrcweir         ContinuousActivityBase( rParms ),
824cdf0e10cSrcweir         mpAnim( rAnim )
825cdf0e10cSrcweir     {
826cdf0e10cSrcweir         ENSURE_OR_THROW( mpAnim, "Invalid animation object" );
827cdf0e10cSrcweir     }
828cdf0e10cSrcweir 
startAnimation()829cdf0e10cSrcweir     virtual void startAnimation()
830cdf0e10cSrcweir     {
831cdf0e10cSrcweir         if (this->isDisposed() || !mpAnim)
832cdf0e10cSrcweir             return;
833cdf0e10cSrcweir         ContinuousActivityBase::startAnimation();
834cdf0e10cSrcweir 
835cdf0e10cSrcweir         // start animation
836cdf0e10cSrcweir         mpAnim->start( getShape(),
837cdf0e10cSrcweir                        getShapeAttributeLayer() );
838cdf0e10cSrcweir     }
839cdf0e10cSrcweir 
endAnimation()840cdf0e10cSrcweir     virtual void endAnimation()
841cdf0e10cSrcweir     {
842cdf0e10cSrcweir         // end animation
843cdf0e10cSrcweir         if (mpAnim)
844cdf0e10cSrcweir             mpAnim->end();
845cdf0e10cSrcweir     }
846cdf0e10cSrcweir 
847cdf0e10cSrcweir     using SimpleContinuousActivityBase::perform;
848cdf0e10cSrcweir 
849cdf0e10cSrcweir     /// perform override for ContinuousActivityBase
perform(double nModifiedTime,sal_uInt32) const850cdf0e10cSrcweir     virtual void perform( double nModifiedTime, sal_uInt32 ) const
851cdf0e10cSrcweir     {
852cdf0e10cSrcweir         if (this->isDisposed() || !mpAnim)
853cdf0e10cSrcweir             return;
854cdf0e10cSrcweir         // no cumulation, simple [0,1] range
855cdf0e10cSrcweir         (*mpAnim)( 1.0 - Direction + nModifiedTime*(2.0*Direction - 1.0) );
856cdf0e10cSrcweir     }
857cdf0e10cSrcweir 
performEnd()858cdf0e10cSrcweir     virtual void performEnd()
859cdf0e10cSrcweir     {
860cdf0e10cSrcweir         // xxx todo: review
861cdf0e10cSrcweir         if (mpAnim)
862cdf0e10cSrcweir             (*mpAnim)( 1.0*Direction );
863cdf0e10cSrcweir     }
864cdf0e10cSrcweir 
865cdf0e10cSrcweir     /// Disposable:
dispose()866cdf0e10cSrcweir     virtual void dispose()
867cdf0e10cSrcweir     {
868cdf0e10cSrcweir         mpAnim.reset();
869cdf0e10cSrcweir         ContinuousActivityBase::dispose();
870cdf0e10cSrcweir     }
871cdf0e10cSrcweir 
872cdf0e10cSrcweir private:
873cdf0e10cSrcweir     NumberAnimationSharedPtr    mpAnim;
874cdf0e10cSrcweir };
875cdf0e10cSrcweir 
876cdf0e10cSrcweir } // anon namespace
877cdf0e10cSrcweir 
878cdf0e10cSrcweir 
createAnimateActivity(const CommonParameters & rParms,const NumberAnimationSharedPtr & rAnim,const uno::Reference<animations::XAnimate> & xNode)879cdf0e10cSrcweir AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
880cdf0e10cSrcweir     const CommonParameters&                        rParms,
881cdf0e10cSrcweir     const NumberAnimationSharedPtr&                rAnim,
882cdf0e10cSrcweir     const uno::Reference< animations::XAnimate >&  xNode )
883cdf0e10cSrcweir {
884cdf0e10cSrcweir     // forward to appropriate template instantiation
885cdf0e10cSrcweir     return createActivity( rParms, xNode, rAnim );
886cdf0e10cSrcweir }
887cdf0e10cSrcweir 
createAnimateActivity(const CommonParameters & rParms,const EnumAnimationSharedPtr & rAnim,const uno::Reference<animations::XAnimate> & xNode)888cdf0e10cSrcweir AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
889cdf0e10cSrcweir     const CommonParameters&                        rParms,
890cdf0e10cSrcweir     const EnumAnimationSharedPtr&                  rAnim,
891cdf0e10cSrcweir     const uno::Reference< animations::XAnimate >&  xNode )
892cdf0e10cSrcweir {
893cdf0e10cSrcweir     // forward to appropriate template instantiation
894cdf0e10cSrcweir     return createActivity( rParms, xNode, rAnim );
895cdf0e10cSrcweir }
896cdf0e10cSrcweir 
createAnimateActivity(const CommonParameters & rParms,const ColorAnimationSharedPtr & rAnim,const uno::Reference<animations::XAnimate> & xNode)897cdf0e10cSrcweir AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
898cdf0e10cSrcweir     const CommonParameters&                        rParms,
899cdf0e10cSrcweir     const ColorAnimationSharedPtr&                 rAnim,
900cdf0e10cSrcweir     const uno::Reference< animations::XAnimate >&  xNode )
901cdf0e10cSrcweir {
902cdf0e10cSrcweir     // forward to appropriate template instantiation
903cdf0e10cSrcweir     return createActivity( rParms, xNode, rAnim );
904cdf0e10cSrcweir }
905cdf0e10cSrcweir 
createAnimateActivity(const CommonParameters & rParms,const HSLColorAnimationSharedPtr & rAnim,const uno::Reference<animations::XAnimateColor> & xNode)906cdf0e10cSrcweir AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
907cdf0e10cSrcweir     const CommonParameters&                            rParms,
908cdf0e10cSrcweir     const HSLColorAnimationSharedPtr&                  rAnim,
909cdf0e10cSrcweir     const uno::Reference< animations::XAnimateColor >& xNode )
910cdf0e10cSrcweir {
911cdf0e10cSrcweir     // forward to appropriate template instantiation
912cdf0e10cSrcweir     return createActivity( rParms,
913cdf0e10cSrcweir                            uno::Reference< animations::XAnimate >(
914cdf0e10cSrcweir                                xNode, uno::UNO_QUERY_THROW ),
915cdf0e10cSrcweir                            rAnim,
916cdf0e10cSrcweir                            // Direction==true means clockwise in SMIL API
917cdf0e10cSrcweir                            Interpolator< HSLColor >( !xNode->getDirection() ) );
918cdf0e10cSrcweir }
919cdf0e10cSrcweir 
createAnimateActivity(const CommonParameters & rParms,const PairAnimationSharedPtr & rAnim,const uno::Reference<animations::XAnimate> & xNode)920cdf0e10cSrcweir AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
921cdf0e10cSrcweir     const CommonParameters&                        rParms,
922cdf0e10cSrcweir     const PairAnimationSharedPtr&                  rAnim,
923cdf0e10cSrcweir     const uno::Reference< animations::XAnimate >&  xNode )
924cdf0e10cSrcweir {
925cdf0e10cSrcweir     // forward to appropriate template instantiation
926cdf0e10cSrcweir     return createActivity( rParms, xNode, rAnim );
927cdf0e10cSrcweir }
928cdf0e10cSrcweir 
createAnimateActivity(const CommonParameters & rParms,const StringAnimationSharedPtr & rAnim,const uno::Reference<animations::XAnimate> & xNode)929cdf0e10cSrcweir AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
930cdf0e10cSrcweir     const CommonParameters&                        rParms,
931cdf0e10cSrcweir     const StringAnimationSharedPtr&                rAnim,
932cdf0e10cSrcweir     const uno::Reference< animations::XAnimate >&  xNode )
933cdf0e10cSrcweir {
934cdf0e10cSrcweir     // forward to appropriate template instantiation
935cdf0e10cSrcweir     return createActivity( rParms, xNode, rAnim );
936cdf0e10cSrcweir }
937cdf0e10cSrcweir 
createAnimateActivity(const CommonParameters & rParms,const BoolAnimationSharedPtr & rAnim,const uno::Reference<animations::XAnimate> & xNode)938cdf0e10cSrcweir AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
939cdf0e10cSrcweir     const CommonParameters&                        rParms,
940cdf0e10cSrcweir     const BoolAnimationSharedPtr&                  rAnim,
941cdf0e10cSrcweir     const uno::Reference< animations::XAnimate >&  xNode )
942cdf0e10cSrcweir {
943cdf0e10cSrcweir     // forward to appropriate template instantiation
944cdf0e10cSrcweir     return createActivity( rParms, xNode, rAnim );
945cdf0e10cSrcweir }
946cdf0e10cSrcweir 
createSimpleActivity(const CommonParameters & rParms,const NumberAnimationSharedPtr & rAnim,bool bDirectionForward)947cdf0e10cSrcweir AnimationActivitySharedPtr ActivitiesFactory::createSimpleActivity(
948cdf0e10cSrcweir     const CommonParameters&         rParms,
949cdf0e10cSrcweir     const NumberAnimationSharedPtr& rAnim,
950cdf0e10cSrcweir     bool                            bDirectionForward )
951cdf0e10cSrcweir {
952cdf0e10cSrcweir     ActivityParameters aActivityParms( rParms.mpEndEvent,
953cdf0e10cSrcweir                                        rParms.mrEventQueue,
954cdf0e10cSrcweir                                        rParms.mrActivitiesQueue,
955cdf0e10cSrcweir                                        rParms.mnMinDuration,
956cdf0e10cSrcweir                                        rParms.maRepeats,
957cdf0e10cSrcweir                                        rParms.mnAcceleration,
958cdf0e10cSrcweir                                        rParms.mnDeceleration,
959cdf0e10cSrcweir                                        rParms.mnMinNumberOfFrames,
960cdf0e10cSrcweir                                        rParms.mbAutoReverse );
961cdf0e10cSrcweir 
962cdf0e10cSrcweir     if( bDirectionForward )
963cdf0e10cSrcweir         return AnimationActivitySharedPtr(
964cdf0e10cSrcweir             new SimpleActivity<1>( aActivityParms, rAnim ) );
965cdf0e10cSrcweir     else
966cdf0e10cSrcweir         return AnimationActivitySharedPtr(
967cdf0e10cSrcweir             new SimpleActivity<0>( aActivityParms, rAnim ) );
968cdf0e10cSrcweir }
969cdf0e10cSrcweir 
970cdf0e10cSrcweir } // namespace internal
971cdf0e10cSrcweir } // namespace presentation
972cdf0e10cSrcweir 
973