diff --git a/effects/CMakeLists.txt b/effects/CMakeLists.txt index 817ea21634..d718aea7e7 100644 --- a/effects/CMakeLists.txt +++ b/effects/CMakeLists.txt @@ -86,6 +86,7 @@ if( KWIN_HAVE_OPENGL_COMPOSITING ) include( cube/CMakeLists.txt ) include( explosion/CMakeLists.txt ) include( flipswitch/CMakeLists.txt ) + include( glide/CMakeLists.txt ) include( invert/CMakeLists.txt ) include( lookingglass/CMakeLists.txt ) include( magnifier/CMakeLists.txt ) diff --git a/effects/configs_builtins.cpp b/effects/configs_builtins.cpp index 15e16d8bbc..53889c83e6 100644 --- a/effects/configs_builtins.cpp +++ b/effects/configs_builtins.cpp @@ -39,6 +39,7 @@ along with this program. If not, see . #include "cube/cube_config.h" #include "cube/cubeslide_config.h" #include "flipswitch/flipswitch_config.h" +#include "glide/glide_config.h" #include "invert/invert_config.h" #include "lookingglass/lookingglass_config.h" #include "mousemark/mousemark_config.h" @@ -74,6 +75,7 @@ KWIN_EFFECT_CONFIG_MULTIPLE( builtins, KWIN_EFFECT_CONFIG_SINGLE( cube, CubeEffectConfig ) KWIN_EFFECT_CONFIG_SINGLE( cubeslide, CubeSlideEffectConfig ) KWIN_EFFECT_CONFIG_SINGLE( flipswitch, FlipSwitchEffectConfig ) + KWIN_EFFECT_CONFIG_SINGLE( glide, GlideEffectConfig ) KWIN_EFFECT_CONFIG_SINGLE( invert, InvertEffectConfig ) KWIN_EFFECT_CONFIG_SINGLE( lookingglass, LookingGlassEffectConfig ) KWIN_EFFECT_CONFIG_SINGLE( mousemark, MouseMarkEffectConfig ) diff --git a/effects/glide/CMakeLists.txt b/effects/glide/CMakeLists.txt new file mode 100644 index 0000000000..75a834c208 --- /dev/null +++ b/effects/glide/CMakeLists.txt @@ -0,0 +1,26 @@ +####################################### +# Effect + +# Source files +set( kwin4_effect_builtins_sources ${kwin4_effect_builtins_sources} + glide/glide.cpp + ) + +# .desktop files +install( FILES + glide/glide.desktop + DESTINATION ${SERVICES_INSTALL_DIR}/kwin ) + +####################################### +# Config + +# Source files +set( kwin4_effect_builtins_config_sources ${kwin4_effect_builtins_config_sources} + glide/glide_config.cpp + glide/glide_config.ui ) + +# .desktop files +install( FILES + glide/glide_config.desktop + DESTINATION ${SERVICES_INSTALL_DIR}/kwin ) + diff --git a/effects/glide/glide.cpp b/effects/glide/glide.cpp new file mode 100644 index 0000000000..420be55d8c --- /dev/null +++ b/effects/glide/glide.cpp @@ -0,0 +1,212 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Philip Falkner +Copyright (C) 2009 Martin Gräßlin +Copyright (C) 2010 Alexandre Pereira + +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 . +*********************************************************************/ + +#include "glide.h" + +#include + +// Effect is based on fade effect by Philip Falkner + +namespace KWin +{ + +KWIN_EFFECT( glide, GlideEffect ) +KWIN_EFFECT_SUPPORTED( glide, GlideEffect::supported() ) + +GlideEffect::GlideEffect() + : windowCount( 0 ) + { + reconfigure( ReconfigureAll ); + } + +bool GlideEffect::supported() + { + return effects->compositingType() == OpenGLCompositing; + } + +void GlideEffect::reconfigure( ReconfigureFlags ) + { + KConfigGroup conf = effects->effectConfig( "Glide" ); + duration = animationTime( conf, "AnimationTime", 350 ); + effect = (EffectStyle) conf.readEntry( "GlideEffect", 0 ); + angle = conf.readEntry( "GlideAngle", -90 ); + } + +void GlideEffect::prePaintScreen( ScreenPrePaintData& data, int time ) + { + if( windowCount > 0 ) + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + effects->prePaintScreen( data, time ); + } + +void GlideEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) + { + if( windows.contains( w ) && ( windows[ w ].added || windows[ w ].closed ) ) + { + if( windows[ w ].added ) + windows[ w ].timeLine->addTime( time ); + if( windows[ w ].closed ) + { + windows[ w ].timeLine->removeTime( time ); + if( windows[ w ].deleted ) + { + w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DELETE ); + } + } + } + effects->prePaintWindow( w, data, time ); + if( windows.contains( w ) && !w->isPaintingEnabled() && !effects->activeFullScreenEffect() ) + { // if the window isn't to be painted, then let's make sure + // to track its progress + if( windows[ w ].added || windows[ w ].closed ) + { // but only if the total change is less than the + // maximum possible change + w->addRepaintFull(); + } + } + } + +void GlideEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) + { + if( windows.contains( w ) ) + { + RotationData rot; + rot.axis = RotationData::XAxis; + rot.angle = angle * ( 1 - windows[ w ].timeLine->value() ); + data.rotation = &rot; + data.opacity *= windows[ w ].timeLine->value(); + if( effect == GlideInOut ) + { + if( windows[ w ].added ) + glideIn( w, data ); + if( windows[ w ].closed ) + glideOut( w, data ); + } + if( effect == GlideOutIn ) + { + if( windows[ w ].added ) + glideOut( w, data ); + if( windows[ w ].closed ) + glideIn( w, data ); + } + if( effect == GlideIn ) + glideIn( w, data ); + if( effect == GlideOut ) + glideOut( w, data ); + effects->paintWindow( w, PAINT_WINDOW_TRANSFORMED, region, data ); + } + else + effects->paintWindow( w, mask, region, data ); + } + +void GlideEffect::glideIn(EffectWindow* w, WindowPaintData& data ) + { + data.xScale *= windows[ w ].timeLine->value(); + data.yScale *= windows[ w ].timeLine->value(); + data.zScale *= windows[ w ].timeLine->value(); + data.xTranslate += int( w->width() / 2 * ( 1 - windows[ w ].timeLine->value() ) ); + data.yTranslate += int( w->height() / 2 * ( 1 - windows[ w ].timeLine->value() ) ); + } + +void GlideEffect::glideOut(EffectWindow* w, WindowPaintData& data ) + { + data.xScale *= ( 2 - windows[ w ].timeLine->value() ); + data.yScale *= ( 2 - windows[ w ].timeLine->value() ); + data.zScale *= ( 2 - windows[ w ].timeLine->value() ); + data.xTranslate -= int( w->width() / 2 * ( 1 - windows[ w ].timeLine->value() ) ); + data.yTranslate -= int( w->height() / 2 * ( 1 - windows[ w ].timeLine->value() ) ); + } + +void GlideEffect::postPaintWindow( EffectWindow* w ) + { + if( windows.contains( w ) ) + { + if( windows[ w ].added && windows[ w ].timeLine->value() == 1.0 ) + { + windows[ w ].added = false; + windowCount--; + effects->addRepaintFull(); + } + if( windows[ w ].closed && windows[ w ].timeLine->value() == 0.0 ) + { + windows[ w ].closed = false; + if( windows[ w ].deleted ) + { + windows.remove( w ); + w->unrefWindow(); + } + windowCount--; + effects->addRepaintFull(); + } + if( windows[ w ].added || windows[ w ].closed ) + w->addRepaintFull(); + } + effects->postPaintWindow( w ); + } + +void GlideEffect::windowAdded( EffectWindow* w ) + { + if( !isGlideWindow( w ) ) + return; + + w->setData( WindowAddedGrabRole, QVariant::fromValue( static_cast( this ))); + windows[ w ] = WindowInfo(); + windows[ w ].added = true; + windows[ w ].closed = false; + windows[ w ].deleted = false; + windows[ w ].timeLine->setDuration( duration ); + windows[ w ].timeLine->setCurveShape( TimeLine::EaseOutCurve ); + windowCount++; + w->addRepaintFull(); + } + +void GlideEffect::windowClosed( EffectWindow* w ) + { + if( !windows.contains( w ) ) + return; + w->setData( WindowClosedGrabRole, QVariant::fromValue( static_cast( this ))); + windows[ w ].added = false; + windows[ w ].closed = true; + windows[ w ].deleted = true; + windows[ w ].timeLine->setDuration( duration ); + windows[ w ].timeLine->setCurveShape( TimeLine::EaseInCurve ); + windowCount++; + w->refWindow(); + w->addRepaintFull(); + } + +void GlideEffect::windowDeleted( EffectWindow* w ) + { + //delete windows[ w ].timeLine; + windows[ w ].timeLine = NULL; + windows.remove( w ); + } + +bool GlideEffect::isGlideWindow( EffectWindow* w ) + { + const void* e = w->data( WindowAddedGrabRole ).value(); + // TODO: isSpecialWindow is rather generic, maybe tell windowtypes separately? + if ( w->isPopupMenu() || w->isSpecialWindow() || w->isUtility() || ( e && e != this )) + return false; + return true; + } +} // namespace diff --git a/effects/glide/glide.desktop b/effects/glide/glide.desktop new file mode 100644 index 0000000000..b9a017c276 --- /dev/null +++ b/effects/glide/glide.desktop @@ -0,0 +1,17 @@ +[Desktop Entry] +Name=Glide +Icon=preferences-system-windows-effect-sheet +Comment=Windows Glide Effect as they are open and closed + +Type=Service +X-KDE-ServiceTypes=KWin/Effect +X-KDE-PluginInfo-Author=Alexandre Pereira +X-KDE-PluginInfo-Email=pereira.alex@gmail.com +X-KDE-PluginInfo-Name=kwin4_effect_glide +X-KDE-PluginInfo-Version=0.1.0 +X-KDE-PluginInfo-Category=Appearance +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=false +X-KDE-Library=kwin4_effect_builtins +X-KDE-Ordering=50 diff --git a/effects/glide/glide.h b/effects/glide/glide.h new file mode 100644 index 0000000000..8e2864c2cc --- /dev/null +++ b/effects/glide/glide.h @@ -0,0 +1,88 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2007 Philip Falkner +Copyright (C) 2009 Martin Gräßlin +Copyright (C) 2010 Alexandre Pereira + +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 . +*********************************************************************/ + +#ifndef KWIN_GLIDE_H +#define KWIN_GLIDE_H + +#include + +namespace KWin +{ + +class GlideEffect + : public Effect + { + public: + GlideEffect(); + virtual void reconfigure( ReconfigureFlags ); + 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 ); + + virtual void windowAdded( EffectWindow* c ); + virtual void windowClosed( EffectWindow* c ); + virtual void windowDeleted( EffectWindow* c ); + + static bool supported(); + private: + void glideIn( EffectWindow* w, WindowPaintData& data ); + void glideOut( EffectWindow* w, WindowPaintData& data ); + class WindowInfo; + bool isGlideWindow( EffectWindow* w ); + QHash< const EffectWindow*, WindowInfo > windows; + float duration; + int angle; + int windowCount; + enum EffectStyle + { + GlideIn = 0, + GlideInOut = 1, + GlideOutIn = 2, + GlideOut = 3 + }; + EffectStyle effect; + }; + +class GlideEffect::WindowInfo + { + public: + WindowInfo() + : deleted( false ) + , added( false ) + , closed( false ) + { + timeLine = new TimeLine(); + } + ~WindowInfo() + { + timeLine = NULL; + } + bool deleted; + bool added; + bool closed; + TimeLine* timeLine; + }; + +} // namespace + +#endif diff --git a/effects/glide/glide_config.cpp b/effects/glide/glide_config.cpp new file mode 100644 index 0000000000..124ac730f1 --- /dev/null +++ b/effects/glide/glide_config.cpp @@ -0,0 +1,76 @@ +/* + * Copyright © 2010 Fredrik Höglund + * Copyright (C) 2010 Alexandre Pereira + * + * 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; see the file COPYING. if not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "glide_config.h" + +#include + +namespace KWin +{ + +KWIN_EFFECT_CONFIG_FACTORY + +GlideEffectConfig::GlideEffectConfig(QWidget *parent, const QVariantList &args) + : KCModule(EffectFactory::componentData(), parent, args) + { + ui.setupUi(this); + connect(ui.slider, SIGNAL(valueChanged(int)), SLOT(valueChanged(int))); + connect(ui.slider2, SIGNAL(valueChanged(int)), SLOT(valueChanged(int))); + load(); + } + +GlideEffectConfig::~GlideEffectConfig() + { + } + +void GlideEffectConfig::load() + { + KCModule::load(); + KConfigGroup cg = EffectsHandler::effectConfig("Glide"); + ui.slider->setValue(cg.readEntry("GlideEffect", 0) ); + ui.slider2->setValue(cg.readEntry("GlideAngle", -90) ); + emit changed(false); + } + +void GlideEffectConfig::save() + { + KCModule::save(); + KConfigGroup cg = EffectsHandler::effectConfig("Glide"); + cg.writeEntry("GlideEffect", ui.slider->value() ); + cg.writeEntry("GlideAngle", ui.slider2->value() ); + cg.sync(); + emit changed(false); + EffectsHandler::sendReloadMessage("glide"); + } + +void GlideEffectConfig::defaults() + { + ui.slider->setValue(0); + ui.slider2->setValue(-90); + emit changed(true); + } + +void GlideEffectConfig::valueChanged(int value) + { + Q_UNUSED(value) + emit changed(true); + } +} // namespace KWin +#include "glide_config.moc" diff --git a/effects/glide/glide_config.desktop b/effects/glide/glide_config.desktop new file mode 100644 index 0000000000..3a6c333d0b --- /dev/null +++ b/effects/glide/glide_config.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Type=Service +X-KDE-ServiceTypes=KCModule + +X-KDE-Library=kcm_kwin4_effect_builtins +X-KDE-ParentComponents=kwin4_effect_glide +X-KDE-PluginKeyword=glide + +Name=Glide diff --git a/effects/glide/glide_config.h b/effects/glide/glide_config.h new file mode 100644 index 0000000000..200fdcf877 --- /dev/null +++ b/effects/glide/glide_config.h @@ -0,0 +1,52 @@ +/* + * Copyright © 2010 Fredrik Höglund + * Copyright (C) 2010 Alexandre Pereira + * + * 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; see the file COPYING. if not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef GLIDE_CONFIG_H +#define GLIDE_CONFIG_H + +#include +#include "ui_glide_config.h" + +namespace KWin +{ + +class GlideEffectConfig : public KCModule +{ + Q_OBJECT + +public: + explicit GlideEffectConfig(QWidget *parent = 0, const QVariantList& args = QVariantList()); + ~GlideEffectConfig(); + + void save(); + void load(); + void defaults(); + +private slots: + void valueChanged(int value); + +private: + ::Ui::GlideEffectConfig ui; +}; + +} // namespace KWin + +#endif + diff --git a/effects/glide/glide_config.ui b/effects/glide/glide_config.ui new file mode 100644 index 0000000000..092498a85a --- /dev/null +++ b/effects/glide/glide_config.ui @@ -0,0 +1,158 @@ + + + GlideEffectConfig + + + + 0 + 0 + 306 + 72 + + + + + + + Glide Effect: + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + In + + + + + + + 0 + + + 3 + + + 1 + + + 1 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + + + + + Out + + + + + + + + + Qt::Vertical + + + + + + + Glide Angle: + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + -90 + + + + + + + -90 + + + 90 + + + 10 + + + 45 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + + + + + 90 + + + + + + + + + Qt::Vertical + + + + + + + +