aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickpopup.cpp
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2016-04-23 20:26:35 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2016-04-25 03:48:09 +0000
commit99fa43b3708d6615e17d0cc5561aca78a9c72d1a (patch)
treea8891fc183b5da10eb53d14184d9c789f51d49fc /src/quicktemplates2/qquickpopup.cpp
parentdd0a29bb332b8ed0acfdf72ab2072be3bbd84006 (diff)
Promote QQuickToolTip's repositioning code to QQuickPopup
QQuickToolTip already had repositioning implemented for both horizontal and vertical directions. Promote that code up to QQuickPopup so that QQuickMenu gets properly repositioned when used as a context menu. As special cases, QQuickComboBox enables vertical flipping for its popup, and QQuickToolTip enables both. In the QQuickPopup base class, both are disabled by default. Task-number: QTBUG-52608 Change-Id: Ia8f835321222d4841a6f79434822b33f057d13fc Reviewed-by: Mitch Curtis <mitch.curtis@theqtcompany.com>
Diffstat (limited to 'src/quicktemplates2/qquickpopup.cpp')
-rw-r--r--src/quicktemplates2/qquickpopup.cpp77
1 files changed, 59 insertions, 18 deletions
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index 2ca16b29..13e562d0 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -127,6 +127,8 @@ QQuickPopupPrivate::QQuickPopupPrivate()
, hasLeftMargin(false)
, hasRightMargin(false)
, hasBottomMargin(false)
+ , allowVerticalFlip(false)
+ , allowHorizontalFlip(false)
, x(0)
, y(0)
, margins(0)
@@ -532,7 +534,9 @@ void QQuickPopupPrivate::reposition()
const qreal iw = popupItem->implicitWidth();
const qreal ih = popupItem->implicitHeight();
- bool adjusted = false;
+ bool widthAdjusted = false;
+ bool heightAdjusted = false;
+
QRectF rect(x, y, iw > 0 ? iw : w, ih > 0 ? ih : h);
if (parentItem) {
rect = parentItem->mapRectToScene(rect);
@@ -552,33 +556,70 @@ void QQuickPopupPrivate::reposition()
if (margins.right() > 0 && rect.right() > bounds.right())
rect.moveRight(bounds.right());
+ if (rect.left() < bounds.left() || rect.right() > bounds.right()) {
+ if (allowHorizontalFlip) {
+ // if the tooltip doesn't fit inside the window, try flipping it around (left <-> right)
+ const QRectF flipped = parentItem->mapRectToScene(QRectF(parentItem->width() - x - rect.width(), y, rect.width(), rect.height()));
+
+ if (flipped.intersected(bounds).width() > rect.intersected(bounds).width())
+ rect.moveLeft(flipped.left());
+ }
+
+ if (iw > 0) {
+ // neither the flipped around geometry fits inside the window, choose
+ // whichever side (left vs. right) fits larger part of the popup
+ if (rect.left() < bounds.left() && bounds.left() + rect.width() <= bounds.right())
+ rect.moveLeft(bounds.left());
+ else if (rect.right() > bounds.right() && bounds.right() - rect.width() >= bounds.left())
+ rect.moveRight(bounds.right());
+
+ // as a last resort, adjust width to fit the window
+ if (rect.left() < bounds.left()) {
+ rect.setLeft(bounds.left());
+ widthAdjusted = true;
+ }
+ if (rect.right() > bounds.right()) {
+ rect.setRight(bounds.right());
+ widthAdjusted = true;
+ }
+ }
+ }
+
if (rect.top() < bounds.top() || rect.bottom() > bounds.bottom()) {
- // if the popup doesn't fit inside the window, try flipping it around (below <-> above)
- const QRectF flipped = parentItem->mapRectToScene(QRectF(x, parentItem->height() - y - rect.height(), rect.width(), rect.height()));
- if (flipped.top() >= bounds.top() && flipped.bottom() < bounds.bottom()) {
- adjusted = true;
- rect = flipped;
- } else if (ih > 0) {
+ if (allowVerticalFlip) {
+ // if the tooltip doesn't fit inside the window, try flipping it around (above <-> below)
+ const QRectF flipped = parentItem->mapRectToScene(QRectF(x, parentItem->height() - y - rect.height(), rect.width(), rect.height()));
+
+ if (flipped.intersected(bounds).height() > rect.intersected(bounds).height())
+ rect.moveTop(flipped.top());
+ }
+
+ if (ih > 0) {
// neither the flipped around geometry fits inside the window, choose
// whichever side (above vs. below) fits larger part of the popup
- const QRectF primary = rect.intersected(bounds);
- const QRectF secondary = flipped.intersected(bounds);
-
- if (primary.height() > secondary.height()) {
- rect.setY(primary.y());
- rect.setHeight(primary.height());
- } else {
- rect.setY(secondary.y());
- rect.setHeight(secondary.height());
+ if (rect.top() < bounds.top() && bounds.top() + rect.height() <= bounds.bottom())
+ rect.moveTop(bounds.top());
+ else if (rect.bottom() > bounds.bottom() && bounds.bottom() - rect.height() >= bounds.top())
+ rect.moveBottom(bounds.bottom());
+
+ // as a last resort, adjust height to fit the window
+ if (rect.top() < bounds.top()) {
+ rect.setTop(bounds.top());
+ heightAdjusted = true;
+ }
+ if (rect.bottom() > bounds.bottom()) {
+ rect.setBottom(bounds.bottom());
+ heightAdjusted = true;
}
- adjusted = true;
}
}
}
}
popupItem->setPosition(rect.topLeft());
- if (adjusted && ih > 0)
+ if (widthAdjusted && rect.width() > 0)
+ popupItem->setWidth(rect.width());
+ if (heightAdjusted && rect.height() > 0)
popupItem->setHeight(rect.height());
}