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