[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kwin
Subject:    Re: physics-based animator
From:       Sebastian Kuegler <sebas () kde ! org>
Date:       2008-03-17 9:49:40
Message-ID: 200803171049.41016.sebas () kde ! org
[Download RAW message or body]

[Attachment #2 (multipart/signed)]

[Attachment #4 (multipart/mixed)]


On Thursday 13 March 2008 16:03:58 Rivo Laks wrote:
> Ühel kenal päeval (neljapäev, 13. märts 2008) kirjutas Sebastian Kuegler:
> > On Wednesday 12 March 2008 21:30:29 Riccardo Iaconelli wrote:
> > > do you think it is ok to introduce an (optional?) dependency on Box2d
> > > http://www.box2d.org/ for the animator
> > > with physical equations? that's already a *good* engine we can use for
> > > fun and profit, without having to worry
> > > to implement a new one from scratch...
> >
> > I like the idea of having more natural animations. At the same time, I'm
> > not so worried about Plasma, but about KWin. I think every single
> > animation in KWin is purely linear (didn't look at the code yet, X11,
> > OpenGL ... those are scary things to me ;-)).
> >
> > We could think of sharing that kind of stuff with KWin too, I think the
> > distinction between large parts of Plasma and KWin are purely technical
> > and not easily graspable from our users' POV.
> >
> > Did anyone actually think of making KWin use for example Plasma::Phase?
> > Lubos, is that something you could support? Am I even right in stating
> > that all (most?) animations in KWin are linear?
> >
> > I talked to Mirco Müller ("MacSlow") who is doing bling things with Cairo
> > some time ago, and he basically said that linear animations feel
> > unnatural, having things ease in and out makes it already feel much
> > better. And if you look at the iPhone / iPod touch, I think having the
> > KDE desktop 'obey the laws of physics' would make it feel a lot smoother.
>
> Something like Plasma::Phase would be useful indeed. You're right that all
> KWin animations are currently linear. In addition to that, each effect
> currently needs to take care of the animation itself which kinda sucks.

I've hacked a bit on the minimize plugin and got it to 'use' QTimeLine. 
Actually, I'm creating the timeline and just adjust the progress for the 
frame in question to the value QTimeLine gives. It looks rather easy, but 
QTimeLine doesn't provide a whole lot of interesting physics. Still it's a 
beginning how this can be done.

There's probably a better place to put this than one effect, but from a quick 
read of effects.(cpp|h) I didn't see where to do this for all effects at once 
(and if we want that).

To make the effect more apparent (it's quite subtle otherwise) I multiplied it 
by itself. I think it's an improvement already, although it's far from 
organic still.

Good enough for some feedback, anyway :-)

> I remember we had a discussion about that a while ago. It would be really
> nice if effect could just do something like
>     window->opacity->set(0.8, 250);
> to set window's opacity to 80% in 250 milliseconds.
>
> Plasma::Phase doesn't really seem usable for KWin without some major
> changes though. It looks like it's meant only for a few different
> animations and only for usage with QGraphicsItems.

I mainly found the signal-based approach to not fit nicely into KWin plugins. 
So I went the easier route and use QTimeLine directly. Phase doesn't add 
specific CurveShapes anyway, so I saw little gain.

> What would be more suitable for KWin (IMHO) would be some kind of (probably
> template) property class which stores current value as well as the target
> value(s) of the property. Opacity, brightness, position, scale, etc would
> then be converted into those properties so that effects can easily have
> them animated. It would also make addition of new such properties very easy
> as you wouldn't need to change any enums or similar in the
> property/phase/animator class.

Not sure I'm really grasping that ... 
-- 
sebas

 http://www.kde.org | http://vizZzion.org |  GPG Key ID: 9119 0EF9 

["kwin-minimize-qtimeline.diff" (text/x-diff)]

diff --git a/workspace/kwin/effects/minimizeanimation.cpp b/workspace/kwin/effects/minimizeanimation.cpp
index 9cf85d6..36a772e 100644
--- a/workspace/kwin/effects/minimizeanimation.cpp
+++ b/workspace/kwin/effects/minimizeanimation.cpp
@@ -18,6 +18,9 @@ You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *********************************************************************/
 
+#include <QTimeLine>
+#include <KDebug>
+
 #include "minimizeanimation.h"
 
 namespace KWin
@@ -28,8 +31,15 @@ KWIN_EFFECT( minimizeanimation, MinimizeAnimationEffect )
 MinimizeAnimationEffect::MinimizeAnimationEffect()
     {
     mActiveAnimations = 0;
+    mDuration = 300; // How long does the animation take?
+    mTimeLine = new QTimeLine(mDuration);
+    mTimeLine->setFrameRange(0, mDuration);
     }
 
+MinimizeAnimationEffect::~MinimizeAnimationEffect()
+{
+    delete mTimeLine;
+}
 
 void MinimizeAnimationEffect::prePaintScreen( ScreenPrePaintData& data, int time )
     {
@@ -44,7 +54,7 @@ void MinimizeAnimationEffect::prePaintScreen( ScreenPrePaintData& data, int time
 
 void MinimizeAnimationEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time )
     {
-    const double changeTime = 300;
+    const double changeTime = mDuration;
     if( mAnimationProgress.contains( w ))
         {
         if( w->isMinimized() )
@@ -80,6 +90,21 @@ void MinimizeAnimationEffect::paintWindow( EffectWindow* w, int mask, QRegion re
         // 0 = not minimized, 1 = fully minimized
         double progress = mAnimationProgress[w];
 
+        int time = (int)(mDuration*progress);
+        qreal adjusted = mTimeLine->valueForTime(time);
+        if (time == 1) 
+            adjusted = 0;
+        /*
+        kDebug() << "- - - - - - - - - ";
+        kDebug() << "Progress: " << progress;
+        kDebug() << "Time:     " << time;
+        kDebug() << "TimeLine: " << adjusted;
+        */
+        progress = (double)adjusted;
+
+        // double the effect to make it more visible
+        progress = progress * progress;
+
         QRect geo = w->geometry();
         QRect icon = w->iconGeometry();
         // If there's no icon geometry, minimize to the center of the screen
@@ -109,6 +134,7 @@ void MinimizeAnimationEffect::postPaintScreen()
 
 void MinimizeAnimationEffect::windowMinimized( EffectWindow* w )
     {
+    mTimeLine->setCurveShape(QTimeLine::EaseOutCurve);
     if( !mAnimationProgress.contains(w) )
         {
         mAnimationProgress[w] = 0.0f;
@@ -117,6 +143,7 @@ void MinimizeAnimationEffect::windowMinimized( EffectWindow* w )
 
 void MinimizeAnimationEffect::windowUnminimized( EffectWindow* w )
     {
+    mTimeLine->setCurveShape(QTimeLine::EaseInCurve);
     if( !mAnimationProgress.contains(w) )
         {
         mAnimationProgress[w] = 1.0f;
diff --git a/workspace/kwin/effects/minimizeanimation.h b/workspace/kwin/effects/minimizeanimation.h
index 97bc268..6408b03 100644
--- a/workspace/kwin/effects/minimizeanimation.h
+++ b/workspace/kwin/effects/minimizeanimation.h
@@ -21,6 +21,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef KWIN_MINIMIZEANIMATION_H
 #define KWIN_MINIMIZEANIMATION_H
 
+#include <QTimeLine>
+
 // Include with base class for effects.
 #include <kwineffects.h>
 
@@ -36,6 +38,7 @@ class MinimizeAnimationEffect
     {
     public:
         MinimizeAnimationEffect();
+        ~MinimizeAnimationEffect();
 
         virtual void prePaintScreen( ScreenPrePaintData& data, int time );
         virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time );
@@ -48,6 +51,8 @@ class MinimizeAnimationEffect
     private:
         QHash< EffectWindow*, double > mAnimationProgress;
         int mActiveAnimations;
+        int mDuration;
+        QTimeLine *mTimeLine;
     };
 
 } // namespace

["signature.asc" (application/pgp-signature)]

_______________________________________________
Kwin mailing list
Kwin@kde.org
https://mail.kde.org/mailman/listinfo/kwin


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic