kwin/effects/howto.cpp
Luboš Luňák 5faa397849 Vertex redesign - redo the way windows are split into smaller parts
for use in effects (and not only). Now a list of window quads (=window areas)
is created at the beginning of the paint pass, prepaint calls can modify
the split itself (i.e. divide it into more parts). The actual paint calls
can then modify these quads (i.e. transform their geometry). This will allow
better control of how the split is done and also allow painting e.g. only
the decoration differently. Still work in progress, but it works.
Also pass data to prepaint functions in a struct, as there is
already quite a number of them.


svn path=/trunk/KDE/kdebase/workspace/; revision=684893
2007-07-07 14:01:32 +00:00

148 lines
6.1 KiB
C++

/*****************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
You can Freely distribute this program under the GNU General Public
License. See the file "COPYING" for the exact licensing terms.
******************************************************************/
/*
Files howto.cpp and howto.h implement HowtoEffect, a commented demo compositing
effect that fades out and again in a window after it has been activated.
Please see file howto.h first.
*/
// Include the class definition.
#include "howto.h"
namespace KWin
{
// This macro creates entry function for the plugin. First argument is name, second is class name.
KWIN_EFFECT( howto, HowtoEffect )
// A pre-paint function that tells the compositing code how this effect will affect
// the painting. During every painting pass this function is called first, before
// the actual painting function.
// Arguments:
// w - the window that will be painted
// mask - a mask of flags controlling the painting, setting or resetting flags changes
// how the painting will be done
// region - the region of the screen that needs to be painted, support for modifying it
// is not fully implemented yet, do not use
// time - time in milliseconds since the last paint, useful for animations
void HowtoEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time )
{
// Is this window the one that is going to be faded out and in again?
if( w == fade_window )
{
// Simply add the time to the total progress. The value of progress will be used
// to determine how far in effect is.
progress += time;
// If progress is < 1000 (milliseconds), the effect is still in progress.
if( progress < 1000 ) // complete change in 1000ms
{
// Since the effect will make the window translucent, explicitly change
// the flags so that the window will be painted only as translucent.
data.mask |= PAINT_WINDOW_TRANSLUCENT;
data.mask &= ~PAINT_WINDOW_OPAQUE;
}
else
{
// If progress has reached 1000 (milliseconds), it means the effect is done
// and there is no window to fade anymore.
fade_window = NULL;
}
}
// Call the next effect (or the actual window painting code if this is the last effect).
// Effects are chained and they all modify something if needed and then call the next one.
effects->prePaintWindow( w, data, time );
}
// The function that handles the actual painting. Some simple modifications are possible
// by only changing the painting data. More complicated effects would do some painting
// or transformations directly.
// Arguments:
// w - the window that will be painted
// mask - a mask of flags controlling the painting
// region - the region of the screen that needs to be painted, if mask includes the TRANSFORMED
// then special care needs to be taken, because the region may be infiniteRegion(), meaning
// everything needs to be painted
// data - painting data that can be modified to do some simple transformations
void HowtoEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
// Is this the window to be faded out and in again?
if( w == fade_window )
{
// This effect, after a window has been activated, fades it out to only 50% transparency
// and then fades it in again to be fully opaque (assuming it's otherwise a fully opaque
// window, otherwise the transparencies will be added).
if( progress <= 500 )
{
// For the first 500 milliseconds (progress being 0 to 500), the window is faded out.
// progress == 0 -> opacity *= 1
// progress == 500 -> opacity *= 0.5
// Note that the division is floating-point division to avoid integer rounding down.
// Note that data.opacity is not set but multiplied - this allows chaining of effects,
// for example if another effect always changes opacity of some window types.
data.opacity *= 1 - 0.5 * ( progress / 500.0 );
}
else
{
// For the second 500 milliseconds (progress being 500 to 1000), the window is
// faded in again.
// progress == 500 -> opacity *= 0.5
// progress == 1000 -> opacity *= 1
data.opacity *= 0.5 + 0.5 * ( progress - 500 ) / 500.0;
}
}
// Call the next effect.
effects->paintWindow( w, mask, region, data );
}
// The function that is called after the painting pass is finished. When an animation is going on,
// it can add repaints of some areas so that the next painting pass has to repaint them again.
void HowtoEffect::postPaintWindow( EffectWindow* w )
{
// Is this the window to be faded out and in again?
if( w == fade_window )
{
// Trigger repaint of the whole window, this will cause it to be repainted the next painting pass.
w->addRepaintFull(); // trigger next animation repaint
}
// Call the next effect.
effects->postPaintWindow( w );
}
// This function is called when a new window becomes active.
void HowtoEffect::windowActivated( EffectWindow* c )
{
// Set the window to be faded (or NULL if no window is active).
fade_window = c;
if( fade_window != NULL )
{
// If there is a window to be faded, reset the progress to zero.
progress = 0;
// And add repaint to the window so that it needs to be repainted.
c->addRepaintFull();
}
}
// This function is called when a window is closed.
void HowtoEffect::windowClosed( EffectWindow* c )
{
// If the window to be faded out and in is closed, just reset the pointer.
// This effect then will do nothing and just call the next effect.
if( fade_window == c )
fade_window = NULL;
}
// That's all. Now only the matching .desktop file is needed.
} // namespace