Libplasma

dialogshadows.cpp
1/*
2 SPDX-FileCopyrightText: 2011 Aaron Seigo <aseigo@kde.org>
3 SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "debug_p.h"
9#include "dialogshadows_p.h"
10
11#include <KWindowShadow>
12
13class DialogShadows::Private
14{
15public:
16 Private(DialogShadows *shadows)
17 : q(shadows)
18 {
19 }
20
21 ~Private()
22 {
23 }
24
25 void clearTiles();
26 void setupTiles();
27 void initTile(const QString &element);
28 void updateShadow(QWindow *window, KSvg::FrameSvg::EnabledBorders);
29 void clearShadow(QWindow *window);
30 void updateShadows();
31 void windowDestroyed(QObject *deletedObject);
32
33 DialogShadows *q;
34
38};
39
41Q_GLOBAL_STATIC(DialogShadowHash, s_privateDialogShadowsInstances)
42
43DialogShadows *DialogShadows::instance(const QString &prefix)
44{
45 DialogShadows *&shadow = (*s_privateDialogShadowsInstances)[prefix];
46 if (!shadow) {
47 shadow = new DialogShadows(qApp, prefix);
48 }
49 return shadow;
50}
51
52DialogShadows::DialogShadows(QObject *parent, const QString &prefix)
53 : KSvg::Svg(parent)
54 , d(new Private(this))
55{
56 setImagePath(prefix);
57 connect(this, SIGNAL(repaintNeeded()), this, SLOT(updateShadows()));
58}
59
60DialogShadows::~DialogShadows()
61{
62 delete d;
63}
64
65void DialogShadows::addWindow(QWindow *window, KSvg::FrameSvg::EnabledBorders enabledBorders)
66{
67 if (!window) {
68 return;
69 }
70
71 d->m_windows[window] = enabledBorders;
72 d->updateShadow(window, enabledBorders);
73 connect(window, SIGNAL(destroyed(QObject *)), this, SLOT(windowDestroyed(QObject *)), Qt::UniqueConnection);
74}
75
76void DialogShadows::removeWindow(QWindow *window)
77{
78 if (!d->m_windows.contains(window)) {
79 return;
80 }
81
82 d->m_windows.remove(window);
83 disconnect(window, nullptr, this, nullptr);
84 d->clearShadow(window);
85
86 if (d->m_windows.isEmpty()) {
87 d->clearTiles();
88 }
89}
90
91void DialogShadows::setEnabledBorders(QWindow *window, KSvg::FrameSvg::EnabledBorders enabledBorders)
92{
93 Q_ASSERT(d->m_windows.contains(window));
94 if (!window || !d->m_windows.contains(window)) {
95 return;
96 }
97
98 d->updateShadow(window, enabledBorders);
99}
100
101void DialogShadows::Private::windowDestroyed(QObject *deletedObject)
102{
103 QWindow *window = static_cast<QWindow *>(deletedObject);
104
105 m_windows.remove(window);
106 clearShadow(window);
107
108 if (m_windows.isEmpty()) {
109 clearTiles();
110 }
111}
112
113void DialogShadows::Private::updateShadows()
114{
115 setupTiles();
117 for (i = m_windows.constBegin(); i != m_windows.constEnd(); ++i) {
118 updateShadow(i.key(), i.value());
119 }
120}
121
122void DialogShadows::Private::initTile(const QString &element)
123{
124 const QImage image = q->pixmap(element).toImage();
125
126 KWindowShadowTile::Ptr tile = KWindowShadowTile::Ptr::create();
127 tile->setImage(image);
128
129 m_tiles << tile;
130}
131
132void DialogShadows::Private::setupTiles()
133{
134 clearTiles();
135
136 initTile(QStringLiteral("shadow-top"));
137 initTile(QStringLiteral("shadow-topright"));
138 initTile(QStringLiteral("shadow-right"));
139 initTile(QStringLiteral("shadow-bottomright"));
140 initTile(QStringLiteral("shadow-bottom"));
141 initTile(QStringLiteral("shadow-bottomleft"));
142 initTile(QStringLiteral("shadow-left"));
143 initTile(QStringLiteral("shadow-topleft"));
144}
145
146void DialogShadows::Private::clearTiles()
147{
148 m_tiles.clear();
149}
150
151void DialogShadows::Private::updateShadow(QWindow *window, KSvg::FrameSvg::EnabledBorders enabledBorders)
152{
153 if (m_tiles.isEmpty()) {
154 setupTiles();
155 }
156
157 KWindowShadow *&shadow = m_shadows[window];
158
159 if (!shadow) {
160 shadow = new KWindowShadow(q);
161 }
162
163 if (shadow->isCreated()) {
164 shadow->destroy();
165 }
166
167 if (enabledBorders & KSvg::FrameSvg::TopBorder) {
168 shadow->setTopTile(m_tiles.at(0));
169 } else {
170 shadow->setTopTile(nullptr);
171 }
172
173 if (enabledBorders & KSvg::FrameSvg::TopBorder && enabledBorders & KSvg::FrameSvg::RightBorder) {
174 shadow->setTopRightTile(m_tiles.at(1));
175 } else {
176 shadow->setTopRightTile(nullptr);
177 }
178
179 if (enabledBorders & KSvg::FrameSvg::RightBorder) {
180 shadow->setRightTile(m_tiles.at(2));
181 } else {
182 shadow->setRightTile(nullptr);
183 }
184
185 if (enabledBorders & KSvg::FrameSvg::BottomBorder && enabledBorders & KSvg::FrameSvg::RightBorder) {
186 shadow->setBottomRightTile(m_tiles.at(3));
187 } else {
188 shadow->setBottomRightTile(nullptr);
189 }
190
191 if (enabledBorders & KSvg::FrameSvg::BottomBorder) {
192 shadow->setBottomTile(m_tiles.at(4));
193 } else {
194 shadow->setBottomTile(nullptr);
195 }
196
197 if (enabledBorders & KSvg::FrameSvg::BottomBorder && enabledBorders & KSvg::FrameSvg::LeftBorder) {
198 shadow->setBottomLeftTile(m_tiles.at(5));
199 } else {
200 shadow->setBottomLeftTile(nullptr);
201 }
202
203 if (enabledBorders & KSvg::FrameSvg::LeftBorder) {
204 shadow->setLeftTile(m_tiles.at(6));
205 } else {
206 shadow->setLeftTile(nullptr);
207 }
208
209 if (enabledBorders & KSvg::FrameSvg::TopBorder && enabledBorders & KSvg::FrameSvg::LeftBorder) {
210 shadow->setTopLeftTile(m_tiles.at(7));
211 } else {
212 shadow->setTopLeftTile(nullptr);
213 }
214
215 QMargins padding;
216
217 if (enabledBorders & KSvg::FrameSvg::TopBorder) {
218 const QSize marginHint = q->elementSize(QStringLiteral("shadow-hint-top-margin")).toSize();
219 if (marginHint.isValid()) {
220 padding.setTop(marginHint.height());
221 } else {
222 padding.setTop(m_tiles[0]->image().height());
223 }
224 }
225
226 if (enabledBorders & KSvg::FrameSvg::RightBorder) {
227 const QSize marginHint = q->elementSize(QStringLiteral("shadow-hint-right-margin")).toSize();
228 if (marginHint.isValid()) {
229 padding.setRight(marginHint.width());
230 } else {
231 padding.setRight(m_tiles[2]->image().width());
232 }
233 }
234
235 if (enabledBorders & KSvg::FrameSvg::BottomBorder) {
236 const QSize marginHint = q->elementSize(QStringLiteral("shadow-hint-bottom-margin")).toSize();
237 if (marginHint.isValid()) {
238 padding.setBottom(marginHint.height());
239 } else {
240 padding.setBottom(m_tiles[4]->image().height());
241 }
242 }
243
244 if (enabledBorders & KSvg::FrameSvg::LeftBorder) {
245 const QSize marginHint = q->elementSize(QStringLiteral("shadow-hint-left-margin")).toSize();
246 if (marginHint.isValid()) {
247 padding.setLeft(marginHint.width());
248 } else {
249 padding.setLeft(m_tiles[6]->image().width());
250 }
251 }
252
253 shadow->setPadding(padding);
254 shadow->setWindow(window);
255
256 if (!shadow->create()) {
257 qCWarning(LOG_PLASMAQUICK) << "Couldn't create KWindowShadow for" << window;
258 }
259}
260
261void DialogShadows::Private::clearShadow(QWindow *window)
262{
263 delete m_shadows.take(window);
264}
265
266bool DialogShadows::enabled() const
267{
268 return hasElement(QStringLiteral("shadow-left"));
269}
270
271#include "moc_dialogshadows_p.cpp"
void setBottomLeftTile(KWindowShadowTile::Ptr tile)
void setWindow(QWindow *window)
bool isCreated() const
void setRightTile(KWindowShadowTile::Ptr tile)
void setTopRightTile(KWindowShadowTile::Ptr tile)
void setBottomTile(KWindowShadowTile::Ptr tile)
void setBottomRightTile(KWindowShadowTile::Ptr tile)
void setTopLeftTile(KWindowShadowTile::Ptr tile)
void setTopTile(KWindowShadowTile::Ptr tile)
void setLeftTile(KWindowShadowTile::Ptr tile)
void setPadding(const QMargins &padding)
QWidget * window(QObject *job)
const Key & key() const const
const T & value() const const
bool isEmpty() const const
bool remove(const Key &key)
void setBottom(int bottom)
void setLeft(int left)
void setRight(int right)
void setTop(int Top)
int height() const const
bool isValid() const const
int width() const const
UniqueConnection
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 22 2024 12:06:24 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.