implement popupPosition

call it only by setting a visualParent, don't expose it to qml for now
This commit is contained in:
Marco Martin 2013-02-20 20:39:15 +01:00
parent a1507092a0
commit de81cdada3
3 changed files with 84 additions and 99 deletions

View File

@ -28,6 +28,7 @@
#include <QQuickItem>
#include <QTimer>
#include <QLayout>
#include <QScreen>
#include <KWindowSystem>
@ -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,73 +214,21 @@ 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<QQuickItem *>(parent());
//search the root object
while (true) {
QQuickItem *ancestor = qobject_cast<QQuickItem *>(actualItem->parent());
if (ancestor) {
actualItem = ancestor;
} else {
break;
}
}
if (!actualItem) {
return QPoint();
}
}
//m_dialog->syncToGraphicsWidget();
Plasma::Corona *corona = qobject_cast<Plasma::Corona *>(actualItem->scene());
if (corona && item) {
return corona->popupPosition(actualItem, m_dialog->size(), (Qt::AlignmentFlag)alignment);
} else {
if (!actualItem->scene()) {
return QPoint();
}
QList<QGraphicsView*> views = actualItem->scene()->views();
if (views.size() < 1) {
return QPoint();
}
QGraphicsView *view = 0;
if (views.size() == 1) {
view = views[0];
} 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);
//If no item was specified try to align at the center of the parent view
QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
if (parentItem && parentItem->window()) {
return parentItem->window()->geometry().center() - QPoint(width()/2, height()/2);
} else {
return QPoint();
}
}
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
@ -271,21 +243,18 @@ QPoint DialogProxy::popupPosition(QQuickItem *item, int alignment)
int xOffset = 0;
if (alignment == Qt::AlignCenter) {
xOffset = actualItem->boundingRect().width()/2 - m_dialog->width()/2;
xOffset = item->boundingRect().width()/2 - width()/2;
} else if (alignment == Qt::AlignRight) {
xOffset = actualItem->boundingRect().width() - m_dialog->width();
xOffset = item->boundingRect().width() - width();
}
const QRect avail = QApplication::desktop()->availableGeometry(view);
QPoint menuPos = view->mapToGlobal(view->mapFromScene(actualItem->scenePos()+QPoint(xOffset, actualItem->boundingRect().height())));
const QRect avail = item->window()->screen()->availableGeometry();
QPoint menuPos = pos.toPoint() + QPoint(xOffset, item->boundingRect().height());
if (menuPos.y() + m_dialog->height() > avail.bottom()) {
menuPos = view->mapToGlobal(view->mapFromScene(actualItem->scenePos() - QPoint(-xOffset, m_dialog->height())));
if (menuPos.y() + height() > avail.bottom()) {
menuPos = pos.toPoint() + QPoint(xOffset, -height());
}
return menuPos;
}
*/
return QPoint(200, 400);
}

View File

@ -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<QQuickItem> m_mainItem;
QWeakPointer<QQuickItem> m_visualParent;
DialogMargins *m_margins;
bool m_activeWindow;
Plasma::Location m_location;

View File

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