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
This commit is contained in:
Rob Scheepmaker 2008-08-28 14:32:48 +00:00
parent 20af95eee1
commit 1bae884531
7 changed files with 74 additions and 57 deletions

View File

@ -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<QGraphicsWidget*>(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<QGraphicsWidget*>(d->offscreenLayout->itemAt(i));
if (foundWidget == widget) {
d->offscreenLayout->removeAt(i);
d->offscreenLayout->invalidate();
}
}
}

View File

@ -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 ||

View File

@ -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
*/

View File

@ -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);
}

View File

@ -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<Corona*>(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<Corona*>(scene());
corona->removeOffscreenWidget(this);
foreach (Containment *containment, corona->containments()) {
foreach (Applet *applet, containment->applets()) {
if (applet->extender() && (applet->sceneBoundingRect().contains(mousePos)

View File

@ -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<Corona *>(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"

View File

@ -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;
};