eb4d377e2c71e6c54d18ad0ab9a7c061eb345b04
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / animation-impl.h
1 #ifndef __DALI_INTERNAL_ANIMATION_H__
2 #define __DALI_INTERNAL_ANIMATION_H__
3
4 /*
5  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/common/vector-wrapper.h>
23 #include <dali/public-api/object/ref-object.h>
24 #include <dali/public-api/animation/animation.h>
25 #include <dali/public-api/object/base-object.h>
26 #include <dali/devel-api/animation/animation-devel.h>
27 #include <dali/devel-api/common/owner-container.h>
28 #include <dali/internal/event/animation/key-frames-impl.h>
29 #include <dali/internal/event/common/event-thread-services.h>
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 namespace SceneGraph
38 {
39 class Animation;
40 class UpdateManager;
41 }
42
43 class Actor;
44 class Animation;
45 class AnimationPlaylist;
46 class AnimatorConnectorBase;
47 class Object;
48 class Path;
49
50 typedef IntrusivePtr<Animation> AnimationPtr;
51 typedef std::vector<AnimationPtr> AnimationContainer;
52
53 typedef AnimationContainer::iterator AnimationIter;
54 typedef AnimationContainer::const_iterator AnimationConstIter;
55
56 /**
57  * Animation is a proxy for a SceneGraph::Animation object.
58  * The UpdateManager owns the Animation object, but the lifetime of the animation is
59  * indirectly controlled by the Animation.
60  */
61 class Animation : public BaseObject
62 {
63 public:
64
65   enum Type
66   {
67     TO,      ///< Animating TO the given value
68     BY,      ///< Animating BY the given value
69     BETWEEN  ///< Animating BETWEEN key-frames
70   };
71
72   typedef Dali::Animation::EndAction EndAction;
73   typedef Dali::Animation::Interpolation Interpolation;
74
75   /**
76    * Create a new Animation object.
77    * @param[in] durationSeconds The duration of the animation.
78    * @return A smart-pointer to the newly allocated Animation.
79    */
80   static AnimationPtr New(float durationSeconds);
81
82   /**
83    * @copydoc Dali::Animation::SetDuration()
84    */
85   void SetDuration(float seconds);
86
87   /**
88    * @copydoc Dali::DevelAnimation::SetProgressNotification()
89    */
90   void SetProgressNotification( float progress );
91
92   /**
93    * @copydoc Dali::DevelAnimation::GetProgressNotification()
94    */
95   float GetProgressNotification();
96
97   /**
98    * @copydoc Dali::Animation::GetDuration()
99    */
100   float GetDuration() const;
101
102   /**
103    * @copydoc Dali::Animation::SetLooping()
104    */
105   void SetLooping(bool on);
106
107   /**
108    * @copydoc Dali::Animation::SetLoopCount()
109    */
110   void SetLoopCount(int count);
111
112   /**
113    * @copydoc Dali::Animation::GetLoopCount()
114    */
115   int GetLoopCount();
116
117   /**
118    * @copydoc Dali::Animation::GetCurrentLoop()
119    */
120   int GetCurrentLoop();
121
122   /**
123    * @copydoc Dali::Animation::IsLooping()
124    */
125   bool IsLooping() const;
126
127   /**
128    * @copydoc Dali::Animation::SetEndAction()
129    */
130   void SetEndAction(EndAction action);
131
132   /**
133    * @copydoc Dali::Animation::GetEndAction()
134    */
135   EndAction GetEndAction() const;
136
137   /**
138    * @copydoc Dali::Animation::SetDisconnectAction()
139    */
140   void SetDisconnectAction(EndAction action);
141
142   /**
143    * @copydoc Dali::Animation::GetDisconnectAction()
144    */
145   EndAction GetDisconnectAction() const;
146
147   /**
148    * @copydoc Dali::Animation::SetDefaultAlphaFunction()
149    */
150   void SetDefaultAlphaFunction(AlphaFunction alpha)
151   {
152     mDefaultAlpha = alpha;
153   }
154
155   /**
156    * @copydoc Dali::Animation::GetDefaultAlphaFunction()
157    */
158   AlphaFunction GetDefaultAlphaFunction() const
159   {
160     return mDefaultAlpha;
161   }
162
163   /**
164    * @copydoc Dali::Animation::Play()
165    */
166   void Play();
167
168   /**
169    * @copydoc Dali::Animation::PlayFrom()
170    */
171   void PlayFrom( float progress );
172
173   /**
174    * @copydoc Dali::Animation::PlayAfter()
175    */
176   void PlayAfter( float delaySeconds );
177
178   /**
179    * @copydoc Dali::Animation::Pause()
180    */
181   void Pause();
182
183   /**
184    * @copydoc Dali::Animation::GetState()
185    */
186   Dali::Animation::State GetState() const;
187
188   /**
189    * @copydoc Dali::Animation::Stop()
190    */
191   void Stop();
192
193   /**
194    * @copydoc Dali::Animation::Clear()
195    */
196   void Clear();
197
198   /**
199    * Query whether a Finished signal should be emitted for this animation.
200    * This should only be called by NotificationManager, before signals are emitted.
201    * @post HasFinished() will return false on subsequent calls, until the animation is replayed to completion.
202    */
203   bool HasFinished();
204
205   /**
206    * @copydoc Dali::Animation::FinishedSignal()
207    */
208   Dali::Animation::AnimationSignalType& FinishedSignal();
209
210   /**
211    * @copydoc Dali::DevelAnimation::ProgressHasBeenReachedSignal()
212    */
213   Dali::Animation::AnimationSignalType& ProgressReachedSignal();
214
215   /**
216    * Emit the Finished signal
217    */
218   void EmitSignalFinish();
219
220   /**
221    * Emit the ProgressReached signal
222    */
223   void EmitSignalProgressReached();
224
225   /**
226    * Connects a callback function with the object's signals.
227    * @param[in] object The object providing the signal.
228    * @param[in] tracker Used to disconnect the signal.
229    * @param[in] signalName The signal to connect to.
230    * @param[in] functor A newly allocated FunctorDelegate.
231    * @return True if the signal was connected.
232    * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
233    */
234   static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
235
236   /**
237    * Performs actions as requested using the action name.
238    * @param[in] object The object on which to perform the action.
239    * @param[in] actionName The action to perform.
240    * @param[in] attributes The attributes with which to perfrom this action.
241    * @return true if action was done
242    */
243   static bool DoAction(BaseObject* object, const std::string& actionName, const Property::Map& attributes);
244
245   /**
246    * @copydoc Dali::Animation::AnimateBy(Property target, Property::Value relativeValue)
247    */
248   void AnimateBy(Property& target, Property::Value& relativeValue);
249
250   /**
251    * @copydoc Dali::Animation::AnimateBy(Property target, Property::Value relativeValue, AlphaFunction alpha)
252    */
253   void AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha);
254
255   /**
256    * @copydoc Dali::Animation::AnimateBy(Property target, Property::Value relativeValue, TimePeriod period)
257    */
258   void AnimateBy(Property& target, Property::Value& relativeValue, TimePeriod period);
259
260   /**
261    * @copydoc Dali::Animation::AnimateBy(Property target, Property::Value relativeValue, AlphaFunction alpha, TimePeriod period)
262    */
263   void AnimateBy(Property& target, Property::Value& relativeValue, AlphaFunction alpha, TimePeriod period);
264
265   /**
266    * @copydoc Dali::Animation::AnimateTo(Property target, Property::Value destinationValue)
267    */
268   void AnimateTo(Property& target, Property::Value& destinationValue);
269
270   /**
271    * @copydoc Dali::Animation::AnimateTo(Property target, Property::Value destinationValue, AlphaFunction alpha)
272    */
273   void AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha);
274
275   /**
276    * @copydoc Dali::Animation::AnimateTo(Property target, Property::Value destinationValue, TimePeriod period)
277    */
278   void AnimateTo(Property& target, Property::Value& destinationValue, TimePeriod period);
279
280   /**
281    * @copydoc Dali::Animation::AnimateTo(Property target, Property::Value destinationValue, AlphaFunction alpha, TimePeriod period)
282    */
283   void AnimateTo(Property& target, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period);
284
285   /**
286    * Animate a property to a destination value.
287    * @param [in] targetObject The target object to animate.
288    * @param [in] targetPropertyIndex The index of the target property.
289    * @param [in] componentIndex Index to a sub component of a property, for use with Vector2, Vector3 and Vector4
290    * @param [in] destinationValue The destination value.
291    * @param [in] alpha The alpha function to apply.
292    * @param [in] period The effect will occur during this time period.
293    */
294   void AnimateTo(Object& targetObject, Property::Index targetPropertyIndex, int componentIndex, Property::Value& destinationValue, AlphaFunction alpha, TimePeriod period);
295
296   /**
297    * @copydoc Dali::Animation::AnimateBetween(Property target, KeyFrames& keyFrames)
298    */
299   void AnimateBetween(Property target, const KeyFrames& keyFrames);
300
301   /**
302    * @copydoc Dali::Animation::AnimateBetween(Property target, KeyFrames& keyFrames, Interpolation interpolation)
303    */
304   void AnimateBetween(Property target, const KeyFrames& keyFrames, Interpolation interpolation );
305
306   /**
307    * @copydoc Dali::Animation::AnimateBetween(Property target, KeyFrames& keyFrames, TimePeriod period)
308    */
309   void AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period);
310
311   /**
312    * @copydoc Dali::Animation::AnimateBetween(Property target, KeyFrames& keyFrames, TimePeriod period, Interpolation interpolation)
313    */
314   void AnimateBetween(Property target, const KeyFrames& keyFrames, TimePeriod period, Interpolation interpolation);
315
316   /**
317    * @copydoc Dali::Animation::AnimateBetween(Property target, KeyFrames& keyFrames, AlphaFunction alpha)
318    */
319   void AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha);
320
321   /**
322    * @copydoc Dali::Animation::AnimateBetween(Property target, KeyFrames& keyFrames, AlphaFunction alpha, Interpolation interpolation)
323    */
324   void AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, Interpolation interpolation);
325
326   /**
327    * @copydoc Dali::Animation::AnimateBetween(Property target, KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period)
328    */
329   void AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period);
330
331   /**
332    * @copydoc Dali::Animation::AnimateBetween(Property target, KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period, Interpolation interpolation )
333    */
334   void AnimateBetween(Property target, const KeyFrames& keyFrames, AlphaFunction alpha, TimePeriod period, Interpolation interpolation );
335
336   // Actor-specific convenience functions
337
338   /**
339    * @copydoc Dali::Animation::Animate( Actor actor, Path path, const Vector3& forward )
340    */
341   void Animate( Actor& actor, const Path& path, const Vector3& forward );
342
343   /**
344    * @copydoc Dali::Animation::Animate( Actor actor, Path path, const Vector3& forward, AlphaFunction alpha )
345    */
346   void Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha );
347
348   /**
349    * @copydoc Dali::Animation::Animate( Actor actor, Path path, const Vector3& forward, TimePeriod period )
350    */
351   void Animate( Actor& actor, const Path& path, const Vector3& forward, TimePeriod period );
352
353   /**
354    * @copydoc Dali::Animation::Animate( Actor actor, Path path, const Vector3& forward, AlphaFunction alpha, TimePeriod period)
355    */
356   void Animate( Actor& actor, const Path& path, const Vector3& forward, AlphaFunction alpha, TimePeriod period);
357
358   /**
359    * @copydoc Dali::Animation::Show()
360    */
361   void Show(Actor& actor, float delaySeconds);
362
363   /**
364    * @copydoc Dali::Animation::Hide()
365    */
366   void Hide(Actor& actor, float delaySeconds);
367
368   /**
369    * @copydoc Dali::Animation::SetCurrentProgress()
370    */
371   void SetCurrentProgress(float progress);
372
373   /**
374    * @copydoc Dali::Animation::GetCurrentProgress()
375    */
376   float GetCurrentProgress();
377
378   /**
379    * @copydoc Dali::Animation::SetSpeedFactor()
380    */
381   void SetSpeedFactor( float factor );
382
383   /**
384    * @copydoc Dali::Animation::GetSpeedFactor()
385    */
386   float GetSpeedFactor() const;
387
388   /**
389    * @copydoc Dali::Animation::SetPlayRange()
390    */
391   void SetPlayRange( const Vector2& range );
392
393   /**
394    * @copydoc Dali::Animation::GetPlayRange()
395    */
396   Vector2 GetPlayRange() const;
397
398   /**
399    * @copydoc Dali::Animation::SetLoopingMode()
400    */
401   void SetLoopingMode( Dali::Animation::LoopingMode loopingMode );
402
403   /**
404    * @copydoc Dali::Animation::GetLoopingMode()
405    */
406   Dali::Animation::LoopingMode GetLoopingMode() const;
407
408 public: // For connecting animators to animations
409
410   /**
411    * Add an animator connector.
412    * @param[in] connector The animator connector.
413    */
414   void AddAnimatorConnector( AnimatorConnectorBase* connector );
415
416   /**
417    * Retrieve the SceneGraph::Animation object.
418    * @return The animation.
419    */
420   const SceneGraph::Animation* GetSceneObject()
421   {
422     return mAnimation;
423   }
424
425   /**
426    * Retrieve the event thread services object
427    * @return The interface for sending messages to the scene graph
428    */
429   EventThreadServices& GetEventThreadServices()
430   {
431     return mEventThreadServices;
432   }
433
434 protected:
435
436   /**
437    * Construct a new Animation.
438    * @param[in] eventThreadServices The interface for sending messages to the scene graph
439    * @param[in] playlist The list of currently playing animations.
440    * @param[in] durationSeconds The duration of the animation in seconds.
441    * @param[in] endAction The action to perform when the animation ends.
442    * @param[in] disconnectAction The action to perform when the property owner of an animator is disconnected.
443    * @param[in] defaultAlpha The default alpha function to apply to animators.
444    */
445   Animation( EventThreadServices& eventThreadServices,
446              AnimationPlaylist& playlist,
447              float durationSeconds,
448              EndAction endAction,
449              EndAction disconnectAction,
450              AlphaFunction defaultAlpha);
451
452   /**
453    * Second-phase constructor.
454    */
455   void Initialize();
456
457   /**
458    * Helper to create a scene-graph animation
459    */
460   void CreateSceneObject();
461
462   /**
463    * Helper to create a scene-graph animation
464    */
465   void DestroySceneObject();
466
467   /**
468    * A reference counted object may only be deleted by calling Unreference()
469    */
470   virtual ~Animation();
471
472 private:
473
474   /**
475    * Extends the duration when an animator is added with TimePeriod that exceeds current duration.
476    * @param[in] timePeriod The time period for an animator.
477    */
478   void ExtendDuration( const TimePeriod& timePeriod );
479
480   // Undefined
481   Animation(const Animation&);
482
483   // Undefined
484   Animation& operator=(const Animation& rhs);
485
486 private:
487
488   struct ConnectorTargetValues
489   {
490     ConnectorTargetValues()
491     : targetValue(),
492       timePeriod( 0.0f ),
493       connectorIndex( 0 ),
494       animatorType( TO )
495     {
496     }
497
498     Property::Value targetValue;
499     TimePeriod timePeriod;
500     std::size_t connectorIndex;
501     Animation::Type animatorType;
502   };
503
504 private:
505
506   /**
507    * Compares the end times of the animators returning true if lhs end time is less than rhs end time.
508    * @param[in] lhs The first comparator
509    * @param[in] rhs The second comparator
510    * @return True if end time of lhs is less, false otherwise.
511    */
512   static bool CompareConnectorEndTimes( const ConnectorTargetValues& lhs, const ConnectorTargetValues& rhs );
513
514   /**
515    * Notifies all the objects whose properties are being animated.
516    */
517   void NotifyObjects();
518
519   /**
520    * Sends message to SceneGraph with final progress value
521    */
522   void SendFinalProgressNotificationMessage();
523
524 private:
525
526   const SceneGraph::Animation* mAnimation;
527
528   EventThreadServices& mEventThreadServices;
529   AnimationPlaylist& mPlaylist;
530
531   Dali::Animation::AnimationSignalType mFinishedSignal;
532
533   Dali::Animation::AnimationSignalType mProgressReachedSignal;
534
535   typedef OwnerContainer< AnimatorConnectorBase* > AnimatorConnectorContainer;
536   AnimatorConnectorContainer mConnectors; ///< Owned by the Animation
537
538   typedef std::vector< ConnectorTargetValues > ConnectorTargetValuesContainer;
539   ConnectorTargetValuesContainer mConnectorTargetValues; //< Used to store animating property target value information
540
541   Vector2 mPlayRange;
542
543   float mDurationSeconds;
544   float mSpeedFactor;
545   int mNotificationCount; ///< Keep track of how many Finished signals have been emitted.
546   int mLoopCount;
547   int mCurrentLoop;
548   EndAction mEndAction;
549   EndAction mDisconnectAction;
550   AlphaFunction mDefaultAlpha;
551   Dali::Animation::State mState;
552   float mProgressReachedMarker;
553   float mDelaySeconds;
554   bool mAutoReverseEnabled;  ///< Flag to identify that the looping mode is auto reverse.
555 };
556
557 } // namespace Internal
558
559 // Helpers for public-api forwarding methods
560
561 inline Internal::Animation& GetImplementation(Dali::Animation& animation)
562 {
563   DALI_ASSERT_ALWAYS( animation && "Animation handle is empty" );
564
565   BaseObject& handle = animation.GetBaseObject();
566
567   return static_cast<Internal::Animation&>(handle);
568 }
569
570 inline const Internal::Animation& GetImplementation(const Dali::Animation& animation)
571 {
572   DALI_ASSERT_ALWAYS( animation && "Animation handle is empty" );
573
574   const BaseObject& handle = animation.GetBaseObject();
575
576   return static_cast<const Internal::Animation&>(handle);
577 }
578
579 } // namespace Dali
580
581 #endif // __DALI_INTERNAL_ANIMATION_H__