• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

Plasma

  • plasma
  • widgets
itembackground.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright 2009 by Alessandro Diaferia <alediaferia@gmail.com> *
3 * Copyright 2009 by Marco Martin <notmart@gmail.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU Library General Public License as *
7 * published by the Free Software Foundation; either version 2, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
19 ***************************************************************************/
20#include "itembackground.h"
21
22#include <QPainter>
23#include <QTimer>
24#include <QStyleOptionGraphicsItem>
25
26#include <QPropertyAnimation>
27
28#include <kdebug.h>
29
30#include <plasma/framesvg.h>
31#include <plasma/animator.h>
32#include <plasma/theme.h>
33namespace Plasma
34{
35
36class ItemBackgroundPrivate
37{
38public:
39 ItemBackgroundPrivate(ItemBackground *parent)
40 : q(parent),
41 target(0)
42 {}
43
44 void animationUpdate(qreal progress);
45 void targetDestroyed(QObject*);
46 void frameSvgChanged();
47 void refreshCurrentTarget();
48
49 ItemBackground * const q;
50 QGraphicsItem *target;
51 Plasma::FrameSvg *frameSvg;
52 QRectF oldGeometry;
53 QRectF newGeometry;
54 QPropertyAnimation *anim;
55 qreal opacity;
56 bool fading;
57 bool fadeIn;
58 bool immediate;
59};
60
61ItemBackground::ItemBackground(QGraphicsWidget *parent)
62 : QGraphicsWidget(parent),
63 d(new ItemBackgroundPrivate(this))
64{
65 d->frameSvg = new Plasma::FrameSvg(this);
66 d->anim = new QPropertyAnimation(this, "animationUpdate", this);
67 d->anim->setStartValue(0);
68 d->anim->setEndValue(1);
69 d->opacity = 1;
70 d->fading = false;
71 d->fadeIn = false;
72 d->immediate = false;
73
74 d->frameSvg->setImagePath("widgets/viewitem");
75 d->frameSvg->setEnabledBorders(Plasma::FrameSvg::AllBorders);
76 d->frameSvg->setCacheAllRenderedFrames(true);
77 d->frameSvg->setElementPrefix("hover");
78
79 setCacheMode(DeviceCoordinateCache);
80 setFlag(ItemIsMovable, false);
81 setFlag(ItemIsSelectable, false);
82 setFlag(ItemIsFocusable, false);
83
84 setFlag(QGraphicsItem::ItemSendsGeometryChanges, false);
85
86 qreal l, t, r, b;
87 d->frameSvg->getMargins(l, t, r, b);
88 setContentsMargins(l, t, r, b);
89
90 connect(d->frameSvg, SIGNAL(repaintNeeded()), this, SLOT(frameSvgChanged()));
91
92 setAcceptedMouseButtons(0);
93 setZValue(-800);
94}
95
96ItemBackground::~ItemBackground()
97{
98 delete d;
99}
100
101QRectF ItemBackground::target() const
102{
103 return d->newGeometry;
104}
105
106void ItemBackground::setTarget(const QRectF &newGeometry)
107{
108 d->oldGeometry = geometry();
109 d->newGeometry = newGeometry;
110
111 if (!isVisible() && (!d->target || !d->target->isVisible())) {
112 setGeometry(d->newGeometry);
113 targetReached(newGeometry);
114 if (d->target) {
115 emit targetItemReached(d->target);
116 }
117 return;
118 }
119
120 QGraphicsWidget *pw = parentWidget();
121 if (pw) {
122 d->newGeometry = d->newGeometry.intersected(QRectF(QPointF(0,0), pw->size()));
123 }
124
125 if (d->anim->state() != QAbstractAnimation::Stopped) {
126 d->anim->stop();
127 }
128
129 if (d->target && d->target->isVisible() && !isVisible()) {
130 setZValue(d->target->zValue()-1);
131 setGeometry(newGeometry);
132 d->oldGeometry = newGeometry;
133 show();
134 } else {
135 d->fading = false;
136 d->opacity = 1;
137 d->anim->start();
138 }
139
140}
141
142void ItemBackground::setTargetItem(QGraphicsItem *target)
143{
144 if (d->target && d->target != target) {
145 QObject *obj = 0;
146 if (d->target->isWidget()) {
147 obj = static_cast<QGraphicsWidget*>(d->target);
148 obj->removeEventFilter(this);
149 } else {
150 d->target->removeSceneEventFilter(this);
151 obj = dynamic_cast<QObject *>(d->target);
152 }
153
154 if (obj) {
155 disconnect(obj, 0, this, 0);
156 }
157 }
158
159 if (!target) {
160 hide();
161 }
162
163 bool newTarget = (d->target != target);
164 d->target = target;
165 if (target) {
166 setZValue(target->zValue() - 1);
167 if (parentItem() != target->parentItem()) {
168 QTransform t = transform();
169 setTransform(QTransform());
170 QRectF geom = mapToScene(geometry()).boundingRect();
171 setGeometry(mapFromScene(geom).boundingRect());
172 setTransform(t);
173 }
174
175 QRectF rect = target->boundingRect();
176 rect.moveTopLeft(mapToParent(mapFromScene(target->mapToScene(QPointF(0, 0)))));
177
178 setTarget(rect);
179
180
181 if (newTarget) {
182 QObject *obj = 0;
183 if (target->isWidget()) {
184 obj = static_cast<QGraphicsWidget*>(target);
185 obj->installEventFilter(this);
186 } else {
187 d->target->installSceneEventFilter(this);
188 obj = dynamic_cast<QObject *>(target);
189 }
190
191 if (obj) {
192 connect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(targetDestroyed(QObject*)));
193 }
194 }
195 }
196}
197
198QGraphicsItem *ItemBackground::targetItem() const
199{
200 return d->target;
201}
202
203bool ItemBackground::eventFilter(QObject *watched, QEvent *event)
204{
205 QGraphicsWidget *targetWidget = static_cast<QGraphicsWidget *>(d->target);
206 if (watched == targetWidget) {
207 if (event->type() == QEvent::GraphicsSceneResize ||
208 event->type() == QEvent::GraphicsSceneMove) {
209 // We need to wait for the parent widget to resize...
210 QTimer::singleShot(0, this, SLOT(refreshCurrentTarget()) );
211 } else if (event->type() == QEvent::Show) {
212 setTargetItem(targetWidget);
213 }
214 }
215
216 return false;
217}
218
219bool ItemBackground::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
220{
221 if (watched == d->target) {
222 if (event->type() == QEvent::GraphicsSceneMove) {
223 QTimer::singleShot(0, this, SLOT(refreshCurrentTarget()) );
224 }
225 }
226
227 return false;
228}
229
230void ItemBackground::resizeEvent(QGraphicsSceneResizeEvent *)
231{
232 d->frameSvg->resizeFrame(size());
233}
234
235QVariant ItemBackground::itemChange(GraphicsItemChange change, const QVariant &value)
236{
237 if (d->immediate) {
238 return value;
239 }
240
241 if (change == ItemVisibleChange) {
242 bool visible = value.toBool();
243 bool retVisible = visible;
244 if (visible == isVisible() || d->anim->state() == QAbstractAnimation::Stopped) {
245 retVisible = true;
246 }
247 d->fading = true;
248 d->fadeIn = visible;
249
250 if (d->anim->state() != QAbstractAnimation::Stopped) {
251 d->anim->stop();
252 }
253
254 d->anim->setDuration(250);
255 d->anim->start();
256
257 return retVisible;
258
259 }
260 return value;
261}
262
263void ItemBackground::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
264{
265 Q_UNUSED(widget)
266
267 if (qFuzzyCompare(d->opacity, (qreal)1.0)) {
268 d->frameSvg->paintFrame(painter, option->rect.topLeft());
269 } else if (qFuzzyCompare(d->opacity+1, (qreal)1.0)) {
270 return;
271 } else {
272 QPixmap framePix = d->frameSvg->framePixmap();
273 QPainter bufferPainter(&framePix);
274 bufferPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
275 bufferPainter.fillRect(framePix.rect(), QColor(0, 0, 0, 255 * d->opacity));
276 bufferPainter.end();
277 painter->drawPixmap(framePix.rect(), framePix, framePix.rect());
278 }
279}
280
281void ItemBackground::setAnimationUpdate(qreal progress)
282{
283 d->animationUpdate(progress);
284}
285
286qreal ItemBackground::animationUpdate() const
287{
288 return d->opacity;
289}
290
291void ItemBackgroundPrivate::animationUpdate(qreal progress)
292{
293 if (progress == 1) {
294 if ((!fading) || (fadeIn)) {
295 emit q->targetReached(newGeometry);
296 if (target) {
297 emit q->targetItemReached(target);
298 }
299 }
300 }
301
302 if (fading) {
303 opacity = fadeIn?progress:1-progress;
304 if (!fadeIn && qFuzzyCompare(opacity+1, (qreal)1.0)) {
305 immediate = true;
306 q->hide();
307 immediate = false;
308 }
309 } else if (oldGeometry != newGeometry) {
310 q->setGeometry(oldGeometry.x() + (newGeometry.x() - oldGeometry.x()) * progress,
311 oldGeometry.y() + (newGeometry.y() - oldGeometry.y()) * progress,
312 oldGeometry.width() + (newGeometry.width() - oldGeometry.width()) * progress,
313 oldGeometry.height() + (newGeometry.height() - oldGeometry.height()) * progress);
314 }
315
316 q->update();
317 emit q->animationStep(progress);
318}
319
320void ItemBackgroundPrivate::targetDestroyed(QObject*)
321{
322 target = 0;
323 q->setTargetItem(0);
324}
325
326void ItemBackgroundPrivate::frameSvgChanged()
327{
328 qreal l, t, r, b;
329 frameSvg->getMargins(l, t, r, b);
330 q->setContentsMargins(l, t, r, b);
331 q->update();
332 emit q->appearanceChanged();
333}
334
335void ItemBackgroundPrivate::refreshCurrentTarget()
336{
337 q->setTargetItem(target);
338}
339
340} // Plasma namespace
341
342
343#include "itembackground.moc"
344
345
animator.h
ItemBackground
a background for QGraphicsWidget based item views with animation effects
Plasma::FrameSvg
Provides an SVG with borders.
Definition: framesvg.h:77
Plasma::FrameSvg::AllBorders
@ AllBorders
Definition: framesvg.h:93
Plasma::ItemBackground::setTargetItem
void setTargetItem(QGraphicsItem *target)
set the ItemBackground geometry to be the target geometry, plus the ItemBackground margins
Definition: itembackground.cpp:142
Plasma::ItemBackground::target
QRectF target
Definition: itembackground.h:43
Plasma::ItemBackground::targetReached
void targetReached(QRectF)
Emitted when the target has been reached.
Plasma::ItemBackground::setTarget
void setTarget(const QRectF &newGeometry)
Sets a new target geometry we want at the end of animation.
Definition: itembackground.cpp:106
Plasma::ItemBackground::targetItemReached
void targetItemReached(QGraphicsItem *)
Emitted when the target has been reached.
QGraphicsWidget
QObject
QStyleOptionGraphicsItem
QWidget
framesvg.h
itembackground.h
Plasma
Namespace for everything in libplasma.
Definition: abstractdialogmanager.cpp:25
theme.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal