1 | /******************************************************************** |
2 | KWin - the KDE window manager |
3 | This file is part of the KDE project. |
4 | |
5 | Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org> |
6 | |
7 | This program is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 2 of the License, or |
10 | (at your option) any later version. |
11 | |
12 | This program is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | GNU General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU General Public License |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | *********************************************************************/ |
20 | |
21 | #include "thumbnailitem.h" |
22 | // KWin |
23 | #include "client.h" |
24 | #include "composite.h" |
25 | #include "effects.h" |
26 | #include "workspace.h" |
27 | #include "composite.h" |
28 | // Qt |
29 | #include <QtDeclarative/QDeclarativeContext> |
30 | #include <QtDeclarative/QDeclarativeEngine> |
31 | #include <QtDeclarative/QDeclarativeView> |
32 | // KDE |
33 | #include <KDE/KDebug> |
34 | |
35 | namespace KWin |
36 | { |
37 | |
38 | AbstractThumbnailItem::AbstractThumbnailItem(QDeclarativeItem *parent) |
39 | : QDeclarativeItem(parent) |
40 | , m_clip(true) |
41 | , m_parent(QWeakPointer<EffectWindowImpl>()) |
42 | , m_parentWindow(0) |
43 | , m_brightness(1.0) |
44 | , m_saturation(1.0) |
45 | { |
46 | setFlags(flags() & ~QGraphicsItem::ItemHasNoContents); |
47 | Q_ASSERT(Compositor::isCreated()); |
48 | connect(Compositor::self(), SIGNAL(compositingToggled(bool)), SLOT(compositingToggled())); |
49 | compositingToggled(); |
50 | QTimer::singleShot(0, this, SLOT(init())); |
51 | } |
52 | |
53 | AbstractThumbnailItem::~AbstractThumbnailItem() |
54 | { |
55 | } |
56 | |
57 | void AbstractThumbnailItem::compositingToggled() |
58 | { |
59 | m_parent.clear(); |
60 | if (effects) { |
61 | connect(effects, SIGNAL(windowAdded(KWin::EffectWindow*)), SLOT(effectWindowAdded())); |
62 | connect(effects, SIGNAL(windowDamaged(KWin::EffectWindow*,QRect)), SLOT(repaint(KWin::EffectWindow*))); |
63 | effectWindowAdded(); |
64 | } |
65 | } |
66 | |
67 | void AbstractThumbnailItem::init() |
68 | { |
69 | findParentEffectWindow(); |
70 | if (!m_parent.isNull()) { |
71 | m_parent.data()->registerThumbnail(this); |
72 | } |
73 | } |
74 | |
75 | void AbstractThumbnailItem::setParentWindow(qulonglong parentWindow) |
76 | { |
77 | m_parentWindow = parentWindow; |
78 | findParentEffectWindow(); |
79 | if (!m_parent.isNull()) { |
80 | m_parent.data()->registerThumbnail(this); |
81 | } |
82 | } |
83 | |
84 | void AbstractThumbnailItem::findParentEffectWindow() |
85 | { |
86 | if (effects) { |
87 | if (m_parentWindow) { |
88 | if (EffectWindowImpl *w = static_cast<EffectWindowImpl*>(effects->findWindow(m_parentWindow))) { |
89 | m_parent = QWeakPointer<EffectWindowImpl>(w); |
90 | return; |
91 | } |
92 | } |
93 | QDeclarativeContext *ctx = QDeclarativeEngine::contextForObject(this); |
94 | if (!ctx) { |
95 | kDebug(1212) << "No Context" ; |
96 | return; |
97 | } |
98 | const QVariant variant = ctx->engine()->rootContext()->contextProperty("viewId" ); |
99 | if (!variant.isValid()) { |
100 | kDebug(1212) << "Required context property 'viewId' not found" ; |
101 | return; |
102 | } |
103 | if (EffectWindowImpl *w = static_cast<EffectWindowImpl*>(effects->findWindow(variant.value<qulonglong>()))) { |
104 | m_parent = QWeakPointer<EffectWindowImpl>(w); |
105 | m_parentWindow = variant.value<qulonglong>(); |
106 | } |
107 | } |
108 | } |
109 | |
110 | void AbstractThumbnailItem::setClip(bool clip) |
111 | { |
112 | m_clip = clip; |
113 | emit clipChanged(clip); |
114 | } |
115 | |
116 | void AbstractThumbnailItem::effectWindowAdded() |
117 | { |
118 | // the window might be added before the EffectWindow is created |
119 | // by using this slot we can register the thumbnail when it is finally created |
120 | if (m_parent.isNull()) { |
121 | findParentEffectWindow(); |
122 | if (!m_parent.isNull()) { |
123 | m_parent.data()->registerThumbnail(this); |
124 | } |
125 | } |
126 | } |
127 | |
128 | void AbstractThumbnailItem::setBrightness(qreal brightness) |
129 | { |
130 | if (qFuzzyCompare(brightness, m_brightness)) { |
131 | return; |
132 | } |
133 | m_brightness = brightness; |
134 | update(); |
135 | emit brightnessChanged(); |
136 | } |
137 | |
138 | void AbstractThumbnailItem::setSaturation(qreal saturation) |
139 | { |
140 | if (qFuzzyCompare(saturation, m_saturation)) { |
141 | return; |
142 | } |
143 | m_saturation = saturation; |
144 | update(); |
145 | emit saturationChanged(); |
146 | } |
147 | |
148 | |
149 | WindowThumbnailItem::WindowThumbnailItem(QDeclarativeItem* parent) |
150 | : AbstractThumbnailItem(parent) |
151 | , m_wId(0) |
152 | , m_client(NULL) |
153 | { |
154 | } |
155 | |
156 | WindowThumbnailItem::~WindowThumbnailItem() |
157 | { |
158 | } |
159 | |
160 | void WindowThumbnailItem::setWId(qulonglong wId) |
161 | { |
162 | if (m_wId == wId) { |
163 | return; |
164 | } |
165 | m_wId = wId; |
166 | if (m_wId != 0) { |
167 | setClient(Workspace::self()->findClient(WindowMatchPredicate(m_wId))); |
168 | } else if (m_client) { |
169 | m_client = NULL; |
170 | emit clientChanged(); |
171 | } |
172 | emit wIdChanged(wId); |
173 | } |
174 | |
175 | void WindowThumbnailItem::setClient(Client *client) |
176 | { |
177 | if (m_client == client) { |
178 | return; |
179 | } |
180 | m_client = client; |
181 | if (m_client) { |
182 | setWId(m_client->window()); |
183 | } else { |
184 | setWId(0); |
185 | } |
186 | emit clientChanged(); |
187 | } |
188 | |
189 | void WindowThumbnailItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
190 | { |
191 | if (effects) { |
192 | QDeclarativeItem::paint(painter, option, widget); |
193 | return; |
194 | } |
195 | Client *client = Workspace::self()->findClient(WindowMatchPredicate(m_wId)); |
196 | if (!client) { |
197 | QDeclarativeItem::paint(painter, option, widget); |
198 | return; |
199 | } |
200 | QPixmap pixmap = client->icon(boundingRect().size().toSize()); |
201 | const QSize size(boundingRect().size().toSize() - pixmap.size()); |
202 | painter->drawPixmap(boundingRect().adjusted(size.width()/2.0, size.height()/2.0, -size.width()/2.0, -size.height()/2.0).toRect(), |
203 | pixmap); |
204 | } |
205 | |
206 | void WindowThumbnailItem::repaint(KWin::EffectWindow *w) |
207 | { |
208 | if (static_cast<KWin::EffectWindowImpl*>(w)->window()->window() == m_wId) { |
209 | update(); |
210 | } |
211 | } |
212 | |
213 | DesktopThumbnailItem::DesktopThumbnailItem(QDeclarativeItem *parent) |
214 | : AbstractThumbnailItem(parent) |
215 | , m_desktop(0) |
216 | { |
217 | } |
218 | |
219 | DesktopThumbnailItem::~DesktopThumbnailItem() |
220 | { |
221 | } |
222 | |
223 | void DesktopThumbnailItem::setDesktop(int desktop) |
224 | { |
225 | desktop = qBound<int>(1, desktop, VirtualDesktopManager::self()->count()); |
226 | if (desktop == m_desktop) { |
227 | return; |
228 | } |
229 | m_desktop = desktop; |
230 | update(); |
231 | emit desktopChanged(m_desktop); |
232 | } |
233 | |
234 | void DesktopThumbnailItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
235 | { |
236 | if (effects) { |
237 | QDeclarativeItem::paint(painter, option, widget); |
238 | return; |
239 | } |
240 | // TODO: render icon |
241 | } |
242 | |
243 | void DesktopThumbnailItem::repaint(EffectWindow *w) |
244 | { |
245 | if (w->isOnDesktop(m_desktop)) { |
246 | update(); |
247 | } |
248 | } |
249 | |
250 | } // namespace KWin |
251 | |