From 89e73cecd2202e34b1550f8f4c4c5d3197819698 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Mon, 19 Oct 2009 21:13:54 +0000 Subject: [PATCH] animate the highlight with the new animation framework. we got a glow item called FocusIndicaotr, it's private for now and probably it should remain so svn path=/trunk/KDE/kdelibs/; revision=1037733 --- CMakeLists.txt | 1 + private/focusindicator.cpp | 114 +++++++++++++++++++++++++++++++++++++ private/focusindicator_p.h | 56 ++++++++++++++++++ widgets/lineedit.cpp | 16 ++---- widgets/spinbox.cpp | 29 ++++------ widgets/spinbox.h | 1 + 6 files changed, 188 insertions(+), 29 deletions(-) create mode 100644 private/focusindicator.cpp create mode 100644 private/focusindicator_p.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 752cdb3ab..eeab248f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,6 +81,7 @@ set(plasma_LIB_SRCS private/desktoptoolbox.cpp private/extenderapplet.cpp private/extenderitemmimedata.cpp + private/focusindicator.cpp private/getsource.cpp private/nativetabbar.cpp private/packages.cpp diff --git a/private/focusindicator.cpp b/private/focusindicator.cpp new file mode 100644 index 000000000..b38898d9f --- /dev/null +++ b/private/focusindicator.cpp @@ -0,0 +1,114 @@ +/* + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library 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 "focusindicator_p.h" + +#include + +#include +#include +#include + +namespace Plasma +{ + +FocusIndicator::FocusIndicator(QGraphicsWidget *parent) + : QGraphicsWidget(parent), + m_parent(parent) +{ + setFlag(QGraphicsItem::ItemStacksBehindParent); + setAcceptsHoverEvents(true); + m_background = new Plasma::FrameSvg(this); + m_background->setImagePath("widgets/lineedit"); + m_background->setElementPrefix("hover"); + m_background->setCacheAllRenderedFrames(true); + + m_fadeIn = new FadeAnimation(1.0); + m_fadeIn->setWidget(this); + m_fadeOut = new FadeAnimation(0.0); + m_fadeOut->setWidget(this); + setOpacity(0); + + parent->installEventFilter(this); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(syncGeometry())); +} + +FocusIndicator::~FocusIndicator() +{ + delete m_fadeIn; + delete m_fadeOut; +} + +void FocusIndicator::setCustomGeometry(const QRectF &geometry) +{ + m_customGeometry = geometry; + syncGeometry(); +} + +bool FocusIndicator::eventFilter(QObject *watched, QEvent *event) +{ + if (static_cast(watched) != m_parent) { + return false; + } + + if (!m_parent->hasFocus() && event->type() == QEvent::GraphicsSceneHoverEnter) { + m_background->setElementPrefix("hover"); + m_fadeIn->start(); + } else if (!m_parent->hasFocus() && event->type() == QEvent::GraphicsSceneHoverLeave) { + m_fadeOut->start(); + } else if (event->type() == QEvent::GraphicsSceneResize) { + syncGeometry(); + } else if (event->type() == QEvent::FocusIn) { + m_background->setElementPrefix("focus"); + m_fadeIn->start(); + } else if (!m_parent->isUnderMouse() && event->type() == QEvent::FocusOut) { + m_fadeOut->start(); + } + + return false; +} + +void FocusIndicator::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + m_background->resizeFrame(event->newSize()); +} + +void FocusIndicator::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + m_background->paintFrame(painter); +} + +void FocusIndicator::syncGeometry() +{ + QRectF geom; + if (!m_customGeometry.isNull()) { + geom = m_customGeometry; + } else { + geom = boundingRect(); + } + + qreal left, top, right, bottom; + m_background->getMargins(left, top, right, bottom); + setGeometry(QRectF(geom.topLeft() + QPointF(-left, -top), geom.size() + QSize(left+right, top+bottom))); +} + +} + +#include + diff --git a/private/focusindicator_p.h b/private/focusindicator_p.h new file mode 100644 index 000000000..c4adc108a --- /dev/null +++ b/private/focusindicator_p.h @@ -0,0 +1,56 @@ +/* + * Copyright 2009 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, 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 Library 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 PLASMA_FOCUSINDICATOR_P +#define PLASMA_FOCUSINDICATOR_P + +#include + +namespace Plasma +{ + class FrameSvg; + class FadeAnimation; + +class FocusIndicator : public QGraphicsWidget +{ + Q_OBJECT +public: + FocusIndicator(QGraphicsWidget *parent); + ~FocusIndicator(); + + void setCustomGeometry(const QRectF &geometry); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + void resizeEvent(QGraphicsSceneResizeEvent *event); + +private Q_SLOTS: + void syncGeometry(); + +private: + QGraphicsWidget *m_parent; + Plasma::FrameSvg *m_background; + FadeAnimation *m_fadeIn; + FadeAnimation *m_fadeOut; + QRectF m_customGeometry; +}; +} +#endif diff --git a/widgets/lineedit.cpp b/widgets/lineedit.cpp index de41d828d..04810443b 100644 --- a/widgets/lineedit.cpp +++ b/widgets/lineedit.cpp @@ -21,10 +21,13 @@ #include +#include + #include #include #include +#include #include "theme.h" #include "svg.h" @@ -72,6 +75,7 @@ LineEdit::LineEdit(QGraphicsWidget *parent) : QGraphicsProxyWidget(parent), d(new LineEditPrivate(this)) { + FocusIndicator *focusIndicator = new FocusIndicator(this); d->style = Plasma::Style::sharedStyle(); d->background = new Plasma::FrameSvg(this); d->background->setImagePath("widgets/lineedit"); @@ -160,18 +164,6 @@ void LineEdit::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q_UNUSED(option) Q_UNUSED(widget) - if (hasFocus() || isUnderMouse()) { - if (hasFocus()) { - d->background->setElementPrefix("focus"); - } else { - d->background->setElementPrefix("hover"); - } - qreal left, top, right, bottom; - d->background->getMargins(left, top, right, bottom); - d->background->resizeFrame(size()+QSizeF(left+right, top+bottom)); - d->background->paintFrame(painter, QPoint(-left, -top)); - } - nativeWidget()->render(painter, QPoint(0, 0), QRegion(), QWidget::DrawChildren|QWidget::IgnoreMask); } diff --git a/widgets/spinbox.cpp b/widgets/spinbox.cpp index b08190fdc..dcc1efcbb 100644 --- a/widgets/spinbox.cpp +++ b/widgets/spinbox.cpp @@ -30,6 +30,7 @@ #include #include #include +#include namespace Plasma { @@ -69,6 +70,7 @@ public: SpinBox *q; Plasma::Style::Ptr style; Plasma::FrameSvg *background; + FocusIndicator *focusIndicator; bool customFont; }; @@ -78,6 +80,8 @@ SpinBox::SpinBox(QGraphicsWidget *parent) { KIntSpinBox *native = new KIntSpinBox; + d->focusIndicator = new FocusIndicator(this); + connect(native, SIGNAL(valueChanged(int)), this, SIGNAL(valueChanged(int))); connect(native, SIGNAL(editingFinished()), this, SIGNAL(editingFinished())); @@ -173,28 +177,19 @@ void SpinBox::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) update(); } +void SpinBox::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + QStyleOptionSpinBox spinOpt; + spinOpt.initFrom(nativeWidget()); + QRect controlrect = nativeWidget()->style()->subControlRect(QStyle::CC_SpinBox, &spinOpt, QStyle::SC_SpinBoxFrame, nativeWidget()); + d->focusIndicator->setCustomGeometry(controlrect); +} + void SpinBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option) Q_UNUSED(widget) - if (hasFocus() || isUnderMouse()) { - if (hasFocus()) { - d->background->setElementPrefix("focus"); - } else { - d->background->setElementPrefix("hover"); - } - qreal left, top, right, bottom; - d->background->getMargins(left, top, right, bottom); - - QStyleOptionSpinBox spinOpt; - spinOpt.initFrom(nativeWidget()); - QRect controlrect = nativeWidget()->style()->subControlRect(QStyle::CC_SpinBox, &spinOpt, QStyle::SC_SpinBoxFrame, nativeWidget()); - - d->background->resizeFrame(controlrect.size()+QSizeF(left+right, top+bottom)); - d->background->paintFrame(painter, QPoint(-left, -top)); - } - QGraphicsProxyWidget::paint(painter, option, widget); } diff --git a/widgets/spinbox.h b/widgets/spinbox.h index 35d3f4baa..97f25d1a5 100644 --- a/widgets/spinbox.h +++ b/widgets/spinbox.h @@ -88,6 +88,7 @@ protected: void changeEvent(QEvent *event); void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + void resizeEvent(QGraphicsSceneResizeEvent *event); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); public Q_SLOTS: