From 22796e978d731b81454ab273ed1fa09b94727f6e Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 26 Mar 2015 16:48:16 +0100 Subject: [PATCH] function to adjust a rect to availableScreenRect Given a geometry, it adjusts it moving it completely inside of the boundaries of availableScreenRegion, returning the topLeft point of the adjusted rectangle reviewed-by: David Edmundson Change-Id: Ib58cbf521d5def1cd5bb34fe90366d4b628f8a89 CCBUG:345401 CCBUG:345002 --- .../qml/plasmoid/containmentinterface.cpp | 101 ++++++++++++++++++ .../qml/plasmoid/containmentinterface.h | 7 ++ 2 files changed, 108 insertions(+) diff --git a/src/scriptengines/qml/plasmoid/containmentinterface.cpp b/src/scriptengines/qml/plasmoid/containmentinterface.cpp index 6bc0eff68..6ac7d7df5 100644 --- a/src/scriptengines/qml/plasmoid/containmentinterface.cpp +++ b/src/scriptengines/qml/plasmoid/containmentinterface.cpp @@ -311,6 +311,107 @@ QPointF ContainmentInterface::mapToApplet(AppletInterface *applet, int x, int y) return pos - applet->mapToScene(QPointF(0, 0)); } +QPointF ContainmentInterface::adjustToAvailableScreenRegion(int x, int y, int w, int h) const +{ + QRegion reg = QRect(0, 0, width(), height()); + int screenId = screen(); + if (screenId > -1 && m_containment->corona()) { + reg = m_containment->corona()->availableScreenRegion(screenId); + } + + const QRect rect(qBound(reg.boundingRect().left(), x, reg.boundingRect().right() - w), + qBound(reg.boundingRect().top(), y, reg.boundingRect().bottom() - h), w, h); + const QRectF ar = availableScreenRect(); + QRect tempRect(rect); + + // in the case we are in the topleft quadrant + // * see if the passed rect is completely in the region, if yes, return + // * otherwise, try to move it horizontally to the screenrect x + // * if now fits, return + // * if fail, move vertically + // * as last resort, move horizontally and vertically + + // top left corner + if (rect.center().x() <= ar.center().x() && rect.center().y() <= ar.center().y()) { + //QRegion::contains doesn't do what it would suggest, so do reg.intersected(rect) != rect instead + if (reg.intersected(rect) != rect) { + tempRect = QRect(qMax(rect.left(), (int)ar.left()), rect.top(), w, h); + if (reg.intersected(tempRect) == tempRect) { + return tempRect.topLeft(); + } + + tempRect = QRect(rect.left(), qMax(rect.top(), (int)ar.top()), w, h); + if (reg.intersected(tempRect) == tempRect) { + return tempRect.topLeft(); + } + + tempRect = QRect(qMax(rect.left(), (int)ar.left()), qMax(rect.top(), (int)ar.top()), w, h); + return tempRect.topLeft(); + } else { + return rect.topLeft(); + } + + //bottom left corner + } else if (rect.center().x() <= ar.center().x() && rect.center().y() > ar.center().y()) { + if (reg.intersected(rect) != rect) { + tempRect = QRect(qMax(rect.left(), (int)ar.left()), rect.top(), w, h); + if (reg.intersected(tempRect) == tempRect) { + return tempRect.topLeft(); + } + + tempRect = QRect(rect.left(), qMin(rect.top(), (int)(ar.bottom() - h)), w, h); + if (reg.intersected(tempRect) == tempRect) { + return tempRect.topLeft(); + } + + tempRect = QRect(qMax(rect.left(), (int)ar.left()), qMin(rect.top(), (int)(ar.bottom() - h)), w, h); + return tempRect.topLeft(); + } else { + return rect.topLeft(); + } + + //top right corner + } else if (rect.center().x() > ar.center().x() && rect.center().y() <= ar.center().y()) { + if (reg.intersected(rect) != rect) { + tempRect = QRect(qMin(rect.left(), (int)(ar.right() - w)), rect.top(), w, h); + if (reg.intersected(tempRect) == tempRect) { + return tempRect.topLeft(); + } + + tempRect = QRect(rect.left(), qMax(rect.top(), (int)ar.top()), w, h); + if (reg.intersected(tempRect) == tempRect) { + return tempRect.topLeft(); + } + + tempRect = QRect(qMin(rect.left(), (int)(ar.right() - w)), qMax(rect.top(), (int)ar.top()), w, h); + return tempRect.topLeft(); + } else { + return rect.topLeft(); + } + + //bottom right corner + } else if (rect.center().x() > ar.center().x() && rect.center().y() > ar.center().y()) { + if (reg.intersected(rect) != rect) { + tempRect = QRect(qMin(rect.left(), (int)(ar.right() - w)), rect.top(), w, h); + if (reg.intersected(tempRect) == tempRect) { + return tempRect.topLeft(); + } + + tempRect = QRect(rect.left(), qMin(rect.top(), (int)(ar.bottom() - h)), w, h); + if (reg.intersected(tempRect) == tempRect) { + return tempRect.topLeft(); + } + + tempRect = QRect(qMin(rect.left(), (int)(ar.right() - w)), qMin(rect.top(), (int)(ar.bottom() - h)), w, h); + return tempRect.topLeft(); + } else { + return rect.topLeft(); + } + } + + return rect.topLeft(); +} + void ContainmentInterface::processMimeData(QObject *mimeDataProxy, int x, int y) { QMimeData* mime = qobject_cast(mimeDataProxy); diff --git a/src/scriptengines/qml/plasmoid/containmentinterface.h b/src/scriptengines/qml/plasmoid/containmentinterface.h index 9248c6c3c..120679f4f 100644 --- a/src/scriptengines/qml/plasmoid/containmentinterface.h +++ b/src/scriptengines/qml/plasmoid/containmentinterface.h @@ -149,6 +149,13 @@ public: */ Q_INVOKABLE QPointF mapToApplet(AppletInterface *applet, int x, int y); + /** + * Given a geometry, it adjusts it moving it completely inside of the boundaries + * of availableScreenRegion + * @return the toLeft point of the rectangle + */ + Q_INVOKABLE QPointF adjustToAvailableScreenRegion(int x, int y, int w, int h) const; + static ContainmentInterface *qmlAttachedProperties(QObject *object) { return qobject_cast(AppletQuickItem::qmlAttachedProperties(object));