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:
parent
20af95eee1
commit
1bae884531
14
corona.cpp
14
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<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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
26
dialog.cpp
26
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 ||
|
||||
|
9
dialog.h
9
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
|
||||
*/
|
||||
|
21
extender.cpp
21
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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user