On Monday 20 July 2009, Marco Martin wrote: > On Monday 20 July 2009, Martin Gräßlin wrote: > > Am Montag 20 Juli 2009 18:18:48 schrieb Marco Martin: > > > Hi all, > > > At the plasma&kwin bof at akademy one of the things we talked about was > > > a new effect that can make popups and panels appear with a slide > > > animation. today i decided to give it a try here is the result, it > > > seems to work quite well. > > > > great :-D > > I just had a look on the code and it looks good. I will try it later on. > > > > Some things I noticed: > > yeah, some whoopsie, the attached patch corrects it > oops, this is the correct one :D
-- Marco Martin
Index: slidingpopups/slidingpopups.cpp =================================================================== --- slidingpopups/slidingpopups.cpp (revision 0) +++ slidingpopups/slidingpopups.cpp (revision 0) @@ -0,0 +1,179 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2009 Marco Martin notm...@gmail.com + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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 "slidingpopups.h" + +#include <kdebug.h> + +namespace KWin +{ + +KWIN_EFFECT( slidingpopups, SlidingPopupsEffect ) + +void SlidingPopupsEffect::prePaintScreen( ScreenPrePaintData& data, int time ) + { + if( !mAppearingWindows.isEmpty() || !mDisappearingWindows.isEmpty() ) + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + effects->prePaintScreen( data, time ); + } + +void SlidingPopupsEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) + { + if( mAppearingWindows.contains( w ) ) + { + mAppearingWindows[ w ].addTime( time ); + if( mAppearingWindows[ w ].value() < 1 ) + data.setTransformed(); + else + mAppearingWindows.remove( w ); + } + else if( mDisappearingWindows.contains( w ) ) + { + mDisappearingWindows[ w ].addTime( time ); + if( mDisappearingWindows[ w ].value() < 1 ) + data.setTransformed(); + else + { + mDisappearingWindows.remove( w ); + w->unrefWindow(); + } + } + effects->prePaintWindow( w, data, time ); + } + +void SlidingPopupsEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) + { + bool animating = false; + bool appearing = false; + QRegion clippedRegion = region; + + if( mAppearingWindows.contains( w ) ) + { + appearing = true; + animating = true; + } + else if( mDisappearingWindows.contains( w ) ) + { + appearing = false; + animating = true; + } + + + if( animating ) + { + qreal progress = appearing?(1 - mAppearingWindows[ w ].value()):mDisappearingWindows[ w ].value(); + + switch (mWindowPositions[ w ]) + { + case West: + data.xTranslate -= w->width() * progress; + clippedRegion = clippedRegion.subtracted(QRegion(w->x()-w->width(), w->y(), w->width(), w->height())); + break; + case North: + data.yTranslate -= w->height() * progress; + clippedRegion = clippedRegion.subtracted(QRegion(w->x(), w->y() - w->height(), w->width(), w->height())); + break; + case East: + data.xTranslate += w->width() * progress; + clippedRegion = clippedRegion.subtracted(QRegion(w->x()+w->width(), w->y(), w->width(), w->height())); + break; + case South: + default: + data.yTranslate += w->height() * progress; + clippedRegion = clippedRegion.subtracted(QRegion(w->x(), w->y() + w->height(), w->width(), w->height())); + } + } + + effects->paintWindow( w, mask, clippedRegion, data ); + } + +void SlidingPopupsEffect::postPaintWindow( EffectWindow* w ) + { + if( mAppearingWindows.contains( w ) || mDisappearingWindows.contains( w ) ) + w->addRepaintFull(); // trigger next animation repaint + effects->postPaintWindow( w ); + } + +void SlidingPopupsEffect::windowAdded( EffectWindow* c ) + { + if( c->isOnCurrentDesktop()) + { + mAppearingWindows[ c ].setDuration( animationTime( 250 )); + mAppearingWindows[ c ].setProgress( 0.0 ); + mAppearingWindows[ c ].setCurveShape( TimeLine::EaseOutCurve ); + + QRect screenRect = effects->clientArea( WorkArea, c); + + int left = c->x() - screenRect.x(); + int top = c->y() - screenRect.y(); + int right = screenRect.right() - (c->x() + c->width()); + int bottom = screenRect.bottom() - (c->y() + c->height()); + + if( left <= top && left <= right && left <= bottom ) + mWindowPositions[ c ] = West; + else if( top <= left && top <= right && top <= bottom ) + mWindowPositions[ c ] = North; + else if( right <= top && right <= left && right <= bottom ) + mWindowPositions[ c ] = East; + else + mWindowPositions[ c ] = South; + + c->addRepaintFull(); + } + } + +void SlidingPopupsEffect::windowClosed( EffectWindow* c ) + { + if( c->isOnCurrentDesktop() && !c->isMinimized()) + { + c->refWindow(); + mAppearingWindows.remove( c ); + mDisappearingWindows[ c ].setDuration( animationTime( 250 )); + mDisappearingWindows[ c ].setProgress( 0.0 ); + mDisappearingWindows[ c ].setCurveShape( TimeLine::EaseOutCurve ); + + QRect screenRect = effects->clientArea( WorkArea, c); + + int left = c->x() - screenRect.x(); + int top = c->y() - screenRect.y(); + int right = screenRect.right() - (c->x() + c->width()); + int bottom = screenRect.bottom() - (c->y() + c->height()); + + if( left <= top && left <= right && left <= bottom ) + mWindowPositions[ c ] = West; + else if( top <= left && top <= right && top <= bottom ) + mWindowPositions[ c ] = North; + else if( right <= top && right <= left && right <= bottom ) + mWindowPositions[ c ] = East; + else + mWindowPositions[ c ] = South; + + c->addRepaintFull(); + } + } + +void SlidingPopupsEffect::windowDeleted( EffectWindow* c ) + { + mAppearingWindows.remove( c ); + mDisappearingWindows.remove( c ); + mWindowPositions.remove( c ); + } + +} // namespace Index: slidingpopups/slidingpopups.h =================================================================== --- slidingpopups/slidingpopups.h (revision 0) +++ slidingpopups/slidingpopups.h (revision 0) @@ -0,0 +1,57 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2009 Marco Martin notm...@gmail.com + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*********************************************************************/ + +#ifndef KWIN_SLIDEBACK_H +#define KWIN_SLIDEBACK_H + +// Include with base class for effects. +#include <kwineffects.h> + +namespace KWin +{ + +class SlidingPopupsEffect + : public Effect + { + public: + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); + virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); + virtual void postPaintWindow( EffectWindow* w ); + // TODO react also on virtual desktop changes + virtual void windowAdded( EffectWindow* c ); + virtual void windowClosed( EffectWindow* c ); + virtual void windowDeleted( EffectWindow* c ); + private: + enum Position + { + North = 1, + South = 2, + East = 3, + West = 4 + }; + QHash< const EffectWindow*, TimeLine > mAppearingWindows; + QHash< const EffectWindow*, TimeLine > mDisappearingWindows; + QHash< const EffectWindow*, Position > mWindowPositions; + }; + +} // namespace + +#endif Index: slidingpopups/slidingpopups.desktop =================================================================== --- slidingpopups/slidingpopups.desktop (revision 0) +++ slidingpopups/slidingpopups.desktop (revision 0) @@ -0,0 +1,18 @@ +[Desktop Entry] +Name=Sliding popups + +Type=Service +Comment=Sliding animation for Plasma popups + +Icon=preferences-system-windows-effect-slidingpopups +X-KDE-ServiceTypes=KWin/Effect +X-KDE-PluginInfo-Author=Marco Martin +x-kde-plugininfo-email=notm...@gmail.com +X-KDE-PluginInfo-Name=kwin4_effect_slidingpopups +X-KDE-PluginInfo-Version=0.1 +X-KDE-PluginInfo-Category=Appearance +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=true +X-KDE-Library=kwin4_effect_builtins +X-KDE-Ordering=50 Index: slidingpopups/CMakeLists.txt =================================================================== --- slidingpopups/CMakeLists.txt (revision 0) +++ slidingpopups/CMakeLists.txt (revision 0) @@ -0,0 +1,12 @@ +####################################### +# Effect + +# Source files +set( kwin4_effect_builtins_sources ${kwin4_effect_builtins_sources} + slidingpopups/slidingpopups.cpp + ) + +# .desktop files +install( FILES + slidingpopups/slidingpopups.desktop + DESTINATION ${SERVICES_INSTALL_DIR}/kwin ) Index: CMakeLists.txt =================================================================== --- CMakeLists.txt (revision 995268) +++ CMakeLists.txt (working copy) @@ -71,6 +71,7 @@ include( showpaint/CMakeLists.txt ) include( slide/CMakeLists.txt ) include( slideback/CMakeLists.txt ) +include( slidingpopups/CMakeLists.txt ) include( taskbarthumbnail/CMakeLists.txt ) include( thumbnailaside/CMakeLists.txt ) include( zoom/CMakeLists.txt )
_______________________________________________ Plasma-devel mailing list Plasma-devel@kde.org https://mail.kde.org/mailman/listinfo/plasma-devel