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) const
8 {
9  int x = 0;
10  int y = 0;
11  int zoomedWidth = static_cast<int>(static_cast<float>(size.width()) * m_hzoom);
12  int zoomedHeight = static_cast<int>(static_cast<float>(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  std::chrono::milliseconds current = MythDate::currentMSecsSinceEpochAsDuration();
103  std::chrono::milliseconds interval = std::clamp(current - m_lastUpdate, 10ms, 50ms);
105 
106  int offset = (direction() == Forward) ? interval.count() : -interval.count();
107  setCurrentTime(currentTime() + offset);
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  auto* 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 }
MythUIAnimation::m_trigger
Trigger m_trigger
Definition: mythuianimation.h:85
UIEffects::TopLeft
@ TopLeft
Definition: mythuianimation.h:16
XMLParseBase::parsePoint
static MythPoint parsePoint(const QString &text, bool normalize=true)
Definition: xmlparsebase.cpp:75
MythUIAnimation::HorizontalZoom
@ HorizontalZoom
Definition: mythuianimation.h:49
MythUIAnimation::m_value
QVariant m_value
Definition: mythuianimation.h:87
MythPoint::toQPoint
QPoint toQPoint(void) const
Definition: mythrect.cpp:594
MythUIAnimation::Type
Type
Definition: mythuianimation.h:49
MythUIAnimation::m_active
bool m_active
Definition: mythuianimation.h:88
MythUIAnimation::ParseElement
static void ParseElement(const QDomElement &element, MythUIType *parent)
Definition: mythuianimation.cpp:193
MythUIAnimation::ParseSection
static void ParseSection(const QDomElement &element, MythUIType *parent, Trigger trigger)
Definition: mythuianimation.cpp:212
MythUIAnimation::parseZoom
static void parseZoom(const QDomElement &element, QVariant &startValue, QVariant &endValue)
Definition: mythuianimation.cpp:320
MythUIAnimation::CopyFrom
void CopyFrom(const MythUIAnimation *animation)
Definition: mythuianimation.cpp:80
MythUIAnimation::m_reversible
bool m_reversible
Definition: mythuianimation.h:90
MythUIAnimation::Trigger
Trigger
Definition: mythuianimation.h:50
UIEffects::BottomLeft
@ BottomLeft
Definition: mythuianimation.h:18
MythPoint::CalculatePoint
void CalculatePoint(QRect parentArea)
Definition: mythrect.cpp:444
MythUIAnimation::MythUIAnimation
MythUIAnimation(MythUIType *parent=nullptr, Trigger trigger=AboutToShow, Type type=Alpha)
Definition: mythuianimation.h:52
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
MythUIAnimation::Alpha
@ Alpha
Definition: mythuianimation.h:49
MythUIAnimation::m_centre
UIEffects::Centre m_centre
Definition: mythuianimation.h:86
MythUIType::GetArea
virtual MythRect GetArea(void) const
If the object has a minimum area defined, return it, other wise return the default area.
Definition: mythuitype.cpp:884
MythUIAnimation::VerticalZoom
@ VerticalZoom
Definition: mythuianimation.h:49
MythUIAnimation::parsePosition
static void parsePosition(const QDomElement &element, QVariant &startValue, QVariant &endValue, MythUIType *parent)
Definition: mythuianimation.cpp:292
UIEffects::Bottom
@ Bottom
Definition: mythuianimation.h:18
MythUIType::SetAlpha
void SetAlpha(int newalpha)
Definition: mythuitype.cpp:945
MythUIType::SetZoom
void SetZoom(float zoom)
Definition: mythuitype.cpp:964
MythUIAnimation::AboutToShow
@ AboutToShow
Definition: mythuianimation.h:50
UIEffects::TopRight
@ TopRight
Definition: mythuianimation.h:16
MythUIType::SetPosition
void SetPosition(int x, int y)
Convenience method, calls SetPosition(const MythPoint&) Override that instead to change functionality...
Definition: mythuitype.cpp:532
hardwareprofile.i18n.t
t
Definition: i18n.py:36
UIEffects::Middle
@ Middle
Definition: mythuianimation.h:17
MythUIAnimation::m_looped
bool m_looped
Definition: mythuianimation.h:89
UIEffects::BottomRight
@ BottomRight
Definition: mythuianimation.h:18
MythPoint::setY
void setY(const QString &sY)
Definition: mythrect.cpp:540
MythUIAnimation::parseAngle
static void parseAngle(const QDomElement &element, QVariant &startValue, QVariant &endValue)
Definition: mythuianimation.cpp:327
MythUIAnimation::updateCurrentValue
void updateCurrentValue(const QVariant &value) override
Definition: mythuianimation.cpp:55
UIEffects::Top
@ Top
Definition: mythuianimation.h:16
MythUIAnimation::SetEasingCurve
void SetEasingCurve(const QString &curve)
Definition: mythuianimation.cpp:131
MythUIAnimation::Angle
@ Angle
Definition: mythuianimation.h:49
UIEffects::m_centre
Centre m_centre
Definition: mythuianimation.h:43
MythUIAnimation::m_type
Type m_type
Definition: mythuianimation.h:84
MythUIType
The base class on which all widgets and screens are based.
Definition: mythuitype.h:85
MythUIAnimation::parseAlpha
static void parseAlpha(const QDomElement &element, QVariant &startValue, QVariant &endValue)
Definition: mythuianimation.cpp:285
MythDate::currentMSecsSinceEpochAsDuration
std::chrono::milliseconds currentMSecsSinceEpochAsDuration(void)
Definition: mythdate.cpp:198
MythUIAnimation::Position
@ Position
Definition: mythuianimation.h:49
MythUIAnimation::m_parent
MythUIType * m_parent
Definition: mythuianimation.h:83
UIEffects::m_vzoom
float m_vzoom
Definition: mythuianimation.h:41
MythUIAnimation::Zoom
@ Zoom
Definition: mythuianimation.h:49
MythUIAnimation::IncrementCurrentTime
void IncrementCurrentTime(void)
Definition: mythuianimation.cpp:97
MythUIAnimation
Definition: mythuianimation.h:46
UIEffects::Left
@ Left
Definition: mythuianimation.h:17
MythUIAnimation::AboutToHide
@ AboutToHide
Definition: mythuianimation.h:50
MythUIType::SetHorizontalZoom
void SetHorizontalZoom(float zoom)
Definition: mythuitype.cpp:970
MythUIType::SetCentre
void SetCentre(UIEffects::Centre centre)
Definition: mythuitype.cpp:959
MythUIType::SetAngle
void SetAngle(float angle)
Definition: mythuitype.cpp:982
MythUIAnimation::Activate
void Activate(void)
Definition: mythuianimation.cpp:49
UIEffects::m_hzoom
float m_hzoom
Definition: mythuianimation.h:40
MythPoint::setX
void setX(const QString &sX)
Definition: mythrect.cpp:530
MythUIType::GetAnimations
QList< MythUIAnimation * > * GetAnimations(void)
Definition: mythuitype.h:124
mythuianimation.h
MythUIType::SetVerticalZoom
void SetVerticalZoom(float zoom)
Definition: mythuitype.cpp:976
mythmainwindow.h
MythUIAnimation::SetCentre
void SetCentre(const QString &centre)
Definition: mythuianimation.cpp:180
UIEffects::Right
@ Right
Definition: mythuianimation.h:17
XMLParseBase::parseBool
static bool parseBool(const QString &text)
Definition: xmlparsebase.cpp:64
UIEffects::GetExtent
QRect GetExtent(QSize size) const
Definition: mythuianimation.cpp:7
MythUIAnimation::m_lastUpdate
std::chrono::milliseconds m_lastUpdate
Definition: mythuianimation.h:91
mythuitype.h
MythPoint
Wrapper around QPoint allowing us to handle percentage and other relative values for positioning in m...
Definition: mythrect.h:88