summaryrefslogtreecommitdiffstats
path: root/xbmc/guilib/VisibleEffect.h
blob: 1cc4a092ccd2423ae5ae8801875967635c49fd0e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*
 *  Copyright (C) 2005-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#pragma once

enum ANIMATION_PROCESS { ANIM_PROCESS_NONE = 0, ANIM_PROCESS_NORMAL, ANIM_PROCESS_REVERSE };
enum ANIMATION_STATE { ANIM_STATE_NONE = 0, ANIM_STATE_DELAYED, ANIM_STATE_IN_PROCESS, ANIM_STATE_APPLIED };

// forward definitions

class TiXmlElement;
class Tweener;
class CGUIListItem;

#include "interfaces/info/InfoBool.h"
#include "utils/ColorUtils.h"
#include "utils/Geometry.h" // for CPoint, CRect
#include "utils/TransformMatrix.h" // needed for the TransformMatrix member

#include <memory>
#include <string>
#include <vector>

enum ANIMATION_TYPE
{
  ANIM_TYPE_UNFOCUS = -3,
  ANIM_TYPE_HIDDEN,
  ANIM_TYPE_WINDOW_CLOSE,
  ANIM_TYPE_NONE,
  ANIM_TYPE_WINDOW_OPEN,
  ANIM_TYPE_VISIBLE,
  ANIM_TYPE_FOCUS,
  ANIM_TYPE_CONDITIONAL       // for animations triggered by a condition change
};

class CAnimEffect
{
public:
  enum EFFECT_TYPE
  {
    EFFECT_TYPE_NONE = 0,
    EFFECT_TYPE_FADE,
    EFFECT_TYPE_FADE_DIFFUSE,
    EFFECT_TYPE_SLIDE,
    EFFECT_TYPE_ROTATE_X,
    EFFECT_TYPE_ROTATE_Y,
    EFFECT_TYPE_ROTATE_Z,
    EFFECT_TYPE_ZOOM
  };

  CAnimEffect(const TiXmlElement *node, EFFECT_TYPE effect);
  CAnimEffect(unsigned int delay, unsigned int length, EFFECT_TYPE effect);
  CAnimEffect(const CAnimEffect &src);

  virtual ~CAnimEffect();
  CAnimEffect& operator=(const CAnimEffect &src);

  void Calculate(unsigned int time, const CPoint &center);
  void ApplyState(ANIMATION_STATE state, const CPoint &center);

  unsigned int GetDelay() const { return m_delay; }
  unsigned int GetLength() const { return m_delay + m_length; }
  const TransformMatrix& GetTransform() const { return m_matrix; }
  EFFECT_TYPE GetType() const { return m_effect; }

  static std::shared_ptr<Tweener> GetTweener(const TiXmlElement *pAnimationNode);
protected:
  TransformMatrix m_matrix;
  EFFECT_TYPE m_effect;

private:
  virtual void ApplyEffect(float offset, const CPoint &center)=0;

  // timing variables
  unsigned int m_length;
  unsigned int m_delay;

  std::shared_ptr<Tweener> m_pTweener;
};

class CFadeEffect : public CAnimEffect
{
public:
  CFadeEffect(const TiXmlElement* node, bool reverseDefaults, EFFECT_TYPE effect);
  CFadeEffect(float start, float end, unsigned int delay, unsigned int length);
  CFadeEffect(UTILS::COLOR::Color start,
              UTILS::COLOR::Color end,
              unsigned int delay,
              unsigned int length);
  ~CFadeEffect() override = default;
private:
  void ApplyEffect(float offset, const CPoint &center) override;

  float m_startAlpha;
  float m_endAlpha;
  UTILS::COLOR::ColorFloats m_startColor;
  UTILS::COLOR::ColorFloats m_endColor;
};

class CSlideEffect : public CAnimEffect
{
public:
  explicit CSlideEffect(const TiXmlElement *node);
  ~CSlideEffect() override = default;
private:
  void ApplyEffect(float offset, const CPoint &center) override;

  float m_startX;
  float m_startY;
  float m_endX;
  float m_endY;
};

class CRotateEffect : public CAnimEffect
{
public:
  CRotateEffect(const TiXmlElement *node, EFFECT_TYPE effect);
  ~CRotateEffect() override = default;
private:
  void ApplyEffect(float offset, const CPoint &center) override;

  float m_startAngle;
  float m_endAngle;

  bool m_autoCenter;
  CPoint m_center;
};

class CZoomEffect : public CAnimEffect
{
public:
  CZoomEffect(const TiXmlElement *node, const CRect &rect);
  ~CZoomEffect() override = default;
private:
  void ApplyEffect(float offset, const CPoint &center) override;

  float m_startX;
  float m_startY;
  float m_endX;
  float m_endY;

  bool m_autoCenter;
  CPoint m_center;
};

class CAnimation
{
public:
  CAnimation();
  CAnimation(const CAnimation &src);

  virtual ~CAnimation();

  CAnimation& operator=(const CAnimation &src);

  static CAnimation CreateFader(float start, float end, unsigned int delay, unsigned int length, ANIMATION_TYPE type = ANIM_TYPE_NONE);

  void Create(const TiXmlElement *node, const CRect &rect, int context);

  void Animate(unsigned int time, bool startAnim);
  void ResetAnimation();
  void ApplyAnimation();
  inline void RenderAnimation(TransformMatrix &matrix)
  {
    RenderAnimation(matrix, CPoint());
  }
  void RenderAnimation(TransformMatrix &matrix, const CPoint &center);
  void QueueAnimation(ANIMATION_PROCESS process);

  inline bool IsReversible() const { return m_reversible; }
  inline ANIMATION_TYPE GetType() const { return m_type; }
  inline ANIMATION_STATE GetState() const { return m_currentState; }
  inline ANIMATION_PROCESS GetProcess() const { return m_currentProcess; }
  inline ANIMATION_PROCESS GetQueuedProcess() const { return m_queuedProcess; }

  bool CheckCondition();
  void UpdateCondition(const CGUIListItem *item = NULL);
  void SetInitialCondition();

private:
  void Calculate(const CPoint &point);
  void AddEffect(const std::string &type, const TiXmlElement *node, const CRect &rect);

  enum ANIM_REPEAT { ANIM_REPEAT_NONE = 0, ANIM_REPEAT_PULSE, ANIM_REPEAT_LOOP };

  // type of animation
  ANIMATION_TYPE m_type;
  bool m_reversible;
  INFO::InfoPtr m_condition;

  // conditional anims can repeat
  ANIM_REPEAT m_repeatAnim;
  bool m_lastCondition;

  // state of animation
  ANIMATION_PROCESS m_queuedProcess;
  ANIMATION_PROCESS m_currentProcess;
  ANIMATION_STATE m_currentState;

  // timing of animation
  unsigned int m_start;
  unsigned int m_length;
  unsigned int m_delay;
  unsigned int m_amount;

  std::vector<CAnimEffect *> m_effects;
};

/**
 * Class used to handle scrolling, allow using tweeners.
 * Usage:
 *   start scrolling using ScrollTo() method / stop scrolling using Stop() method
 *   update scroll value each frame with current time using Update() method
 *   get/set scroll value using GetValue()/SetValue()
 */
class CScroller
{
public:
  CScroller(unsigned int duration = 200, std::shared_ptr<Tweener> tweener = std::shared_ptr<Tweener>());
  CScroller(const CScroller& right);
  CScroller& operator=(const CScroller &src);
  ~CScroller();

  /**
   * Set target value scroller will be scrolling to
   * @param endPos target
   */
  void ScrollTo(float endPos);

  /**
   * Immediately stop scrolling
   */
  void Stop() { m_delta = 0; }
  /**
   * Update the scroller to where it would be at the given time point, calculating a new Value.
   * @param time time point
   * @return True if we are scrolling at given time point
   */
  bool Update(unsigned int time);

  /**
   * Value of scroll
   */
  float GetValue() const { return m_scrollValue; }
  void SetValue(float scrollValue) { m_scrollValue = scrollValue; }

  bool IsScrolling() const { return m_delta != 0; }
  bool IsScrollingUp() const { return m_delta < 0; }
  bool IsScrollingDown() const { return m_delta > 0; }

  unsigned int GetDuration() const { return m_duration; }

private:
  float Tween(float progress);

  float        m_scrollValue;
  float        m_delta;                   //!< Brief distance that we have to travel during scroll
  float        m_startPosition;           //!< Brief starting position of scroll
  bool         m_hasResumePoint;          //!< Brief check if we should tween from middle of the tween
  unsigned int m_startTime;               //!< Brief starting time of scroll

  unsigned int m_duration;                //!< Brief duration of scroll
  std::shared_ptr<Tweener> m_pTweener;
};