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

« back to all changes in this revision

Viewing changes to kwin/effects/sheet/sheet.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
 
 
8
This program is free software; you can redistribute it and/or modify
 
9
it under the terms of the GNU General Public License as published by
 
10
the Free Software Foundation; either version 2 of the License, or
 
11
(at your option) any later version.
 
12
 
 
13
This program is distributed in the hope that it will be useful,
 
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
GNU General Public License for more details.
 
17
 
 
18
You should have received a copy of the GNU General Public License
 
19
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
*********************************************************************/
 
21
 
 
22
#include "sheet.h"
 
23
 
 
24
#include <kconfiggroup.h>
 
25
#include <QtCore/QTimeLine>
 
26
 
 
27
// Effect is based on fade effect by Philip Falkner
 
28
 
 
29
namespace KWin
 
30
{
 
31
 
 
32
KWIN_EFFECT(sheet, SheetEffect)
 
33
KWIN_EFFECT_SUPPORTED(sheet, SheetEffect::supported())
 
34
 
 
35
static const int IsSheetWindow = 0x22A982D5;
 
36
 
 
37
SheetEffect::SheetEffect()
 
38
{
 
39
    reconfigure(ReconfigureAll);
 
40
    connect(effects, SIGNAL(windowAdded(EffectWindow*)), this, SLOT(slotWindowAdded(EffectWindow*)));
 
41
    connect(effects, SIGNAL(windowClosed(EffectWindow*)), this, SLOT(slotWindowClosed(EffectWindow*)));
 
42
    connect(effects, SIGNAL(windowDeleted(EffectWindow*)), this, SLOT(slotWindowDeleted(EffectWindow*)));
 
43
}
 
44
 
 
45
bool SheetEffect::supported()
 
46
{
 
47
    return effects->compositingType() == OpenGLCompositing;
 
48
}
 
49
 
 
50
void SheetEffect::reconfigure(ReconfigureFlags)
 
51
{
 
52
    KConfigGroup conf = effects->effectConfig("Sheet");
 
53
    duration = animationTime(conf, "AnimationTime", 500);
 
54
}
 
55
 
 
56
void SheetEffect::prePaintScreen(ScreenPrePaintData& data, int time)
 
57
{
 
58
    if (!windows.isEmpty()) {
 
59
        data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
 
60
        screenTime = time;
 
61
    }
 
62
    effects->prePaintScreen(data, time);
 
63
}
 
64
 
 
65
void SheetEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
 
66
{
 
67
    InfoMap::iterator info = windows.find(w);
 
68
    if (info != windows.end()) {
 
69
        data.setTransformed();
 
70
        if (info->added)
 
71
            info->timeLine->setCurrentTime(info->timeLine->currentTime() + screenTime);
 
72
        else if (info->closed) {
 
73
            info->timeLine->setCurrentTime(info->timeLine->currentTime() - screenTime);
 
74
            if (info->deleted)
 
75
                w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DELETE);
 
76
        }
 
77
    }
 
78
 
 
79
    effects->prePaintWindow(w, data, time);
 
80
 
 
81
    // if the window isn't to be painted, then let's make sure
 
82
    // to track its progress
 
83
    if (info != windows.end() && !w->isPaintingEnabled() && !effects->activeFullScreenEffect())
 
84
        w->addRepaintFull();
 
85
}
 
86
 
 
87
void SheetEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
 
88
{
 
89
    InfoMap::const_iterator info = windows.constFind(w);
 
90
    if (info != windows.constEnd()) {
 
91
        const double progress = info->timeLine->currentValue();
 
92
        RotationData rot;
 
93
        rot.axis = RotationData::XAxis;
 
94
        rot.angle = 60.0 * (1.0 - progress);
 
95
        data.rotation = &rot;
 
96
        data.yScale *= progress;
 
97
        data.zScale *= progress;
 
98
        data.yTranslate -= (w->y() - info->parentY) * (1.0 - progress);
 
99
    }
 
100
    effects->paintWindow(w, mask, region, data);
 
101
}
 
102
 
 
103
void SheetEffect::postPaintWindow(EffectWindow* w)
 
104
{
 
105
    InfoMap::iterator info = windows.find(w);
 
106
    if (info != windows.end()) {
 
107
        if (info->added && info->timeLine->currentValue() == 1.0) {
 
108
            windows.remove(w);
 
109
            effects->addRepaintFull();
 
110
        } else if (info->closed && info->timeLine->currentValue() == 0.0) {
 
111
            info->closed = false;
 
112
            if (info->deleted) {
 
113
                windows.remove(w);
 
114
                w->unrefWindow();
 
115
            }
 
116
            effects->addRepaintFull();
 
117
        }
 
118
        if (info->added || info->closed)
 
119
            w->addRepaintFull();
 
120
    }
 
121
    effects->postPaintWindow(w);
 
122
}
 
123
 
 
124
void SheetEffect::slotWindowAdded(EffectWindow* w)
 
125
{
 
126
    if (!isSheetWindow(w))
 
127
        return;
 
128
    w->setData(IsSheetWindow, true);
 
129
 
 
130
    InfoMap::iterator it = windows.find(w);
 
131
    WindowInfo *info = (it == windows.end()) ? &windows[w] : &it.value();
 
132
    info->added = true;
 
133
    info->closed = false;
 
134
    info->deleted = false;
 
135
    delete info->timeLine;
 
136
    info->timeLine = new QTimeLine(duration);
 
137
    const EffectWindowList stack = effects->stackingOrder();
 
138
    // find parent
 
139
    foreach (EffectWindow * window, stack) {
 
140
        if (window->findModal() == w) {
 
141
            info->parentY = window->y();
 
142
            break;
 
143
        }
 
144
    }
 
145
    w->addRepaintFull();
 
146
}
 
147
 
 
148
void SheetEffect::slotWindowClosed(EffectWindow* w)
 
149
{
 
150
    if (!isSheetWindow(w))
 
151
        return;
 
152
 
 
153
    w->refWindow();
 
154
 
 
155
    InfoMap::iterator it = windows.find(w);
 
156
    WindowInfo *info = (it == windows.end()) ? &windows[w] : &it.value();
 
157
    info->added = false;
 
158
    info->closed = true;
 
159
    info->deleted = true;
 
160
    delete info->timeLine;
 
161
    info->timeLine = new QTimeLine(duration);
 
162
    info->timeLine->setCurrentTime(duration);
 
163
 
 
164
    bool found = false;
 
165
    // find parent
 
166
    const EffectWindowList stack = effects->stackingOrder();
 
167
    foreach (EffectWindow * window, stack) {
 
168
        if (window->findModal() == w) {
 
169
            info->parentY = window->y();
 
170
            found = true;
 
171
            break;
 
172
        }
 
173
    }
 
174
    if (!found)
 
175
        info->parentY = 0;
 
176
    w->addRepaintFull();
 
177
}
 
178
 
 
179
void SheetEffect::slotWindowDeleted(EffectWindow* w)
 
180
{
 
181
    windows.remove(w);
 
182
}
 
183
 
 
184
bool SheetEffect::isSheetWindow(EffectWindow* w)
 
185
{
 
186
    return (w->isModal() || w->data(IsSheetWindow).toBool());
 
187
}
 
188
 
 
189
SheetEffect::WindowInfo::WindowInfo()
 
190
    : deleted(false)
 
191
    , added(false)
 
192
    , closed(false)
 
193
    , timeLine(0)
 
194
    , parentY(0)
 
195
{
 
196
}
 
197
 
 
198
SheetEffect::WindowInfo::~WindowInfo()
 
199
{
 
200
    delete timeLine;
 
201
}
 
202
 
 
203
} // namespace