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

Plasma

itembackground.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright 2009 by Alessandro Diaferia <alediaferia@gmail.com>         *
00003  *   Copyright 2009 by Marco Martin <notmart@gmail.com>                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Library General Public License as       *
00007  *   published by the Free Software Foundation; either version 2, or       *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
00019  ***************************************************************************/
00020 #include "itembackground.h"
00021 
00022 #include <QPainter>
00023 #include <QTimer>
00024 #include <QStyleOptionGraphicsItem>
00025 
00026 #include <QPropertyAnimation>
00027 
00028 #include <kdebug.h>
00029 
00030 #include <plasma/framesvg.h>
00031 #include <plasma/animator.h>
00032 #include <plasma/theme.h>
00033 namespace Plasma
00034 {
00035 
00036 class ItemBackgroundPrivate
00037 {
00038 public:
00039     ItemBackgroundPrivate(ItemBackground *parent)
00040         : q(parent),
00041           target(0)
00042     {}
00043 
00044     void animationUpdate(qreal progress);
00045     void targetDestroyed(QObject*);
00046     void frameSvgChanged();
00047     void refreshCurrentTarget();
00048 
00049     ItemBackground * const q;
00050     QGraphicsItem *target;
00051     Plasma::FrameSvg *frameSvg;
00052     QRectF oldGeometry;
00053     QRectF newGeometry;
00054     QPropertyAnimation *anim;
00055     qreal opacity;
00056     bool fading;
00057     bool fadeIn;
00058     bool immediate;
00059 };
00060 
00061 ItemBackground::ItemBackground(QGraphicsWidget *parent)
00062     : QGraphicsWidget(parent),
00063       d(new ItemBackgroundPrivate(this))
00064 {
00065     d->frameSvg = new Plasma::FrameSvg(this);
00066     d->anim = new QPropertyAnimation(this, "animationUpdate", this);
00067     d->anim->setStartValue(0);
00068     d->anim->setEndValue(1);
00069     d->opacity = 1;
00070     d->fading = false;
00071     d->fadeIn = false;
00072     d->immediate = false;
00073 
00074     d->frameSvg->setImagePath("widgets/viewitem");
00075     d->frameSvg->setEnabledBorders(Plasma::FrameSvg::AllBorders);
00076     d->frameSvg->setCacheAllRenderedFrames(true);
00077     d->frameSvg->setElementPrefix("hover");
00078 
00079     setCacheMode(DeviceCoordinateCache);
00080     setFlag(ItemIsMovable, false);
00081     setFlag(ItemIsSelectable, false);
00082     setFlag(ItemIsFocusable, false);
00083 
00084     setFlag(QGraphicsItem::ItemSendsGeometryChanges, false);
00085 
00086     qreal l, t, r, b;
00087     d->frameSvg->getMargins(l, t, r, b);
00088     setContentsMargins(l, t, r, b);
00089 
00090     connect(d->frameSvg, SIGNAL(repaintNeeded()), this, SLOT(frameSvgChanged()));
00091 
00092     setAcceptedMouseButtons(0);
00093     setZValue(-800);
00094 }
00095 
00096 ItemBackground::~ItemBackground()
00097 {
00098     delete d;
00099 }
00100 
00101 QRectF ItemBackground::target() const
00102 {
00103     return d->newGeometry;
00104 }
00105 
00106 void ItemBackground::setTarget(const QRectF &newGeometry)
00107 {
00108     d->oldGeometry = geometry();
00109     d->newGeometry = newGeometry;
00110 
00111     if (!isVisible() && (!d->target || !d->target->isVisible())) {
00112         setGeometry(d->newGeometry);
00113         targetReached(newGeometry);
00114         if (d->target) {
00115             emit targetItemReached(d->target);
00116         }
00117         return;
00118     }
00119 
00120     QGraphicsWidget *pw = parentWidget();
00121     if (pw) {
00122         d->newGeometry = d->newGeometry.intersected(QRectF(QPointF(0,0), pw->size()));
00123     }
00124 
00125     if (d->anim->state() != QAbstractAnimation::Stopped) {
00126         d->anim->stop();
00127     }
00128 
00129     if (d->target && d->target->isVisible() && !isVisible()) {
00130         setZValue(d->target->zValue()-1);
00131         setGeometry(newGeometry);
00132         d->oldGeometry = newGeometry;
00133         show();
00134     } else {
00135         d->fading = false;
00136         d->opacity = 1;
00137         d->anim->start();
00138     }
00139 
00140 }
00141 
00142 void ItemBackground::setTargetItem(QGraphicsItem *target)
00143 {
00144     if (d->target && d->target != target) {
00145         QObject *obj = 0;
00146         if (d->target->isWidget()) {
00147             obj = static_cast<QGraphicsWidget*>(d->target);
00148             obj->removeEventFilter(this);
00149         } else {
00150             d->target->removeSceneEventFilter(this);
00151             obj = dynamic_cast<QObject *>(d->target);
00152         }
00153 
00154         if (obj) {
00155             disconnect(obj, 0, this, 0);
00156         }
00157     }
00158 
00159     if (!target) {
00160         hide();
00161     }
00162 
00163     bool newTarget = (d->target != target);
00164     d->target = target;
00165     if (target) {
00166         setZValue(target->zValue() - 1);
00167         if (parentItem() != target->parentItem()) {
00168             QTransform t = transform();
00169             setTransform(QTransform());
00170             QRectF geom = mapToScene(geometry()).boundingRect();
00171             setGeometry(mapFromScene(geom).boundingRect());
00172             setTransform(t);
00173         }
00174 
00175         QRectF rect = target->boundingRect();
00176         rect.moveTopLeft(mapToParent(mapFromScene(target->mapToScene(QPointF(0, 0)))));
00177 
00178         setTarget(rect);
00179 
00180 
00181         if (newTarget) {
00182             QObject *obj = 0;
00183             if (target->isWidget()) {
00184                 obj = static_cast<QGraphicsWidget*>(target);
00185                 obj->installEventFilter(this);
00186             } else {
00187                 d->target->installSceneEventFilter(this);
00188                 obj = dynamic_cast<QObject *>(target);
00189             }
00190 
00191             if (obj) {
00192                 connect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(targetDestroyed(QObject*)));
00193             }
00194         }
00195     }
00196 }
00197 
00198 QGraphicsItem *ItemBackground::targetItem() const
00199 {
00200     return d->target;
00201 }
00202 
00203 bool ItemBackground::eventFilter(QObject *watched, QEvent *event)
00204 {
00205     QGraphicsWidget *targetWidget = static_cast<QGraphicsWidget *>(d->target);
00206     if (watched == targetWidget) {
00207         if (event->type() == QEvent::GraphicsSceneResize ||
00208             event->type() == QEvent::GraphicsSceneMove) {
00209             // We need to wait for the parent widget to resize...
00210             QTimer::singleShot(0, this, SLOT(refreshCurrentTarget()) );
00211         } else if (event->type() == QEvent::Show) {
00212             setTargetItem(targetWidget);
00213         }
00214     }
00215 
00216     return false;
00217 }
00218 
00219 bool ItemBackground::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
00220 {
00221     if (watched == d->target) {
00222         if (event->type() == QEvent::GraphicsSceneMove) {
00223             QTimer::singleShot(0, this, SLOT(refreshCurrentTarget()) );
00224         }
00225     }
00226 
00227     return false;
00228 }
00229 
00230 void ItemBackground::resizeEvent(QGraphicsSceneResizeEvent *)
00231 {
00232     d->frameSvg->resizeFrame(size());
00233 }
00234 
00235 QVariant ItemBackground::itemChange(GraphicsItemChange change, const QVariant &value)
00236 {
00237     if (d->immediate) {
00238         return value;
00239     }
00240 
00241     if (change == ItemVisibleChange) {
00242         bool visible = value.toBool();
00243         bool retVisible = visible;
00244         if (visible == isVisible() || d->anim->state() == QAbstractAnimation::Stopped) {
00245             retVisible = true;
00246         }
00247         d->fading = true;
00248         d->fadeIn = visible;
00249 
00250         if (d->anim->state() != QAbstractAnimation::Stopped) {
00251             d->anim->stop();
00252         }
00253 
00254         d->anim->setDuration(250);
00255         d->anim->start();
00256 
00257         return retVisible;
00258 
00259     }
00260     return value;
00261 }
00262 
00263 void ItemBackground::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
00264 {
00265     Q_UNUSED(widget)
00266 
00267     if (qFuzzyCompare(d->opacity, (qreal)1.0)) {
00268         d->frameSvg->paintFrame(painter, option->rect.topLeft());
00269     } else if (qFuzzyCompare(d->opacity+1, (qreal)1.0)) {
00270         return;
00271     } else {
00272         QPixmap framePix = d->frameSvg->framePixmap();
00273         QPainter bufferPainter(&framePix);
00274         bufferPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00275         bufferPainter.fillRect(framePix.rect(), QColor(0, 0, 0, 255 * d->opacity));
00276         bufferPainter.end();
00277         painter->drawPixmap(framePix.rect(), framePix, framePix.rect());
00278     }
00279 }
00280 
00281 void ItemBackground::setAnimationUpdate(qreal progress)
00282 {
00283     d->animationUpdate(progress);
00284 }
00285 
00286 qreal ItemBackground::animationUpdate() const
00287 {
00288     return d->opacity;
00289 }
00290 
00291 void ItemBackgroundPrivate::animationUpdate(qreal progress)
00292 {
00293     if (progress == 1) {
00294         if ((!fading) || (fadeIn)) {
00295             emit q->targetReached(newGeometry);
00296             if (target) {
00297                 emit q->targetItemReached(target);
00298             }
00299         }
00300     }
00301 
00302     if (fading) {
00303         opacity = fadeIn?progress:1-progress;
00304         if (!fadeIn && qFuzzyCompare(opacity+1, (qreal)1.0)) {
00305             immediate = true;
00306             q->hide();
00307             immediate = false;
00308         }
00309     } else if (oldGeometry != newGeometry) {
00310         q->setGeometry(oldGeometry.x() + (newGeometry.x() - oldGeometry.x()) * progress,
00311                        oldGeometry.y() + (newGeometry.y() - oldGeometry.y()) * progress,
00312                        oldGeometry.width() + (newGeometry.width() - oldGeometry.width()) * progress,
00313                        oldGeometry.height() + (newGeometry.height() - oldGeometry.height()) * progress);
00314     }
00315 
00316     q->update();
00317     emit q->animationStep(progress);
00318 }
00319 
00320 void ItemBackgroundPrivate::targetDestroyed(QObject*)
00321 {
00322     target = 0;
00323     q->setTargetItem(0);
00324 }
00325 
00326 void ItemBackgroundPrivate::frameSvgChanged()
00327 {
00328     qreal l, t, r, b;
00329     frameSvg->getMargins(l, t, r, b);
00330     q->setContentsMargins(l, t, r, b);
00331     q->update();
00332     emit q->appearanceChanged();
00333 }
00334 
00335 void ItemBackgroundPrivate::refreshCurrentTarget()
00336 {
00337     q->setTargetItem(target);
00338 }
00339 
00340 } // Plasma namespace
00341 
00342 
00343 #include "itembackground.moc"
00344 
00345 

Plasma

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • 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
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal