2007-04-29 17:35:43 +00:00
|
|
|
/*****************************************************************
|
|
|
|
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.
|
2011-01-30 14:34:42 +00:00
|
|
|
|
2007-04-29 17:35:43 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
// 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.
|
2011-01-30 14:34:42 +00:00
|
|
|
KWIN_EFFECT(howto, HowtoEffect)
|
2007-04-29 17:35:43 +00:00
|
|
|
|
|
|
|
// 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
|
2011-01-30 14:34:42 +00:00
|
|
|
void HowtoEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
|
|
|
|
{
|
2007-04-29 17:35:43 +00:00
|
|
|
// Is this window the one that is going to be faded out and in again?
|
2011-01-30 14:34:42 +00:00
|
|
|
if (w == fade_window) {
|
2007-04-29 17:35:43 +00:00
|
|
|
// 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.
|
2011-01-30 14:34:42 +00:00
|
|
|
if (progress < 1000) { // complete change in 1000ms
|
2007-04-29 17:35:43 +00:00
|
|
|
// Since the effect will make the window translucent, explicitly change
|
|
|
|
// the flags so that the window will be painted only as translucent.
|
2007-07-19 13:32:46 +00:00
|
|
|
// Use a helper that also takes care of changing the clipping rectangle.
|
|
|
|
data.setTranslucent();
|
2011-01-30 14:34:42 +00:00
|
|
|
} else {
|
2007-04-29 17:35:43 +00:00
|
|
|
// If progress has reached 1000 (milliseconds), it means the effect is done
|
|
|
|
// and there is no window to fade anymore.
|
|
|
|
fade_window = NULL;
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
2007-04-29 17:35:43 +00:00
|
|
|
// 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.
|
2011-01-30 14:34:42 +00:00
|
|
|
effects->prePaintWindow(w, data, time);
|
|
|
|
}
|
2007-04-29 17:35:43 +00:00
|
|
|
|
|
|
|
// 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
|
2011-01-30 14:34:42 +00:00
|
|
|
void HowtoEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
|
|
|
|
{
|
2007-04-29 17:35:43 +00:00
|
|
|
// Is this the window to be faded out and in again?
|
2011-01-30 14:34:42 +00:00
|
|
|
if (w == fade_window) {
|
2007-04-29 17:35:43 +00:00
|
|
|
// 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).
|
2011-01-30 14:34:42 +00:00
|
|
|
if (progress <= 500) {
|
2007-04-29 17:35:43 +00:00
|
|
|
// 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.
|
2011-01-30 14:34:42 +00:00
|
|
|
data.opacity *= 1 - 0.5 * (progress / 500.0);
|
|
|
|
} else {
|
2007-04-29 17:35:43 +00:00
|
|
|
// 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
|
2011-01-30 14:34:42 +00:00
|
|
|
data.opacity *= 0.5 + 0.5 * (progress - 500) / 500.0;
|
2007-04-29 17:35:43 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
// Call the next effect.
|
|
|
|
effects->paintWindow(w, mask, region, data);
|
|
|
|
}
|
2007-04-29 17:35:43 +00:00
|
|
|
|
|
|
|
// 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.
|
2011-01-30 14:34:42 +00:00
|
|
|
void HowtoEffect::postPaintWindow(EffectWindow* w)
|
|
|
|
{
|
2007-04-29 17:35:43 +00:00
|
|
|
// Is this the window to be faded out and in again?
|
2011-01-30 14:34:42 +00:00
|
|
|
if (w == fade_window) {
|
2007-04-29 17:35:43 +00:00
|
|
|
// Trigger repaint of the whole window, this will cause it to be repainted the next painting pass.
|
|
|
|
w->addRepaintFull(); // trigger next animation repaint
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
// Call the next effect.
|
|
|
|
effects->postPaintWindow(w);
|
|
|
|
}
|
2007-04-29 17:35:43 +00:00
|
|
|
|
|
|
|
// This function is called when a new window becomes active.
|
2011-01-30 14:34:42 +00:00
|
|
|
void HowtoEffect::windowActivated(EffectWindow* c)
|
|
|
|
{
|
2007-04-29 17:35:43 +00:00
|
|
|
// Set the window to be faded (or NULL if no window is active).
|
|
|
|
fade_window = c;
|
2011-01-30 14:34:42 +00:00
|
|
|
if (fade_window != NULL) {
|
2007-04-29 17:35:43 +00:00
|
|
|
// 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();
|
|
|
|
}
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
2007-04-29 17:35:43 +00:00
|
|
|
|
|
|
|
// This function is called when a window is closed.
|
2011-01-30 14:34:42 +00:00
|
|
|
void HowtoEffect::windowClosed(EffectWindow* c)
|
|
|
|
{
|
2007-04-29 17:35:43 +00:00
|
|
|
// 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.
|
2011-01-30 14:34:42 +00:00
|
|
|
if (fade_window == c)
|
2007-04-29 17:35:43 +00:00
|
|
|
fade_window = NULL;
|
2011-01-30 14:34:42 +00:00
|
|
|
}
|
2007-04-29 17:35:43 +00:00
|
|
|
|
|
|
|
// That's all. Now only the matching .desktop file is needed.
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace
|