From 1bae88453176d72a936bed156488c76e2d88c998 Mon Sep 17 00:00:00 2001 From: Rob Scheepmaker Date: Thu, 28 Aug 2008 14:32:48 +0000 Subject: [PATCH] Improved Extender support in popupApplet. Dialog resizes correctly, and even the last item is removable. Implementation is still not perfect, but it's now a lot better then it was. svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=853962 --- corona.cpp | 14 ++++++++++++-- dialog.cpp | 26 ++++++++++++++++++-------- dialog.h | 9 +++++---- extender.cpp | 21 ++++++++++----------- extenderitem.cpp | 25 +++++++++++-------------- popupapplet.cpp | 35 +++++++++++++++++------------------ popupapplet.h | 1 + 7 files changed, 74 insertions(+), 57 deletions(-) diff --git a/corona.cpp b/corona.cpp index 11abea15f..54e7ef511 100644 --- a/corona.cpp +++ b/corona.cpp @@ -350,10 +350,9 @@ Containment* Corona::addContainmentDelayed(const QString& name, const QVariantLi void Corona::addOffscreenWidget(QGraphicsWidget *widget) { - kDebug() << "adding offscreen widget."; widget->setParentItem(0); if (!d->offscreenLayout) { - kDebug() << "adding offscreen widget."; + kDebug() << "adding offscreen widget."; QGraphicsWidget *offscreenWidget = new QGraphicsWidget(0); addItem(offscreenWidget); d->offscreenLayout = new QGraphicsGridLayout(offscreenWidget); @@ -362,6 +361,16 @@ void Corona::addOffscreenWidget(QGraphicsWidget *widget) offscreenWidget->setLayout(d->offscreenLayout); } + //check if the layout allready contains this widget. + //XXX: duplicated from removeOffscreenWidget() + for (int i = 0; i < d->offscreenLayout->count(); i++) { + QGraphicsWidget *foundWidget = + dynamic_cast(d->offscreenLayout->itemAt(i)); + if (foundWidget == widget) { + return; + } + } + d->offscreenLayout->addItem(widget, d->offscreenLayout->rowCount() + 1, d->offscreenLayout->columnCount() + 1); @@ -381,6 +390,7 @@ void Corona::removeOffscreenWidget(QGraphicsWidget *widget) dynamic_cast(d->offscreenLayout->itemAt(i)); if (foundWidget == widget) { d->offscreenLayout->removeAt(i); + d->offscreenLayout->invalidate(); } } } diff --git a/dialog.cpp b/dialog.cpp index c34c187a2..1f467c3a1 100644 --- a/dialog.cpp +++ b/dialog.cpp @@ -66,7 +66,6 @@ public: void themeUpdated(); void adjustView(); - Plasma::Dialog *q; /** * Holds the background SVG, to be re-rendered when the cache is invalidated, @@ -89,9 +88,26 @@ void DialogPrivate::themeUpdated() void DialogPrivate::adjustView() { if (view && widget) { + QSize prevSize = q->size(); + + //reposition and resize the view. view->setSceneRect(widget->mapToScene(widget->boundingRect()).boundingRect()); - view->resize(widget->minimumSize().toSize()); + view->resize(widget->preferredSize().toSize()); view->centerOn(widget); + + //set the sizehints correctly: + int left, top, right, bottom; + q->getContentsMargins(&left, &top, &right, &bottom); + q->setMinimumSize(view->size().width() + left + right, + view->size().height() + top + bottom); + q->setMaximumSize(view->size().width() + left + right, + view->size().height() + top + bottom); + q->updateGeometry(); + + if (q->size() != prevSize) { + //the size of the dialog has changed, emit the signal: + emit q->dialogResized(); + } } } @@ -171,12 +187,6 @@ QGraphicsWidget *Dialog::graphicsWidget() return d->widget; } -void Dialog::adjustView() -{ - d->adjustView(); - adjustSize(); -} - bool Dialog::eventFilter(QObject *watched, QEvent *event) { if (watched == d->widget && (event->type() == QEvent::GraphicsSceneResize || diff --git a/dialog.h b/dialog.h index 0c6454a2f..591f550c1 100644 --- a/dialog.h +++ b/dialog.h @@ -61,12 +61,11 @@ class PLASMA_EXPORT Dialog : public QWidget void setGraphicsWidget(QGraphicsWidget *widget); QGraphicsWidget *graphicsWidget(); - public Q_SLOTS: + Q_SIGNALS: /** - * Call when the size of the graphicsWidget changes, to adjust the view and resize the - * dialog. + * Fires when the dialog automatically resizes. */ - void adjustView(); + void dialogResized(); protected: /** @@ -78,6 +77,8 @@ class PLASMA_EXPORT Dialog : public QWidget private: DialogPrivate * const d; + + friend class DialogPrivate; /** * React to theme changes */ diff --git a/extender.cpp b/extender.cpp index c570faf91..0cb69e739 100644 --- a/extender.cpp +++ b/extender.cpp @@ -162,8 +162,7 @@ void Extender::itemAddedEvent(ExtenderItem *item, const QPointF &pos) //remove the empty extender message if needed. if (d->emptyExtenderLabel) { d->layout->removeItem(d->emptyExtenderLabel); - delete d->emptyExtenderLabel; - d->emptyExtenderLabel = 0; + d->emptyExtenderLabel->hide(); } d->adjustSizeHints(); @@ -176,9 +175,10 @@ void Extender::itemRemovedEvent(ExtenderItem *item) d->layout->removeItem(item); //add the empty extender message if needed. - if (!attachedItems().count() && !d->emptyExtenderLabel) { - d->emptyExtenderLabel = new Label(this); - d->emptyExtenderLabel->setText(d->emptyExtenderMessage); + if (!attachedItems().count()) { + d->emptyExtenderLabel->show(); + //just in case: + d->layout->removeItem(d->emptyExtenderLabel); d->layout->addItem(d->emptyExtenderLabel); } @@ -187,7 +187,7 @@ void Extender::itemRemovedEvent(ExtenderItem *item) void Extender::itemHoverEnterEvent(ExtenderItem *item) { - Q_UNUSED(item); + itemHoverMoveEvent(item, QPointF(0, 0)); } void Extender::itemHoverMoveEvent(ExtenderItem *item, const QPointF &pos) @@ -215,8 +215,7 @@ void Extender::itemHoverMoveEvent(ExtenderItem *item, const QPointF &pos) //XXX: duplicated from itemAttachedEvent. if (d->emptyExtenderLabel) { d->layout->removeItem(d->emptyExtenderLabel); - delete d->emptyExtenderLabel; - d->emptyExtenderLabel = 0; + d->emptyExtenderLabel->hide(); } d->adjustSizeHints(); @@ -235,9 +234,9 @@ void Extender::itemHoverLeaveEvent(ExtenderItem *item) d->currentSpacerIndex = -1; //Make sure we add a 'no detachables' label when the layout is empty. - if (!attachedItems().count() && !d->emptyExtenderLabel) { - d->emptyExtenderLabel = new Label(this); - d->emptyExtenderLabel->setText(d->emptyExtenderMessage); + if (!attachedItems().count()) { + d->emptyExtenderLabel->show(); + d->layout->removeItem(d->emptyExtenderLabel); d->layout->addItem(d->emptyExtenderLabel); } diff --git a/extenderitem.cpp b/extenderitem.cpp index f4a72fcd5..47e9becfd 100644 --- a/extenderitem.cpp +++ b/extenderitem.cpp @@ -128,7 +128,6 @@ class ExtenderItemPrivate void updateToolBox() { if (toolbox && dragger && toolboxLayout) { - kDebug() << "updating toolbox"; //clean the layout. uint iconHeight = dragger->elementSize("hint-preferred-icon-size").height(); @@ -651,11 +650,9 @@ void ExtenderItem::mousePressEvent(QGraphicsSceneMouseEvent *event) parentApplet->raise(); setZValue(parentApplet->zValue()); - d->extender->d->removeExtenderItem(this); - if (d->extender) { d->extender->itemHoverEnterEvent(this); - d->extender->itemHoverMoveEvent(this, d->extender->mapFromScene(event->scenePos())); + //d->extender->itemHoverMoveEvent(this, d->extender->mapFromScene(event->scenePos())); } //call the move event, since that spawns a toplevel view when this extender item is in a @@ -663,13 +660,13 @@ void ExtenderItem::mousePressEvent(QGraphicsSceneMouseEvent *event) //able to receive any move events. mouseMoveEvent(event); + d->extender->d->removeExtenderItem(this); + QApplication::setOverrideCursor(Qt::ClosedHandCursor); } void ExtenderItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { - Q_UNUSED(event); - if (!d->mousePressed) { return; } @@ -684,6 +681,8 @@ void ExtenderItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) screenRect.setTopLeft(event->screenPos() - d->mousePos); screenRect.setSize(d->screenRect().size()); + Corona *corona = d->hostApplet()->containment()->corona(); + if (d->leaveCurrentView(screenRect)) { //we're moving the applet to a toplevel view, so place it somewhere out of sight //first: in the topleft quadrant. @@ -691,14 +690,9 @@ void ExtenderItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) if (!d->toplevel) { //XXX duplication from applethandle //create a toplevel view and aim it at the applet. - Corona *corona = d->hostApplet()->containment()->corona(); d->toplevel = new QGraphicsView(corona, 0); - //TODO: use addOffscreenWidget - if (sceneBoundingRect().left() > 0) { - setParentItem(0); - //only move to topleft quadrant if it isn't there allready. - setPos(-12000, -12000); - } + + corona->addOffscreenWidget(this); d->toplevel->setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); @@ -721,6 +715,7 @@ void ExtenderItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) d->toplevel->setSceneRect(sceneBoundingRect()); d->toplevel->setGeometry(screenRect); } else { + corona->removeOffscreenWidget(this); setParentItem(d->hostApplet()); setPos(d->deltaScene); @@ -739,7 +734,6 @@ void ExtenderItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) //find the extender we're hovering over. Extender *targetExtender = 0; - Corona *corona = qobject_cast(scene()); foreach (Containment *containment, corona->containments()) { foreach (Applet *applet, containment->applets()) { if (applet->extender() && (applet->sceneBoundingRect().contains(mousePos) @@ -813,6 +807,9 @@ void ExtenderItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) //find the extender we're hovering over. Extender *targetExtender = 0; Corona *corona = qobject_cast(scene()); + + corona->removeOffscreenWidget(this); + foreach (Containment *containment, corona->containments()) { foreach (Applet *applet, containment->applets()) { if (applet->extender() && (applet->sceneBoundingRect().contains(mousePos) diff --git a/popupapplet.cpp b/popupapplet.cpp index ea7d2b441..5f3e936fb 100644 --- a/popupapplet.cpp +++ b/popupapplet.cpp @@ -62,6 +62,7 @@ public: void togglePopup(); void hideTimedPopup(); + void dialogSizeChanged(); PopupApplet *q; Plasma::Icon *icon; @@ -207,6 +208,7 @@ void PopupApplet::constraintsEvent(Plasma::Constraints constraints) if (!d->dialog) { d->dialog = new Plasma::Dialog(); d->dialog->setWindowFlags(Qt::Popup); + connect(d->dialog, SIGNAL(dialogResized()), this, SLOT(dialogSizeChanged())); if (graphicsWidget()) { Corona *corona = qobject_cast(graphicsWidget()->scene()); @@ -241,7 +243,6 @@ void PopupApplet::constraintsEvent(Plasma::Constraints constraints) void PopupApplet::showPopup(uint popupDuration) { if (d->dialog && (formFactor() == Horizontal || formFactor() == Vertical)) { - d->dialog->adjustView(); d->dialog->move(popupPosition(d->dialog->size())); d->dialog->show(); @@ -269,24 +270,13 @@ void PopupApplet::hidePopup() void PopupApplet::widgetGeometryChanged() { - if (graphicsWidget()) { + if (graphicsWidget() && layout()) { //sizes are recalculated in the constraintsevent so let's just call that. - if (layout()) { - constraintsEvent(Plasma::FormFactorConstraint); + constraintsEvent(Plasma::FormFactorConstraint); - //resize vertically if necesarry. - if (formFactor() == Plasma::MediaCenter || formFactor() == Plasma::Planar) { - resize(QSizeF(size().width(), minimumHeight())); - } else { - if (graphicsWidget()) { - graphicsWidget()->resize(graphicsWidget()->minimumSize()); - graphicsWidget()->update(); - } - if (d->dialog) { - d->dialog->adjustView(); - d->dialog->move(popupPosition(d->dialog->size())); - } - } + //resize vertically if necesarry. + if (formFactor() == Plasma::MediaCenter || formFactor() == Plasma::Planar) { + resize(QSizeF(size().width(), minimumHeight())); } } } @@ -297,7 +287,7 @@ void PopupAppletPrivate::togglePopup() if (dialog->isVisible()) { dialog->hide(); } else { - dialog->move(q->popupPosition(dialog->sizeHint())); + dialog->move(q->popupPosition(dialog->size())); dialog->show(); } @@ -311,6 +301,15 @@ void PopupAppletPrivate::hideTimedPopup() q->hidePopup(); } +void PopupAppletPrivate::dialogSizeChanged() +{ + //Reposition the dialog. + if (dialog) { + dialog->updateGeometry(); + dialog->move(q->popupPosition(dialog->size())); + } +} + } // Plasma namespace #include "popupapplet.moc" diff --git a/popupapplet.h b/popupapplet.h index da9fca774..6c489a908 100644 --- a/popupapplet.h +++ b/popupapplet.h @@ -106,6 +106,7 @@ protected: private: Q_PRIVATE_SLOT(d, void togglePopup()) Q_PRIVATE_SLOT(d, void hideTimedPopup()) + Q_PRIVATE_SLOT(d, void dialogSizeChanged()) PopupAppletPrivate * const d; };