You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
6.3 KiB
151 lines
6.3 KiB
/***************************************************************** |
|
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" |
|
|
|
|
|
// Note that currently effects need to be manually enabled in the EffectsHandler |
|
// class constructor (in effects.cpp). |
|
|
|
namespace KWinInternal |
|
{ |
|
|
|
// 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( Scene::Window* w, int* mask, QRegion* region, int time ) |
|
{ |
|
// Is this window the one that is going to be faded out and in again? |
|
// Note that since the effects framework is still work in progress, the window() |
|
// function is used to access internal class Toplevel. The plan is to hide away |
|
// internal classes and have only API for effects. |
|
if( w->window() == 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. |
|
*mask |= Scene::PAINT_WINDOW_TRANSLUCENT; |
|
*mask &= ~Scene::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, mask, region, 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( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ) |
|
{ |
|
// Is this the window to be faded out and in again? |
|
if( w->window() == 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 damage some areas so that the next painting pass has to repaint them again. |
|
void HowtoEffect::postPaintWindow( Scene::Window* w ) |
|
{ |
|
// Is this the window to be faded out and in again? |
|
if( w->window() == fade_window ) |
|
{ |
|
// Damage the whole window, this will cause it to be repainted the next painting pass. |
|
w->window()->addDamageFull(); // trigger next animation repaint |
|
} |
|
// Call the next effect. |
|
effects->postPaintWindow( w ); |
|
} |
|
|
|
// This function is called when a new window becomes active. |
|
void HowtoEffect::windowActivated( Toplevel* 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 damage the window so that it needs to be repainted. |
|
c->addDamageFull(); |
|
} |
|
} |
|
|
|
// This function is called when a window is destroyed. |
|
void HowtoEffect::windowDeleted( Toplevel* c ) |
|
{ |
|
// If the window to be faded out and in is destroyed, 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. Don't forget to enable the effect as described at the beginning of this file. |
|
|
|
} // namespace
|
|
|