~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to kwin/effects/glide/glide.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/********************************************************************
 
2
 KWin - the KDE window manager
 
3
 This file is part of the KDE project.
 
4
 
 
5
Copyright (C) 2007 Philip Falkner <philip.falkner@gmail.com>
 
6
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.com>
 
7
Copyright (C) 2010 Alexandre Pereira <pereira.alex@gmail.com>
 
8
 
 
9
This program is free software; you can redistribute it and/or modify
 
10
it under the terms of the GNU General Public License as published by
 
11
the Free Software Foundation; either version 2 of the License, or
 
12
(at your option) any later version.
 
13
 
 
14
This program is distributed in the hope that it will be useful,
 
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
GNU General Public License for more details.
 
18
 
 
19
You should have received a copy of the GNU General Public License
 
20
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
*********************************************************************/
 
22
 
 
23
#include "glide.h"
 
24
 
 
25
#include <kconfiggroup.h>
 
26
#include <QtCore/QTimeLine>
 
27
 
 
28
// Effect is based on fade effect by Philip Falkner
 
29
 
 
30
namespace KWin
 
31
{
 
32
 
 
33
KWIN_EFFECT(glide, GlideEffect)
 
34
KWIN_EFFECT_SUPPORTED(glide, GlideEffect::supported())
 
35
 
 
36
static const int IsGlideWindow = 0x22A982D4;
 
37
 
 
38
GlideEffect::GlideEffect()
 
39
{
 
40
    reconfigure(ReconfigureAll);
 
41
    connect(effects, SIGNAL(windowAdded(EffectWindow*)), this, SLOT(slotWindowAdded(EffectWindow*)));
 
42
    connect(effects, SIGNAL(windowClosed(EffectWindow*)), this, SLOT(slotWindowClosed(EffectWindow*)));
 
43
    connect(effects, SIGNAL(windowDeleted(EffectWindow*)), this, SLOT(slotWindowDeleted(EffectWindow*)));
 
44
}
 
45
 
 
46
bool GlideEffect::supported()
 
47
{
 
48
    return effects->compositingType() == OpenGLCompositing;
 
49
}
 
50
 
 
51
void GlideEffect::reconfigure(ReconfigureFlags)
 
52
{
 
53
    KConfigGroup conf = effects->effectConfig("Glide");
 
54
    duration = animationTime(conf, "AnimationTime", 350);
 
55
    effect = (EffectStyle) conf.readEntry("GlideEffect", 0);
 
56
    angle = conf.readEntry("GlideAngle", -90);
 
57
}
 
58
 
 
59
void GlideEffect::prePaintScreen(ScreenPrePaintData& data, int time)
 
60
{
 
61
    if (!windows.isEmpty())
 
62
        data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
 
63
    effects->prePaintScreen(data, time);
 
64
}
 
65
 
 
66
void GlideEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
 
67
{
 
68
    InfoHash::iterator info = windows.find(w);
 
69
    if (info != windows.end()) {
 
70
        data.setTransformed();
 
71
        if (info->added)
 
72
            info->timeLine->setCurrentTime(info->timeLine->currentTime() + time);
 
73
        else if (info->closed) {
 
74
            info->timeLine->setCurrentTime(info->timeLine->currentTime() - time);
 
75
            if (info->deleted)
 
76
                w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
 
77
        }
 
78
    }
 
79
 
 
80
    effects->prePaintWindow(w, data, time);
 
81
 
 
82
    // if the window isn't to be painted, then let's make sure
 
83
    // to track its progress
 
84
    if (info != windows.end() && !w->isPaintingEnabled() && !effects->activeFullScreenEffect())
 
85
        w->addRepaintFull();
 
86
}
 
87
 
 
88
void GlideEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
 
89
{
 
90
    InfoHash::const_iterator info = windows.constFind(w);
 
91
    if (info != windows.constEnd()) {
 
92
        const double progress = info->timeLine->currentValue();
 
93
        RotationData rot;
 
94
        rot.axis = RotationData::XAxis;
 
95
        rot.angle = angle * (1 - progress);
 
96
        data.rotation = &rot;
 
97
        data.opacity *= progress;
 
98
        switch(effect) {
 
99
        default:
 
100
        case GlideInOut:
 
101
            if (info->added)
 
102
                glideIn(w, data);
 
103
            else if (info->closed)
 
104
                glideOut(w, data);
 
105
            break;
 
106
        case GlideOutIn:
 
107
            if (info->added)
 
108
                glideOut(w, data);
 
109
            if (info->closed)
 
110
                glideIn(w, data);
 
111
            break;
 
112
        case GlideIn: glideIn(w, data); break;
 
113
        case GlideOut: glideOut(w, data); break;
 
114
        }
 
115
    }
 
116
    effects->paintWindow(w, mask, region, data);
 
117
}
 
118
 
 
119
void GlideEffect::glideIn(EffectWindow* w, WindowPaintData& data)
 
120
{
 
121
    InfoHash::const_iterator info = windows.constFind(w);
 
122
    if (info == windows.constEnd())
 
123
        return;
 
124
    const double progress = info->timeLine->currentValue();
 
125
    data.xScale *= progress;
 
126
    data.yScale *= progress;
 
127
    data.zScale *= progress;
 
128
    data.xTranslate += int(w->width() / 2 * (1 - progress));
 
129
    data.yTranslate += int(w->height() / 2 * (1 - progress));
 
130
}
 
131
 
 
132
void GlideEffect::glideOut(EffectWindow* w, WindowPaintData& data)
 
133
{
 
134
    InfoHash::const_iterator info = windows.constFind(w);
 
135
    if (info == windows.constEnd())
 
136
        return;
 
137
    const double progress = info->timeLine->currentValue();
 
138
    data.xScale *= (2 - progress);
 
139
    data.yScale *= (2 - progress);
 
140
    data.zScale *= (2 - progress);
 
141
    data.xTranslate -= int(w->width() / 2 * (1 - progress));
 
142
    data.yTranslate -= int(w->height() / 2 * (1 - progress));
 
143
}
 
144
 
 
145
void GlideEffect::postPaintWindow(EffectWindow* w)
 
146
{
 
147
    InfoHash::iterator info = windows.find(w);
 
148
    if (info != windows.end()) {
 
149
        if (info->added && info->timeLine->currentValue() == 1.0) {
 
150
            windows.remove(w);
 
151
            effects->addRepaintFull();
 
152
        } else if (info->closed && info->timeLine->currentValue() == 0.0) {
 
153
            info->closed = false;
 
154
            if (info->deleted) {
 
155
                windows.remove(w);
 
156
                w->unrefWindow();
 
157
            }
 
158
            effects->addRepaintFull();
 
159
        }
 
160
        if (info->added || info->closed)
 
161
            w->addRepaintFull();
 
162
    }
 
163
    effects->postPaintWindow(w);
 
164
}
 
165
 
 
166
void GlideEffect::slotWindowAdded(EffectWindow* w)
 
167
{
 
168
    if (!isGlideWindow(w))
 
169
        return;
 
170
    w->setData(IsGlideWindow, true);
 
171
    const void *addGrab = w->data(WindowAddedGrabRole).value<void*>();
 
172
    if (addGrab && addGrab != this)
 
173
        return;
 
174
    w->setData(WindowAddedGrabRole, QVariant::fromValue(static_cast<void*>(this)));
 
175
 
 
176
    InfoHash::iterator it = windows.find(w);
 
177
    WindowInfo *info = (it == windows.end()) ? &windows[w] : &it.value();
 
178
    info->added = true;
 
179
    info->closed = false;
 
180
    info->deleted = false;
 
181
    delete info->timeLine;
 
182
    info->timeLine = new QTimeLine(duration);
 
183
    info->timeLine->setCurveShape(QTimeLine::EaseOutCurve);
 
184
    w->addRepaintFull();
 
185
}
 
186
 
 
187
void GlideEffect::slotWindowClosed(EffectWindow* w)
 
188
{
 
189
    if (!isGlideWindow(w))
 
190
        return;
 
191
    const void *closeGrab = w->data(WindowClosedGrabRole).value<void*>();
 
192
    if (closeGrab && closeGrab != this)
 
193
        return;
 
194
    w->refWindow();
 
195
    w->setData(WindowClosedGrabRole, QVariant::fromValue(static_cast<void*>(this)));
 
196
 
 
197
    InfoHash::iterator it = windows.find(w);
 
198
    WindowInfo *info = (it == windows.end()) ? &windows[w] : &it.value();
 
199
    info->added = false;
 
200
    info->closed = true;
 
201
    info->deleted = true;
 
202
    delete info->timeLine;
 
203
    info->timeLine = new QTimeLine(duration);
 
204
    info->timeLine->setCurveShape(QTimeLine::EaseInCurve);
 
205
    info->timeLine->setCurrentTime(info->timeLine->duration());
 
206
    w->addRepaintFull();
 
207
}
 
208
 
 
209
void GlideEffect::slotWindowDeleted(EffectWindow* w)
 
210
{
 
211
    windows.remove(w);
 
212
}
 
213
 
 
214
bool GlideEffect::isGlideWindow(EffectWindow* w)
 
215
{
 
216
    if (effects->activeFullScreenEffect())
 
217
        return false;
 
218
    if (w->data(IsGlideWindow).toBool())
 
219
        return true;
 
220
    if (w->hasDecoration())
 
221
        return true;
 
222
    if (!w->isManaged() || w->isMenu() ||  w->isNotification() || w->isDesktop() ||
 
223
            w->isDock() ||  w->isSplash() || w->isTopMenu() || w->isToolbar() ||
 
224
            w->windowClass() == "dashboard dashboard")
 
225
        return false;
 
226
    return true;
 
227
}
 
228
 
 
229
GlideEffect::WindowInfo::WindowInfo()
 
230
    : deleted(false)
 
231
    , added(false)
 
232
    , closed(false)
 
233
    , timeLine(0)
 
234
{
 
235
}
 
236
 
 
237
GlideEffect::WindowInfo::~WindowInfo()
 
238
{
 
239
    delete timeLine;
 
240
}
 
241
 
 
242
} // namespace