MythTV  master
mythuianimation.cpp
Go to the documentation of this file.
1 #include "mythuianimation.h"
2 #include "mythuitype.h"
3 #include "mythmainwindow.h"
4 
5 #include <QDomDocument>
6 
7 QRect UIEffects::GetExtent(const QSize &size)
8 {
9  int x = 0, y = 0;
10  int zoomedWidth = size.width() * m_hzoom;
11  int zoomedHeight = size.height() * m_vzoom;
12 
13  switch (m_centre)
14  {
15  case TopLeft:
16  case Top:
17  case TopRight:
18  y = -zoomedHeight / 2; break;
19  case Left:
20  case Middle:
21  case Right:
22  y = -size.height() / 2; break;
23  case BottomLeft:
24  case Bottom:
25  case BottomRight:
26  y = size.height() - zoomedHeight / 2; break;
27  }
28 
29  switch (m_centre)
30  {
31  case TopLeft:
32  case Left:
33  case BottomLeft:
34  x = -zoomedWidth / 2; break;
35  case Top:
36  case Middle:
37  case Bottom:
38  x = -size.width() / 2; break;
39  case TopRight:
40  case Right:
41  case BottomRight:
42  x = size.width() - zoomedWidth / 2; break;
43  }
44 
45  return {x, y, zoomedWidth, zoomedHeight};
46 }
47 
49 {
50  m_active = true;
51  setCurrentTime(0);
52 }
53 
54 void MythUIAnimation::updateCurrentValue(const QVariant& value)
55 {
56  if (!m_active)
57  return;
58 
59  m_value = value;
60  if (m_parent)
61  {
63 
64  if (Position == m_type)
65  m_parent->SetPosition(m_value.toPoint());
66  else if (Alpha == m_type)
67  m_parent->SetAlpha(m_value.toInt());
68  else if (Zoom == m_type)
69  m_parent->SetZoom(m_value.toFloat());
70  else if (HorizontalZoom == m_type)
72  else if (VerticalZoom == m_type)
73  m_parent->SetVerticalZoom(m_value.toFloat());
74  else if (Angle == m_type)
75  m_parent->SetAngle(m_value.toFloat());
76  }
77 }
78 
80 {
81  m_type = animation->m_type;
82  m_value = animation->m_value;
83  m_trigger = animation->m_trigger;
84  m_looped = animation->m_looped;
85  m_reversible = animation->m_reversible;
86  m_centre = animation->m_centre;
87 
88  setStartValue(animation->startValue());
89  setEndValue(animation->endValue());
90  setEasingCurve(animation->easingCurve());
91  setDuration(animation->duration());
92  if (m_looped)
93  setLoopCount(-1);
94 }
95 
97 {
98  if (!m_active)
99  return;
100 
101  int time = currentTime();
102  if (direction() == Forward)
103  time += GetMythMainWindow()->GetDrawInterval();
104  else
105  time -= GetMythMainWindow()->GetDrawInterval();
106 
107  setCurrentTime(time);
108 
109  if (endValue() == currentValue())
110  {
111  if (direction() == Forward)
112  {
113  if (m_reversible)
114  setDirection(Backward);
115  else if (!m_looped)
116  m_active = false;
117  }
118  }
119  else if (startValue() == currentValue())
120  {
121  if (direction() == Backward)
122  {
123  if (m_reversible)
124  setDirection(Forward);
125  else if (!m_looped)
126  m_active = false;
127  }
128  }
129 }
130 
131 void MythUIAnimation::SetEasingCurve(const QString& curve)
132 {
133  if (curve == "Linear") setEasingCurve(QEasingCurve::Linear);
134  else if (curve == "InQuad") setEasingCurve(QEasingCurve::InQuad);
135  else if (curve == "OutQuad") setEasingCurve(QEasingCurve::OutQuad);
136  else if (curve == "InOutQuad") setEasingCurve(QEasingCurve::InOutQuad);
137  else if (curve == "OutInQuad") setEasingCurve(QEasingCurve::OutInQuad);
138  else if (curve == "InCubic") setEasingCurve(QEasingCurve::InCubic);
139  else if (curve == "OutCubic") setEasingCurve(QEasingCurve::OutCubic);
140  else if (curve == "InOutCubic") setEasingCurve(QEasingCurve::InOutCubic);
141  else if (curve == "OutInCubic") setEasingCurve(QEasingCurve::OutInCubic);
142  else if (curve == "InQuart") setEasingCurve(QEasingCurve::InQuart);
143  else if (curve == "OutQuart") setEasingCurve(QEasingCurve::OutQuart);
144  else if (curve == "InOutQuart") setEasingCurve(QEasingCurve::InOutQuart);
145  else if (curve == "OutInQuart") setEasingCurve(QEasingCurve::OutInQuart);
146  else if (curve == "InQuint") setEasingCurve(QEasingCurve::InQuint);
147  else if (curve == "OutQuint") setEasingCurve(QEasingCurve::OutQuint);
148  else if (curve == "InOutQuint") setEasingCurve(QEasingCurve::InOutQuint);
149  else if (curve == "OutInQuint") setEasingCurve(QEasingCurve::OutInQuint);
150  else if (curve == "InSine") setEasingCurve(QEasingCurve::InSine);
151  else if (curve == "OutSine") setEasingCurve(QEasingCurve::OutSine);
152  else if (curve == "InOutSine") setEasingCurve(QEasingCurve::InOutSine);
153  else if (curve == "OutInSine") setEasingCurve(QEasingCurve::OutInSine);
154  else if (curve == "InExpo") setEasingCurve(QEasingCurve::InExpo);
155  else if (curve == "OutExpo") setEasingCurve(QEasingCurve::OutExpo);
156  else if (curve == "InOutExpo") setEasingCurve(QEasingCurve::InOutExpo);
157  else if (curve == "OutInExpo") setEasingCurve(QEasingCurve::OutInExpo);
158  else if (curve == "InCirc") setEasingCurve(QEasingCurve::InCirc);
159  else if (curve == "OutCirc") setEasingCurve(QEasingCurve::OutCirc);
160  else if (curve == "InOutCirc") setEasingCurve(QEasingCurve::InOutCirc);
161  else if (curve == "OutInCirc") setEasingCurve(QEasingCurve::OutInCirc);
162  else if (curve == "InElastic") setEasingCurve(QEasingCurve::InElastic);
163  else if (curve == "OutElastic") setEasingCurve(QEasingCurve::OutElastic);
164  else if (curve == "InOutElastic") setEasingCurve(QEasingCurve::InOutElastic);
165  else if (curve == "OutInElastic") setEasingCurve(QEasingCurve::OutInElastic);
166  else if (curve == "InBack") setEasingCurve(QEasingCurve::InBack);
167  else if (curve == "OutBack") setEasingCurve(QEasingCurve::OutBack);
168  else if (curve == "InOutBack") setEasingCurve(QEasingCurve::InOutBack);
169  else if (curve == "OutInBack") setEasingCurve(QEasingCurve::OutInBack);
170  else if (curve == "InBounce") setEasingCurve(QEasingCurve::InBounce);
171  else if (curve == "OutBounce") setEasingCurve(QEasingCurve::OutBounce);
172  else if (curve == "InOutBounce") setEasingCurve(QEasingCurve::InOutBounce);
173  else if (curve == "OutInBounce") setEasingCurve(QEasingCurve::OutInBounce);
174  else if (curve == "InCurve") setEasingCurve(QEasingCurve::InCurve);
175  else if (curve == "OutCurve") setEasingCurve(QEasingCurve::OutCurve);
176  else if (curve == "SineCurve") setEasingCurve(QEasingCurve::SineCurve);
177  else if (curve == "CosineCurve") setEasingCurve(QEasingCurve::CosineCurve);
178 }
179 
180 void MythUIAnimation::SetCentre(const QString &centre)
181 {
182  if (centre == "topleft") m_centre = UIEffects::TopLeft;
183  else if (centre == "top") m_centre = UIEffects::Top;
184  else if (centre == "topright") m_centre = UIEffects::TopRight;
185  else if (centre == "left") m_centre = UIEffects::Left;
186  else if (centre == "middle") m_centre = UIEffects::Middle;
187  else if (centre == "right") m_centre = UIEffects::Right;
188  else if (centre == "bottomleft") m_centre = UIEffects::BottomLeft;
189  else if (centre == "bottom") m_centre = UIEffects::Bottom;
190  else if (centre == "bottomright") m_centre = UIEffects::BottomRight;
191 }
192 
193 void MythUIAnimation::ParseElement(const QDomElement &element,
194  MythUIType* parent)
195 {
196  QString t = element.attribute("trigger", "AboutToShow");
197  Trigger trigger = AboutToShow;
198  if ("AboutToHide" == t)
199  trigger = AboutToHide;
200 
201  for (QDomNode child = element.firstChild(); !child.isNull();
202  child = child.nextSibling())
203  {
204  QDomElement section = child.toElement();
205  if (section.isNull())
206  continue;
207  if (section.tagName() == "section")
208  ParseSection(section, parent, trigger);
209  }
210 }
211 
212 void MythUIAnimation::ParseSection(const QDomElement &element,
213  MythUIType* parent, Trigger trigger)
214 {
215  int duration = element.attribute("duration", "500").toInt();
216  QString centre = element.attribute("centre", "Middle");
217  for (QDomNode child = element.firstChild(); !child.isNull();
218  child = child.nextSibling())
219  {
220  QDomElement effect = child.toElement();
221  if (effect.isNull())
222  continue;
223 
224  Type type = Alpha;
225  int effectduration = duration;
226  // override individual durations
227  QString effect_duration = effect.attribute("duration", "");
228  if (!effect_duration.isEmpty())
229  effectduration = effect_duration.toInt();
230 
231  bool looped = parseBool(effect.attribute("looped", "false"));
232  bool reversible = parseBool(effect.attribute("reversible", "false"));
233  QString easingcurve = effect.attribute("easingcurve", "Linear");
234  QVariant start;
235  QVariant end;
236 
237  QString fxtype = effect.tagName();
238  if (fxtype == "alpha")
239  {
240  type = Alpha;
241  parseAlpha(effect, start, end);
242  }
243  else if (fxtype == "position")
244  {
245  type = Position;
246  parsePosition(effect, start, end, parent);
247  }
248  else if (fxtype == "angle")
249  {
250  type = Angle;
251  parseAngle(effect, start, end);
252  }
253  else if (fxtype == "zoom")
254  {
255  type = Zoom;
256  parseZoom(effect, start, end);
257  }
258  else if (fxtype == "horizontalzoom")
259  {
261  parseZoom(effect, start, end);
262  }
263  else if (fxtype == "verticalzoom")
264  {
265  type = VerticalZoom;
266  parseZoom(effect, start, end);
267  }
268  else
269  continue;
270 
271  MythUIAnimation* a = new MythUIAnimation(parent, trigger, type);
272  a->setStartValue(start);
273  a->setEndValue(end);
274  a->setDuration(effectduration);
275  a->SetEasingCurve(easingcurve);
276  a->SetCentre(centre);
277  a->SetLooped(looped);
278  a->SetReversible(reversible);
279  if (looped)
280  a->setLoopCount(-1);
281  parent->GetAnimations()->append(a);
282  }
283 }
284 
285 void MythUIAnimation::parseAlpha(const QDomElement& element,
286  QVariant& startValue, QVariant& endValue)
287 {
288  startValue = element.attribute("start", "0").toInt();
289  endValue = element.attribute("end", "0").toInt();
290 }
291 
292 void MythUIAnimation::parsePosition(const QDomElement& element,
293  QVariant& startValue, QVariant& endValue,
294  MythUIType *parent)
295 {
296  MythPoint start = parsePoint(element.attribute("start", "0,0"), false);
297  MythPoint startN = parsePoint(element.attribute("start", "0,0"));
298  MythPoint end = parsePoint(element.attribute("end", "0,0"), false);
299  MythPoint endN = parsePoint(element.attribute("end", "0,0"));
300 
301  if (start.x() == -1)
302  startN.setX(parent->GetArea().x());
303 
304  if (start.y() == -1)
305  startN.setY(parent->GetArea().y());
306 
307  if (end.x() == -1)
308  endN.setX(parent->GetArea().x());
309 
310  if (end.y() == -1)
311  endN.setY(parent->GetArea().y());
312 
313  startN.CalculatePoint(parent->GetArea());
314  endN.CalculatePoint(parent->GetArea());
315 
316  startValue = startN.toQPoint();
317  endValue = endN.toQPoint();
318 }
319 
320 void MythUIAnimation::parseZoom(const QDomElement& element,
321  QVariant& startValue, QVariant& endValue)
322 {
323  startValue = element.attribute("start", "0").toFloat() / 100.0F;
324  endValue = element.attribute("end", "0").toFloat() /100.0F;
325 }
326 
327 void MythUIAnimation::parseAngle(const QDomElement& element,
328  QVariant& startValue, QVariant& endValue)
329 {
330  startValue = element.attribute("start", "0").toFloat();
331  endValue = element.attribute("end", "0").toFloat();
332 }
void SetCentre(const QString &centre)
void SetVerticalZoom(float zoom)
Definition: mythuitype.cpp:955
void setX(const QString &sX)
Definition: mythrect.cpp:450
static void parsePosition(const QDomElement &element, QVariant &startValue, QVariant &endValue, MythUIType *parent)
void SetReversible(bool rev)
void SetAlpha(int newalpha)
Definition: mythuitype.cpp:924
void SetHorizontalZoom(float zoom)
Definition: mythuitype.cpp:949
static void parseAngle(const QDomElement &element, QVariant &startValue, QVariant &endValue)
The base class on which all widgets and screens are based.
Definition: mythuitype.h:63
void SetPosition(int x, int y)
Convenience method, calls SetPosition(const MythPoint&) Override that instead to change functionality...
Definition: mythuitype.cpp:519
static MythPoint parsePoint(const QString &text, bool normalize=true)
void CopyFrom(const MythUIAnimation *animation)
Centre m_centre
MythUIType * m_parent
static void ParseElement(const QDomElement &element, MythUIType *parent)
virtual MythRect GetArea(void) const
If the object has a minimum area defined, return it, other wise return the default area.
Definition: mythuitype.cpp:863
unsigned char t
Definition: ParseText.cpp:329
int GetDrawInterval() const
static void parseAlpha(const QDomElement &element, QVariant &startValue, QVariant &endValue)
MythUIAnimation(MythUIType *parent=nullptr, Trigger trigger=AboutToShow, Type type=Alpha)
QRect GetExtent(const QSize &size)
MythMainWindow * GetMythMainWindow(void)
void SetEasingCurve(const QString &curve)
static void parseZoom(const QDomElement &element, QVariant &startValue, QVariant &endValue)
void SetLooped(bool looped)
static void ParseSection(const QDomElement &element, MythUIType *parent, Trigger trigger)
QList< MythUIAnimation * > * GetAnimations(void)
Definition: mythuitype.h:101
Wrapper around QPoint allowing us to handle percentage and other relative values for positioning in m...
Definition: mythrect.h:86
void updateCurrentValue(const QVariant &value) override
UIEffects::Centre m_centre
void SetAngle(float angle)
Definition: mythuitype.cpp:961
static bool parseBool(const QString &text)
void IncrementCurrentTime(void)
void SetCentre(UIEffects::Centre centre)
Definition: mythuitype.cpp:938
void SetZoom(float zoom)
Definition: mythuitype.cpp:943