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"
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 );
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
;
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());
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;
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 );
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
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
);
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() )
141 void FallApartEffect::windowClosed( EffectWindow
* c
)
143 if ( !isRealWindow( c
) )
149 void FallApartEffect::windowDeleted( EffectWindow
* c
)