From 77160a9e50e20e0526bcbd516b1b66d3dcc47a82 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Sun, 30 Aug 2009 21:17:52 +0000 Subject: [PATCH] new widget: ItemBackground. can be used for all fake item views based on qgraphicswidgets svn path=/trunk/KDE/kdelibs/; revision=1017544 --- CMakeLists.txt | 1 + widgets/itembackground.cpp | 156 +++++++++++++++++++++++++++++++++++++ widgets/itembackground.h | 69 ++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 widgets/itembackground.cpp create mode 100644 widgets/itembackground.h diff --git a/CMakeLists.txt b/CMakeLists.txt index de876d0ee..b4b4e455b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,6 +111,7 @@ set(plasma_LIB_SRCS widgets/frame.cpp widgets/groupbox.cpp widgets/iconwidget.cpp + widgets/itembackground.cpp widgets/label.cpp widgets/lineedit.cpp widgets/meter.cpp diff --git a/widgets/itembackground.cpp b/widgets/itembackground.cpp new file mode 100644 index 000000000..dae7868b5 --- /dev/null +++ b/widgets/itembackground.cpp @@ -0,0 +1,156 @@ +/*************************************************************************** + * Copyright 2009 by Alessandro Diaferia * + * Copyright 2009 by Marco Martin * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ +#include "itembackground.h" + +#include +#include + +#include + +#include +#include +#include + +class ItemBackgroundPrivate +{ +public: + ItemBackgroundPrivate() + {} + + Plasma::FrameSvg *frameSvg; + QRectF oldGeometry; + QRectF newGeometry; + int animId; + qreal opacity; + bool fading; + bool fadeIn; +}; + +ItemBackground::ItemBackground(QGraphicsWidget *parent) + : QGraphicsWidget(parent) +{ + d->frameSvg = new Plasma::FrameSvg(this); + d->animId = 0; + d->opacity = 1; + d->fading = false; + d->fadeIn = false; + setContentsMargins(0, 0, 0, 0); + + d->frameSvg->setImagePath("widgets/viewitem"); + d->frameSvg->setEnabledBorders(Plasma::FrameSvg::AllBorders); + d->frameSvg->setCacheAllRenderedFrames(true); + d->frameSvg->setElementPrefix("hover"); + + setAcceptedMouseButtons(0); + +} + +ItemBackground::~ItemBackground() +{} + +void ItemBackground::setTarget(const QRectF &newGeometry) +{ + if (!isVisible()) { + return; + } + qreal left, top, right, bottom; + d->frameSvg->getMargins(left, top, right, bottom); + + d->oldGeometry = geometry(); + d->newGeometry = newGeometry.adjusted(-left, -top, right, bottom); + + QGraphicsWidget *pw = parentWidget(); + if (pw) { + d->newGeometry = d->newGeometry.intersected(QRectF(QPointF(0,0), pw->size())); + } + + if (d->animId != 0) { + Plasma::Animator::self()->stopCustomAnimation(d->animId); + } + + d->fading = false; + d->opacity = 1; + d->animId = Plasma::Animator::self()->customAnimation( + 15, 250, Plasma::Animator::EaseInOutCurve, this, "animationUpdate"); +} + +void ItemBackground::setTargetItem(QGraphicsItem *target) +{ + setTarget(target->boundingRect()); +} + +QVariant ItemBackground::itemChange(GraphicsItemChange change, const QVariant &value) +{ + if (change == ItemVisibleChange) { + bool visible = value.toBool(); + d->fading = true; + d->fadeIn = visible; + + if (d->animId != 0) { + Plasma::Animator::self()->stopCustomAnimation(d->animId); + } + + d->animId = Plasma::Animator::self()->customAnimation( + 10, 250, Plasma::Animator::EaseInCurve, this, "animationUpdate"); + } +} + +void ItemBackground::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget) + + if (d->frameSvg->frameSize() != option->rect.size()) { + d->frameSvg->resizeFrame(option->rect.size()); + } + + if (qFuzzyCompare(d->opacity, (qreal)1.0)) { + d->frameSvg->paintFrame(painter, option->rect.topLeft()); + } else if (qFuzzyCompare(d->opacity+1, (qreal)1.0)) { + return; + } else { + QPixmap framePix = d->frameSvg->framePixmap(); + QPainter bufferPainter(&framePix); + bufferPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); + bufferPainter.fillRect(framePix.rect(), QColor(0, 0, 0, 255 * d->opacity)); + bufferPainter.end(); + painter->drawPixmap(framePix.rect(), framePix, framePix.rect()); + } +} + +void ItemBackground::animationUpdate(qreal progress) +{ + if (progress == 1) { + d->animId = 0; + } + + if (d->fading) { + d->opacity = d->fadeIn?progress:1-progress; + if (!d->fadeIn && qFuzzyCompare(d->opacity+1, (qreal)1.0)) { + hide(); + } + } else { + setGeometry(d->oldGeometry.x() + (d->newGeometry.x() - d->oldGeometry.x()) * progress, + d->oldGeometry.y() + (d->newGeometry.y() - d->oldGeometry.y()) * progress, + + d->oldGeometry.width() + (d->newGeometry.width() - d->oldGeometry.width()) * progress, + d->oldGeometry.height() + (d->newGeometry.height() - d->oldGeometry.height()) * progress); + } + update(); +} diff --git a/widgets/itembackground.h b/widgets/itembackground.h new file mode 100644 index 000000000..73e981c63 --- /dev/null +++ b/widgets/itembackground.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright 2009 by Alessandro Diaferia * + * Copyright 2009 by Marco Martin * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef ITEMBACKGROUND_H +#define ITEMBACKGROUND_H + +#include + +namespace Plasma { + class FrameSvg; +} + +class ItemBackgroundPrivate; + +/** + * @class ItemBackground plasma/widgets/itembackground.h + * + * @short a background for QGraphicsWidget based item views with animation effects + * + * @since 4.4 + */ +class ItemBackground : public QGraphicsWidget +{ + Q_OBJECT +public: + ItemBackground(QGraphicsWidget *parent = 0); + ~ItemBackground(); + + /** + * Sets a new target geometry we want at the end of animation + * + * @arg newGeometry the final geometry target + */ + void setTarget(const QRectF &newGeometry); + + /** + * set the ItemBackground geometry to be the target geometry, plus the ItemBackground margins + */ + void setTargetItem(QGraphicsItem *target); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +protected: + QVariant itemChange(GraphicsItemChange change, const QVariant &value); + +private Q_SLOTS: + void animationUpdate(qreal progress); +private: + ItemBackgroundPrivate *d; +}; + +#endif