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 10cdf0e10cSrcweir * 1170f497fbSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 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. 19cdf0e10cSrcweir * 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 { 64cdf0e10cSrcweir 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 { 74cdf0e10cSrcweir 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... 119cdf0e10cSrcweir 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 */ 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 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 225*e630ada4SAndre 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 237cdf0e10cSrcweir virtual void endAnimation() 238cdf0e10cSrcweir { 239cdf0e10cSrcweir // end animation 240cdf0e10cSrcweir if (mpAnim) 241cdf0e10cSrcweir mpAnim->end(); 242cdf0e10cSrcweir } 243cdf0e10cSrcweir 244cdf0e10cSrcweir /// perform override for ContinuousActivityBase 245cdf0e10cSrcweir 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, 253*e630ada4SAndre Fischer maInterpolator( maStartValue, 254cdf0e10cSrcweir maEndValue, 255cdf0e10cSrcweir nModifiedTime ) ) ) ); 256cdf0e10cSrcweir } 257cdf0e10cSrcweir 258cdf0e10cSrcweir using BaseType::perform; 259cdf0e10cSrcweir 260cdf0e10cSrcweir /// perform override for DiscreteActivityBase base 261cdf0e10cSrcweir 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, 269*e630ada4SAndre Fischer maStartValue, 270cdf0e10cSrcweir maEndValue, 271cdf0e10cSrcweir nFrame, 272cdf0e10cSrcweir BaseType::getNumberOfKeyTimes() ) ) ) ); 273cdf0e10cSrcweir } 274cdf0e10cSrcweir 275cdf0e10cSrcweir using BaseType::isAutoReverse; 276cdf0e10cSrcweir 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: 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> 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... 422cdf0e10cSrcweir 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 */ 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 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 478cdf0e10cSrcweir virtual void endAnimation() 479cdf0e10cSrcweir { 480cdf0e10cSrcweir // end animation 481cdf0e10cSrcweir if (mpAnim) 482cdf0e10cSrcweir mpAnim->end(); 483cdf0e10cSrcweir } 484cdf0e10cSrcweir 485cdf0e10cSrcweir /// perform override for ContinuousKeyTimeActivityBase base 486cdf0e10cSrcweir 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( 498cdf0e10cSrcweir accumulate( 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 508cdf0e10cSrcweir 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( 518cdf0e10cSrcweir accumulate( maValues.back(), 519cdf0e10cSrcweir mbCumulative ? nRepeatCount : 0, 520cdf0e10cSrcweir maValues[ nFrame ] ) ) ); 521cdf0e10cSrcweir } 522cdf0e10cSrcweir 523cdf0e10cSrcweir virtual void performEnd() 524cdf0e10cSrcweir { 525cdf0e10cSrcweir // xxx todo: good guess 526cdf0e10cSrcweir if (mpAnim) 527cdf0e10cSrcweir (*mpAnim)( getPresentationValue( maValues.back() ) ); 528cdf0e10cSrcweir } 529cdf0e10cSrcweir 530cdf0e10cSrcweir /// Disposable: 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> 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> 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 */ 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 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 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 850cdf0e10cSrcweir 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 858cdf0e10cSrcweir virtual void performEnd() 859cdf0e10cSrcweir { 860cdf0e10cSrcweir // xxx todo: review 861cdf0e10cSrcweir if (mpAnim) 862cdf0e10cSrcweir (*mpAnim)( 1.0*Direction ); 863cdf0e10cSrcweir } 864cdf0e10cSrcweir 865cdf0e10cSrcweir /// Disposable: 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 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 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 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 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 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 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 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 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