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