diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c8e162f78..3db6a88e51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,7 @@ set(kwin_KDEINIT_SRCS effects/test_input.cpp effects/presentwindows.cpp effects/wavywindows.cpp + effects/minimizeanimation.cpp ) qt4_add_dbus_adaptor( kwin_KDEINIT_SRCS org.kde.KWin.xml workspace.h KWinInternal::Workspace ) diff --git a/effects.cpp b/effects.cpp index eca0030975..262c49ef14 100644 --- a/effects.cpp +++ b/effects.cpp @@ -19,6 +19,7 @@ License. See the file "COPYING" for the exact licensing terms. #include "effects/fadeout.h" #include "effects/howto.h" #include "effects/maketransparent.h" +#include "effects/minimizeanimation.h" #include "effects/presentwindows.h" #include "effects/scalein.h" #include "effects/shakymove.h" @@ -117,6 +118,7 @@ EffectsHandler::EffectsHandler( Workspace* ws ) // effects.append( new ZoomEffect( ws )); // effects.append( new PresentWindowsEffect( ws )); // effects.append( new WavyWindowsEffect( ws )); +// effects.append( new MinimizeAnimationEffect( ws )); // effects.append( new HowtoEffect ); // effects.append( new MakeTransparentEffect ); // effects.append( new ShakyMoveEffect ); diff --git a/effects/minimizeanimation.cpp b/effects/minimizeanimation.cpp new file mode 100644 index 0000000000..667fd1a51c --- /dev/null +++ b/effects/minimizeanimation.cpp @@ -0,0 +1,128 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Rivo Laks + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + + +#include "minimizeanimation.h" + +#include +#include + + +// Note that currently effects need to be manually enabled in the EffectsHandler +// class constructor (in effects.cpp). + +namespace KWinInternal +{ + +MinimizeAnimationEffect::MinimizeAnimationEffect( Workspace* ws ) : Effect() + { + mWorkspace = ws; + mActiveAnimations = 0; + } + + +void MinimizeAnimationEffect::prePaintScreen( int* mask, QRegion* region, int time ) + { + if( mActiveAnimations > 0 ) + // We need to mark the screen as transformed. Otherwise the whole + // screen won't be repainted, resulting in artefacts + *mask |= Scene::PAINT_SCREEN_TRANSFORMED; + + effects->prePaintScreen(mask, region, time); + } + +void MinimizeAnimationEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time ) + { + const float changeTime = 500; + if( mAnimationProgress.contains( w )) + { + Client* c = static_cast< Client* >( w->window() ); + if( c->isMinimized() ) + { + mAnimationProgress[w] += time / changeTime; + if( mAnimationProgress[w] >= 1.0f ) + mAnimationProgress.remove( w ); + } + else + { + mAnimationProgress[w] -= time / changeTime; + if( mAnimationProgress[w] <= 0.0f ) + mAnimationProgress.remove( w ); + } + + // Schedule window for transformation if the animation is still in + // progress + if( mAnimationProgress.contains( w )) + { + // We'll transform this window + *mask |= Scene::PAINT_WINDOW_TRANSFORMED; + *mask &= ~Scene::PAINT_WINDOW_DISABLED; + } + else + // Animation just finished + mActiveAnimations--; + } + + effects->prePaintWindow( w, mask, region, time ); + } + +void MinimizeAnimationEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) + { + if( mAnimationProgress.contains( w )) + { + // 0 = not minimized, 1 = fully minimized + float progress = mAnimationProgress[w]; + + Client* c = static_cast< Client* >( w->window() ); + QRect geo = c->geometry(); + QRect icon = c->iconGeometry(); + + data.xScale *= interpolate(1.0, icon.width() / (float)geo.width(), progress); + data.yScale *= interpolate(1.0, icon.height() / (float)geo.height(), progress); + data.xTranslate = (int)interpolate(data.xTranslate, icon.x() - geo.x(), progress); + data.yTranslate = (int)interpolate(data.yTranslate, icon.y() - geo.y(), progress); + } + + // Call the next effect. + effects->paintWindow( w, mask, region, data ); + } + +void MinimizeAnimationEffect::postPaintScreen() + { + if( mActiveAnimations > 0 ) + // Damage the workspace so that everything would be repainted next time + mWorkspace->addDamageFull(); + + // Call the next effect. + effects->postPaintScreen(); + } + +void MinimizeAnimationEffect::windowMinimized( EffectWindow* w ) + { + Client* client = static_cast< Client* >( w->window() ); + if( !mAnimationProgress.contains(w) && client->iconGeometry().isValid() ) + { + mAnimationProgress[w] = 0.0f; + mActiveAnimations++; + } + } + +void MinimizeAnimationEffect::windowUnminimized( EffectWindow* w ) + { + Client* client = static_cast< Client* >( w->window() ); + if( !mAnimationProgress.contains(w) && client->iconGeometry().isValid() ) + { + mAnimationProgress[w] = 1.0f; + mActiveAnimations++; + } + } + +} // namespace + diff --git a/effects/minimizeanimation.h b/effects/minimizeanimation.h new file mode 100644 index 0000000000..6cd9b766a9 --- /dev/null +++ b/effects/minimizeanimation.h @@ -0,0 +1,46 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Rivo Laks + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + +#ifndef KWIN_MINIMIZEANIMATION_H +#define KWIN_MINIMIZEANIMATION_H + +// Include with base class for effects. +#include + + +namespace KWinInternal +{ + +/** + * Animates minimize/unminimize + **/ +class MinimizeAnimationEffect + : public Effect + { + public: + MinimizeAnimationEffect( Workspace* ws ); + + virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* region, int time ); + virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); + virtual void postPaintScreen(); + + virtual void windowMinimized( EffectWindow* c ); + virtual void windowUnminimized( EffectWindow* c ); + + private: + Workspace* mWorkspace; + QMap< EffectWindow*, float > mAnimationProgress; + int mActiveAnimations; + }; + +} // namespace + +#endif