24 #include <QStyleOptionGraphicsItem>
26 #include <QPropertyAnimation>
36 class ItemBackgroundPrivate
44 void animationUpdate(qreal progress);
46 void frameSvgChanged();
47 void refreshCurrentTarget();
50 QGraphicsItem *target;
54 QPropertyAnimation *anim;
63 d(new ItemBackgroundPrivate(this))
66 d->anim =
new QPropertyAnimation(
this,
"animationUpdate",
this);
67 d->anim->setStartValue(0);
68 d->anim->setEndValue(1);
74 d->frameSvg->setImagePath(
"widgets/viewitem");
76 d->frameSvg->setCacheAllRenderedFrames(
true);
77 d->frameSvg->setElementPrefix(
"hover");
79 setCacheMode(DeviceCoordinateCache);
80 setFlag(ItemIsMovable,
false);
81 setFlag(ItemIsSelectable,
false);
82 setFlag(ItemIsFocusable,
false);
84 setFlag(QGraphicsItem::ItemSendsGeometryChanges,
false);
87 d->frameSvg->getMargins(l, t, r, b);
88 setContentsMargins(l, t, r, b);
90 connect(d->frameSvg, SIGNAL(repaintNeeded()),
this, SLOT(frameSvgChanged()));
92 setAcceptedMouseButtons(0);
103 return d->newGeometry;
108 d->oldGeometry = geometry();
109 d->newGeometry = newGeometry;
111 if (!isVisible() && (!d->target || !d->target->isVisible())) {
112 setGeometry(d->newGeometry);
122 d->newGeometry = d->newGeometry.intersected(QRectF(QPointF(0,0), pw->size()));
125 if (d->anim->state() != QAbstractAnimation::Stopped) {
129 if (d->target && d->target->isVisible() && !isVisible()) {
130 setZValue(d->target->zValue()-1);
131 setGeometry(newGeometry);
132 d->oldGeometry = newGeometry;
144 if (d->target && d->target != target) {
146 if (d->target->isWidget()) {
148 obj->removeEventFilter(
this);
150 d->target->removeSceneEventFilter(
this);
151 obj =
dynamic_cast<QObject *
>(d->target);
155 disconnect(obj, 0,
this, 0);
163 bool newTarget = (d->target !=
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());
175 QRectF rect = target->boundingRect();
176 rect.moveTopLeft(mapToParent(mapFromScene(target->mapToScene(QPointF(0, 0)))));
183 if (target->isWidget()) {
185 obj->installEventFilter(
this);
187 d->target->installSceneEventFilter(
this);
192 connect(obj, SIGNAL(destroyed(
QObject*)),
this, SLOT(targetDestroyed(
QObject*)));
206 if (watched == targetWidget) {
207 if (event->type() == QEvent::GraphicsSceneResize ||
208 event->type() == QEvent::GraphicsSceneMove) {
210 QTimer::singleShot(0,
this, SLOT(refreshCurrentTarget()) );
211 }
else if (event->type() == QEvent::Show) {
221 if (watched == d->target) {
222 if (event->type() == QEvent::GraphicsSceneMove) {
223 QTimer::singleShot(0,
this, SLOT(refreshCurrentTarget()) );
232 d->frameSvg->resizeFrame(size());
241 if (change == ItemVisibleChange) {
242 bool visible = value.toBool();
243 bool retVisible = visible;
244 if (visible == isVisible() || d->anim->state() == QAbstractAnimation::Stopped) {
250 if (d->anim->state() != QAbstractAnimation::Stopped) {
254 d->anim->setDuration(250);
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)) {
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));
277 painter->drawPixmap(framePix.rect(), framePix, framePix.rect());
281 void ItemBackground::setAnimationUpdate(qreal progress)
283 d->animationUpdate(progress);
286 qreal ItemBackground::animationUpdate()
const
291 void ItemBackgroundPrivate::animationUpdate(qreal progress)
294 if ((!fading) || (fadeIn)) {
295 emit q->targetReached(newGeometry);
297 emit q->targetItemReached(target);
303 opacity = fadeIn?progress:1-progress;
304 if (!fadeIn && qFuzzyCompare(opacity+1, (qreal)1.0)) {
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);
317 emit q->animationStep(progress);
320 void ItemBackgroundPrivate::targetDestroyed(
QObject*)
326 void ItemBackgroundPrivate::frameSvgChanged()
329 frameSvg->getMargins(l, t, r, b);
330 q->setContentsMargins(l, t, r, b);
332 emit q->appearanceChanged();
335 void ItemBackgroundPrivate::refreshCurrentTarget()
337 q->setTargetItem(target);
343 #include "itembackground.moc"
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
bool eventFilter(QObject *watched, QEvent *event)
QGraphicsItem * targetItem() const
bool sceneEventFilter(QGraphicsItem *watched, QEvent *event)
void resizeEvent(QGraphicsSceneResizeEvent *)
void targetReached(QRectF)
Emitted when the target has been reached.
Provides an SVG with borders.
void setTarget(const QRectF &newGeometry)
Sets a new target geometry we want at the end of animation.
ItemBackground(QGraphicsWidget *parent=0)
a background for QGraphicsWidget based item views with animation effects
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
void setTargetItem(QGraphicsItem *target)
set the ItemBackground geometry to be the target geometry, plus the ItemBackground margins ...
void targetItemReached(QGraphicsItem *)
Emitted when the target has been reached.