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: Dodge =========================
42
DodgeAnim::applyDodgeTransform ()
44
if (mDodgeData->isDodgeSubject && mDodgeDirection == DodgeDirectionNone)
50
if (mDodgeMaxAmountX != 0)
51
amountX = sin (M_PI * mTransformProgress) * mDodgeMaxAmountX;
53
if (mDodgeMaxAmountY != 0)
54
amountY = sin (M_PI * mTransformProgress) * mDodgeMaxAmountY;
56
mTransform.translate (amountX, amountY, 0.0f);
60
DodgeAnim::moveUpdate ()
62
if (mDodgeData->isDodgeSubject &&
63
mDodgeDirection == DodgeDirectionXY)
65
mDodgeDirection = DodgeDirectionNone;
70
CompWindow *wBottommost =
71
ExtensionPluginAnimation::getBottommostInRestackChain (mWindow);
73
// Update dodge amount for the dodgers of all subjects
74
// in the restack chain
75
RestackPersistentData *dataCur;
76
for (CompWindow *wCur = wBottommost; wCur;
77
wCur = dataCur->mMoreToBePaintedNext)
79
AnimWindow *awCur = AnimWindow::get (wCur);
80
dataCur = static_cast<RestackPersistentData *>
81
(awCur->persistentData["restack"]);
85
Animation *curAnim = awCur->curAnimation ();
86
if (!curAnim || curAnim->info () != AnimEffectDodge)
89
DodgePersistentData *dodgeDataDodger;
91
// Update dodge amount for each dodger
92
for (CompWindow *dw = mDodgeData->dodgeChainStart; dw;
93
dw = dodgeDataDodger->dodgeChainNext)
95
AnimWindow *adw = AnimWindow::get (dw);
97
static_cast<DodgePersistentData *>
98
(adw->persistentData["dodge"]);
100
DodgeAnim *animDodger =
101
dynamic_cast<DodgeAnim *> (adw->curAnimation ());
105
if (animDodger->mDodgeSubjectWin &&
106
animDodger->mTransformProgress <= 0.5f)
108
animDodger->updateDodgerDodgeAmount ();
116
/// Should only be called for non-subjects.
118
DodgeAnim::updateDodgerDodgeAmount ()
120
// Find the box to be dodged, it can contain multiple windows
121
// when there are dialog/utility windows of subject windows
122
// (stacked in the mMoreToBePaintedNext chain).
123
// Then this would be a bounding box of the subject windows
124
// intersecting with dodger.
125
CompRect subjectRect (unionRestackChain (mDodgeSubjectWin).boundingRect ());
127
// Update dodge amount if subject window(s) moved during dodge
128
float newDodgeAmount =
129
getDodgeAmount (subjectRect, mWindow, mDodgeDirection);
131
// Only update if amount got larger
132
if (((mDodgeDirection == DodgeDirectionDown && newDodgeAmount > 0) ||
133
(mDodgeDirection == DodgeDirectionUp && newDodgeAmount < 0)) &&
134
abs (newDodgeAmount) > abs (mDodgeMaxAmountY))
136
mDodgeMaxAmountY = newDodgeAmount;
138
else if (((mDodgeDirection == DodgeDirectionRight && newDodgeAmount > 0) ||
139
(mDodgeDirection == DodgeDirectionLeft && newDodgeAmount < 0)) &&
140
abs (newDodgeAmount) > abs (mDodgeMaxAmountX))
142
mDodgeMaxAmountX = newDodgeAmount;
147
DodgeAnim::dodgeProgress ()
149
float forwardProgress = progressLinear ();
151
forwardProgress = 1 - forwardProgress;
152
return forwardProgress;
158
TransformAnim::step ();
160
mTransformProgress = 0;
162
float forwardProgress = dodgeProgress ();
163
if (forwardProgress > mTransformStartProgress)
165
// Compute transform progress and normalize
167
(forwardProgress - mTransformStartProgress) /
168
(1 - mTransformStartProgress);
172
applyDodgeTransform ();
176
DodgeAnim::updateTransform (GLMatrix &wTransform)
178
TransformAnim::updateTransform (wTransform);
182
DodgeAnim::postPreparePaint ()
184
// Only dodge subjects (with dodger chains) should be processed here
185
if (!mDodgeData || !mDodgeData->isDodgeSubject ||
186
!mDodgeData->dodgeChainStart)
189
if (!mRestackData || !mRestackData->restackInfo ())
192
if (mDodgeData->skipPostPrepareScreen)
195
// Find the bottommost subject in restack chain
196
CompWindow *wBottommost = mWindow;
197
RestackPersistentData *dataCur;
198
for (CompWindow *wCur = mRestackData->mMoreToBePaintedPrev; wCur;
199
wCur = dataCur->mMoreToBePaintedPrev)
202
dataCur = static_cast<RestackPersistentData *>
203
(AnimWindow::get (wCur)->persistentData["restack"]);
207
AnimWindow *awBottommost = AnimWindow::get (wBottommost);
208
RestackPersistentData *restackDataBottommost =
209
static_cast<RestackPersistentData *>
210
(awBottommost->persistentData["restack"]);
212
// Find the first dodging window that hasn't yet
213
// reached 50% progress yet. The subject window should be
214
// painted right behind that one (or right in front of it
215
// if subject is being lowered).
216
RestackPersistentData *restackDataDodger;
217
DodgePersistentData *dodgeDataDodger;
219
for (dw = mDodgeData->dodgeChainStart; dw;
220
dw = dodgeDataDodger->dodgeChainNext)
222
AnimWindow *adw = AnimWindow::get (dw);
223
restackDataDodger = static_cast<RestackPersistentData *>
224
(adw->persistentData["restack"]);
225
dodgeDataDodger = static_cast<DodgePersistentData *>
226
(adw->persistentData["dodge"]);
228
DodgeAnim *animDodger =
229
dynamic_cast<DodgeAnim *> (adw->curAnimation ());
231
if (!(animDodger->mTransformProgress > 0.5f))
235
RestackInfo *bottommostRestackInfo = restackDataBottommost->restackInfo ();
236
if (!bottommostRestackInfo)
239
if (bottommostRestackInfo->raised &&
240
// if mWindow's host should change
241
dw != restackDataBottommost->mWinThisIsPaintedBefore)
243
if (restackDataBottommost->mWinThisIsPaintedBefore)
246
RestackPersistentData *dataOldHost =
247
static_cast<RestackPersistentData *>
248
(AnimWindow::get (restackDataBottommost->
249
mWinThisIsPaintedBefore)->
250
persistentData["restack"]);
251
dataOldHost->mWinToBePaintedBeforeThis = 0;
253
// if a dodger win. is still at <0.5 progress
254
if (dw && restackDataDodger)
256
// Put subject right behind new host
257
restackDataDodger->mWinToBePaintedBeforeThis = wBottommost;
259
// otherwise all dodger win.s have passed 0.5 progress
261
CompWindow *wCur = wBottommost;
264
RestackPersistentData *dataCur =
265
static_cast<RestackPersistentData *>
266
(AnimWindow::get (wCur)->persistentData["restack"]);
267
// dw can be null, which is ok
268
dataCur->mWinThisIsPaintedBefore = dw;
269
wCur = dataCur->mMoreToBePaintedNext;
272
else if (!bottommostRestackInfo->raised)
274
// Put the subject right in front of dw.
275
// But we need to find the (dodger) window above dw
276
// (since we need to put the subject *behind* a window).
278
CompWindow *wDodgeChainAbove = 0;
280
// if a dodger win. is still at <0.5 progress
281
if (dw && dodgeDataDodger)
283
if (dodgeDataDodger->dodgeChainPrev)
285
wDodgeChainAbove = dodgeDataDodger->dodgeChainPrev;
289
// Use the wOldAbove of topmost subject
290
wDodgeChainAbove = mRestackData->restackInfo ()->wOldAbove;
292
if (!wDodgeChainAbove)
293
compLogMessage ("animation", CompLogLevelError,
294
"%s: error at line %d", __FILE__, __LINE__);
295
else if (restackDataBottommost->mWinThisIsPaintedBefore !=
296
wDodgeChainAbove) // w's host is changing
298
RestackPersistentData *dataNewHost =
299
static_cast<RestackPersistentData *>
300
(AnimWindow::get (wDodgeChainAbove)->
301
persistentData["restack"]);
303
// Put subject right behind new host
304
dataNewHost->mWinToBePaintedBeforeThis = wBottommost;
307
if (restackDataBottommost->mWinThisIsPaintedBefore &&
308
restackDataBottommost->mWinThisIsPaintedBefore != wDodgeChainAbove)
311
RestackPersistentData *dataOldHost =
312
static_cast<RestackPersistentData *>
313
(AnimWindow::get (restackDataBottommost->
314
mWinThisIsPaintedBefore)->
315
persistentData["restack"]);
316
dataOldHost->mWinToBePaintedBeforeThis = 0;
318
// otherwise all dodger win.s have passed 0.5 progress
320
CompWindow *wCur = wBottommost;
323
RestackPersistentData *dataCur =
324
static_cast<RestackPersistentData *>
325
(AnimWindow::get (wCur)->persistentData["restack"]);
326
// wDodgeChainAbove can be null, which is ok
327
dataCur->mWinThisIsPaintedBefore = wDodgeChainAbove;
328
wCur = dataCur->mMoreToBePaintedNext;
334
DodgeAnim::shouldDamageWindowOnStart ()
336
// for dodging windows only, when subject is fixed
337
return !(mDodgeMode == AnimationOptions::DodgeModeFixedClickedWindow &&
338
mDodgeData->isDodgeSubject);
342
DodgeAnim::updateBB (CompOutput &output)
344
TransformAnim::updateBB (output);
347
DodgeAnim::DodgeAnim (CompWindow *w,
348
WindowEvent curWindowEvent,
350
const AnimEffect info,
351
const CompRect &icon) :
352
Animation::Animation (w, curWindowEvent, duration, info, icon),
353
RestackAnim::RestackAnim (w, curWindowEvent, duration, info, icon),
354
TransformAnim::TransformAnim (w, curWindowEvent, duration, info, icon),
355
mDodgeData (static_cast<DodgePersistentData *>
356
(AnimWindow::get (w)->persistentData["dodge"])),
357
mDodgeSubjectWin (0),
358
mDodgeMaxAmountX (0),
359
mDodgeMaxAmountY (0),
360
mDodgeDirection (DodgeDirectionNone),
361
mDodgeMode (optValI (AnimationOptions::DodgeMode))
366
DodgeAnim::cleanUp (bool closing,
369
// Remove this window from its subject's dodger chain
370
if (mDodgeSubjectWin)
372
CompWindow *w = mDodgeSubjectWin;
373
AnimWindow *aw = AnimWindow::get (w);
374
Animation *curAnim = aw->curAnimation ();
375
DodgePersistentData *dodgeData = static_cast<DodgePersistentData *>
376
(aw->persistentData["dodge"]);
378
if (curAnim && curAnim->info () == AnimEffectDodge &&
379
// Only process subjects with a dodge chain
380
dodgeData && dodgeData->dodgeChainStart &&
381
dodgeData->isDodgeSubject)
383
// Go through each dodger, checking if this is that one
385
DodgePersistentData *dodgeDataDodger;
386
for (CompWindow *dw = dodgeData->dodgeChainStart; dw;
387
dw = dodgeDataDodger->dodgeChainNext)
389
AnimWindow *adw = AnimWindow::get (dw);
390
dodgeDataDodger = static_cast<DodgePersistentData *>
391
(adw->persistentData["dodge"]);
394
// Remove mWindow from the chain
395
CompWindow *dwNext = dodgeDataDodger->dodgeChainNext;
398
AnimWindow *adwNext = AnimWindow::get (dwNext);
399
DodgePersistentData *dodgeDataDodgerNext =
400
static_cast<DodgePersistentData *>
401
(adwNext->persistentData["dodge"]);
402
dodgeDataDodgerNext->dodgeChainPrev =
403
dodgeDataDodger->dodgeChainPrev;
405
CompWindow *dwPrev = dodgeDataDodger->dodgeChainPrev;
408
AnimWindow *adwPrev = AnimWindow::get (dwPrev);
409
DodgePersistentData *dodgeDataDodgerPrev =
410
static_cast<DodgePersistentData *>
411
(adwPrev->persistentData["dodge"]);
412
dodgeDataDodgerPrev->dodgeChainNext =
413
dodgeDataDodger->dodgeChainNext;
415
if (dodgeData->dodgeChainStart == mWindow)
416
dodgeData->dodgeChainStart =
417
dodgeDataDodger->dodgeChainNext;
418
dodgeDataDodger->dodgeChainPrev = 0;
419
dodgeDataDodger->dodgeChainNext = 0;
426
DodgePersistentData *dodgeData = static_cast<DodgePersistentData *>
427
(mAWindow->persistentData["dodge"]);
429
if (dodgeData && dodgeData->isDodgeSubject)
431
// Update this window's dodgers so that they no longer point
432
// to this window as their subject
433
DodgePersistentData *dodgeDataDodger;
434
for (CompWindow *dw = dodgeData->dodgeChainStart; dw;
435
dw = dodgeDataDodger->dodgeChainNext)
437
AnimWindow *adw = AnimWindow::get (dw);
440
dodgeDataDodger = static_cast<DodgePersistentData *>
441
(adw->persistentData["dodge"]);
443
Animation *curAnim = adw->curAnimation ();
445
if (curAnim && curAnim->info () == AnimEffectDodge)
447
DodgeAnim *animDodger = dynamic_cast<DodgeAnim *> (curAnim);
448
if (animDodger->mDodgeSubjectWin == mWindow)
449
animDodger->mDodgeSubjectWin = NULL;
455
// Reset dodge parameters
456
//if (!(restackData->mMoreToBePaintedPrev ||
457
// restackData->mMoreToBePaintedNext))
459
mDodgeData->isDodgeSubject = false;
460
mDodgeData->skipPostPrepareScreen = false;
462
RestackAnim::cleanUp (closing, destructing);
466
DodgeAnim::getDodgeAmount (CompRect &rect,
470
CompRect dRect (dw->borderRect ().x () +
471
(dw->outputRect ().x () - dw->borderRect ().x ()) / 2,
472
dw->borderRect ().y () +
473
(dw->outputRect ().y () - dw->borderRect ().y ()) / 2,
474
(dw->borderRect ().width () +
475
dw->outputRect ().width ()) / 2,
476
(dw->borderRect ().height () +
477
dw->outputRect ().height ()) / 2);
482
case DodgeDirectionUp:
483
amount = (rect.y () - (dRect.y () + dRect.height ()));
485
case DodgeDirectionDown:
486
amount = (rect.y () + rect.height () - dRect.y ());
488
case DodgeDirectionLeft:
489
amount = (rect.x () - (dRect.x () + dRect.width ()));
491
case DodgeDirectionRight:
492
amount = (rect.x () + rect.width () - dRect.x ());
501
DodgeAnim::processCandidate (CompWindow *candidateWin,
502
CompWindow *subjectWin,
503
CompRegion &candidateAndSubjectIntersection,
504
int &numSelectedCandidates)
506
AnimWindow *aCandidateWin = AnimWindow::get (candidateWin);
507
AnimScreen *as = AnimScreen::get (::screen);
509
if ((!aCandidateWin->curAnimation () ||
510
aCandidateWin->curAnimation ()->info () == AnimEffectDodge) &&
511
candidateWin != subjectWin) // don't let the subject dodge itself
513
// Mark this window for dodge
515
bool nonMatching = false;
516
if (as->getMatchingAnimSelection (candidateWin, AnimEventFocus, 0) !=
520
numSelectedCandidates++;
521
DodgePersistentData *data = static_cast<DodgePersistentData *>
522
(aCandidateWin->persistentData["dodge"]);
523
data->dodgeOrder = numSelectedCandidates;
524
if (nonMatching) // Use neg. values for non-matching windows
525
data->dodgeOrder *= -1;
530
DodgeAnim::postInitiateRestackAnim (int numSelectedCandidates,
536
DodgePersistentData *dataSubject = mDodgeData;
540
dataSubject->isDodgeSubject = true;
541
dataSubject->dodgeChainStart = 0;
543
if (mRestackData && mRestackData->mIsSecondary)
544
return; // We're done here
546
float maxTransformTotalProgress = 0;
547
float dodgeMaxStartProgress =
548
numSelectedCandidates * optValF (AnimationOptions::DodgeGapRatio) *
551
CompWindow *wDodgeChainLastVisited = 0;
553
// dw: Dodger window(s)
554
for (CompWindow *dw = wStart; dw && dw != wEnd->next; dw = dw->next)
556
AnimWindow *adw = AnimWindow::get (dw);
557
DodgePersistentData *dataDodger = static_cast<DodgePersistentData *>
558
(adw->persistentData["dodge"]);
561
if (dataDodger->dodgeOrder == 0)
564
// Initiate dodge for this window
566
bool stationaryDodger = false;
567
if (dataDodger->dodgeOrder < 0)
569
dataDodger->dodgeOrder *= -1; // Make it positive again
570
stationaryDodger = true;
572
if (!adw->curAnimation ())
574
// Create dodge animation for dodger
575
adw->createFocusAnimation (AnimEffectDodge);
576
ExtensionPluginAnimation *extPlugin =
577
static_cast<ExtensionPluginAnimation *>
578
(getExtensionPluginInfo ());
579
extPlugin->incrementCurRestackAnimCount ();
582
DodgeAnim *animDodger =
583
dynamic_cast<DodgeAnim *> (adw->curAnimation ());
585
animDodger->mDodgeSubjectWin = mWindow;
587
if (mDodgeMode == AnimationOptions::DodgeModeFixedClickedWindow)
589
// Slight change in dodge movement start
590
// to reflect stacking order of dodger windows
592
animDodger->mTransformStartProgress =
593
dodgeMaxStartProgress *
594
(dataDodger->dodgeOrder - 1) / numSelectedCandidates;
596
animDodger->mTransformStartProgress =
597
dodgeMaxStartProgress *
598
(1 - (float)dataDodger->dodgeOrder / numSelectedCandidates);
601
float transformTotalProgress =
602
1 + animDodger->mTransformStartProgress;
604
if (maxTransformTotalProgress < transformTotalProgress)
605
maxTransformTotalProgress = transformTotalProgress;
608
animDodger->mTransformStartProgress /= transformTotalProgress;
610
if (stationaryDodger)
612
animDodger->mTransformStartProgress = 0;
613
transformTotalProgress = 0;
616
animDodger->mTotalTime = transformTotalProgress * duration;
617
animDodger->mRemainingTime = animDodger->mTotalTime;
619
// Put window on dodge chain
621
// if dodge chain was started before
622
if (wDodgeChainLastVisited)
624
DodgePersistentData *dataDodgeChainLastVisited =
625
static_cast<DodgePersistentData *>
626
(AnimWindow::get (wDodgeChainLastVisited)->
627
persistentData["dodge"]);
630
dataDodgeChainLastVisited->dodgeChainNext = dw;
633
dataDodgeChainLastVisited->dodgeChainPrev = dw;
635
else if (raised) // mark chain start
637
dataSubject->dodgeChainStart = dw;
641
dataDodger->dodgeChainPrev = wDodgeChainLastVisited;
642
dataDodger->dodgeChainNext = 0;
646
dataDodger->dodgeChainPrev = 0;
647
dataDodger->dodgeChainNext = wDodgeChainLastVisited;
650
wDodgeChainLastVisited = dw;
652
// Reset back to 0 for the next dodge calculation
653
dataDodger->dodgeOrder = 0;
656
// if subject is being lowered,
657
// point chain-start to the topmost doding window
659
dataSubject->dodgeChainStart = wDodgeChainLastVisited;
661
mTotalTime = maxTransformTotalProgress * duration;
662
mRemainingTime = mTotalTime;
666
DodgeAnim::calculateDodgeAmounts ()
668
// holds whether each side of the subject is covered by dodgers or not
669
bool coveredSides[4] = {false, false, false, false};
671
// maximum distance between a dodger window and the subject in X and Y axes
673
int maxDistXActual = 0;
675
int maxDistYActual = 0;
677
CompRect subjectRect (unionRestackChain (mWindow).boundingRect ());
679
// Go through each dodger, calculating its dodge amount.
681
DodgePersistentData *dodgeDataDodger;
682
for (CompWindow *dw = mDodgeData->dodgeChainStart; dw;
683
dw = dodgeDataDodger->dodgeChainNext)
685
AnimWindow *adw = AnimWindow::get (dw);
687
dodgeDataDodger = static_cast<DodgePersistentData *>
688
(adw->persistentData["dodge"]);
690
DodgeAnim *animDodger =
691
dynamic_cast<DodgeAnim *> (adw->curAnimation ());
695
// Find direction (left, right, up, down) that minimizes dodge amount
699
for (int i = 0; i < 4; i++)
701
DodgeAnim::getDodgeAmount (subjectRect, dw, (DodgeDirection)i);
703
int amountMinActual = dodgeAmount[0];
704
int amountMinAbs = abs (amountMinActual);
706
for (int i=1; i<4; i++)
708
int absAmount = abs (dodgeAmount[i]);
709
if (amountMinAbs > absAmount)
711
amountMinAbs = absAmount;
712
amountMinActual = dodgeAmount[i];
716
if (iMin == DodgeDirectionUp ||
717
iMin == DodgeDirectionDown)
719
animDodger->mDodgeMaxAmountX = 0;
720
animDodger->mDodgeMaxAmountY = dodgeAmount[iMin];
721
if (mDodgeMode == AnimationOptions::DodgeModeAllMoving &&
722
maxDistY < amountMinAbs)
724
maxDistY = amountMinAbs;
725
maxDistYActual = amountMinActual;
730
animDodger->mDodgeMaxAmountX = dodgeAmount[iMin];
731
animDodger->mDodgeMaxAmountY = 0;
732
if (mDodgeMode == AnimationOptions::DodgeModeAllMoving && maxDistX < amountMinAbs)
734
maxDistX = amountMinAbs;
735
maxDistXActual = amountMinActual;
738
animDodger->mDodgeDirection = (DodgeDirection)iMin;
740
coveredSides[iMin] = true;
743
if (mDodgeMode == AnimationOptions::DodgeModeFixedClickedWindow)
745
// Subject doesn't move
746
mDodgeMaxAmountX = 0;
747
mDodgeMaxAmountY = 0;
748
mDodgeDirection = DodgeDirectionNone;
752
// Subject should dodge in an axis if only one side is
753
// covered by a dodger.
754
bool subjectDodgesInX = (coveredSides[DodgeDirectionLeft] ^
755
coveredSides[DodgeDirectionRight]);
756
bool subjectDodgesInY = (coveredSides[DodgeDirectionUp] ^
757
coveredSides[DodgeDirectionDown]);
759
float dodgeAmountX = subjectDodgesInX ? -maxDistXActual / 2 : 0;
760
float dodgeAmountY = subjectDodgesInY ? -maxDistYActual / 2 : 0;
761
DodgeDirection dodgeDirection;
763
if (!subjectDodgesInX && !subjectDodgesInY)
764
dodgeDirection = DodgeDirectionNone;
766
dodgeDirection = DodgeDirectionXY;
768
CompWindow *wBottommost =
769
ExtensionPluginAnimation::getBottommostInRestackChain (mWindow);
773
float offsetIncrementX = (dodgeAmountX == 0 ? 0 :
774
100 * dodgeAmountX / fabs (dodgeAmountX));
775
float offsetIncrementY = (dodgeAmountY == 0 ? 0 :
776
100 * dodgeAmountY / fabs (dodgeAmountY));
778
// Set dodge amount and direction for all subjects
779
// in the restack chain
780
RestackPersistentData *dataCur;
781
for (CompWindow *wCur = wBottommost; wCur;
782
wCur = dataCur->mMoreToBePaintedNext,
783
offsetX += offsetIncrementX,
784
offsetY += offsetIncrementY)
786
AnimWindow *awCur = AnimWindow::get (wCur);
788
dataCur = static_cast<RestackPersistentData *>
789
(awCur->persistentData["restack"]);
793
Animation *curAnim = awCur->curAnimation ();
794
if (!curAnim || curAnim->info () != AnimEffectDodge)
796
DodgeAnim *dodgeAnim = dynamic_cast<DodgeAnim *> (curAnim);
798
dodgeAnim->mDodgeMaxAmountX = dodgeAmountX + offsetX;
799
dodgeAnim->mDodgeMaxAmountY = dodgeAmountY + offsetY;
800
dodgeAnim->mDodgeDirection = dodgeDirection;
802
dodgeAnim->mTransformStartProgress = 0;
805
if (dodgeDirection == DodgeDirectionXY)
807
// Go through each dodger, adjusting its dodge amount if the
808
// subject(s) is dodging in that axis (X or Y).
810
DodgePersistentData *dodgeDataDodger;
811
for (CompWindow *dw = mDodgeData->dodgeChainStart; dw;
812
dw = dodgeDataDodger->dodgeChainNext)
814
AnimWindow *adw = AnimWindow::get (dw);
816
dodgeDataDodger = static_cast<DodgePersistentData *>
817
(adw->persistentData["dodge"]);
819
DodgeAnim *animDodger =
820
dynamic_cast<DodgeAnim *> (adw->curAnimation ());
824
// if both dodge in X axis
825
if (subjectDodgesInX && animDodger->mDodgeMaxAmountX != 0)
827
if (animDodger->mDodgeMaxAmountX *
828
(animDodger->mDodgeMaxAmountX + dodgeAmountX) < 0)
830
// If the sign is going to change, just reset instead
831
animDodger->mDodgeMaxAmountX = 0;
834
animDodger->mDodgeMaxAmountX += dodgeAmountX;
837
// if both dodge in Y axis
838
if (subjectDodgesInY && animDodger->mDodgeMaxAmountY != 0)
840
if (animDodger->mDodgeMaxAmountY *
841
(animDodger->mDodgeMaxAmountY + dodgeAmountY) < 0)
843
// If the sign is going to change, just reset instead
844
animDodger->mDodgeMaxAmountY = 0;
847
animDodger->mDodgeMaxAmountY += dodgeAmountY;
855
DodgeAnim::paintedElsewhere ()
859
mRestackData->mWinThisIsPaintedBefore && // has to be currently hosted
861
mDodgeData->isDodgeSubject &&
867
DodgePersistentData::DodgePersistentData () :
869
isDodgeSubject (false),
870
skipPostPrepareScreen (false),