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

libplasma

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

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