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