kwin/effects/fade.cpp
Philip Falkner 09bb0f7cd2 Experimental fade effect, blatantly inspired by compiz.
Note that this while this can reliably fade opened/closed windows, it
will only fade opacity/brightness/saturation changes from previously
loaded effects.  Until we can specify effects' loading order, the
results may not be what you expect.  Don't be too surprised if this
gets reverted.


svn path=/trunk/KDE/kdebase/workspace/; revision=683983
2007-07-05 20:19:10 +00:00

182 lines
6.1 KiB
C++

/*****************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2007 Philip Falkner <philip.falkner@gmail.com>
You can Freely distribute this program under the GNU General Public
License. See the file "COPYING" for the exact licensing terms.
******************************************************************/
#include "fade.h"
#include <kconfiggroup.h>
namespace KWin
{
KWIN_EFFECT( fade, FadeEffect )
FadeEffect::FadeEffect()
{
KConfigGroup conf = effects->effectConfig( "Fade" );
fadeInTime = qMax( conf.readEntry( "FadeInTime", 150 ), 1 );
fadeOutTime = qMax( conf.readEntry( "FadeOutTime", 150 ), 1 );
fadeWindows = conf.readEntry( "FadeWindows", true );
}
void FadeEffect::prePaintScreen( int* mask, QRegion* region, int time )
{
if( !windows.isEmpty())
{
fadeInStep = time / double( fadeInTime );
fadeOutStep = time / double( fadeOutTime );
}
effects->prePaintScreen( mask, region, time );
}
void FadeEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time )
{
if( windows.contains( w ))
{
windows[ w ].fadeInStep += fadeInStep;
windows[ w ].fadeOutStep += fadeOutStep;
if( windows[ w ].opacity < 1.0 )
{
*mask &= ~PAINT_WINDOW_OPAQUE;
*mask |= PAINT_WINDOW_TRANSLUCENT;
}
if( windows[ w ].deleted )
{
if( windows[ w ].opacity <= 0.0 )
{
windows.remove( w );
w->unrefWindow();
}
else
w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DELETE );
}
}
effects->prePaintWindow( w, mask, paint, clip, time );
if( windows.contains( w ) && !w->isPaintingEnabled())
{ // if the window isn't to be painted, then let's make sure
// to track its progress
if( windows[ w ].fadeInStep < 1.0
|| windows[ w ].fadeOutStep < 1.0 )
{ // but only if the total change is less than the
// maximum possible change
w->addRepaintFull();
}
}
}
void FadeEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
if( windows.contains( w ))
{
if( windows[ w ].deleted
|| windows[ w ].opacity != data.opacity
|| windows[ w ].saturation != data.saturation
|| windows[ w ].brightness != data.brightness )
{
WindowPaintData new_data = data;
if( windows[ w ].deleted )
new_data.opacity = 0.0;
if( new_data.opacity > windows[ w ].opacity )
{
windows[ w ].opacity = qMin( new_data.opacity,
windows[ w ].opacity + windows[ w ].fadeInStep );
}
else if( new_data.opacity < windows[ w ].opacity )
{
windows[ w ].opacity = qMax( new_data.opacity,
windows[ w ].opacity - windows[ w ].fadeOutStep );
}
if( new_data.saturation > windows[ w ].saturation )
{
windows[ w ].saturation = qMin( new_data.saturation,
windows[ w ].saturation + float( windows[ w ].fadeInStep ));
}
else if( new_data.saturation < windows[ w ].saturation )
{
windows[ w ].saturation = qMax( new_data.saturation,
windows[ w ].saturation - float( windows[ w ].fadeOutStep ));
}
if( new_data.brightness > windows[ w ].brightness )
{
windows[ w ].brightness = qMin( new_data.brightness,
windows[ w ].brightness + float( windows[ w ].fadeInStep ));
}
else if( new_data.brightness < windows[ w ].brightness )
{
windows[ w ].brightness = qMax( new_data.brightness,
windows[ w ].brightness - float( windows[ w ].fadeOutStep ));
}
windows[ w ].opacity = qBound( 0.0, windows[ w ].opacity, 1.0 );
windows[ w ].saturation = qBound( 0.0f, windows[ w ].saturation, 1.0f );
windows[ w ].brightness = qBound( 0.0f, windows[ w ].brightness, 1.0f );
windows[ w ].fadeInStep = 0.0;
windows[ w ].fadeOutStep = 0.0;
new_data.opacity = windows[ w ].opacity;
new_data.saturation = windows[ w ].saturation;
new_data.brightness = windows[ w ].brightness;
effects->paintWindow( w, mask, region, new_data );
if( windows[ w ].opacity != data.opacity
|| windows[ w ].saturation != data.saturation
|| windows[ w ].brightness != data.brightness )
w->addRepaintFull();
return;
}
windows[ w ].fadeInStep = 0.0;
windows[ w ].fadeOutStep = 0.0;
}
effects->paintWindow( w, mask, region, data );
}
void FadeEffect::windowOpacityChanged( EffectWindow* w, double old_opacity )
{
if( !windows.contains( w ))
windows[ w ].opacity = old_opacity;
if( windows[ w ].opacity == 1.0 )
windows[ w ].opacity -= 0.1 / fadeOutTime;
w->addRepaintFull();
}
void FadeEffect::windowAdded( EffectWindow* w )
{
if( !fadeWindows || !isFadeWindow( w ))
return;
windows[ w ].opacity = 0.0;
w->addRepaintFull();
}
void FadeEffect::windowClosed( EffectWindow* w )
{
if( !fadeWindows || !isFadeWindow( w ))
return;
if( !windows.contains( w ))
windows[ w ].opacity = w->opacity();
if( windows[ w ].opacity == 1.0 )
windows[ w ].opacity -= 0.1 / fadeOutTime;
windows[ w ].deleted = true;
w->refWindow();
w->addRepaintFull();
}
void FadeEffect::windowDeleted( EffectWindow* w )
{
windows.remove( w );
}
bool FadeEffect::isFadeWindow( EffectWindow* w )
{
return !w->isDesktop();
}
} // namespace