Snow effect from Martin Graesslin <ubuntu@martin-graesslin.com>.

svn path=/trunk/KDE/kdebase/workspace/; revision=758626
This commit is contained in:
Luboš Luňák 2008-01-08 15:47:31 +00:00
parent 2f1e9eba44
commit a6fbe3d13e
10 changed files with 577 additions and 0 deletions

View file

@ -102,6 +102,7 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
mousemark.cpp mousemark.cpp
shadow.cpp shadow.cpp
sharpen.cpp sharpen.cpp
snow.cpp
trackmouse.cpp trackmouse.cpp
) )
install( FILES install( FILES
@ -113,6 +114,7 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
mousemark.desktop mousemark.desktop
shadow.desktop shadow.desktop
sharpen.desktop sharpen.desktop
snow.desktop
trackmouse.desktop trackmouse.desktop
DESTINATION ${SERVICES_INSTALL_DIR}/kwin ) DESTINATION ${SERVICES_INSTALL_DIR}/kwin )
install( FILES install( FILES
@ -132,6 +134,7 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
data/lookingglass.frag data/lookingglass.frag
data/lookingglass.vert data/lookingglass.vert
data/shadow-texture.png data/shadow-texture.png
data/snowflake.png
data/circle.png data/circle.png
data/circle-edgy.png data/circle-edgy.png
DESTINATION ${DATA_INSTALL_DIR}/kwin ) DESTINATION ${DATA_INSTALL_DIR}/kwin )
@ -144,6 +147,8 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
mousemark_config.cpp mousemark_config.cpp
mousemark_config.ui mousemark_config.ui
sharpen_config.cpp sharpen_config.cpp
snow_config.cpp
snow_config.ui
trackmouse_config.cpp trackmouse_config.cpp
) )
install( FILES install( FILES
@ -152,6 +157,7 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
magnifier_config.desktop magnifier_config.desktop
mousemark_config.desktop mousemark_config.desktop
sharpen_config.desktop sharpen_config.desktop
snow_config.desktop
trackmouse_config.desktop trackmouse_config.desktop
DESTINATION ${SERVICES_INSTALL_DIR}/kwin ) DESTINATION ${SERVICES_INSTALL_DIR}/kwin )
endif(KWIN_HAVE_OPENGL_COMPOSITING) endif(KWIN_HAVE_OPENGL_COMPOSITING)

View file

@ -35,6 +35,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "mousemark_config.h" #include "mousemark_config.h"
#include "magnifier_config.h" #include "magnifier_config.h"
#include "sharpen_config.h" #include "sharpen_config.h"
#include "snow_config.h"
#include "trackmouse_config.h" #include "trackmouse_config.h"
#endif #endif
@ -60,6 +61,7 @@ KWIN_EFFECT_CONFIG_FACTORY
registerPlugin<KWin::MouseMarkEffectConfig>("mousemark"); \ registerPlugin<KWin::MouseMarkEffectConfig>("mousemark"); \
registerPlugin<KWin::MagnifierEffectConfig>("magnifier"); \ registerPlugin<KWin::MagnifierEffectConfig>("magnifier"); \
registerPlugin<KWin::SharpenEffectConfig>("sharpen"); \ registerPlugin<KWin::SharpenEffectConfig>("sharpen"); \
registerPlugin<KWin::SnowEffectConfig>("snow"); \
registerPlugin<KWin::TrackMouseEffectConfig>("trackmouse"); \ registerPlugin<KWin::TrackMouseEffectConfig>("trackmouse"); \
#ifdef KWIN_HAVE_OPENGL_COMPOSITING #ifdef KWIN_HAVE_OPENGL_COMPOSITING

BIN
effects/data/snowflake.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

181
effects/snow.cpp Normal file
View file

@ -0,0 +1,181 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2007 Martin Gräßlin <ubuntu@martin-graesslin.com
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 <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "snow.h"
#include <kwinconfig.h>
#include <kaction.h>
#include <kactioncollection.h>
#include <kconfiggroup.h>
#include <kglobal.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kdebug.h>
#include <QApplication>
#include <QDesktopWidget>
#include <ctime>
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
#include <GL/gl.h>
#endif
namespace KWin
{
KWIN_EFFECT( snow, SnowEffect )
SnowEffect::SnowEffect()
: texture( NULL )
, flakes( NULL )
, active( false)
{
srandom( std::time( NULL ) );
lastFlakeTime = QTime::currentTime();
nextFlakeMillis = 0;
KConfigGroup conf = effects->effectConfig("Snow");
mNumberFlakes = conf.readEntry("Number", 50);
mMinFlakeSize = conf.readEntry("MinFlakes", 10);
mMaxFlakeSize = conf.readEntry("MaxFlakes", 50);
KActionCollection* actionCollection = new KActionCollection( this );
KAction* a = static_cast< KAction* >( actionCollection->addAction( "Snow" ));
a->setText( i18n("Snow" ));
a->setGlobalShortcut( KShortcut( Qt::CTRL + Qt::META + Qt::Key_F12 ));
connect( a, SIGNAL( triggered( bool )), this, SLOT( toggle()));
}
SnowEffect::~SnowEffect()
{
delete texture;
delete flakes;
}
void SnowEffect::prePaintScreen( ScreenPrePaintData& data, int time )
{
if ( active )
{
if (! flakes )
{
flakes = new QList<QRect>();
lastFlakeTime.start();
}
int count = flakes->count();
for (int i=0; i<count; i++)
{
// move flake to bottom. Therefore pop the flake, change y and push
// flake back to QVector
QRect flake = flakes->first();
flakes->pop_front();
int size = flake.height();
int y = flake.y();
// if flake has reached bottom, don't push it back
if ( y >= QApplication::desktop()->geometry().bottom() )
{
continue;
}
int speed;
float factor = (float)(size-mMinFlakeSize) / (float)(mMaxFlakeSize-mMinFlakeSize);
if (factor >= 0.5) speed = 2;
else speed = 1;
flake.setY(y + speed);
flake.setHeight(size);
flakes->append(flake);
}
// if number of active snowflakes is smaller than maximum number
// create a random new snowflake
if ( ( lastFlakeTime.elapsed() >= nextFlakeMillis ) && flakes->count() < mNumberFlakes)
{
int size = 0;
while ( size < mMinFlakeSize )
size = random() % mMaxFlakeSize;
QRect flake = QRect( random() % (QApplication::desktop()->geometry().right() - size), -1 * size, size, size );
flakes->append( flake );
// calculation of next time of snowflake
// depends on the time the flow needs to get to the bottom (screen size)
// and the fps
int speed;
float factor = (float)(size-mMinFlakeSize) / (float)(mMaxFlakeSize-mMinFlakeSize);
if (factor >= 0.5) speed = 4;
else speed = 2;
long next = ((1000/(time+5))*(Effect::displayHeight()/speed))/mNumberFlakes;
nextFlakeMillis = next;
lastFlakeTime.restart();
}
}
effects->prePaintScreen( data, time );
}
void SnowEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
{
effects->paintScreen( mask, region, data ); // paint normal screen
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
if( active )
{
if(! texture ) loadTexture();
if( texture )
{
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT );
texture->bind();
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
for (int i=0; i<flakes->count(); i++)
{
texture->render( false, region, flakes->at(i));
}
texture->unbind();
glPopAttrib();
}
}
#endif
}
void SnowEffect::postPaintScreen()
{
if( active )
{
effects->addRepaintFull();
}
effects->postPaintScreen();
}
void SnowEffect::toggle()
{
active = !active;
if (!active) flakes->clear();
effects->addRepaintFull();
}
void SnowEffect::loadTexture()
{
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
QString file = KGlobal::dirs()->findResource( "appdata", "snowflake.png" );
if( file.isEmpty())
return;
texture = new GLTexture( file );
#endif
}
} // namespace

28
effects/snow.desktop Normal file
View file

@ -0,0 +1,28 @@
[Desktop Entry]
# Name of the effect
Name=Snow
Comment=Let it snow on the desktop
Icon=preferences-system-windows-effect-snow
# This is KWin effect
Type=Service
X-KDE-ServiceTypes=KWin/Effect
# Author and email of the author
X-KDE-PluginInfo-Author=Martin Gräßlin
X-KDE-PluginInfo-Email=ubuntu@martin-graesslin.com
# Internal name of the effect
X-KDE-PluginInfo-Name=kwin4_effect_snow
# Category of the effect, for config dialog
X-KDE-PluginInfo-Category=Appearance
# Version and license
X-KDE-PluginInfo-Version=0.1.2
X-KDE-PluginInfo-License=GPL
# If the effect depends on any other effect(s) to be active, then internal
# names of those effects can be given here
X-KDE-PluginInfo-Depends=
# Whether this effect should be enabled by default
X-KDE-PluginInfo-EnabledByDefault=false
# The plugin (library) which contains the effect. One library may contain more effects.
X-KDE-Library=kwin4_effect_builtins
# The order in which this effect is loaded. Lower numbers are loaded first.
X-Ordering=90

62
effects/snow.h Normal file
View file

@ -0,0 +1,62 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2007 Martin Gräßlin <ubuntu@martin-graesslin.com
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 <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_SNOW_H
#define KWIN_SNOW_H
#include <kwineffects.h>
#include <kwinglutils.h>
#include <qobject.h>
#include <QList>
#include <QTime>
namespace KWin
{
class SnowEffect
: public QObject, public Effect
{
Q_OBJECT
public:
SnowEffect();
virtual ~SnowEffect();
virtual void prePaintScreen( ScreenPrePaintData& data, int time );
virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data );
virtual void postPaintScreen();
private slots:
void toggle();
private:
void loadTexture();
GLTexture* texture;
QList<QRect>* flakes;
QTime lastFlakeTime;
long nextFlakeMillis;
int mNumberFlakes;
int mMinFlakeSize;
int mMaxFlakeSize;
bool active;
};
} // namespace
#endif

125
effects/snow_config.cpp Normal file
View file

@ -0,0 +1,125 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2007 Martin Gräßlin <ubuntu@martin-graesslin.com
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 <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "snow_config.h"
#include <kwineffects.h>
#include <klocale.h>
#include <kdebug.h>
#include <KActionCollection>
#include <kaction.h>
#include <KGlobalAccel>
#include <kconfiggroup.h>
#include <QGridLayout>
#ifndef KDE_USE_FINAL
KWIN_EFFECT_CONFIG_FACTORY
#endif
namespace KWin
{
SnowEffectConfigForm::SnowEffectConfigForm(QWidget* parent) : QWidget(parent)
{
setupUi(this);
}
SnowEffectConfig::SnowEffectConfig(QWidget* parent, const QVariantList& args) :
KCModule(EffectFactory::componentData(), parent, args)
{
kDebug() ;
m_ui = new SnowEffectConfigForm(this);
QGridLayout* layout = new QGridLayout(this);
layout->addWidget(m_ui, 0, 0);
connect(m_ui->editor, SIGNAL(keyChange()), this, SLOT(changed()));
connect(m_ui->numberFlakes, SIGNAL(valueChanged(int)), this, SLOT(changed()));
connect(m_ui->minSizeFlake, SIGNAL(valueChanged(int)), this, SLOT(changed()));
connect(m_ui->maxSizeFlake, SIGNAL(valueChanged(int)), this, SLOT(changed()));
KGlobalAccel::self()->overrideMainComponentData(componentData());
m_actionCollection = new KActionCollection( this, componentData() );
m_actionCollection->setConfigGroup("Snow");
m_actionCollection->setConfigGlobal(true);
KAction* a = (KAction*)m_actionCollection->addAction( "Snow" );
a->setText( i18n("Toggle Snow on the desktop" ));
a->setGlobalShortcut( KShortcut( Qt::CTRL + Qt::META + Qt::Key_F12 ));
load();
}
SnowEffectConfig::~SnowEffectConfig()
{
kDebug() ;
}
void SnowEffectConfig::load()
{
kDebug() ;
KCModule::load();
KConfigGroup conf = EffectsHandler::effectConfig("Snow");
int number = conf.readEntry("Number", 50);
int minFlake = conf.readEntry("MinFlakes", 10);
int maxFlake = conf.readEntry("MaxFlakes", 50);
m_ui->numberFlakes->setValue( number );
m_ui->minSizeFlake->setValue( minFlake );
m_ui->maxSizeFlake->setValue( maxFlake );
m_actionCollection->readSettings();
m_ui->editor->addCollection(m_actionCollection);
emit changed(false);
}
void SnowEffectConfig::save()
{
kDebug() ;
KConfigGroup conf = EffectsHandler::effectConfig("Snow");
conf.writeEntry("Number", m_ui->numberFlakes->value());
conf.writeEntry("MinFlakes", m_ui->minSizeFlake->value());
conf.writeEntry("MaxFlakes", m_ui->maxSizeFlake->value());
m_actionCollection->writeSettings();
conf.sync();
emit changed(false);
EffectsHandler::sendReloadMessage( "snow" );
}
void SnowEffectConfig::defaults()
{
kDebug() ;
m_ui->numberFlakes->setValue( 50 );
m_ui->minSizeFlake->setValue( 10 );
m_ui->maxSizeFlake->setValue( 50 );
emit changed(true);
}
} // namespace
#include "snow_config.moc"

View file

@ -0,0 +1,9 @@
[Desktop Entry]
Type=Service
X-KDE-ServiceTypes=KCModule
X-KDE-Library=kcm_kwin4_effect_builtins
X-KDE-ParentComponents=kwin4_effect_snow
X-KDE-PluginKeyword=snow
Name=Snow

61
effects/snow_config.h Normal file
View file

@ -0,0 +1,61 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2007 Martin Gräßlin <ubuntu@martin-graesslin.com
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 <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_SNOW_CONFIG_H
#define KWIN_SNOW_CONFIG_H
#define KDE3_SUPPORT
#include <kcmodule.h>
#undef KDE3_SUPPORT
#include "ui_snow_config.h"
class KActionCollection;
namespace KWin
{
class SnowEffectConfigForm : public QWidget, public Ui::SnowEffectConfigForm
{
Q_OBJECT
public:
explicit SnowEffectConfigForm(QWidget* parent);
};
class SnowEffectConfig : public KCModule
{
Q_OBJECT
public:
explicit SnowEffectConfig(QWidget* parent = 0, const QVariantList& args = QVariantList());
~SnowEffectConfig();
public slots:
virtual void save();
virtual void load();
virtual void defaults();
private:
SnowEffectConfigForm* m_ui;
KActionCollection* m_actionCollection;
};
} // namespace
#endif

103
effects/snow_config.ui Normal file
View file

@ -0,0 +1,103 @@
<ui version="4.0" >
<class>KWin::SnowEffectConfigForm</class>
<widget class="QWidget" name="KWin::SnowEffectConfigForm" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<layout class="QVBoxLayout" >
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>Appearance</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>&amp;Number of snowflakes</string>
</property>
<property name="buddy" >
<cstring>numberFlakes</cstring>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QSpinBox" name="numberFlakes" >
<property name="maximum" >
<number>1000</number>
</property>
<property name="value" >
<number>50</number>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>M&amp;inimum size of snowflake</string>
</property>
<property name="buddy" >
<cstring>minSizeFlake</cstring>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QSpinBox" name="minSizeFlake" >
<property name="suffix" >
<string> px</string>
</property>
<property name="maximum" >
<number>30</number>
</property>
<property name="value" >
<number>10</number>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>M&amp;aximum size of snowflake</string>
</property>
<property name="buddy" >
<cstring>maxSizeFlake</cstring>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QSpinBox" name="maxSizeFlake" >
<property name="suffix" >
<string> px</string>
</property>
<property name="maximum" >
<number>1000</number>
</property>
<property name="value" >
<number>50</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="KWin::GlobalShortcutsEditor" native="1" name="editor" />
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KWin::GlobalShortcutsEditor</class>
<extends>QWidget</extends>
<header location="global" >kwineffects.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>