diff --git a/applet.cpp b/applet.cpp index a623dffd3..3d689a528 100644 --- a/applet.cpp +++ b/applet.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -284,6 +285,7 @@ public: KPluginInfo appletDescription; Package* package; QList watchedForFocus; + QList watchedForMouseMove; QStringList loadedEngines; Plasma::SvgPanel *background; Plasma::LineEdit *failureText; @@ -1104,19 +1106,37 @@ QString Applet::instanceName() const void Applet::watchForFocus(QObject *widget, bool watch) { - if ( !widget ) { + if (!widget) { return; } int index = d->watchedForFocus.indexOf(widget); - if ( watch ) { - if ( index == -1 ) { - d->watchedForFocus.append( widget ); - widget->installEventFilter( this ); + if (watch) { + if (index == -1) { + d->watchedForFocus.append(widget); + widget->installEventFilter(this); } - } else if ( index != -1 ) { - d->watchedForFocus.removeAt( index ); - widget->removeEventFilter( this ); + } else if (index != -1) { + d->watchedForFocus.removeAt(index); + widget->removeEventFilter(this); + } +} + +void Applet::watchForMouseMove( QGraphicsItem * watched, bool watch ) +{ + if (!watched) { + return; + } + + int index = d->watchedForMouseMove.indexOf(watched); + if (watch) { + if (index == -1) { + d->watchedForMouseMove.append(watched); + watched->installSceneEventFilter(this); + } + } else if (index != -1) { + d->watchedForMouseMove.removeAt(index); + watched->removeSceneEventFilter(this); } } @@ -1154,6 +1174,51 @@ bool Applet::eventFilter( QObject *o, QEvent * e ) return QObject::eventFilter(o, e); } +bool Applet::sceneEventFilter( QGraphicsItem * watched, QEvent * event ) +{ + switch (event->type()) { + case QEvent::GraphicsSceneMouseMove: { + if (d->watchedForMouseMove.contains( watched )) { + mouseMoveEvent(static_cast(event)); + return true; + } + break; + } + + default: + break; + } + + return QGraphicsItem::sceneEventFilter(watched, event); +} + +void Applet::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if (!isImmutable() && formFactor() == Plasma::Planar) { + QGraphicsItem *parent = parentItem(); + Plasma::Applet *applet = qgraphicsitem_cast(parent); + + if (applet && applet->isContainment()) { + // our direct parent is a containment. just move ourselves. + QPointF curPos = event->pos(); + QPointF lastPos = event->lastPos(); + QPointF delta = curPos-lastPos; + + moveBy(delta.x(),delta.y()); + } else if (parent) { + //don't move the icon as well because our parent (usually an appletHandle) will do it for us + //parent->moveBy(delta.x(),delta.y()); + QPointF curPos = parent->transform().map(event->pos()); + QPointF lastPos = parent->transform().map(event->lastPos()); + QPointF delta = curPos-lastPos; + + parent->setPos(parent->pos() + delta); + } + + } +} + + void Applet::showConfigurationInterface() { if (d->package && d->configXml) { diff --git a/applet.h b/applet.h index 176a181ab..542140431 100644 --- a/applet.h +++ b/applet.h @@ -722,12 +722,24 @@ class PLASMA_EXPORT Applet : public Widget /** * Register widgets that can receive keyboard focus. * - * Calling this results in an eventFilter being places on the widget. + * Calling this results in an eventFilter being placed on the widget. * * @param widget the widget to watch for keyboard focus * @param watch whether to start watching the widget, or to stop doing so */ - void watchForFocus( QObject *widget, bool watch = true ); + void watchForFocus(QObject *widget, bool watch = true); + + /** + * Register the widgets that manages mouse clicks but you still want + * to be able to drag the applet around when holding the mouse pointer + * on that widgets. + * + * Calling this results in an eventFilter being places on the widget. + * + * @param widget the widget to watch for mouse move + * @param watch whether to start watching the widget, or to stop doing so + */ + void watchForMouseMove(QGraphicsItem * watched, bool watch); /** * Call this whenever focus is needed or not needed. @@ -745,6 +757,16 @@ class PLASMA_EXPORT Applet : public Widget **/ bool eventFilter( QObject *o, QEvent *e ); + /** + * @internal scene event filter; used to manage applet dragging + */ + bool sceneEventFilter ( QGraphicsItem * watched, QEvent * event ); + + /** + * @internal manage the mouse movement to drag the applet around + */ + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + /** * Reimpmlemented from LayoutItem */