Changeset View
Changeset View
Standalone View
Standalone View
effects/magiclamp/magiclamp.cpp
Show All 18 Lines | |||||
19 | *********************************************************************/ | 19 | *********************************************************************/ | ||
20 | 20 | | |||
21 | // based on minimize animation by Rivo Laks <rivolaks@hot.ee> | 21 | // based on minimize animation by Rivo Laks <rivolaks@hot.ee> | ||
22 | 22 | | |||
23 | #include "magiclamp.h" | 23 | #include "magiclamp.h" | ||
24 | // KConfigSkeleton | 24 | // KConfigSkeleton | ||
25 | #include "magiclampconfig.h" | 25 | #include "magiclampconfig.h" | ||
26 | 26 | | |||
27 | #include <kwinconfig.h> | | |||
28 | #include <kconfiggroup.h> | | |||
29 | #include <QTimeLine> | | |||
30 | #include <QtDebug> | | |||
31 | | ||||
32 | namespace KWin | 27 | namespace KWin | ||
33 | { | 28 | { | ||
34 | 29 | | |||
35 | MagicLampEffect::MagicLampEffect() | 30 | MagicLampEffect::MagicLampEffect() | ||
36 | { | 31 | { | ||
37 | initConfig<MagicLampConfig>(); | 32 | initConfig<MagicLampConfig>(); | ||
38 | mActiveAnimations = 0; | | |||
39 | reconfigure(ReconfigureAll); | 33 | reconfigure(ReconfigureAll); | ||
40 | connect(effects, SIGNAL(windowDeleted(KWin::EffectWindow*)), this, SLOT(slotWindowDeleted(KWin::EffectWindow*))); | 34 | connect(effects, SIGNAL(windowDeleted(KWin::EffectWindow*)), this, SLOT(slotWindowDeleted(KWin::EffectWindow*))); | ||
41 | connect(effects, SIGNAL(windowMinimized(KWin::EffectWindow*)), this, SLOT(slotWindowMinimized(KWin::EffectWindow*))); | 35 | connect(effects, SIGNAL(windowMinimized(KWin::EffectWindow*)), this, SLOT(slotWindowMinimized(KWin::EffectWindow*))); | ||
42 | connect(effects, SIGNAL(windowUnminimized(KWin::EffectWindow*)), this, SLOT(slotWindowUnminimized(KWin::EffectWindow*))); | 36 | connect(effects, SIGNAL(windowUnminimized(KWin::EffectWindow*)), this, SLOT(slotWindowUnminimized(KWin::EffectWindow*))); | ||
43 | } | 37 | } | ||
44 | 38 | | |||
45 | bool MagicLampEffect::supported() | 39 | bool MagicLampEffect::supported() | ||
46 | { | 40 | { | ||
47 | return effects->isOpenGLCompositing() && effects->animationsSupported(); | 41 | return effects->isOpenGLCompositing() && effects->animationsSupported(); | ||
48 | } | 42 | } | ||
49 | 43 | | |||
50 | void MagicLampEffect::reconfigure(ReconfigureFlags) | 44 | void MagicLampEffect::reconfigure(ReconfigureFlags) | ||
51 | { | 45 | { | ||
52 | MagicLampConfig::self()->read(); | 46 | MagicLampConfig::self()->read(); | ||
53 | // TODO: rename animationDuration to duration | 47 | | ||
54 | mAnimationDuration = animationTime(MagicLampConfig::animationDuration() != 0 ? MagicLampConfig::animationDuration() : 250); | 48 | // TODO: Rename animationDuration to duration so we can use | ||
49 | // animationTime<MagicLampConfig>(250). | ||||
50 | const int d = MagicLampConfig::animationDuration() != 0 | ||||
51 | ? MagicLampConfig::animationDuration() | ||||
52 | : 250; | ||||
53 | m_duration = std::chrono::milliseconds(static_cast<int>(animationTime(d))); | ||||
55 | } | 54 | } | ||
56 | 55 | | |||
57 | void MagicLampEffect::prePaintScreen(ScreenPrePaintData& data, int time) | 56 | void MagicLampEffect::prePaintScreen(ScreenPrePaintData& data, int time) | ||
58 | { | 57 | { | ||
58 | const std::chrono::milliseconds delta(time); | ||||
59 | 59 | | |||
60 | QHash< EffectWindow*, QTimeLine* >::iterator entry = mTimeLineWindows.begin(); | 60 | auto animationIt = m_animations.begin(); | ||
61 | bool erase = false; | 61 | while (animationIt != m_animations.end()) { | ||
62 | while (entry != mTimeLineWindows.end()) { | 62 | (*animationIt).update(delta); | ||
63 | QTimeLine *timeline = entry.value(); | 63 | ++animationIt; | ||
64 | if (entry.key()->isMinimized()) { | | |||
65 | timeline->setCurrentTime(timeline->currentTime() + time); | | |||
66 | erase = (timeline->currentValue() >= 1.0f); | | |||
67 | } else { | | |||
68 | timeline->setCurrentTime(timeline->currentTime() - time); | | |||
69 | erase = (timeline->currentValue() <= 0.0f); | | |||
70 | } | | |||
71 | if (erase) { | | |||
72 | delete timeline; | | |||
73 | entry = mTimeLineWindows.erase(entry); | | |||
74 | } else | | |||
75 | ++entry; | | |||
76 | } | 64 | } | ||
77 | 65 | | |||
78 | mActiveAnimations = mTimeLineWindows.count(); | | |||
79 | if (mActiveAnimations > 0) | | |||
80 | // We need to mark the screen windows as transformed. Otherwise the | 66 | // We need to mark the screen windows as transformed. Otherwise the | ||
81 | // whole screen won't be repainted, resulting in artefacts | 67 | // whole screen won't be repainted, resulting in artefacts. | ||
82 | data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; | 68 | data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; | ||
83 | 69 | | |||
84 | effects->prePaintScreen(data, time); | 70 | effects->prePaintScreen(data, time); | ||
85 | } | 71 | } | ||
86 | 72 | | |||
87 | void MagicLampEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) | 73 | void MagicLampEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time) | ||
88 | { | 74 | { | ||
89 | // Schedule window for transformation if the animation is still in | 75 | // Schedule window for transformation if the animation is still in | ||
90 | // progress | 76 | // progress | ||
91 | if (mTimeLineWindows.contains(w)) { | 77 | if (m_animations.contains(w)) { | ||
92 | // We'll transform this window | 78 | // We'll transform this window | ||
93 | data.setTransformed(); | 79 | data.setTransformed(); | ||
94 | data.quads = data.quads.makeGrid(40); | 80 | data.quads = data.quads.makeGrid(40); | ||
95 | w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE); | 81 | w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE); | ||
96 | } | 82 | } | ||
97 | 83 | | |||
98 | effects->prePaintWindow(w, data, time); | 84 | effects->prePaintWindow(w, data, time); | ||
99 | } | 85 | } | ||
100 | 86 | | |||
101 | void MagicLampEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) | 87 | void MagicLampEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data) | ||
102 | { | 88 | { | ||
103 | if (mTimeLineWindows.contains(w)) { | 89 | auto animationIt = m_animations.constFind(w); | ||
90 | if (animationIt != m_animations.constEnd()) { | ||||
104 | // 0 = not minimized, 1 = fully minimized | 91 | // 0 = not minimized, 1 = fully minimized | ||
105 | float progress = mTimeLineWindows[w]->currentValue(); | 92 | const qreal progress = (*animationIt).value(); | ||
106 | 93 | | |||
107 | QRect geo = w->geometry(); | 94 | QRect geo = w->geometry(); | ||
108 | QRect icon = w->iconGeometry(); | 95 | QRect icon = w->iconGeometry(); | ||
109 | IconPosition position = Top; | 96 | IconPosition position = Top; | ||
110 | // If there's no icon geometry, minimize to the center of the screen | 97 | // If there's no icon geometry, minimize to the center of the screen | ||
111 | if (!icon.isValid()) { | 98 | if (!icon.isValid()) { | ||
112 | QRect extG = geo; | 99 | QRect extG = geo; | ||
113 | QPoint pt = cursorPos(); | 100 | QPoint pt = cursorPos(); | ||
▲ Show 20 Lines • Show All 203 Lines • ▼ Show 20 Line(s) | 190 | #define SET_QUADS(_SET_A_, _A_, _DA_, _SET_B_, _B_, _O0_, _O1_, _O2_, _O3_) quad[0]._SET_A_((icon._A_() + icon._DA_()*(quad[0]._A_() / geo._DA_()) - (quad[0]._A_() + geo._A_()))*p_progress[_O0_] + quad[0]._A_());\ | |||
317 | } | 304 | } | ||
318 | 305 | | |||
319 | // Call the next effect. | 306 | // Call the next effect. | ||
320 | effects->paintWindow(w, mask, region, data); | 307 | effects->paintWindow(w, mask, region, data); | ||
321 | } | 308 | } | ||
322 | 309 | | |||
323 | void MagicLampEffect::postPaintScreen() | 310 | void MagicLampEffect::postPaintScreen() | ||
324 | { | 311 | { | ||
325 | if (mActiveAnimations > 0) | 312 | auto animationIt = m_animations.begin(); | ||
326 | // Repaint the workspace so that everything would be repainted next time | 313 | while (animationIt != m_animations.end()) { | ||
314 | if ((*animationIt).done()) { | ||||
315 | animationIt = m_animations.erase(animationIt); | ||||
316 | } else { | ||||
317 | ++animationIt; | ||||
318 | } | ||||
319 | } | ||||
320 | | ||||
327 | effects->addRepaintFull(); | 321 | effects->addRepaintFull(); | ||
328 | mActiveAnimations = mTimeLineWindows.count(); | | |||
329 | 322 | | |||
330 | // Call the next effect. | 323 | // Call the next effect. | ||
331 | effects->postPaintScreen(); | 324 | effects->postPaintScreen(); | ||
332 | } | 325 | } | ||
333 | 326 | | |||
334 | void MagicLampEffect::slotWindowDeleted(EffectWindow* w) | 327 | void MagicLampEffect::slotWindowDeleted(EffectWindow* w) | ||
335 | { | 328 | { | ||
336 | delete mTimeLineWindows.take(w); | 329 | m_animations.remove(w); | ||
337 | } | 330 | } | ||
338 | 331 | | |||
339 | void MagicLampEffect::slotWindowMinimized(EffectWindow* w) | 332 | void MagicLampEffect::slotWindowMinimized(EffectWindow* w) | ||
340 | { | 333 | { | ||
341 | if (effects->activeFullScreenEffect()) | 334 | if (effects->activeFullScreenEffect()) | ||
342 | return; | 335 | return; | ||
343 | if (!mTimeLineWindows.contains(w)) { | 336 | | ||
344 | mTimeLineWindows.insert(w, new QTimeLine(mAnimationDuration, this)); | 337 | TimeLine &timeLine = m_animations[w]; | ||
345 | mTimeLineWindows[w]->setCurrentTime(0); | 338 | | ||
346 | mTimeLineWindows[w]->setCurveShape(QTimeLine::LinearCurve); | 339 | if (timeLine.running()) { | ||
340 | timeLine.toggleDirection(); | ||||
341 | } else { | ||||
342 | timeLine.setDirection(TimeLine::Forward); | ||||
343 | timeLine.setDuration(m_duration); | ||||
344 | timeLine.setEasingCurve(QEasingCurve::Linear); | ||||
347 | } | 345 | } | ||
346 | | ||||
347 | effects->addRepaintFull(); | ||||
348 | } | 348 | } | ||
349 | 349 | | |||
350 | void MagicLampEffect::slotWindowUnminimized(EffectWindow* w) | 350 | void MagicLampEffect::slotWindowUnminimized(EffectWindow* w) | ||
351 | { | 351 | { | ||
352 | if (effects->activeFullScreenEffect()) | 352 | if (effects->activeFullScreenEffect()) | ||
353 | return; | 353 | return; | ||
354 | if (!mTimeLineWindows.contains(w)) { | 354 | | ||
355 | mTimeLineWindows.insert(w, new QTimeLine(mAnimationDuration, this)); | 355 | TimeLine &timeLine = m_animations[w]; | ||
356 | mTimeLineWindows[w]->setCurrentTime(mAnimationDuration); | 356 | | ||
357 | mTimeLineWindows[w]->setCurveShape(QTimeLine::LinearCurve); | 357 | if (timeLine.running()) { | ||
358 | timeLine.toggleDirection(); | ||||
359 | } else { | ||||
360 | timeLine.setDirection(TimeLine::Backward); | ||||
361 | timeLine.setDuration(m_duration); | ||||
362 | timeLine.setEasingCurve(QEasingCurve::Linear); | ||||
358 | } | 363 | } | ||
364 | | ||||
365 | effects->addRepaintFull(); | ||||
359 | } | 366 | } | ||
360 | 367 | | |||
361 | bool MagicLampEffect::isActive() const | 368 | bool MagicLampEffect::isActive() const | ||
362 | { | 369 | { | ||
363 | return !mTimeLineWindows.isEmpty(); | 370 | return !m_animations.isEmpty(); | ||
364 | } | 371 | } | ||
365 | 372 | | |||
366 | } // namespace | 373 | } // namespace |