1 /*
2  *  Copyright (C) 2005-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 enum ANIMATION_PROCESS { ANIM_PROCESS_NONE = 0, ANIM_PROCESS_NORMAL, ANIM_PROCESS_REVERSE };
12 enum ANIMATION_STATE { ANIM_STATE_NONE = 0, ANIM_STATE_DELAYED, ANIM_STATE_IN_PROCESS, ANIM_STATE_APPLIED };
13 
14 // forward definitions
15 
16 class TiXmlElement;
17 class Tweener;
18 class CGUIListItem;
19 
20 #include "utils/TransformMatrix.h"  // needed for the TransformMatrix member
21 #include "utils/Geometry.h"         // for CPoint, CRect
22 #include <memory>
23 #include "interfaces/info/InfoBool.h"
24 
25 #include <string>
26 #include <vector>
27 
28 enum ANIMATION_TYPE
29 {
30   ANIM_TYPE_UNFOCUS = -3,
31   ANIM_TYPE_HIDDEN,
32   ANIM_TYPE_WINDOW_CLOSE,
33   ANIM_TYPE_NONE,
34   ANIM_TYPE_WINDOW_OPEN,
35   ANIM_TYPE_VISIBLE,
36   ANIM_TYPE_FOCUS,
37   ANIM_TYPE_CONDITIONAL       // for animations triggered by a condition change
38 };
39 
40 class CAnimEffect
41 {
42 public:
43   enum EFFECT_TYPE { EFFECT_TYPE_NONE = 0, EFFECT_TYPE_FADE, EFFECT_TYPE_SLIDE, EFFECT_TYPE_ROTATE_X, EFFECT_TYPE_ROTATE_Y, EFFECT_TYPE_ROTATE_Z, EFFECT_TYPE_ZOOM };
44 
45   CAnimEffect(const TiXmlElement *node, EFFECT_TYPE effect);
46   CAnimEffect(unsigned int delay, unsigned int length, EFFECT_TYPE effect);
47   CAnimEffect(const CAnimEffect &src);
48 
49   virtual ~CAnimEffect();
50   CAnimEffect& operator=(const CAnimEffect &src);
51 
52   void Calculate(unsigned int time, const CPoint &center);
53   void ApplyState(ANIMATION_STATE state, const CPoint &center);
54 
GetDelay()55   unsigned int GetDelay() const { return m_delay; };
GetLength()56   unsigned int GetLength() const { return m_delay + m_length; };
GetTransform()57   const TransformMatrix &GetTransform() const { return m_matrix; };
GetType()58   EFFECT_TYPE GetType() const { return m_effect; };
59 
60   static std::shared_ptr<Tweener> GetTweener(const TiXmlElement *pAnimationNode);
61 protected:
62   TransformMatrix m_matrix;
63   EFFECT_TYPE m_effect;
64 
65 private:
66   virtual void ApplyEffect(float offset, const CPoint &center)=0;
67 
68   // timing variables
69   unsigned int m_length;
70   unsigned int m_delay;
71 
72   std::shared_ptr<Tweener> m_pTweener;
73 };
74 
75 class CFadeEffect : public CAnimEffect
76 {
77 public:
78   CFadeEffect(const TiXmlElement *node, bool reverseDefaults);
79   CFadeEffect(float start, float end, unsigned int delay, unsigned int length);
80   ~CFadeEffect() override = default;
81 private:
82   void ApplyEffect(float offset, const CPoint &center) override;
83 
84   float m_startAlpha;
85   float m_endAlpha;
86 };
87 
88 class CSlideEffect : public CAnimEffect
89 {
90 public:
91   explicit CSlideEffect(const TiXmlElement *node);
92   ~CSlideEffect() override = default;
93 private:
94   void ApplyEffect(float offset, const CPoint &center) override;
95 
96   float m_startX;
97   float m_startY;
98   float m_endX;
99   float m_endY;
100 };
101 
102 class CRotateEffect : public CAnimEffect
103 {
104 public:
105   CRotateEffect(const TiXmlElement *node, EFFECT_TYPE effect);
106   ~CRotateEffect() override = default;
107 private:
108   void ApplyEffect(float offset, const CPoint &center) override;
109 
110   float m_startAngle;
111   float m_endAngle;
112 
113   bool m_autoCenter;
114   CPoint m_center;
115 };
116 
117 class CZoomEffect : public CAnimEffect
118 {
119 public:
120   CZoomEffect(const TiXmlElement *node, const CRect &rect);
121   ~CZoomEffect() override = default;
122 private:
123   void ApplyEffect(float offset, const CPoint &center) override;
124 
125   float m_startX;
126   float m_startY;
127   float m_endX;
128   float m_endY;
129 
130   bool m_autoCenter;
131   CPoint m_center;
132 };
133 
134 class CAnimation
135 {
136 public:
137   CAnimation();
138   CAnimation(const CAnimation &src);
139 
140   virtual ~CAnimation();
141 
142   CAnimation& operator=(const CAnimation &src);
143 
144   static CAnimation CreateFader(float start, float end, unsigned int delay, unsigned int length, ANIMATION_TYPE type = ANIM_TYPE_NONE);
145 
146   void Create(const TiXmlElement *node, const CRect &rect, int context);
147 
148   void Animate(unsigned int time, bool startAnim);
149   void ResetAnimation();
150   void ApplyAnimation();
RenderAnimation(TransformMatrix & matrix)151   inline void RenderAnimation(TransformMatrix &matrix)
152   {
153     RenderAnimation(matrix, CPoint());
154   }
155   void RenderAnimation(TransformMatrix &matrix, const CPoint &center);
156   void QueueAnimation(ANIMATION_PROCESS process);
157 
IsReversible()158   inline bool IsReversible() const { return m_reversible; };
GetType()159   inline ANIMATION_TYPE GetType() const { return m_type; };
GetState()160   inline ANIMATION_STATE GetState() const { return m_currentState; };
GetProcess()161   inline ANIMATION_PROCESS GetProcess() const { return m_currentProcess; };
GetQueuedProcess()162   inline ANIMATION_PROCESS GetQueuedProcess() const { return m_queuedProcess; };
163 
164   bool CheckCondition();
165   void UpdateCondition(const CGUIListItem *item = NULL);
166   void SetInitialCondition();
167 
168 private:
169   void Calculate(const CPoint &point);
170   void AddEffect(const std::string &type, const TiXmlElement *node, const CRect &rect);
171 
172   enum ANIM_REPEAT { ANIM_REPEAT_NONE = 0, ANIM_REPEAT_PULSE, ANIM_REPEAT_LOOP };
173 
174   // type of animation
175   ANIMATION_TYPE m_type;
176   bool m_reversible;
177   INFO::InfoPtr m_condition;
178 
179   // conditional anims can repeat
180   ANIM_REPEAT m_repeatAnim;
181   bool m_lastCondition;
182 
183   // state of animation
184   ANIMATION_PROCESS m_queuedProcess;
185   ANIMATION_PROCESS m_currentProcess;
186   ANIMATION_STATE m_currentState;
187 
188   // timing of animation
189   unsigned int m_start;
190   unsigned int m_length;
191   unsigned int m_delay;
192   unsigned int m_amount;
193 
194   std::vector<CAnimEffect *> m_effects;
195 };
196 
197 /**
198  * Class used to handle scrolling, allow using tweeners.
199  * Usage:
200  *   start scrolling using ScrollTo() method / stop scrolling using Stop() method
201  *   update scroll value each frame with current time using Update() method
202  *   get/set scroll value using GetValue()/SetValue()
203  */
204 class CScroller
205 {
206 public:
207   CScroller(unsigned int duration = 200, std::shared_ptr<Tweener> tweener = std::shared_ptr<Tweener>());
208   CScroller(const CScroller& right);
209   CScroller& operator=(const CScroller &src);
210   ~CScroller();
211 
212   /**
213    * Set target value scroller will be scrolling to
214    * @param endPos target
215    */
216   void ScrollTo(float endPos);
217 
218   /**
219    * Immediately stop scrolling
220    */
Stop()221   void Stop() { m_delta = 0; };
222   /**
223    * Update the scroller to where it would be at the given time point, calculating a new Value.
224    * @param time time point
225    * @return True if we are scrolling at given time point
226    */
227   bool Update(unsigned int time);
228 
229   /**
230    * Value of scroll
231    */
GetValue()232   float GetValue() const { return m_scrollValue; };
SetValue(float scrollValue)233   void SetValue(float scrollValue) { m_scrollValue = scrollValue; };
234 
IsScrolling()235   bool IsScrolling() const { return m_delta != 0; };
IsScrollingUp()236   bool IsScrollingUp() const { return m_delta < 0; };
IsScrollingDown()237   bool IsScrollingDown() const { return m_delta > 0; };
238 
GetDuration()239   unsigned int GetDuration() const { return m_duration; };
240 private:
241   float Tween(float progress);
242 
243   float        m_scrollValue;
244   float        m_delta;                   //!< Brief distance that we have to travel during scroll
245   float        m_startPosition;           //!< Brief starting position of scroll
246   bool         m_hasResumePoint;          //!< Brief check if we should tween from middle of the tween
247   unsigned int m_startTime;               //!< Brief starting time of scroll
248 
249   unsigned int m_duration;                //!< Brief duration of scroll
250   std::shared_ptr<Tweener> m_pTweener;
251 };
252