00001 #include "mythuianimation.h"
00002 #include "mythuitype.h"
00003 #include "mythmainwindow.h"
00004
00005 #include <QDomDocument>
00006
00007 MythUIAnimation::MythUIAnimation(MythUIType* parent, Trigger trigger, Type type)
00008 : m_parent(parent), m_type(type), m_trigger(trigger),
00009 m_centre(UIEffects::Middle), m_active(false), m_looped(false),
00010 m_reversible(false)
00011 {
00012 }
00013
00014 void MythUIAnimation::Activate(void)
00015 {
00016 m_active = true;
00017 setCurrentTime(0);
00018 }
00019
00020 void MythUIAnimation::updateCurrentValue(const QVariant& value)
00021 {
00022 if (!m_active)
00023 return;
00024
00025 m_value = value;
00026 if (m_parent)
00027 {
00028 m_parent->SetCentre(m_centre);
00029
00030 if (Position == m_type)
00031 m_parent->SetPosition(m_value.toPoint());
00032 else if (Alpha == m_type)
00033 m_parent->SetAlpha(m_value.toInt());
00034 else if (Zoom == m_type)
00035 m_parent->SetZoom(m_value.toFloat());
00036 else if (HorizontalZoom == m_type)
00037 m_parent->SetHorizontalZoom(m_value.toFloat());
00038 else if (VerticalZoom == m_type)
00039 m_parent->SetVerticalZoom(m_value.toFloat());
00040 else if (Angle == m_type)
00041 m_parent->SetAngle(m_value.toFloat());
00042 }
00043 }
00044
00045 void MythUIAnimation::CopyFrom(const MythUIAnimation* animation)
00046 {
00047 m_type = animation->m_type;
00048 m_value = animation->m_value;
00049 m_trigger = animation->m_trigger;
00050 m_looped = animation->m_looped;
00051 m_reversible = animation->m_reversible;
00052 m_centre = animation->m_centre;
00053
00054 setStartValue(animation->startValue());
00055 setEndValue(animation->endValue());
00056 setEasingCurve(animation->easingCurve());
00057 setDuration(animation->duration());
00058 if (m_looped)
00059 setLoopCount(-1);
00060 }
00061
00062 void MythUIAnimation::IncrementCurrentTime(void)
00063 {
00064 if (!m_active)
00065 return;
00066
00067 int time = currentTime();
00068 if (direction() == Forward)
00069 time += GetMythMainWindow()->GetDrawInterval();
00070 else
00071 time -= GetMythMainWindow()->GetDrawInterval();
00072
00073 setCurrentTime(time);
00074
00075 if (endValue() == currentValue())
00076 {
00077 if (direction() == Forward)
00078 {
00079 if (m_reversible)
00080 setDirection(Backward);
00081 else if (!m_looped)
00082 m_active = false;
00083 }
00084 }
00085 else if (startValue() == currentValue())
00086 {
00087 if (direction() == Backward)
00088 {
00089 if (m_reversible)
00090 setDirection(Forward);
00091 else if (!m_looped)
00092 m_active = false;
00093 }
00094 }
00095 }
00096
00097 void MythUIAnimation::SetEasingCurve(const QString& curve)
00098 {
00099 if (curve == "Linear") setEasingCurve(QEasingCurve::Linear);
00100 else if (curve == "InQuad") setEasingCurve(QEasingCurve::InQuad);
00101 else if (curve == "OutQuad") setEasingCurve(QEasingCurve::OutQuad);
00102 else if (curve == "InOutQuad") setEasingCurve(QEasingCurve::InOutQuad);
00103 else if (curve == "OutInQuad") setEasingCurve(QEasingCurve::OutInQuad);
00104 else if (curve == "InCubic") setEasingCurve(QEasingCurve::InCubic);
00105 else if (curve == "OutCubic") setEasingCurve(QEasingCurve::OutCubic);
00106 else if (curve == "InOutCubic") setEasingCurve(QEasingCurve::InOutCubic);
00107 else if (curve == "OutInCubic") setEasingCurve(QEasingCurve::OutInCubic);
00108 else if (curve == "InQuart") setEasingCurve(QEasingCurve::InQuart);
00109 else if (curve == "OutQuart") setEasingCurve(QEasingCurve::OutQuart);
00110 else if (curve == "InOutQuart") setEasingCurve(QEasingCurve::InOutQuart);
00111 else if (curve == "OutInQuart") setEasingCurve(QEasingCurve::OutInQuart);
00112 else if (curve == "InQuint") setEasingCurve(QEasingCurve::InQuint);
00113 else if (curve == "OutQuint") setEasingCurve(QEasingCurve::OutQuint);
00114 else if (curve == "InOutQuint") setEasingCurve(QEasingCurve::InOutQuint);
00115 else if (curve == "OutInQuint") setEasingCurve(QEasingCurve::OutInQuint);
00116 else if (curve == "InSine") setEasingCurve(QEasingCurve::InSine);
00117 else if (curve == "OutSine") setEasingCurve(QEasingCurve::OutSine);
00118 else if (curve == "InOutSine") setEasingCurve(QEasingCurve::InOutSine);
00119 else if (curve == "OutInSine") setEasingCurve(QEasingCurve::OutInSine);
00120 else if (curve == "InExpo") setEasingCurve(QEasingCurve::InExpo);
00121 else if (curve == "OutExpo") setEasingCurve(QEasingCurve::OutExpo);
00122 else if (curve == "InOutExpo") setEasingCurve(QEasingCurve::InOutExpo);
00123 else if (curve == "OutInExpo") setEasingCurve(QEasingCurve::OutInExpo);
00124 else if (curve == "InCirc") setEasingCurve(QEasingCurve::InCirc);
00125 else if (curve == "OutCirc") setEasingCurve(QEasingCurve::OutCirc);
00126 else if (curve == "InOutCirc") setEasingCurve(QEasingCurve::InOutCirc);
00127 else if (curve == "OutInCirc") setEasingCurve(QEasingCurve::OutInCirc);
00128 else if (curve == "InElastic") setEasingCurve(QEasingCurve::InElastic);
00129 else if (curve == "OutElastic") setEasingCurve(QEasingCurve::OutElastic);
00130 else if (curve == "InOutElastic") setEasingCurve(QEasingCurve::InOutElastic);
00131 else if (curve == "OutInElastic") setEasingCurve(QEasingCurve::OutInElastic);
00132 else if (curve == "InBack") setEasingCurve(QEasingCurve::InBack);
00133 else if (curve == "OutBack") setEasingCurve(QEasingCurve::OutBack);
00134 else if (curve == "InOutBack") setEasingCurve(QEasingCurve::InOutBack);
00135 else if (curve == "OutInBack") setEasingCurve(QEasingCurve::OutInBack);
00136 else if (curve == "InBounce") setEasingCurve(QEasingCurve::InBounce);
00137 else if (curve == "OutBounce") setEasingCurve(QEasingCurve::OutBounce);
00138 else if (curve == "InOutBounce") setEasingCurve(QEasingCurve::InOutBounce);
00139 else if (curve == "OutInBounce") setEasingCurve(QEasingCurve::OutInBounce);
00140 else if (curve == "InCurve") setEasingCurve(QEasingCurve::InCurve);
00141 else if (curve == "OutCurve") setEasingCurve(QEasingCurve::OutCurve);
00142 else if (curve == "SineCurve") setEasingCurve(QEasingCurve::SineCurve);
00143 else if (curve == "CosineCurve") setEasingCurve(QEasingCurve::CosineCurve);
00144 }
00145
00146 void MythUIAnimation::SetCentre(const QString ¢re)
00147 {
00148 if (centre == "topleft") m_centre = UIEffects::TopLeft;
00149 else if (centre == "top") m_centre = UIEffects::Top;
00150 else if (centre == "topright") m_centre = UIEffects::TopRight;
00151 else if (centre == "left") m_centre = UIEffects::Left;
00152 else if (centre == "middle") m_centre = UIEffects::Middle;
00153 else if (centre == "right") m_centre = UIEffects::Right;
00154 else if (centre == "bottomleft") m_centre = UIEffects::BottomLeft;
00155 else if (centre == "bottom") m_centre = UIEffects::Bottom;
00156 else if (centre == "bottomright") m_centre = UIEffects::BottomRight;
00157 }
00158
00159 void MythUIAnimation::ParseElement(const QDomElement &element,
00160 MythUIType* parent)
00161 {
00162 QString t = element.attribute("trigger", "AboutToShow");
00163 Trigger trigger = AboutToShow;
00164 if ("AboutToHide" == t)
00165 trigger = AboutToHide;
00166
00167 for (QDomNode child = element.firstChild(); !child.isNull();
00168 child = child.nextSibling())
00169 {
00170 QDomElement section = child.toElement();
00171 if (section.isNull())
00172 continue;
00173 if (section.tagName() == "section")
00174 ParseSection(section, parent, trigger);
00175 }
00176 }
00177
00178 void MythUIAnimation::ParseSection(const QDomElement &element,
00179 MythUIType* parent, Trigger trigger)
00180 {
00181 int duration = element.attribute("duration", "500").toInt();
00182 QString centre = element.attribute("centre", "Middle");
00183 for (QDomNode child = element.firstChild(); !child.isNull();
00184 child = child.nextSibling())
00185 {
00186 QDomElement effect = child.toElement();
00187 if (effect.isNull())
00188 continue;
00189
00190 Type type = Alpha;
00191 int effectduration = duration;
00192
00193 QString effect_duration = effect.attribute("duration", "");
00194 if (!effect_duration.isEmpty())
00195 effectduration = effect_duration.toInt();
00196
00197 bool looped = parseBool(effect.attribute("looped", "false"));
00198 bool reversible = parseBool(effect.attribute("reversible", "false"));
00199 QString easingcurve = effect.attribute("easingcurve", "Linear");
00200 QVariant start;
00201 QVariant end;
00202
00203 QString fxtype = effect.tagName();
00204 if (fxtype == "alpha")
00205 {
00206 type = Alpha;
00207 parseAlpha(effect, start, end);
00208 }
00209 else if (fxtype == "position")
00210 {
00211 type = Position;
00212 parsePosition(effect, start, end, parent);
00213 }
00214 else if (fxtype == "angle")
00215 {
00216 type = Angle;
00217 parseAngle(effect, start, end);
00218 }
00219 else if (fxtype == "zoom")
00220 {
00221 type = Zoom;
00222 parseZoom(effect, start, end);
00223 }
00224 else if (fxtype == "horizontalzoom")
00225 {
00226 type = HorizontalZoom;
00227 parseZoom(effect, start, end);
00228 }
00229 else if (fxtype == "verticalzoom")
00230 {
00231 type = VerticalZoom;
00232 parseZoom(effect, start, end);
00233 }
00234 else
00235 continue;
00236
00237 MythUIAnimation* a = new MythUIAnimation(parent, trigger, type);
00238 a->setStartValue(start);
00239 a->setEndValue(end);
00240 a->setDuration(effectduration);
00241 a->SetEasingCurve(easingcurve);
00242 a->SetCentre(centre);
00243 a->SetLooped(looped);
00244 a->SetReversible(reversible);
00245 if (looped)
00246 a->setLoopCount(-1);
00247 parent->GetAnimations()->append(a);
00248 }
00249 }
00250
00251 void MythUIAnimation::parseAlpha(const QDomElement& element,
00252 QVariant& startValue, QVariant& endValue)
00253 {
00254 startValue = element.attribute("start", "0").toInt();
00255 endValue = element.attribute("end", "0").toInt();
00256 }
00257
00258 void MythUIAnimation::parsePosition(const QDomElement& element,
00259 QVariant& startValue, QVariant& endValue,
00260 MythUIType *parent)
00261 {
00262 MythPoint start = parsePoint(element.attribute("start", "0,0"), false);
00263 MythPoint startN = parsePoint(element.attribute("start", "0,0"));
00264 MythPoint end = parsePoint(element.attribute("end", "0,0"), false);
00265 MythPoint endN = parsePoint(element.attribute("end", "0,0"));
00266
00267 if (start.x() == -1)
00268 startN.setX(parent->GetArea().x());
00269
00270 if (start.y() == -1)
00271 startN.setY(parent->GetArea().y());
00272
00273 if (end.x() == -1)
00274 endN.setX(parent->GetArea().x());
00275
00276 if (end.y() == -1)
00277 endN.setY(parent->GetArea().y());
00278
00279 startN.CalculatePoint(parent->GetArea());
00280 endN.CalculatePoint(parent->GetArea());
00281
00282 startValue = startN.toQPoint();
00283 endValue = endN.toQPoint();
00284 }
00285
00286 void MythUIAnimation::parseZoom(const QDomElement& element,
00287 QVariant& startValue, QVariant& endValue)
00288 {
00289 startValue = element.attribute("start", "0").toFloat() / 100.0;
00290 endValue = element.attribute("end", "0").toFloat() /100.0;
00291 }
00292
00293 void MythUIAnimation::parseAngle(const QDomElement& element,
00294 QVariant& startValue, QVariant& endValue)
00295 {
00296 startValue = element.attribute("start", "0").toFloat();
00297 endValue = element.attribute("end", "0").toFloat();
00298 }