not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / kwin / effects / fallapart.cpp
blobc8bbe1f23e148a54d0796aeb1e023fa8d070c9ce
1 /********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
5 Copyright (C) 2007 Lubos Lunak <l.lunak@kde.org>
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 *********************************************************************/
21 #include "fallapart.h"
22 #include <kdebug.h>
23 #include <assert.h>
24 #include <math.h>
26 namespace KWin
29 KWIN_EFFECT( fallapart, FallApartEffect )
31 void FallApartEffect::prePaintScreen( ScreenPrePaintData& data, int time )
33 if( !windows.isEmpty())
34 data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
35 effects->prePaintScreen(data, time);
38 void FallApartEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time )
40 if( windows.contains( w ) && isRealWindow( w ))
42 if( windows[ w ] < 1 )
44 windows[ w ] += time / animationTime( 1000. );
45 data.setTransformed();
46 w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DELETE );
47 // Request the window to be divided into cells
48 data.quads = data.quads.makeGrid( 40 );
50 else
52 windows.remove( w );
53 w->unrefWindow();
56 effects->prePaintWindow( w, data, time );
59 void FallApartEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
61 if( windows.contains( w ) && isRealWindow( w ) )
63 WindowQuadList new_quads;
64 int cnt = 0;
65 foreach( WindowQuad quad, data.quads )
67 // make fragments move in various directions, based on where
68 // they are (left pieces generally move to the left, etc.)
69 QPointF p1( quad[ 0 ].x(), quad[ 0 ].y());
70 double xdiff = 0;
71 if( p1.x() < w->width() / 2 )
72 xdiff = -( w->width() / 2 - p1.x()) / w->width() * 100;
73 if( p1.x() > w->width() / 2 )
74 xdiff = ( p1.x() - w->width() / 2 ) / w->width() * 100;
75 double ydiff = 0;
76 if( p1.y() < w->height() / 2 )
77 ydiff = -( w->height() / 2 - p1.y()) / w->height() * 100;
78 if( p1.y() > w->height() / 2 )
79 ydiff = ( p1.y() - w->height() / 2 ) / w->height() * 100;
80 double modif = windows[ w ] * windows[ w ] * 64;
81 srandom( cnt ); // change direction randomly but consistently
82 xdiff += ( rand() % 21 - 10 );
83 ydiff += ( rand() % 21 - 10 );
84 for( int j = 0;
85 j < 4;
86 ++j )
88 quad[ j ].move( quad[ j ].x() + xdiff * modif, quad[ j ].y() + ydiff * modif );
90 // also make the fragments rotate around their center
91 QPointF center(( quad[ 0 ].x() + quad[ 1 ].x() + quad[ 2 ].x() + quad[ 3 ].x()) / 4,
92 ( quad[ 0 ].y() + quad[ 1 ].y() + quad[ 2 ].y() + quad[ 3 ].y()) / 4 );
93 double adiff = ( rand() % 720 - 360 ) / 360. * 2 * M_PI; // spin randomly
94 for( int j = 0;
95 j < 4;
96 ++j )
98 double x = quad[ j ].x() - center.x();
99 double y = quad[ j ].y() - center.y();
100 double angle = atan2( y, x );
101 angle += windows[ w ] * adiff;
102 double dist = sqrt( x * x + y * y );
103 x = dist * cos( angle );
104 y = dist * sin( angle );
105 quad[ j ].move( center.x() + x, center.y() + y );
107 new_quads.append( quad );
108 ++cnt;
110 data.quads = new_quads;
112 effects->paintWindow( w, mask, region, data );
115 void FallApartEffect::postPaintScreen()
117 if( !windows.isEmpty())
118 effects->addRepaintFull();
119 effects->postPaintScreen();
122 bool FallApartEffect::isRealWindow( EffectWindow* w )
124 // TODO: isSpecialWindow is rather generic, maybe tell windowtypes separately?
126 kDebug(1212) << "--" << w->caption() << "--------------------------------";
127 kDebug(1212) << "Tooltip:" << w->isTooltip();
128 kDebug(1212) << "Toolbar:" << w->isToolbar();
129 kDebug(1212) << "Desktop:" << w->isDesktop();
130 kDebug(1212) << "Special:" << w->isSpecialWindow();
131 kDebug(1212) << "TopMenu:" << w->isTopMenu();
132 kDebug(1212) << "Notific:" << w->isNotification();
133 kDebug(1212) << "Splash:" << w->isSplash();
134 kDebug(1212) << "Normal:" << w->isNormalWindow();
136 if ( !w->isNormalWindow() )
137 return false;
138 return true;
141 void FallApartEffect::windowClosed( EffectWindow* c )
143 if ( !isRealWindow( c ) )
144 return;
145 windows[ c ] = 0;
146 c->refWindow();
149 void FallApartEffect::windowDeleted( EffectWindow* c )
151 windows.remove( c );
154 } // namespace