1 /********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
5 Copyright (C) 2007 Martin Gräßlin <ubuntu@martin-graesslin.com
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *********************************************************************/
23 #include <kwinconfig.h>
26 #include <kactioncollection.h>
27 #include <kconfiggroup.h>
30 #include <kstandarddirs.h>
33 #include <QApplication>
34 #include <QDesktopWidget>
38 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
46 KWIN_EFFECT( snow
, SnowEffect
)
48 SnowEffect::SnowEffect()
53 srandom( std::time( NULL
) );
54 lastFlakeTime
= QTime::currentTime();
56 KConfigGroup conf
= effects
->effectConfig("Snow");
57 mNumberFlakes
= conf
.readEntry("Number", 50);
58 mMinFlakeSize
= conf
.readEntry("MinFlakes", 10);
59 mMaxFlakeSize
= conf
.readEntry("MaxFlakes", 50);
61 KActionCollection
* actionCollection
= new KActionCollection( this );
62 KAction
* a
= static_cast< KAction
* >( actionCollection
->addAction( "Snow" ));
63 a
->setText( i18n("Snow" ));
64 a
->setGlobalShortcut( KShortcut( Qt::CTRL
+ Qt::META
+ Qt::Key_F12
));
65 connect( a
, SIGNAL( triggered( bool )), this, SLOT( toggle()));
68 SnowEffect::~SnowEffect()
74 void SnowEffect::prePaintScreen( ScreenPrePaintData
& data
, int time
)
80 flakes
= new QList
<QRect
>();
81 lastFlakeTime
.start();
83 int count
= flakes
->count();
84 for (int i
=0; i
<count
; i
++)
86 // move flake to bottom. Therefore pop the flake, change y and push
87 // flake back to QVector
88 QRect flake
= flakes
->first();
90 int size
= flake
.height();
92 // if flake has reached bottom, don't push it back
93 if ( y
>= QApplication::desktop()->geometry().bottom() )
98 float factor
= (float)(size
-mMinFlakeSize
) / (float)(mMaxFlakeSize
-mMinFlakeSize
);
99 if (factor
>= 0.5) speed
= 2;
101 flake
.setY(y
+ speed
);
102 flake
.setHeight(size
);
103 flakes
->append(flake
);
105 // if number of active snowflakes is smaller than maximum number
106 // create a random new snowflake
107 if ( ( lastFlakeTime
.elapsed() >= nextFlakeMillis
) && flakes
->count() < mNumberFlakes
)
110 while ( size
< mMinFlakeSize
)
111 size
= random() % mMaxFlakeSize
;
112 QRect flake
= QRect( random() % (QApplication::desktop()->geometry().right() - size
), -1 * size
, size
, size
);
113 flakes
->append( flake
);
115 // calculation of next time of snowflake
116 // depends on the time the flow needs to get to the bottom (screen size)
119 float factor
= (float)(size
-mMinFlakeSize
) / (float)(mMaxFlakeSize
-mMinFlakeSize
);
120 if (factor
>= 0.5) speed
= 4;
122 long next
= ((1000/(time
+5))*(Effect::displayHeight()/speed
))/mNumberFlakes
;
123 nextFlakeMillis
= next
;
124 lastFlakeTime
.restart();
127 effects
->prePaintScreen( data
, time
);
130 void SnowEffect::paintScreen( int mask
, QRegion region
, ScreenPaintData
& data
)
132 effects
->paintScreen( mask
, region
, data
); // paint normal screen
133 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
136 if(! texture
) loadTexture();
139 glPushAttrib( GL_CURRENT_BIT
| GL_ENABLE_BIT
);
141 glEnable( GL_BLEND
);
142 glBlendFunc( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
143 for (int i
=0; i
<flakes
->count(); i
++)
145 texture
->render( region
, flakes
->at(i
));
154 void SnowEffect::postPaintScreen()
158 effects
->addRepaintFull();
160 effects
->postPaintScreen();
163 void SnowEffect::toggle()
166 if (!active
) flakes
->clear();
167 effects
->addRepaintFull();
170 void SnowEffect::loadTexture()
172 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
173 QString file
= KGlobal::dirs()->findResource( "appdata", "snowflake.png" );
176 texture
= new GLTexture( file
);