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