Changeset View
Changeset View
Standalone View
Standalone View
kcmkwin/kwindecoration/declarative-plugin/previewitem.cpp
Show All 24 Lines | |||||
25 | #include <KDecoration2/DecorationSettings> | 25 | #include <KDecoration2/DecorationSettings> | ||
26 | #include <KDecoration2/DecorationShadow> | 26 | #include <KDecoration2/DecorationShadow> | ||
27 | #include <KDecoration2/DecoratedClient> | 27 | #include <KDecoration2/DecoratedClient> | ||
28 | #include <QCursor> | 28 | #include <QCursor> | ||
29 | #include <QPainter> | 29 | #include <QPainter> | ||
30 | #include <QQmlContext> | 30 | #include <QQmlContext> | ||
31 | #include <QQmlEngine> | 31 | #include <QQmlEngine> | ||
32 | 32 | | |||
33 | #include <cmath> | ||||
34 | | ||||
33 | #include <QDebug> | 35 | #include <QDebug> | ||
34 | 36 | | |||
35 | namespace KDecoration2 | 37 | namespace KDecoration2 | ||
36 | { | 38 | { | ||
37 | namespace Preview | 39 | namespace Preview | ||
38 | { | 40 | { | ||
39 | 41 | | |||
40 | PreviewItem::PreviewItem(QQuickItem *parent) | 42 | PreviewItem::PreviewItem(QQuickItem *parent) | ||
▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Line(s) | |||||
166 | } | 168 | } | ||
167 | 169 | | |||
168 | void PreviewItem::paintShadow(QPainter *painter, int &paddingLeft, int &paddingRight, int &paddingTop, int &paddingBottom) | 170 | void PreviewItem::paintShadow(QPainter *painter, int &paddingLeft, int &paddingRight, int &paddingTop, int &paddingBottom) | ||
169 | { | 171 | { | ||
170 | const auto &shadow = ((const Decoration*)(m_decoration))->shadow(); | 172 | const auto &shadow = ((const Decoration*)(m_decoration))->shadow(); | ||
171 | if (!shadow) { | 173 | if (!shadow) { | ||
172 | return; | 174 | return; | ||
173 | } | 175 | } | ||
176 | | ||||
174 | paddingLeft = shadow->paddingLeft(); | 177 | paddingLeft = shadow->paddingLeft(); | ||
175 | paddingTop = shadow->paddingTop(); | 178 | paddingTop = shadow->paddingTop(); | ||
176 | paddingRight = shadow->paddingRight(); | 179 | paddingRight = shadow->paddingRight(); | ||
177 | paddingBottom = shadow->paddingBottom(); | 180 | paddingBottom = shadow->paddingBottom(); | ||
178 | const QImage img = shadow->shadow(); | 181 | | ||
179 | if (img.isNull()) { | 182 | const QImage shadowPixmap = shadow->shadow(); | ||
183 | if (shadowPixmap.isNull()) { | ||||
180 | return; | 184 | return; | ||
181 | } | 185 | } | ||
182 | const QRect &topLeft = shadow->topLeftGeometry(); | 186 | | ||
183 | const QRect &top = shadow->topGeometry(); | 187 | const QRect outerRect(-paddingLeft, -paddingTop, width(), height()); | ||
184 | const QRect &topRight = shadow->topRightGeometry(); | 188 | const QRect shadowRect(shadowPixmap.rect()); | ||
185 | const QRect &right = shadow->rightGeometry(); | 189 | | ||
186 | const QRect &left = shadow->leftGeometry(); | 190 | const QSize topLeftSize(shadow->topLeftGeometry().size()); | ||
187 | const QRect &bottomLeft = shadow->bottomLeftGeometry(); | 191 | QRect topLeftTarget( | ||
188 | const QRect &bottom = shadow->bottomGeometry(); | 192 | QPoint(outerRect.x(), outerRect.y()), | ||
189 | const QRect &bottomRight = shadow->bottomRightGeometry(); | 193 | topLeftSize); | ||
194 | | ||||
195 | const QSize topRightSize(shadow->topRightGeometry().size()); | ||||
196 | QRect topRightTarget( | ||||
197 | QPoint(outerRect.x() + outerRect.width() - topRightSize.width(), | ||||
198 | outerRect.y()), | ||||
199 | topRightSize); | ||||
200 | | ||||
201 | const QSize bottomRightSize(shadow->bottomRightGeometry().size()); | ||||
202 | QRect bottomRightTarget( | ||||
203 | QPoint(outerRect.x() + outerRect.width() - bottomRightSize.width(), | ||||
204 | outerRect.y() + outerRect.height() - bottomRightSize.height()), | ||||
205 | bottomRightSize); | ||||
206 | | ||||
207 | const QSize bottomLeftSize(shadow->bottomLeftGeometry().size()); | ||||
208 | QRect bottomLeftTarget( | ||||
209 | QPoint(outerRect.x(), | ||||
210 | outerRect.y() + outerRect.height() - bottomLeftSize.height()), | ||||
211 | bottomLeftSize); | ||||
212 | | ||||
213 | // Re-distribute the corner tiles so no one of them is overlapping with others. | ||||
214 | // By doing this, we assume that shadow's corner tiles are symmetric | ||||
215 | // and it is OK to not draw top/right/bottom/left tile between corners. | ||||
216 | // For example, let's say top-left and top-right tiles are overlapping. | ||||
217 | // In that case, the right side of the top-left tile will be shifted to left, | ||||
218 | // the left side of the top-right tile will shifted to right, and the top | ||||
219 | // tile won't be rendered. | ||||
220 | bool drawTop = true; | ||||
221 | if (topLeftTarget.x() + topLeftTarget.width() >= topRightTarget.x()) { | ||||
222 | const float halfOverlap = qAbs(topLeftTarget.x() + topLeftTarget.width() - topRightTarget.x()) / 2.0f; | ||||
223 | topLeftTarget.setRight(topLeftTarget.right() - std::floor(halfOverlap)); | ||||
224 | topRightTarget.setLeft(topRightTarget.left() + std::ceil(halfOverlap)); | ||||
225 | drawTop = false; | ||||
226 | } | ||||
227 | | ||||
228 | bool drawRight = true; | ||||
229 | if (topRightTarget.y() + topRightTarget.height() >= bottomRightTarget.y()) { | ||||
230 | const float halfOverlap = qAbs(topRightTarget.y() + topRightTarget.height() - bottomRightTarget.y()) / 2.0f; | ||||
231 | topRightTarget.setBottom(topRightTarget.bottom() - std::floor(halfOverlap)); | ||||
232 | bottomRightTarget.setTop(bottomRightTarget.top() + std::ceil(halfOverlap)); | ||||
233 | drawRight = false; | ||||
234 | } | ||||
235 | | ||||
236 | bool drawBottom = true; | ||||
237 | if (bottomLeftTarget.x() + bottomLeftTarget.width() >= bottomRightTarget.x()) { | ||||
238 | const float halfOverlap = qAbs(bottomLeftTarget.x() + bottomLeftTarget.width() - bottomRightTarget.x()) / 2.0f; | ||||
239 | bottomLeftTarget.setRight(bottomLeftTarget.right() - std::floor(halfOverlap)); | ||||
240 | bottomRightTarget.setLeft(bottomRightTarget.left() + std::ceil(halfOverlap)); | ||||
241 | drawBottom = false; | ||||
242 | } | ||||
243 | | ||||
244 | bool drawLeft = true; | ||||
245 | if (topLeftTarget.y() + topLeftTarget.height() >= bottomLeftTarget.y()) { | ||||
246 | const float halfOverlap = qAbs(topLeftTarget.y() + topLeftTarget.height() - bottomLeftTarget.y()) / 2.0f; | ||||
247 | topLeftTarget.setBottom(topLeftTarget.bottom() - std::floor(halfOverlap)); | ||||
248 | bottomLeftTarget.setTop(bottomLeftTarget.top() + std::ceil(halfOverlap)); | ||||
249 | drawLeft = false; | ||||
250 | } | ||||
190 | 251 | | |||
191 | painter->translate(paddingLeft, paddingTop); | 252 | painter->translate(paddingLeft, paddingTop); | ||
192 | 253 | | |||
193 | // top left | 254 | painter->drawImage(topLeftTarget, shadowPixmap, | ||
194 | painter->drawImage(QPoint(-paddingLeft, -paddingTop), img, topLeft); | 255 | QRect(QPoint(0, 0), topLeftTarget.size())); | ||
195 | // top | 256 | | ||
196 | painter->drawImage(QRect(-paddingLeft + topLeft.width(), -paddingTop, width() - topLeft.width() - topRight.width(), top.height()), img, top); | 257 | painter->drawImage(topRightTarget, shadowPixmap, | ||
197 | // top right | 258 | QRect(QPoint(shadowRect.width() - topRightTarget.width(), 0), | ||
198 | painter->drawImage(QPoint(width() - topRight.width() - paddingLeft, -paddingTop), img, topRight); | 259 | topRightTarget.size())); | ||
199 | // right | 260 | | ||
200 | painter->drawImage(QRect(width() - right.width() - paddingLeft, -paddingTop + topRight.height(), right.width(), height() - topRight.height() - bottomRight.height()), img, right); | 261 | painter->drawImage(bottomRightTarget, shadowPixmap, | ||
201 | // bottom right | 262 | QRect(QPoint(shadowRect.width() - bottomRightTarget.width(), | ||
202 | painter->drawImage(QPoint(width() - paddingLeft - bottomRight.width(), height() - paddingTop - bottomRight.height()), img, bottomRight); | 263 | shadowRect.height() - bottomRightTarget.height()), | ||
203 | // bottom | 264 | bottomRightTarget.size())); | ||
204 | painter->drawImage(QRect(-paddingLeft + bottomLeft.width(), height() - bottom.height() - paddingTop, width() - bottomLeft.width() - bottomRight.width(), bottom.height()), img, bottom); | 265 | | ||
205 | // bottom left | 266 | painter->drawImage(bottomLeftTarget, shadowPixmap, | ||
206 | painter->drawImage(QPoint(-paddingLeft, height() - bottomLeft.height() - paddingTop), img, bottomLeft); | 267 | QRect(QPoint(0, shadowRect.height() - bottomLeftTarget.height()), | ||
207 | // left | 268 | bottomLeftTarget.size())); | ||
208 | painter->drawImage(QRect(-paddingLeft, -paddingTop + topLeft.height(), left.width(), height() - topLeft.height() - bottomLeft.height()), img, left); | 269 | | ||
270 | if (drawTop) { | ||||
271 | QRect topTarget(topLeftTarget.x() + topLeftTarget.width(), | ||||
272 | topLeftTarget.y(), | ||||
273 | topRightTarget.x() - topLeftTarget.x() - topLeftTarget.width(), | ||||
274 | topRightTarget.height()); | ||||
275 | QRect topSource(shadow->topGeometry()); | ||||
276 | topSource.setHeight(topTarget.height()); | ||||
277 | topSource.moveTop(shadowRect.top()); | ||||
278 | painter->drawImage(topTarget, shadowPixmap, topSource); | ||||
279 | } | ||||
280 | | ||||
281 | if (drawRight) { | ||||
282 | QRect rightTarget(topRightTarget.x(), | ||||
283 | topRightTarget.y() + topRightTarget.height(), | ||||
284 | topRightTarget.width(), | ||||
285 | bottomRightTarget.y() - topRightTarget.y() - topRightTarget.height()); | ||||
286 | QRect rightSource(shadow->rightGeometry()); | ||||
287 | rightSource.setWidth(rightTarget.width()); | ||||
288 | rightSource.moveRight(shadowRect.right()); | ||||
289 | painter->drawImage(rightTarget, shadowPixmap, rightSource); | ||||
290 | } | ||||
291 | | ||||
292 | if (drawBottom) { | ||||
293 | QRect bottomTarget(bottomLeftTarget.x() + bottomLeftTarget.width(), | ||||
294 | bottomLeftTarget.y(), | ||||
295 | bottomRightTarget.x() - bottomLeftTarget.x() - bottomLeftTarget.width(), | ||||
296 | bottomRightTarget.height()); | ||||
297 | QRect bottomSource(shadow->bottomGeometry()); | ||||
298 | bottomSource.setHeight(bottomTarget.height()); | ||||
299 | bottomSource.moveBottom(shadowRect.bottom()); | ||||
300 | painter->drawImage(bottomTarget, shadowPixmap, bottomSource); | ||||
301 | } | ||||
302 | | ||||
303 | if (drawLeft) { | ||||
304 | QRect leftTarget(topLeftTarget.x(), | ||||
305 | topLeftTarget.y() + topLeftTarget.height(), | ||||
306 | topLeftTarget.width(), | ||||
307 | bottomLeftTarget.y() - topLeftTarget.y() - topLeftTarget.height()); | ||||
308 | QRect leftSource(shadow->leftGeometry()); | ||||
309 | leftSource.setWidth(leftTarget.width()); | ||||
310 | leftSource.moveLeft(shadowRect.left()); | ||||
311 | painter->drawImage(leftTarget, shadowPixmap, leftSource); | ||||
312 | } | ||||
209 | } | 313 | } | ||
210 | 314 | | |||
211 | void PreviewItem::mouseDoubleClickEvent(QMouseEvent *event) | 315 | void PreviewItem::mouseDoubleClickEvent(QMouseEvent *event) | ||
212 | { | 316 | { | ||
213 | const auto &shadow = m_decoration->shadow(); | 317 | const auto &shadow = m_decoration->shadow(); | ||
214 | if (shadow) { | 318 | if (shadow) { | ||
215 | QMouseEvent e(event->type(), | 319 | QMouseEvent e(event->type(), | ||
216 | event->localPos() - QPointF(shadow->paddingLeft(), shadow->paddingTop()), | 320 | event->localPos() - QPointF(shadow->paddingLeft(), shadow->paddingTop()), | ||
▲ Show 20 Lines • Show All 179 Lines • Show Last 20 Lines |