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

Plasma

toolbox.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 "toolbox_p.h"
00022 
00023 #include <QAction>
00024 #include <QApplication>
00025 #include <QGraphicsSceneHoverEvent>
00026 #include <QGraphicsView>
00027 #include <QPainter>
00028 #include <QRadialGradient>
00029 
00030 #include <kcolorscheme.h>
00031 #include <kconfiggroup.h>
00032 #include <kdebug.h>
00033 
00034 #include "corona.h"
00035 #include "theme.h"
00036 #include "widgets/iconwidget.h"
00037 
00038 namespace Plasma
00039 {
00040 
00041 class ToolBoxPrivate
00042 {
00043 public:
00044     ToolBoxPrivate(Containment *c)
00045       : containment(c),
00046         size(50),
00047         iconSize(32, 32),
00048         corner(ToolBox::TopRight),
00049         hidden(false),
00050         showing(false),
00051         movable(false),
00052         toolbar(false),
00053         dragging(false),
00054         userMoved(false)
00055     {}
00056 
00057     Containment *containment;
00058     int size;
00059     QSize iconSize;
00060     ToolBox::Corner corner;
00061     QPoint dragStartRelative;
00062     QTransform viewTransform;
00063     bool hidden : 1;
00064     bool showing : 1;
00065     bool movable : 1;
00066     bool toolbar : 1;
00067     bool dragging : 1;
00068     bool userMoved : 1;
00069 };
00070 
00071 ToolBox::ToolBox(Containment *parent)
00072     : QGraphicsItem(parent),
00073       d(new ToolBoxPrivate(parent))
00074 {
00075     d->userMoved = false;
00076     setAcceptsHoverEvents(true);
00077 }
00078 
00079 ToolBox::~ToolBox()
00080 {
00081     delete d;
00082 }
00083 
00084 QPoint ToolBox::toolPosition(int toolHeight)
00085 {
00086     switch (d->corner) {
00087     case TopRight:
00088         return QPoint(d->size, -toolHeight);
00089     case Top:
00090         return QPoint((int)boundingRect().center().x() - d->iconSize.width(), -toolHeight);
00091     case TopLeft:
00092         return QPoint(-d->size, -toolHeight);
00093     case Left:
00094         return QPoint(-d->size, (int)boundingRect().center().y() - d->iconSize.height());
00095     case Right:
00096         return QPoint(d->size, (int)boundingRect().center().y() - d->iconSize.height());
00097     case BottomLeft:
00098         return QPoint(-d->size, toolHeight);
00099     case Bottom:
00100         return QPoint((int)boundingRect().center().x() - d->iconSize.width(), toolHeight);
00101     case BottomRight:
00102     default:
00103         return QPoint(d->size, toolHeight);
00104     }
00105 }
00106 
00107 void ToolBox::addTool(QAction *action)
00108 {
00109     if (!action) {
00110         return;
00111     }
00112 
00113     Plasma::IconWidget *tool = new Plasma::IconWidget(this);
00114 
00115     tool->setAction(action);
00116     tool->setDrawBackground(true);
00117     tool->setOrientation(Qt::Horizontal);
00118     tool->resize(tool->sizeFromIconSize(22));
00119 
00120     tool->hide();
00121     const int height = static_cast<int>(tool->boundingRect().height());
00122     tool->setPos(toolPosition(height));
00123     tool->setZValue(zValue() + 10);
00124     tool->setToolTip(action->text());
00125 
00126     //make enabled/disabled tools appear/disappear instantly
00127     connect(tool, SIGNAL(changed()), this, SLOT(updateToolBox()));
00128     //kDebug() << "added tool" << action->text() << (QGraphicsItem*)tool;
00129 }
00130 
00131 void ToolBox::updateToolBox()
00132 {
00133     if (d->showing) {
00134         d->showing = false;
00135         showToolBox();
00136     } else if (Plasma::IconWidget *tool = qobject_cast<Plasma::IconWidget *>(sender())) {
00137         tool->hide();
00138     }
00139 }
00140 
00141 void ToolBox::removeTool(QAction *action)
00142 {
00143     foreach (QGraphicsItem *child, QGraphicsItem::children()) {
00144         //kDebug() << "checking tool" << child << child->data(ToolName);
00145         Plasma::IconWidget *tool = dynamic_cast<Plasma::IconWidget*>(child);
00146         if (tool && tool->action() == action) {
00147             //kDebug() << "tool found!";
00148             delete tool;
00149             break;
00150         }
00151     }
00152 }
00153 
00154 int ToolBox::size() const
00155 {
00156     return  d->size;
00157 }
00158 
00159 void ToolBox::setSize(const int newSize)
00160 {
00161     d->size = newSize;
00162 }
00163 
00164 QSize ToolBox::iconSize() const
00165 {
00166     return d->iconSize;
00167 }
00168 
00169 void ToolBox::setIconSize(const QSize newSize)
00170 {
00171     d->iconSize = newSize;
00172 }
00173 
00174 bool ToolBox::showing() const
00175 {
00176     return  d->showing;
00177 }
00178 
00179 void ToolBox::setShowing(const bool show)
00180 {
00181     d->showing = show;
00182 }
00183 
00184 void ToolBox::setCorner(const Corner corner)
00185 {
00186     d->corner = corner;
00187 }
00188 
00189 ToolBox::Corner ToolBox::corner() const
00190 {
00191     return d->corner;
00192 }
00193 
00194 void ToolBox::mousePressEvent(QGraphicsSceneMouseEvent *event)
00195 {
00196     event->accept();
00197     // set grab position relative to toolbox
00198     d->dragStartRelative = mapToParent(event->pos()).toPoint() - pos().toPoint();
00199 }
00200 
00201 void ToolBox::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
00202 {
00203     if (!d->movable || (!d->dragging && boundingRect().contains(event->pos())) || isToolbar()) {
00204         return;
00205     }
00206 
00207     d->dragging = true;
00208     d->userMoved = true;
00209     const QPoint newPos = mapToParent(event->pos()).toPoint();
00210     const QPoint curPos = pos().toPoint();
00211     const int h = abs((int)boundingRect().height());
00212     const int w = abs((int)boundingRect().width());
00213 
00214     const int areaWidth = parentWidget()->size().width();
00215     const int areaHeight = parentWidget()->size().height();
00216 
00217     int x = curPos.x();
00218     int y = curPos.y();
00219 
00220     // jump to the nearest desktop border
00221     int distanceToLeft = newPos.x() - d->dragStartRelative.x();
00222     int distanceToRight = areaWidth - w - distanceToLeft;
00223     int distanceToTop = newPos.y() - d->dragStartRelative.y();
00224     int distanceToBottom = areaHeight - h - distanceToTop;
00225 
00226     // decide which border is the nearest
00227     if (distanceToLeft < distanceToTop && distanceToLeft < distanceToRight &&
00228         distanceToLeft < distanceToBottom ) {
00229         x = 0;
00230         y = (newPos.y() - d->dragStartRelative.y());
00231     }
00232     else if (distanceToRight < distanceToTop && distanceToRight < distanceToLeft &&
00233              distanceToRight < distanceToBottom) {
00234         x = areaWidth - w;
00235         y = (newPos.y() - d->dragStartRelative.y());
00236     }
00237     else if (distanceToTop < distanceToLeft && distanceToTop < distanceToRight &&
00238              distanceToTop < distanceToBottom ) {
00239         y = 0;
00240         x = (newPos.x() - d->dragStartRelative.x());
00241     }
00242     else if (distanceToBottom < distanceToLeft && distanceToBottom < distanceToRight &&
00243              distanceToBottom < distanceToTop) {
00244         y = areaHeight - h;
00245         x = (newPos.x() - d->dragStartRelative.x());
00246     }
00247 
00248     //kDebug() << "distances from borders" << (newPos - d->dragStartRelative) << distanceToLeft << distanceToRight << distanceToTop << distanceToBottom << "=>" << x << y;
00249 /*
00250     if (y == 0 || y + h >= areaHeight) {
00251         x = curPos.x() + (newPos.x() - d->dragStart.x());
00252         if (x < 0) {
00253             x = 0;
00254         } else if (x + w > areaWidth) {
00255             x = areaWidth - w;
00256         }
00257     }
00258 
00259     //kDebug() << x << w << areaWidth;
00260     if (x == 0 || x + w >= areaWidth) {
00261         //kDebug() << "moving along the y axis" << curPos << newPos << d->dragStart;
00262         y = curPos.y() + (newPos.y() - d->dragStart.y());
00263 
00264         if (y < 0) {
00265             y = 0;
00266         } else if (y + h > areaHeight) {
00267             y = areaHeight - h;
00268         }
00269     }
00270 */
00271     x = qBound(0, x, areaWidth - w);
00272     y = qBound(0, y, areaHeight - h);
00273 
00274     Corner newCorner = d->corner;
00275     if (x == 0) {
00276         if (y == 0) {
00277             newCorner = TopLeft;
00278         } else if (y + h >= areaHeight) {
00279             newCorner = BottomLeft;
00280         } else {
00281             newCorner = Left;
00282         }
00283     } else if (y == 0) {
00284         if (x + w >= areaWidth) {
00285             newCorner = TopRight;
00286         } else {
00287             newCorner = Top;
00288         }
00289     } else if (x + w >= areaWidth) {
00290         if (y + h >= areaHeight) {
00291             newCorner = BottomRight;
00292         } else {
00293             newCorner = Right;
00294         }
00295     } else {
00296         newCorner = Bottom;
00297     }
00298 
00299     if (newCorner != d->corner) {
00300         prepareGeometryChange();
00301         d->corner = newCorner;
00302     }
00303 
00304     setPos(x, y);
00305 }
00306 
00307 void ToolBox::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
00308 {
00309     if (!d->dragging && boundingRect().contains(event->pos())) {
00310         emit toggled();
00311     }
00312 
00313     d->dragging = false;
00314     KConfigGroup cg(d->containment->config());
00315     save(cg);
00316 }
00317 
00318 bool ToolBox::isMovable() const
00319 {
00320     return d->movable;
00321 }
00322 
00323 void ToolBox::setIsMovable(bool movable)
00324 {
00325     d->movable = movable;
00326 }
00327 
00328 bool ToolBox::isToolbar() const
00329 {
00330     return d->toolbar;
00331 }
00332 
00333 void ToolBox::setIsToolbar(bool toolbar)
00334 {
00335     d->toolbar = toolbar;
00336 }
00337 
00338 QTransform ToolBox::viewTransform() const
00339 {
00340     return d->viewTransform;
00341 }
00342 
00343 void ToolBox::setViewTransform(QTransform transform)
00344 {
00345     if (transform.isScaling()) {
00346         d->toolbar = true;
00347         showToolBox();
00348     } else {
00349         d->toolbar = false;
00350         if (d->viewTransform != transform) {
00351             hideToolBox();
00352         }
00353     }
00354     d->viewTransform = transform;
00355 }
00356 
00357 void ToolBox::save(KConfigGroup &cg) const
00358 {
00359     if (!d->movable) {
00360         return;
00361     }
00362 
00363     KConfigGroup group(&cg, "ToolBox");
00364     if (!d->userMoved) {
00365         group.deleteGroup();
00366         return;
00367     }
00368 
00369     int offset = 0;
00370     if (d->corner == ToolBox::Left ||
00371         d->corner == ToolBox::Right) {
00372         offset = y();
00373     } else if (d->corner == ToolBox::Left ||
00374                d->corner == ToolBox::Right) {
00375         offset = x();
00376     }
00377 
00378     group.writeEntry("corner", int(d->corner));
00379     group.writeEntry("offset", offset);
00380 }
00381 
00382 void ToolBox::load()
00383 {
00384     if (!d->movable) {
00385         return;
00386     }
00387 
00388     KConfigGroup group = d->containment->config();
00389     group = KConfigGroup(&group, "ToolBox");
00390 
00391     if (!group.hasKey("corner")) {
00392         return;
00393     }
00394 
00395     d->userMoved = true;
00396     d->corner = Corner(group.readEntry("corner", int(d->corner)));
00397 
00398     int offset = group.readEntry("offset", 0);
00399     switch (d->corner) {
00400         case ToolBox::TopLeft:
00401             setPos(0, 0);
00402             break;
00403         case ToolBox::Top:
00404             setPos(offset, 0);
00405             break;
00406         case ToolBox::TopRight:
00407             setPos(d->containment->size().width() - d->size, 0);
00408             break;
00409         case ToolBox::Right:
00410             setPos(d->containment->size().width() - d->size, offset);
00411             break;
00412         case ToolBox::BottomRight:
00413             setPos(d->containment->size().width() - d->size, d->containment->size().height() - d->size);
00414             break;
00415         case ToolBox::Bottom:
00416             setPos(offset, d->containment->size().height() - d->size);
00417             break;
00418         case ToolBox::BottomLeft:
00419             setPos(0, d->containment->size().height() - d->size);
00420             break;
00421         case ToolBox::Left:
00422             setPos(0, offset);
00423             break;
00424     }
00425     //kDebug() << "marked as user moved" << pos()
00426     //         << (d->containment->containmentType() == Containment::PanelContainment);
00427 }
00428 
00429 void ToolBox::reposition()
00430 {
00431     if (d->userMoved) {
00432         //FIXME: adjust for situations like changing of the available space
00433         load();
00434         return;
00435     }
00436 
00437     if (d->containment->containmentType() == Containment::PanelContainment) {
00438         QRectF rect = boundingRect();
00439         if (d->containment->formFactor() == Vertical) {
00440             setCorner(ToolBox::Bottom);
00441             setPos(d->containment->geometry().width() / 2 - rect.width() / 2,
00442                    d->containment->geometry().height() - rect.height());
00443         } else {
00444             //defaulting to Horizontal right now
00445             if (QApplication::layoutDirection() == Qt::RightToLeft) {
00446                 setPos(d->containment->geometry().left(),
00447                        d->containment->geometry().height() / 2 - rect.height() / 2);
00448                 setCorner(ToolBox::Left);
00449             } else {
00450                 setPos(d->containment->geometry().width() - rect.width(),
00451                        d->containment->geometry().height() / 2 - rect.height() / 2);
00452                 setCorner(ToolBox::Right);
00453             }
00454         }
00455         //kDebug() << pos();
00456     } else if (d->containment->corona()) {
00457         //kDebug() << "desktop";
00458 
00459         int screen = d->containment->screen();
00460         QRectF avail = d->containment->geometry();
00461         QRectF screenGeom = avail;
00462 
00463         if (screen > -1 && screen < d->containment->corona()->numScreens()) {
00464             avail = d->containment->corona()->availableScreenRegion(screen).boundingRect();
00465             screenGeom = d->containment->corona()->screenGeometry(screen);
00466             avail.translate(-screenGeom.topLeft());
00467         }
00468 
00469         // Transform to the containment's coordinate system.
00470         screenGeom.moveTo(0, 0);
00471 
00472         if (!d->containment->view() || !d->containment->view()->transform().isScaling()) {
00473             if (QApplication::layoutDirection() == Qt::RightToLeft) {
00474                 if (avail.top() > screenGeom.top()) {
00475                     setPos(avail.topLeft() - QPoint(0, d->size));
00476                     setCorner(ToolBox::Left);
00477                 } else if (avail.left() > screenGeom.left()) {
00478                     setPos(avail.topLeft() - QPoint(d->size, 0));
00479                     setCorner(ToolBox::Top);
00480                 } else {
00481                     setPos(avail.topLeft());
00482                     setCorner(ToolBox::TopLeft);
00483                 }
00484             } else {
00485                 if (avail.top() > screenGeom.top()) {
00486                     setPos(avail.topRight() - QPoint(0, d->size));
00487                     setCorner(ToolBox::Right);
00488                 } else if (avail.right() < screenGeom.right()) {
00489                     setPos(avail.topRight() - QPoint(d->size, 0));
00490                     setCorner(ToolBox::Top);
00491                 } else {
00492                     setPos(avail.topRight() - QPoint(d->size, 0));
00493                     setCorner(ToolBox::TopRight);
00494                 }
00495             }
00496         } else {
00497             if (QApplication::layoutDirection() == Qt::RightToLeft) {
00498                 setPos(d->containment->mapFromScene(QPointF(d->containment->geometry().topLeft())));
00499                 setCorner(ToolBox::TopLeft);
00500             } else {
00501                 setPos(d->containment->mapFromScene(QPointF(d->containment->geometry().topRight())));
00502                 setCorner(ToolBox::TopRight);
00503             }
00504         }
00505     }
00506 }
00507 
00508 } // plasma namespace
00509 
00510 #include "toolbox_p.moc"
00511 

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
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
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