2
* Animation plugin for compiz/beryl
6
* Copyright : (C) 2006 Erkin Bahceci
7
* E-mail : erkinbah@gmail.com
9
* Based on Wobbly and Minimize plugins by
11
* E-mail : davidr@novell.com>
13
* Particle system added by : (C) 2006 Dennis Kasprzyk
14
* E-mail : onestone@beryl-project.org
16
* Beam-Up added by : Florencio Guimaraes
17
* E-mail : florencio@nexcorp.com.br
19
* Hexagon tessellator added by : Mike Slegeir
20
* E-mail : mikeslegeir@mail.utexas.edu>
22
* This program is free software; you can redistribute it and/or
23
* modify it under the terms of the GNU General Public License
24
* as published by the Free Software Foundation; either version 2
25
* of the License, or (at your option) any later version.
27
* This program is distributed in the hope that it will be useful,
28
* but WITHOUT ANY WARRANTY; without even the implied warranty of
29
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30
* GNU General Public License for more details.
32
* You should have received a copy of the GNU General Public License
33
* along with this program; if not, write to the Free Software
34
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
39
// ===================== Effect: Zoom and Sidekick =========================
41
const float ZoomAnim::kDurationFactor = 1.33;
42
const float ZoomAnim::kSpringyDurationFactor = 1.82;
43
const float ZoomAnim::kNonspringyDurationFactor = 1.67;
45
ZoomAnim::ZoomAnim (CompWindow *w,
46
WindowEvent curWindowEvent,
48
const AnimEffect info,
49
const CompRect &icon) :
50
Animation::Animation (w, curWindowEvent, duration, info, icon),
51
TransformAnim::TransformAnim (w, curWindowEvent, duration, info, icon),
52
FadeAnim::FadeAnim (w, curWindowEvent, duration, info, icon)
54
CompRect outRect (mAWindow->savedRectsValid () ?
55
mAWindow->savedOutRect () :
56
mWindow->outputRect ());
58
if (isZoomFromCenter ())
60
mIcon.setX (outRect.x () + outRect.width () / 2 - mIcon.width () / 2);
61
mIcon.setY (outRect.y () + outRect.height () / 2 - mIcon.height () / 2);
65
SidekickAnim::SidekickAnim (CompWindow *w,
66
WindowEvent curWindowEvent,
68
const AnimEffect info,
69
const CompRect &icon) :
70
Animation::Animation (w, curWindowEvent, duration, info, icon),
71
TransformAnim::TransformAnim (w, curWindowEvent, duration, info, icon),
72
ZoomAnim::ZoomAnim (w, curWindowEvent, duration, info, icon)
74
// determine number of rotations randomly in [0.9, 1.1] range
76
optValF (AnimationOptions::SidekickNumRotations) *
77
(1.0f + 0.2f * rand () / RAND_MAX - 0.1f);
79
CompRect outRect (mAWindow->savedRectsValid () ?
80
mAWindow->savedOutRect () :
81
mWindow->outputRect ());
83
float winCenterX = outRect.x () + outRect.width () / 2.0;
84
float iconCenterX = mIcon.x () + mIcon.width () / 2.0;
86
// if window is to the right of icon, rotate clockwise instead
87
// to make rotation look more pleasant
88
if (winCenterX > iconCenterX)
93
ZoomAnim::getSpringiness ()
95
return 2 * optValF (AnimationOptions::ZoomSpringiness);
99
SidekickAnim::getSpringiness ()
101
return 1.6 * optValF (AnimationOptions::SidekickSpringiness);
105
ZoomAnim::isZoomFromCenter ()
107
return (optValI (AnimationOptions::ZoomFromCenter) ==
108
AnimationOptions::ZoomFromCenterOn ||
109
((mCurWindowEvent == WindowEventMinimize ||
110
mCurWindowEvent == WindowEventUnminimize) &&
111
optValI (AnimationOptions::ZoomFromCenter) ==
112
AnimationOptions::ZoomFromCenterMinimizeUnminimizeOnly) ||
113
((mCurWindowEvent == WindowEventOpen ||
114
mCurWindowEvent == WindowEventClose) &&
115
optValI (AnimationOptions::ZoomFromCenter) ==
116
AnimationOptions::ZoomFromCenterOpenCloseOnly));
120
SidekickAnim::isZoomFromCenter ()
122
return (optValI (AnimationOptions::SidekickZoomFromCenter) ==
123
AnimationOptions::ZoomFromCenterOn ||
124
((mCurWindowEvent == WindowEventMinimize ||
125
mCurWindowEvent == WindowEventUnminimize) &&
126
optValI (AnimationOptions::SidekickZoomFromCenter) ==
127
AnimationOptions::SidekickZoomFromCenterMinimizeUnminimizeOnly) ||
128
((mCurWindowEvent == WindowEventOpen ||
129
mCurWindowEvent == WindowEventClose) &&
130
optValI (AnimationOptions::SidekickZoomFromCenter) ==
131
AnimationOptions::SidekickZoomFromCenterOpenCloseOnly));
135
ZoomAnim::adjustDuration ()
137
// allow extra time for spring damping / deceleration
138
if ((mCurWindowEvent == WindowEventUnminimize ||
139
mCurWindowEvent == WindowEventOpen) &&
140
getSpringiness () > 1e-4)
142
mTotalTime *= kSpringyDurationFactor;
144
else if (mCurWindowEvent == WindowEventOpen ||
145
mCurWindowEvent == WindowEventClose)
147
mTotalTime *= kNonspringyDurationFactor;
151
mTotalTime *= kDurationFactor;
153
mRemainingTime = mTotalTime;
157
ZoomAnim::getZoomProgress (float *pMoveProgress,
158
float *pScaleProgress,
161
float forwardProgress =
163
(mTotalTime - mTimestep);
164
forwardProgress = MIN (forwardProgress, 1);
165
forwardProgress = MAX (forwardProgress, 0);
167
float x = forwardProgress;
168
bool backwards = false;
169
int animProgressDir = 1;
171
if (mCurWindowEvent == WindowEventUnminimize ||
172
mCurWindowEvent == WindowEventOpen)
174
if (mOverrideProgressDir != 0)
175
animProgressDir = mOverrideProgressDir;
176
if ((animProgressDir == 1 &&
177
(mCurWindowEvent == WindowEventUnminimize ||
178
mCurWindowEvent == WindowEventOpen)) ||
179
(animProgressDir == 2 &&
180
(mCurWindowEvent == WindowEventMinimize ||
181
mCurWindowEvent == WindowEventClose)))
186
float dampBase = (pow (1-pow (x,1.2)*0.5,10)-pow (0.5,10))/(1-pow (0.5,10));
187
float nonSpringyProgress =
188
1 - pow (progressDecelerateCustom (1 - x, .5f, .8f), 1.7f);
194
((pow (1-(pow (x,0.7)*0.5),10)-pow (0.5,10))/(1-pow (0.5,10))) *
196
float springiness = 0;
198
// springy only when appearing
199
if ((mCurWindowEvent == WindowEventUnminimize ||
200
mCurWindowEvent == WindowEventOpen) &&
203
springiness = getSpringiness ();
206
float springyMoveProgress =
207
cos (2*M_PI*pow (x,1)*1.25) * damping * damping2;
212
if (springiness > 1e-4f)
216
springyMoveProgress *= springiness;
220
// interpolate between (springyMoveProgress * springiness)
221
// and springyMoveProgress for smooth transition at 0.2
222
// (where it crosses y=0)
223
float progressUpto02 = x / 0.2f;
224
springyMoveProgress =
225
(1 - progressUpto02) * springyMoveProgress +
226
progressUpto02 * springyMoveProgress * springiness;
228
moveProgress = 1 - springyMoveProgress;
232
moveProgress = nonSpringyProgress;
234
if (mCurWindowEvent == WindowEventUnminimize ||
235
mCurWindowEvent == WindowEventOpen)
236
moveProgress = 1 - moveProgress;
238
moveProgress = 1 - moveProgress;
240
float scProgress = nonSpringyProgress;
241
if (mCurWindowEvent == WindowEventUnminimize ||
242
mCurWindowEvent == WindowEventOpen)
243
scProgress = 1 - scProgress;
245
scProgress = 1 - scProgress;
248
pow (scProgress, 1.25);
251
*pMoveProgress = moveProgress;
253
*pScaleProgress = scaleProgress;
257
ZoomAnim::getFadeProgress ()
260
getZoomProgress (0, &fadeProgress, false);
265
ZoomAnim::getCenterScaleFull (Point *pCurCenter, Point *pCurScale,
266
Point *pWinCenter, Point *pIconCenter,
267
float *pMoveProgress)
269
CompRect outRect (mAWindow->savedRectsValid () ?
270
mAWindow->savedOutRect () :
271
mWindow->outputRect ());
273
Point winCenter ((outRect.x () + outRect.width () / 2.0),
274
(outRect.y () + outRect.height () / 2.0));
275
Point iconCenter (mIcon.x () + mIcon.width () / 2.0,
276
mIcon.y () + mIcon.height () / 2.0);
277
Point winSize (outRect.width (), outRect.height ());
279
winSize.setX (winSize.x () == 0 ? 1 : winSize.x ());
280
winSize.setY (winSize.y () == 0 ? 1 : winSize.y ());
285
getZoomProgress (&moveProgress, &scaleProgress, neverSpringy ());
288
((1 - moveProgress) * winCenter.x () + moveProgress * iconCenter.x (),
289
(1 - moveProgress) * winCenter.y () + moveProgress * iconCenter.y ());
291
(((1 - scaleProgress) * winSize.x () +
292
scaleProgress * mIcon.width ()) / winSize.x (),
293
((1 - scaleProgress) * winSize.y () +
294
scaleProgress * mIcon.height ()) / winSize.y ());
296
// Copy calculated variables
298
*pCurCenter = curCenter;
300
*pCurScale = curScale;
302
*pWinCenter = winCenter;
304
*pIconCenter = iconCenter;
306
*pMoveProgress = moveProgress;
310
ZoomAnim::applyTransform ()
320
getCenterScaleFull (&curCenter, &curScale,
321
&winCenter, &iconCenter, &moveProgress);
323
if (scaleAroundIcon ())
325
mTransform.translate (iconCenter.x (), iconCenter.y (), 0);
326
mTransform.scale (curScale.x (), curScale.y (), curScale.y ());
327
mTransform.translate (-iconCenter.x (), -iconCenter.y (), 0);
329
if (hasExtraTransform ())
331
mTransform.translate (winCenter.x (), winCenter.y (), 0);
332
applyExtraTransform (moveProgress);
333
mTransform.translate (-winCenter.x (), -winCenter.y (), 0);
338
mTransform.translate (winCenter.x (), winCenter.y (), 0);
340
if (shouldAvoidParallelogramLook ())
342
// avoid parallelogram look
343
float maxScale = MAX (curScale.x (), curScale.y ());
344
mTransform.scale (maxScale, maxScale, maxScale);
345
tx = (curCenter.x () - winCenter.x ()) / maxScale;
346
ty = (curCenter.y () - winCenter.y ()) / maxScale;
350
mTransform.scale (curScale.x (), curScale.y (), curScale.y ());
351
tx = (curCenter.x () - winCenter.x ()) / curScale.x ();
352
ty = (curCenter.y () - winCenter.y ()) / curScale.y ();
354
mTransform.translate (tx, ty, 0);
355
applyExtraTransform (moveProgress);
356
mTransform.translate (-winCenter.x (), -winCenter.y (), 0);
361
SidekickAnim::applyExtraTransform (float progress)
363
mTransform.rotate (progress * 360 * mNumRotations, 0.0f, 0.0f, 1.0f);
367
ZoomAnim::scaleAroundIcon ()
369
return (getSpringiness () == 0.0f &&
370
(mCurWindowEvent == WindowEventOpen ||
371
mCurWindowEvent == WindowEventClose));
375
ZoomAnim::getCenterScale (Point *pCurCenter, Point *pCurScale)
377
getCenterScaleFull (pCurCenter, pCurScale, NULL, NULL, NULL);
381
ZoomAnim::getActualProgress ()
383
float forwardProgress = 0;
386
getZoomProgress (&forwardProgress, 0, true);
388
forwardProgress = progressLinear ();
390
return forwardProgress;
394
ZoomAnim::getCenter ()
400
getCenterScale (¢er, 0);
404
float forwardProgress = progressLinear ();
406
CompRect inRect (mAWindow->savedRectsValid () ?
407
mAWindow->savedInRect () :
408
mWindow->inputRect ());
410
center.setX (inRect.x () + inRect.width () / 2.0);
412
if (mCurWindowEvent == WindowEventShade ||
413
mCurWindowEvent == WindowEventUnshade)
415
float origCenterY = (inRect.y () +
416
inRect.height () / 2.0);
417
center.setY ((1 - forwardProgress) * origCenterY +
418
forwardProgress * (inRect.y () +
421
else // i.e. (un)minimizing without zooming
423
center.setY (inRect.y () + inRect.height () / 2.0);
429
GridZoomAnim::GridZoomAnim (CompWindow *w,
430
WindowEvent curWindowEvent,
432
const AnimEffect info,
433
const CompRect &icon) :
434
Animation::Animation (w, curWindowEvent, duration, info, icon),
435
TransformAnim::TransformAnim (w, curWindowEvent, duration, info, icon),
436
GridTransformAnim::GridTransformAnim (w, curWindowEvent, duration, info,
438
ZoomAnim::ZoomAnim (w, curWindowEvent, duration, info, icon)
443
GridZoomAnim::adjustDuration ()
447
mTotalTime *= ZoomAnim::kDurationFactor;
448
mRemainingTime = mTotalTime;