~kzmd-deactivatedaccount/ubuntu/natty/compiz-plugins-main/popup-delay-fix-772177

« back to all changes in this revision

Viewing changes to animation/src/zoomside.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2011-02-24 17:34:18 UTC
  • Revision ID: james.westby@ubuntu.com-20110224173418-b81hfllshqpciq6n
Tags: upstream-0.9.4
ImportĀ upstreamĀ versionĀ 0.9.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Animation plugin for compiz/beryl
 
3
 *
 
4
 * animation.c
 
5
 *
 
6
 * Copyright : (C) 2006 Erkin Bahceci
 
7
 * E-mail    : erkinbah@gmail.com
 
8
 *
 
9
 * Based on Wobbly and Minimize plugins by
 
10
 *           : David Reveman
 
11
 * E-mail    : davidr@novell.com>
 
12
 *
 
13
 * Particle system added by : (C) 2006 Dennis Kasprzyk
 
14
 * E-mail                   : onestone@beryl-project.org
 
15
 *
 
16
 * Beam-Up added by : Florencio Guimaraes
 
17
 * E-mail           : florencio@nexcorp.com.br
 
18
 *
 
19
 * Hexagon tessellator added by : Mike Slegeir
 
20
 * E-mail                       : mikeslegeir@mail.utexas.edu>
 
21
 *
 
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.
 
26
 *
 
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.
 
31
 *
 
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.
 
35
 */
 
36
 
 
37
#include "private.h"
 
38
 
 
39
// =====================  Effect: Zoom and Sidekick  =========================
 
40
 
 
41
const float ZoomAnim::kDurationFactor = 1.33;
 
42
const float ZoomAnim::kSpringyDurationFactor = 1.82;
 
43
const float ZoomAnim::kNonspringyDurationFactor = 1.67;
 
44
 
 
45
ZoomAnim::ZoomAnim (CompWindow *w,
 
46
                    WindowEvent curWindowEvent,
 
47
                    float duration,
 
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)
 
53
{
 
54
    CompRect outRect (mAWindow->savedRectsValid () ?
 
55
                      mAWindow->savedOutRect () :
 
56
                      mWindow->outputRect ());
 
57
 
 
58
    if (isZoomFromCenter ())
 
59
    {
 
60
        mIcon.setX (outRect.x () + outRect.width () / 2 - mIcon.width () / 2);
 
61
        mIcon.setY (outRect.y () + outRect.height () / 2 - mIcon.height () / 2);
 
62
    }
 
63
}
 
64
 
 
65
SidekickAnim::SidekickAnim (CompWindow *w,
 
66
                            WindowEvent curWindowEvent,
 
67
                            float duration,
 
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)
 
73
{
 
74
    // determine number of rotations randomly in [0.9, 1.1] range
 
75
    mNumRotations =
 
76
        optValF (AnimationOptions::SidekickNumRotations) *
 
77
        (1.0f + 0.2f * rand () / RAND_MAX - 0.1f);
 
78
 
 
79
    CompRect outRect (mAWindow->savedRectsValid () ?
 
80
                      mAWindow->savedOutRect () :
 
81
                      mWindow->outputRect ());
 
82
 
 
83
    float winCenterX = outRect.x () + outRect.width () / 2.0;
 
84
    float iconCenterX = mIcon.x () + mIcon.width () / 2.0;
 
85
 
 
86
    // if window is to the right of icon, rotate clockwise instead
 
87
    // to make rotation look more pleasant
 
88
    if (winCenterX > iconCenterX)
 
89
        mNumRotations *= -1;
 
90
}
 
91
 
 
92
float
 
93
ZoomAnim::getSpringiness ()
 
94
{
 
95
    return 2 * optValF (AnimationOptions::ZoomSpringiness);
 
96
}
 
97
 
 
98
float
 
99
SidekickAnim::getSpringiness ()
 
100
{
 
101
    return 1.6 * optValF (AnimationOptions::SidekickSpringiness);
 
102
}
 
103
 
 
104
bool
 
105
ZoomAnim::isZoomFromCenter ()
 
106
{
 
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));
 
117
}
 
118
 
 
119
bool
 
120
SidekickAnim::isZoomFromCenter ()
 
121
{
 
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));
 
132
}
 
133
 
 
134
void
 
135
ZoomAnim::adjustDuration ()
 
136
{
 
137
    // allow extra time for spring damping / deceleration
 
138
    if ((mCurWindowEvent == WindowEventUnminimize ||
 
139
         mCurWindowEvent == WindowEventOpen) &&
 
140
        getSpringiness () > 1e-4)
 
141
    {
 
142
        mTotalTime *= kSpringyDurationFactor;
 
143
    }
 
144
    else if (mCurWindowEvent == WindowEventOpen ||
 
145
             mCurWindowEvent == WindowEventClose)
 
146
    {
 
147
        mTotalTime *= kNonspringyDurationFactor;
 
148
    }
 
149
    else
 
150
    {
 
151
        mTotalTime *= kDurationFactor;
 
152
    }
 
153
    mRemainingTime = mTotalTime;
 
154
}
 
155
 
 
156
void
 
157
ZoomAnim::getZoomProgress (float *pMoveProgress,
 
158
                           float *pScaleProgress,
 
159
                           bool neverSpringy)
 
160
{
 
161
    float forwardProgress =
 
162
        1 - mRemainingTime /
 
163
        (mTotalTime - mTimestep);
 
164
    forwardProgress = MIN (forwardProgress, 1);
 
165
    forwardProgress = MAX (forwardProgress, 0);
 
166
 
 
167
    float x = forwardProgress;
 
168
    bool backwards = false;
 
169
    int animProgressDir = 1;
 
170
 
 
171
    if (mCurWindowEvent == WindowEventUnminimize ||
 
172
        mCurWindowEvent == WindowEventOpen)
 
173
        animProgressDir = 2;
 
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)))
 
182
        backwards = true;
 
183
    if (backwards)
 
184
        x = 1 - x;
 
185
 
 
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);
 
189
 
 
190
    float damping =
 
191
        pow (dampBase, 0.5);
 
192
 
 
193
    float damping2 =
 
194
        ((pow (1-(pow (x,0.7)*0.5),10)-pow (0.5,10))/(1-pow (0.5,10))) *
 
195
        0.7 + 0.3;
 
196
    float springiness = 0;
 
197
 
 
198
    // springy only when appearing
 
199
    if ((mCurWindowEvent == WindowEventUnminimize ||
 
200
         mCurWindowEvent == WindowEventOpen) &&
 
201
        !neverSpringy)
 
202
    {
 
203
        springiness = getSpringiness ();
 
204
    }
 
205
 
 
206
    float springyMoveProgress =
 
207
        cos (2*M_PI*pow (x,1)*1.25) * damping * damping2;
 
208
 
 
209
    float scaleProgress;
 
210
    float moveProgress;
 
211
 
 
212
    if (springiness > 1e-4f)
 
213
    {
 
214
        if (x > 0.2)
 
215
        {
 
216
            springyMoveProgress *= springiness;
 
217
        }
 
218
        else
 
219
        {
 
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;
 
227
        }
 
228
        moveProgress = 1 - springyMoveProgress;
 
229
    }
 
230
    else
 
231
    {
 
232
        moveProgress = nonSpringyProgress;
 
233
    }
 
234
    if (mCurWindowEvent == WindowEventUnminimize ||
 
235
        mCurWindowEvent == WindowEventOpen)
 
236
        moveProgress = 1 - moveProgress;
 
237
    if (backwards)
 
238
        moveProgress = 1 - moveProgress;
 
239
 
 
240
    float scProgress = nonSpringyProgress;
 
241
    if (mCurWindowEvent == WindowEventUnminimize ||
 
242
        mCurWindowEvent == WindowEventOpen)
 
243
        scProgress = 1 - scProgress;
 
244
    if (backwards)
 
245
        scProgress = 1 - scProgress;
 
246
 
 
247
    scaleProgress =
 
248
        pow (scProgress, 1.25);
 
249
 
 
250
    if (pMoveProgress)
 
251
        *pMoveProgress = moveProgress;
 
252
    if (pScaleProgress)
 
253
        *pScaleProgress = scaleProgress;
 
254
}
 
255
 
 
256
float
 
257
ZoomAnim::getFadeProgress ()
 
258
{
 
259
    float fadeProgress;
 
260
    getZoomProgress (0, &fadeProgress, false);
 
261
    return fadeProgress;
 
262
}
 
263
 
 
264
void
 
265
ZoomAnim::getCenterScaleFull (Point *pCurCenter, Point *pCurScale,
 
266
                              Point *pWinCenter, Point *pIconCenter,
 
267
                              float *pMoveProgress)
 
268
{
 
269
    CompRect outRect (mAWindow->savedRectsValid () ?
 
270
                      mAWindow->savedOutRect () :
 
271
                      mWindow->outputRect ());
 
272
 
 
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 ());
 
278
 
 
279
    winSize.setX (winSize.x () == 0 ? 1 : winSize.x ());
 
280
    winSize.setY (winSize.y () == 0 ? 1 : winSize.y ());
 
281
 
 
282
    float scaleProgress;
 
283
    float moveProgress;
 
284
 
 
285
    getZoomProgress (&moveProgress, &scaleProgress, neverSpringy ());
 
286
 
 
287
    Point curCenter
 
288
        ((1 - moveProgress) * winCenter.x () + moveProgress * iconCenter.x (),
 
289
         (1 - moveProgress) * winCenter.y () + moveProgress * iconCenter.y ());
 
290
    Point curScale
 
291
        (((1 - scaleProgress) * winSize.x () +
 
292
          scaleProgress * mIcon.width ()) / winSize.x (),
 
293
         ((1 - scaleProgress) * winSize.y () +
 
294
          scaleProgress * mIcon.height ()) / winSize.y ());
 
295
 
 
296
    // Copy calculated variables
 
297
    if (pCurCenter)
 
298
        *pCurCenter = curCenter;
 
299
    if (pCurScale)
 
300
        *pCurScale = curScale;
 
301
    if (pWinCenter)
 
302
        *pWinCenter = winCenter;
 
303
    if (pIconCenter)
 
304
        *pIconCenter = iconCenter;
 
305
    if (pMoveProgress)
 
306
        *pMoveProgress = moveProgress;
 
307
}
 
308
 
 
309
void
 
310
ZoomAnim::applyTransform ()
 
311
{
 
312
    if (!zoomToIcon ())
 
313
        return;
 
314
    Point curCenter;
 
315
    Point curScale;
 
316
    Point winCenter;
 
317
    Point iconCenter;
 
318
    float moveProgress;
 
319
 
 
320
    getCenterScaleFull (&curCenter, &curScale,
 
321
                        &winCenter, &iconCenter, &moveProgress);
 
322
 
 
323
    if (scaleAroundIcon ())
 
324
    {
 
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);
 
328
 
 
329
        if (hasExtraTransform ())
 
330
        {
 
331
            mTransform.translate (winCenter.x (), winCenter.y (), 0);
 
332
            applyExtraTransform (moveProgress);
 
333
            mTransform.translate (-winCenter.x (), -winCenter.y (), 0);
 
334
        }
 
335
    }
 
336
    else
 
337
    {
 
338
        mTransform.translate (winCenter.x (), winCenter.y (), 0);
 
339
        float tx, ty;
 
340
        if (shouldAvoidParallelogramLook ())
 
341
        {
 
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;
 
347
        }
 
348
        else
 
349
        {
 
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 ();
 
353
        }
 
354
        mTransform.translate (tx, ty, 0);
 
355
        applyExtraTransform (moveProgress);
 
356
        mTransform.translate (-winCenter.x (), -winCenter.y (), 0);
 
357
    }
 
358
}
 
359
 
 
360
void
 
361
SidekickAnim::applyExtraTransform (float progress)
 
362
{
 
363
    mTransform.rotate (progress * 360 * mNumRotations, 0.0f, 0.0f, 1.0f);
 
364
}
 
365
 
 
366
bool
 
367
ZoomAnim::scaleAroundIcon ()
 
368
{
 
369
    return (getSpringiness () == 0.0f &&
 
370
            (mCurWindowEvent == WindowEventOpen ||
 
371
             mCurWindowEvent == WindowEventClose));
 
372
}
 
373
 
 
374
void
 
375
ZoomAnim::getCenterScale (Point *pCurCenter, Point *pCurScale)
 
376
{
 
377
    getCenterScaleFull (pCurCenter, pCurScale, NULL, NULL, NULL);
 
378
}
 
379
 
 
380
float
 
381
ZoomAnim::getActualProgress ()
 
382
{
 
383
    float forwardProgress = 0;
 
384
 
 
385
    if (zoomToIcon ())
 
386
        getZoomProgress (&forwardProgress, 0, true);
 
387
    else
 
388
        forwardProgress = progressLinear ();
 
389
 
 
390
    return forwardProgress;
 
391
}
 
392
 
 
393
Point
 
394
ZoomAnim::getCenter ()
 
395
{
 
396
    Point center;
 
397
 
 
398
    if (zoomToIcon ())
 
399
    {
 
400
        getCenterScale (&center, 0);
 
401
    }
 
402
    else
 
403
    {
 
404
        float forwardProgress = progressLinear ();
 
405
 
 
406
        CompRect inRect (mAWindow->savedRectsValid () ?
 
407
                         mAWindow->savedInRect () :
 
408
                         mWindow->inputRect ());
 
409
 
 
410
        center.setX (inRect.x () + inRect.width () / 2.0);
 
411
 
 
412
        if (mCurWindowEvent == WindowEventShade ||
 
413
            mCurWindowEvent == WindowEventUnshade)
 
414
        {
 
415
            float origCenterY = (inRect.y () +
 
416
                                 inRect.height () / 2.0);
 
417
            center.setY ((1 - forwardProgress) * origCenterY +
 
418
                         forwardProgress * (inRect.y () +
 
419
                                            mDecorTopHeight));
 
420
        }
 
421
        else // i.e. (un)minimizing without zooming
 
422
        {
 
423
            center.setY (inRect.y () + inRect.height () / 2.0);
 
424
        }
 
425
    }
 
426
    return center;
 
427
}
 
428
 
 
429
GridZoomAnim::GridZoomAnim (CompWindow *w,
 
430
                            WindowEvent curWindowEvent,
 
431
                            float duration,
 
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,
 
437
                                          icon),
 
438
    ZoomAnim::ZoomAnim (w, curWindowEvent, duration, info, icon)
 
439
{
 
440
}
 
441
 
 
442
void
 
443
GridZoomAnim::adjustDuration ()
 
444
{
 
445
    if (zoomToIcon ())
 
446
    {
 
447
        mTotalTime *= ZoomAnim::kDurationFactor;
 
448
        mRemainingTime = mTotalTime;
 
449
    }
 
450
}
 
451