• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

libplasma

desktoptoolbox.cpp

Go to the documentation of this file.
00001 /*
00002  *   Copyright 2007 by Aaron Seigo <aseigo@kde.org>
00003  *   Copyright 2008 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 Library General Public
00016  *   License 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 
00021 #include "desktoptoolbox_p.h"
00022 
00023 #include <QGraphicsSceneHoverEvent>
00024 #include <QPainter>
00025 #include <QRadialGradient>
00026 #include <QGraphicsView>
00027 
00028 #include <plasma/theme.h>
00029 #include <KColorScheme>
00030 
00031 #include <KDebug>
00032 
00033 #include <plasma/applet.h>
00034 
00035 
00036 namespace Plasma
00037 {
00038 
00039 class EmptyGraphicsItem : public QGraphicsItem
00040 {
00041     public:
00042         EmptyGraphicsItem(QGraphicsItem *parent)
00043             : QGraphicsItem(parent)
00044         {
00045             setAcceptsHoverEvents(true);
00046         }
00047 
00048         QRectF boundingRect() const
00049         {
00050             return QRectF(QPointF(0, 0), m_rect.size());
00051         }
00052 
00053         QRectF rect() const
00054         {
00055             return m_rect;
00056         }
00057 
00058         void setRect(const QRectF &rect)
00059         {
00060             //kDebug() << "setting rect to" << rect;
00061             prepareGeometryChange();
00062             m_rect = rect;
00063             setPos(rect.topLeft());
00064         }
00065 
00066         void paint(QPainter * p, const QStyleOptionGraphicsItem*, QWidget*)
00067         {
00068             Q_UNUSED(p)
00069             //p->setPen(Qt::red);
00070             //p->drawRect(boundingRect());
00071         }
00072 
00073     private:
00074         QRectF m_rect;
00075 };
00076 
00077 // used with QGrahphicsItem::setData
00078 static const int ToolName = 7001;
00079 
00080 class DesktopToolBoxPrivate
00081 {
00082 public:
00083     DesktopToolBoxPrivate()
00084       : icon("plasma"),
00085         toolBacker(0),
00086         animCircleId(0),
00087         animHighlightId(0),
00088         animCircleFrame(0),
00089         animHighlightFrame(0),
00090         hovering(0)
00091     {}
00092 
00093     KIcon icon;
00094     EmptyGraphicsItem *toolBacker;
00095     int animCircleId;
00096     int animHighlightId;
00097     qreal animCircleFrame;
00098     qreal animHighlightFrame;
00099     bool hovering : 1;
00100 };
00101 
00102 DesktopToolBox::DesktopToolBox(QGraphicsItem *parent)
00103     : ToolBox(parent),
00104       d(new DesktopToolBoxPrivate)
00105 {
00106     connect(Plasma::Animator::self(), SIGNAL(movementFinished(QGraphicsItem*)), this, SLOT(toolMoved(QGraphicsItem*)));
00107     connect(this, SIGNAL(toggled()), this, SLOT(toggle()));
00108 
00109     setZValue(10000000);
00110     setFlag(ItemClipsToShape, true);
00111     setFlag(ItemClipsChildrenToShape, false);
00112     setFlag(ItemIgnoresTransformations, true);
00113 }
00114 
00115 DesktopToolBox::~DesktopToolBox()
00116 {
00117     delete d;
00118 }
00119 
00120 QRectF DesktopToolBox::boundingRect() const
00121 {
00122     return QRectF(0, 0, -size()*2, size()*2);
00123 }
00124 
00125 void DesktopToolBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
00126 {
00127     Q_UNUSED(option)
00128     Q_UNUSED(widget)
00129 
00130     painter->save();
00131     painter->translate(boundingRect().topLeft());
00132 
00133     QColor color1 = KColorScheme(QPalette::Active, KColorScheme::Window,
00134                                Plasma::Theme::defaultTheme()->colorScheme()).background().color();
00135     color1.setAlpha(64);
00136 
00137     QColor color2 = KColorScheme(QPalette::Active, KColorScheme::Window,
00138                                Plasma::Theme::defaultTheme()->colorScheme()).foreground().color();
00139     color2.setAlpha(64);
00140 
00141     QPainterPath p = shape();
00142     QRadialGradient gradient(boundingRect().topLeft(), size() + d->animCircleFrame);
00143     gradient.setFocalPoint(boundingRect().topLeft());
00144     gradient.setColorAt(0, color1);
00145     gradient.setColorAt(.87, color1);
00146     gradient.setColorAt(.97, color2);
00147     color2.setAlpha(0);
00148     gradient.setColorAt(1, color2);
00149     painter->save();
00150     painter->setPen(Qt::NoPen);
00151     painter->setRenderHint(QPainter::Antialiasing, true);
00152     painter->setBrush(gradient);
00153     painter->drawPath(p);
00154     painter->restore();
00155 
00156     const qreal progress = d->animHighlightFrame;
00157 
00158     if (progress <= 0.9) {
00159         d->icon.paint(painter, QRect(QPoint((int)boundingRect().left() - iconSize().width() + 2, 2), iconSize()), Qt::AlignCenter, QIcon::Disabled, QIcon::Off);
00160     }
00161 
00162     if (progress > 0.1) {
00163         painter->save();
00164         painter->setOpacity(progress);
00165         d->icon.paint(painter, QRect(QPoint((int)boundingRect().left() - iconSize().width() + 2, 2), iconSize()));
00166         painter->restore();
00167     }
00168 
00169     painter->restore();
00170 }
00171 
00172 QPainterPath DesktopToolBox::shape() const
00173 {
00174     QPainterPath path;
00175     int toolSize = size() + (int)d->animCircleFrame;
00176     path.arcTo(QRectF(boundingRect().left() - toolSize, boundingRect().top() - toolSize, toolSize*2, toolSize*2), 180, 90);
00177 
00178     return path;
00179 }
00180 
00181 void DesktopToolBox::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
00182 {
00183     if (showing() || d->hovering) {
00184         QGraphicsItem::hoverEnterEvent(event);
00185         return;
00186     }
00187     Plasma::Animator* animdriver = Plasma::Animator::self();
00188     if (d->animHighlightId) {
00189         animdriver->stopCustomAnimation(d->animHighlightId);
00190     }
00191     d->hovering = true;
00192     d->animHighlightId = animdriver->customAnimation(10, 240, Plasma::Animator::EaseInCurve, this, "animateHighlight");
00193 
00194     QGraphicsItem::hoverEnterEvent(event);
00195 }
00196 
00197 void DesktopToolBox::showToolBox()
00198 {
00199     if (showing()) {
00200         return;
00201     }
00202 
00203     int maxwidth = 0;
00204     foreach (QGraphicsItem* tool, QGraphicsItem::children()) {
00205         if (!tool->isEnabled()) {
00206             continue;
00207         }
00208         maxwidth = qMax(static_cast<int>(tool->boundingRect().width()), maxwidth);
00209     }
00210 
00211     // put tools 5px from icon edge
00212     const int iconWidth = 32;
00213     int x = (int)boundingRect().left() - maxwidth - iconWidth - 5;
00214     int y = (int)boundingRect().top() + 5;
00215     Plasma::Animator* animdriver = Plasma::Animator::self();
00216     foreach (QGraphicsItem* tool, QGraphicsItem::children()) {
00217         if (tool == d->toolBacker) {
00218             continue;
00219         }
00220 
00221         if (!tool->isEnabled()) {
00222             if (tool->isVisible()) {
00223                 const int height = static_cast<int>(tool->boundingRect().height());
00224                 animdriver->moveItem(tool, Plasma::Animator::SlideOutMovement, QPoint(size() * 2, -height));
00225             }
00226             continue;
00227         }
00228 
00229         //kDebug() << "let's show and move" << tool << tool->boundingRect();
00230         tool->show();
00231         animdriver->moveItem(tool, Plasma::Animator::SlideInMovement, QPoint(x, y));
00232         //x += 0;
00233         y += static_cast<int>(tool->boundingRect().height()) + 5;
00234     }
00235 
00236     if (!d->toolBacker) {
00237         d->toolBacker = new EmptyGraphicsItem(this);
00238     }
00239     d->toolBacker->setRect(QRectF(QPointF(x, 0), QSizeF(maxwidth, y - 10)));
00240     d->toolBacker->show();
00241 
00242     if (d->animCircleId) {
00243         animdriver->stopCustomAnimation(d->animCircleId);
00244     }
00245 
00246     setShowing(true);
00247     // TODO: 10 and 200 shouldn't be hardcoded here. There needs to be a way to
00248     // match whatever the time is that moveItem() takes. Same in hoverLeaveEvent().
00249     d->animCircleId = animdriver->customAnimation(10, 240, Plasma::Animator::EaseInCurve, this, "animateCircle");
00250 }
00251 
00252 void DesktopToolBox::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
00253 {
00254     //kDebug() << event->pos() << event->scenePos() << d->toolBacker->rect().contains(event->scenePos().toPoint());
00255     if (! d->hovering) {
00256         QGraphicsItem::hoverLeaveEvent(event);
00257         return;
00258     }
00259 
00260     hideToolBox();
00261     Plasma::Animator* animdriver = Plasma::Animator::self();
00262     if (d->animHighlightId) {
00263         animdriver->stopCustomAnimation(d->animHighlightId);
00264     }
00265     d->hovering = false;
00266     d->animHighlightId = animdriver->customAnimation(10, 240, Plasma::Animator::EaseOutCurve, this, "animateHighlight");
00267 
00268     QGraphicsItem::hoverLeaveEvent(event);
00269 }
00270 
00271 void DesktopToolBox::hideToolBox()
00272 {
00273     if (!showing()) {
00274         return;
00275     }
00276 
00277     int x = size() * 2;
00278     int y = 0;
00279     Plasma::Animator* animdriver = Plasma::Animator::self();
00280     foreach (QGraphicsItem* tool, QGraphicsItem::children()) {
00281         if (tool == d->toolBacker) {
00282             continue;
00283         }
00284 
00285         const int height = static_cast<int>(tool->boundingRect().height());
00286         animdriver->moveItem(tool, Plasma::Animator::SlideOutMovement, QPoint(x, y-height));
00287     }
00288 
00289     if (d->animCircleId) {
00290         animdriver->stopCustomAnimation(d->animCircleId);
00291     }
00292 
00293     setShowing(false);
00294     d->animCircleId = animdriver->customAnimation(10, 240, Plasma::Animator::EaseOutCurve, this, "animateCircle");
00295 
00296     if (d->toolBacker) {
00297         d->toolBacker->hide();
00298     }
00299 }
00300 
00301 void DesktopToolBox::animateCircle(qreal progress)
00302 {
00303     if (showing()) {
00304         d->animCircleFrame = size() * progress;
00305     } else {
00306         d->animCircleFrame = size() * (1.0 - progress);
00307     }
00308 
00309     if (progress >= 1) {
00310         d->animCircleId = 0;
00311     }
00312 
00313     update();
00314 }
00315 
00316 void DesktopToolBox::animateHighlight(qreal progress)
00317 {
00318     if (d->hovering) {
00319         d->animHighlightFrame = progress;
00320     } else {
00321         d->animHighlightFrame = 1.0 - progress;
00322     }
00323 
00324     if (progress >= 1) {
00325         d->animHighlightId = 0;
00326     }
00327 
00328     update();
00329 }
00330 
00331 void DesktopToolBox::toolMoved(QGraphicsItem *item)
00332 {
00333     //kDebug() << "geometry is now " << static_cast<Plasma::Widget*>(item)->geometry();
00334     if (!showing() &&
00335         QGraphicsItem::children().indexOf(static_cast<Plasma::Applet*>(item)) != -1) {
00336         item->hide();
00337     }
00338 }
00339 
00340 void DesktopToolBox::toggle()
00341 {
00342     if (showing()) {
00343         hideToolBox();
00344     } else {
00345         showToolBox();
00346     }
00347 }
00348 
00349 } // plasma namespace
00350 
00351 #include "desktoptoolbox_p.moc"
00352 

libplasma

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

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libplasma
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.4
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