From b953f0a046e9cd1b92f282a1654886e24e6dd510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20K=C3=BCgler?= Date: Fri, 18 Apr 2008 23:57:05 +0000 Subject: [PATCH] Introduce TimeLine, a class providing non-linear animation patterns to KWin effects. The class basically wraps QTimeLine right now, but it's easy to pop in function implementing different animation timeline patterns. Patches to the first effects using this TimeLine are coming up ... svn path=/trunk/KDE/kdebase/workspace/; revision=798719 --- lib/kwineffects.cpp | 105 ++++++++++++++++++++++++++++++++++++++++ lib/kwineffects.h | 115 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 220 insertions(+) diff --git a/lib/kwineffects.cpp b/lib/kwineffects.cpp index 8fb82557e3..140bb67eea 100644 --- a/lib/kwineffects.cpp +++ b/lib/kwineffects.cpp @@ -25,6 +25,7 @@ along with this program. If not, see . #include #include #include +#include #include #include #include @@ -866,6 +867,110 @@ QRect PaintClipper::Iterator::boundingRect() const } +/*************************************************************** + TimeLine +***************************************************************/ + +TimeLine::TimeLine(const int duration) + { + m_Time = 0; + m_CurveShape = TimeLine::EaseInCurve; + m_Duration = duration; + m_TimeLine = new QTimeLine(m_Duration); + m_TimeLine->setFrameRange(0, m_Duration); + m_TimeLine->setCurveShape(QTimeLine::EaseInCurve); + } + +TimeLine::TimeLine(const TimeLine &other) + { + m_Time = other.m_Time; + m_CurveShape = other.m_CurveShape; + m_Duration = other.m_Duration; + m_TimeLine = new QTimeLine(m_Duration); + m_TimeLine->setFrameRange(0, m_Duration); + setProgress(m_Progress); + setCurveShape(m_CurveShape); + } + +TimeLine::~TimeLine() + { + delete m_TimeLine; + } + +int TimeLine::duration() const + { + return m_Duration; + } + +void TimeLine::setDuration(const int msec) + { + m_Duration = msec; + m_TimeLine->setDuration(msec); + } + +double TimeLine::value() const + { + return valueForTime(m_Time); + } + +double TimeLine::valueForTime(const int msec) const + { + // Catch non QTimeLine CurveShapes here, (but there are none right now) + + + // else use QTimeLine ... + return m_TimeLine->valueForTime(msec); + } + +void TimeLine::addTime(const int msec) + { + m_Time = qMin(m_Duration, m_Time + msec); + } + +void TimeLine::removeTime(const int msec) + { + m_Time = qMax(0, m_Time - msec); + } + +void TimeLine::setProgress(const double progress) + { + m_Progress = progress; + m_Time = (int)(m_Duration * progress); + } + +double TimeLine::progress() const + { + return m_Progress; + } + +void TimeLine::addProgress(const double progress) + { + m_Progress += progress; + } + +void TimeLine::setCurveShape(CurveShape curveShape) + { + switch (curveShape) + { + case EaseInCurve: + m_TimeLine->setCurveShape(QTimeLine::EaseInCurve); + break; + case EaseOutCurve: + m_TimeLine->setCurveShape(QTimeLine::EaseOutCurve); + break; + case EaseInOutCurve: + m_TimeLine->setCurveShape(QTimeLine::EaseInOutCurve); + break; + case LinearCurve: + m_TimeLine->setCurveShape(QTimeLine::LinearCurve); + break; + case SineCurve: + m_TimeLine->setCurveShape(QTimeLine::SineCurve); + break; + } + m_CurveShape = curveShape; + } + #ifdef KWIN_HAVE_XRENDER_COMPOSITING // Convert QRegion to XserverRegion. All code uses XserverRegion // only when really necessary as the shared implementation uses diff --git a/lib/kwineffects.h b/lib/kwineffects.h index ce366d5384..0b9e912a6c 100644 --- a/lib/kwineffects.h +++ b/lib/kwineffects.h @@ -33,6 +33,7 @@ along with this program. If not, see . #include #include #include +#include #include #include @@ -981,6 +982,120 @@ class KWIN_EXPORT PaintClipper static QStack< QRegion >* areas; }; + +/** + * @short Wrapper class for using timelines in KWin effects. + * + * This class provides an easy and specialised interface for + * effects that want a non-linear timeline. Currently, most + * it does is wrapping QTimeLine. In the future, this class + * could help using physics animations in KWin. + */ +class KWIN_EXPORT TimeLine + { + + Q_ENUMS( CurveShape ) + + public: + /** + * The CurveShape describes the relationship between time + * and values. We can pass some of them through to QTimeLine + * but also invent our own ones. + */ + enum CurveShape + { + EaseInCurve = 0, + EaseOutCurve, + EaseInOutCurve, + LinearCurve, + SineCurve + }; + + /** + * Creates a TimeLine and computes the progress data. The default + * duration can be overridden from the Effect. Usually, for larger + * animations you want to choose values more towards 300 milliseconds. + * For small animations, values around 150 milliseconds are sensible. + */ + explicit TimeLine(const int duration = 250); + + /** + * Creates a copy of the TimeLine so we can have the state copied + * as well. + */ + TimeLine(const TimeLine &other); + /** + * Cleans up. + */ + ~TimeLine(); + /** + * Returns the duration of the timeline in msec. + */ + int duration() const; + /** + * Set the duration of the TimeLine. + */ + void setDuration(const int msec); + /** + * Returns the Value at the time set, this method will + * usually be used to get the progress in the paintWindow() + * and related methods. + */ + double value() const; + /** + * Returns the Value at the time provided, this method will + * usually be used to get the progress in the paintWindow() + * and related methods, the y value of the current state x. + */ + double valueForTime(const int msec) const; + /** + * Returns the progress of the TimeLine, between 0 and 1, + * it's equivalent to the y-axis on a curve. + */ + double progress() const; + /** + * Increases the internal progress accounting of the timeline. + */ + void addProgress(const double progress); + /** + * Increases the internal counter, this is usually done in + * prePaintWindow(). + */ + void addTime(const int msec); + /** + * Decreases the internal counter, this is usually done in + * prePaintWindow(). This function comes handy for reverse + * animations. + */ + void removeTime(const int msec); + /** + * Set the time to progress * duration. This will change the + * internal time in the TimeLine. It's usually used in + * prePaintWindow() or prePaintScreen() so the value() + * taken in paint* is increased. + */ + void setProgress(const double progress); + /** + * Set the CurveShape. The CurveShape describes the relation + * between the value and the time. progress is between 0 and 1 + * It's used as input for the timeline, the x axis of the curve. + */ + void setCurveShape(CurveShape curveShape); + /** + * Set the CurveShape. The CurveShape describes the relation + * between the value and the time. + */ + //void setCurveShape(CurveShape curveShape); + + private: + QTimeLine* m_TimeLine; + int m_Time; + double m_Progress; + int m_Duration; + CurveShape m_CurveShape; + //Q_DISABLE_COPY(TimeLine) + }; + /** * Pointer to the global EffectsHandler object. **/