From de81cdada3ea992df0975f5d5e8728ccb06fd30a Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Wed, 20 Feb 2013 20:39:15 +0100 Subject: [PATCH] implement popupPosition call it only by setting a visualParent, don't expose it to qml for now --- src/declarativeimports/core/dialog.cpp | 153 +++++++----------- src/declarativeimports/core/dialog.h | 12 +- .../desktop/contents/ui/CompactApplet.qml | 18 ++- 3 files changed, 84 insertions(+), 99 deletions(-) diff --git a/src/declarativeimports/core/dialog.cpp b/src/declarativeimports/core/dialog.cpp index 3c4cdb02d..75e2c167f 100644 --- a/src/declarativeimports/core/dialog.cpp +++ b/src/declarativeimports/core/dialog.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -166,6 +167,25 @@ void DialogProxy::setMainItem(QQuickItem *mainItem) } } +QQuickItem *DialogProxy::visualParent() const +{ + return m_visualParent.data(); +} + +void DialogProxy::setVisualParent(QQuickItem *visualParent) +{ + if (m_visualParent.data() == visualParent) { + return; + } + + if (visualParent) { + setPosition(popupPosition(visualParent, Qt::AlignCenter)); + } + + m_visualParent = visualParent; + emit visualParentChanged(); +} + bool DialogProxy::isVisible() const { return QQuickWindow::isVisible(); @@ -176,6 +196,10 @@ void DialogProxy::setVisible(const bool visible) if (visible) { syncToMainItemSize(); + if (m_visualParent) { + setPosition(popupPosition(m_visualParent.data(), Qt::AlignCenter)); + } + const QRect workArea(KWindowSystem::workArea()); if (!workArea.contains(geometry())) { setPosition(qBound(workArea.left(), x(), workArea.right() - width()), @@ -190,102 +214,47 @@ void DialogProxy::setVisible(const bool visible) QPoint DialogProxy::popupPosition(QQuickItem *item, int alignment) { - /* - QQuickItem *actualItem = item; - - //if no item is passed search the root item in order to figure out the view - if (!actualItem) { - actualItem = qobject_cast(parent()); - - //search the root object - while (true) { - QQuickItem *ancestor = qobject_cast(actualItem->parent()); - - if (ancestor) { - actualItem = ancestor; - } else { - break; - } - } - if (!actualItem) { - return QPoint(); - } - } - - //m_dialog->syncToGraphicsWidget(); - - Plasma::Corona *corona = qobject_cast(actualItem->scene()); - if (corona && item) { - return corona->popupPosition(actualItem, m_dialog->size(), (Qt::AlignmentFlag)alignment); - } else { - - if (!actualItem->scene()) { - return QPoint(); - } - - QList views = actualItem->scene()->views(); - - - if (views.size() < 1) { - return QPoint(); - } - - QGraphicsView *view = 0; - if (views.size() == 1) { - view = views[0]; + if (!item) { + //If no item was specified try to align at the center of the parent view + QQuickItem *parentItem = qobject_cast(parent()); + if (parentItem && parentItem->window()) { + return parentItem->window()->geometry().center() - QPoint(width()/2, height()/2); } else { - QGraphicsView *found = 0; - QGraphicsView *possibleFind = 0; - - foreach (QGraphicsView *v, views) { - if (v->sceneRect().intersects(actualItem->sceneBoundingRect()) || - v->sceneRect().contains(actualItem->scenePos())) { - if (v->isActiveWindow()) { - found = v; - } else { - possibleFind = v; - } - } - } - view = found ? found : possibleFind; - } - - if (!view) { return QPoint(); } - - //if no item was explicitly specified, align the dialog in the center of the parent view - if (!item) { - return view->geometry().center() - QPoint(m_dialog->width()/2, m_dialog->height()/2); - } - - //swap direction if necessary - if (QApplication::isRightToLeft() && alignment != Qt::AlignCenter) { - if (alignment == Qt::AlignRight) { - alignment = Qt::AlignLeft; - } else { - alignment = Qt::AlignRight; - } - } - - int xOffset = 0; - - if (alignment == Qt::AlignCenter) { - xOffset = actualItem->boundingRect().width()/2 - m_dialog->width()/2; - } else if (alignment == Qt::AlignRight) { - xOffset = actualItem->boundingRect().width() - m_dialog->width(); - } - - const QRect avail = QApplication::desktop()->availableGeometry(view); - QPoint menuPos = view->mapToGlobal(view->mapFromScene(actualItem->scenePos()+QPoint(xOffset, actualItem->boundingRect().height()))); - - if (menuPos.y() + m_dialog->height() > avail.bottom()) { - menuPos = view->mapToGlobal(view->mapFromScene(actualItem->scenePos() - QPoint(-xOffset, m_dialog->height()))); - } - return menuPos; } - */ - return QPoint(200, 400); + + QPointF pos = item->mapToScene(QPointF(0, 0)); + if (item->window() && item->window()->screen()) { + pos = item->window()->mapToGlobal(pos.toPoint()); + } else { + return QPoint(); + } + + //swap direction if necessary + if (QApplication::isRightToLeft() && alignment != Qt::AlignCenter) { + if (alignment == Qt::AlignRight) { + alignment = Qt::AlignLeft; + } else { + alignment = Qt::AlignRight; + } + } + + int xOffset = 0; + + if (alignment == Qt::AlignCenter) { + xOffset = item->boundingRect().width()/2 - width()/2; + } else if (alignment == Qt::AlignRight) { + xOffset = item->boundingRect().width() - width(); + } + + const QRect avail = item->window()->screen()->availableGeometry(); + QPoint menuPos = pos.toPoint() + QPoint(xOffset, item->boundingRect().height()); + + if (menuPos.y() + height() > avail.bottom()) { + menuPos = pos.toPoint() + QPoint(xOffset, -height()); + } + return menuPos; } diff --git a/src/declarativeimports/core/dialog.h b/src/declarativeimports/core/dialog.h index 0fb80c081..2a5ab65c2 100644 --- a/src/declarativeimports/core/dialog.h +++ b/src/declarativeimports/core/dialog.h @@ -100,6 +100,11 @@ class DialogProxy : public QQuickWindow */ Q_PROPERTY(QQuickItem *mainItem READ mainItem WRITE setMainItem NOTIFY mainItemChanged) + /** + * The main QML item that will be displayed in the Dialog + */ + Q_PROPERTY(QQuickItem *visualParent READ visualParent WRITE setVisualParent NOTIFY visualParentChanged) + /** * Visibility of the Dialog window. Doesn't have anything to do with the visibility of the mainItem. */ @@ -146,6 +151,9 @@ public: QQuickItem *mainItem() const; void setMainItem(QQuickItem *mainItem); + QQuickItem *visualParent() const; + void setVisualParent(QQuickItem *visualParent); + bool isVisible() const; void setVisible(const bool visible); @@ -176,7 +184,7 @@ public: * @arg alignment alignment of the popup compared to the item */ //FIXME: alignment should be Qt::AlignmentFlag - Q_INVOKABLE QPoint popupPosition(QQuickItem *item, int alignment=Qt::AlignLeft) ; + QPoint popupPosition(QQuickItem *item, int alignment=Qt::AlignLeft) ; /** * Set a Qt.WidgetAttribute to the dialog window @@ -192,6 +200,7 @@ Q_SIGNALS: void visibleChanged(); void activeWindowChanged(); void locationChanged(); + void visualParentChanged(); private Q_SLOTS: void syncToMainItemSize(); @@ -206,6 +215,7 @@ private: Qt::WindowFlags m_flags; QTimer *m_syncTimer; QWeakPointer m_mainItem; + QWeakPointer m_visualParent; DialogMargins *m_margins; bool m_activeWindow; Plasma::Location m_location; diff --git a/src/shell/qmlpackages/desktop/contents/ui/CompactApplet.qml b/src/shell/qmlpackages/desktop/contents/ui/CompactApplet.qml index 6e7e842e7..dca851933 100644 --- a/src/shell/qmlpackages/desktop/contents/ui/CompactApplet.qml +++ b/src/shell/qmlpackages/desktop/contents/ui/CompactApplet.qml @@ -44,12 +44,7 @@ Item { //windowFlags: Qt.Popup color: Qt.rgba(0,0,0,0) visible: plasmoid.expanded - onVisibleChanged: { - if (!visible) { - plasmoid.expanded = false - } - } - + visualParent: root mainItem: Rectangle { id: appletParent radius: 5 @@ -58,5 +53,16 @@ Item { onWidthChanged: applet.width = width onHeightChanged: applet.height = height } + + onActiveWindowChanged: { + if (!activeWindow) { + plasmoid.expanded = false + } + } + onVisibleChanged: { + if (!visible) { + plasmoid.expanded = false + } + } } }