aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickpopup.cpp
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2016-05-06 16:29:21 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2016-05-10 12:47:20 +0000
commit0935e65a50f8a90569e300021ccaafabbead4e79 (patch)
treed059e88341ad2bb25904abf216fe892431c4dc5a /src/quicktemplates2/qquickpopup.cpp
parent13bc1d6f34f6aa4425b318ea874270cd994ee336 (diff)
Popup: use margins to determine whether to push inside window bounds
Previously, we were planning to introduce complex policy flags to make it possible to specify whether a Popup is allowed to go outside the screen or not. Using margins for that purpose avoids the need of introducing such dedicated API just for that. From now on, margins are used to determine whether a popup is pushed to fit inside the window bounds (margins removed), and implicit size is used to determined whether a popup is resized to fit inside the window. In other words, a popup with negative margins and no implicit size is allowed to move outside the window bounds. Change-Id: Ife1665755e4dae434751977ae3289eb1aa4f3c6d Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/quicktemplates2/qquickpopup.cpp')
-rw-r--r--src/quicktemplates2/qquickpopup.cpp131
1 files changed, 70 insertions, 61 deletions
diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp
index f614c0af..2aa77aae 100644
--- a/src/quicktemplates2/qquickpopup.cpp
+++ b/src/quicktemplates2/qquickpopup.cpp
@@ -133,7 +133,7 @@ QQuickPopupPrivate::QQuickPopupPrivate()
, allowHorizontalFlip(false)
, x(0)
, y(0)
- , margins(0)
+ , margins(-1)
, topMargin(0)
, leftMargin(0)
, rightMargin(0)
@@ -560,71 +560,65 @@ void QQuickPopupPrivate::reposition()
const QMarginsF margins = getMargins();
const QRectF bounds = QRectF(0, 0, window->width(), window->height()).marginsRemoved(margins);
- // push inside the margins
- if (margins.top() > 0 && rect.top() < bounds.top())
+ // if the popup doesn't fit horizontally inside the window, try flipping it around (left <-> right)
+ if (allowHorizontalFlip && (rect.left() < bounds.left() || rect.right() > bounds.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 the popup doesn't fit vertically inside the window, try flipping it around (above <-> below)
+ if (allowVerticalFlip && (rect.top() < bounds.top() || rect.bottom() > bounds.bottom())) {
+ 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());
+ }
+
+ // push inside the margins if specified
+ if (margins.top() >= 0 && rect.top() < bounds.top())
rect.moveTop(margins.top());
- if (margins.bottom() > 0 && rect.bottom() > bounds.bottom())
+ if (margins.bottom() >= 0 && rect.bottom() > bounds.bottom())
rect.moveBottom(bounds.bottom());
- if (margins.left() > 0 && rect.left() < bounds.left())
+ if (margins.left() >= 0 && rect.left() < bounds.left())
rect.moveLeft(margins.left());
- if (margins.right() > 0 && rect.right() > bounds.right())
+ 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 && (rect.left() < bounds.left() || rect.right() > bounds.right())) {
+ // neither the flipped or pushed 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 the width to fit the window
+ if (rect.left() < bounds.left()) {
+ rect.setLeft(bounds.left());
+ widthAdjusted = true;
}
-
- 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.right() > bounds.right()) {
+ rect.setRight(bounds.right());
+ widthAdjusted = true;
}
}
- if (rect.top() < bounds.top() || rect.bottom() > bounds.bottom()) {
- 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 && (rect.top() < bounds.top() || rect.bottom() > bounds.bottom())) {
+ // neither the flipped or pushed geometry fits inside the window, choose
+ // whichever side (above vs. below) fits larger part of the popup
+ 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 the height to fit the window
+ if (rect.top() < bounds.top()) {
+ rect.setTop(bounds.top());
+ heightAdjusted = true;
}
-
- if (ih > 0) {
- // neither the flipped around geometry fits inside the window, choose
- // whichever side (above vs. below) fits larger part of the popup
- 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;
- }
+ if (rect.bottom() > bounds.bottom()) {
+ rect.setBottom(bounds.bottom());
+ heightAdjusted = true;
}
}
}
@@ -1027,6 +1021,9 @@ qreal QQuickPopup::availableHeight() const
This property holds the default margins around the popup.
+ A popup with negative margins is not pushed within the bounds
+ of the enclosing window. The default value is \c -1.
+
\sa topMargin, leftMargin, rightMargin, bottomMargin
*/
qreal QQuickPopup::margins() const
@@ -1057,7 +1054,7 @@ void QQuickPopup::setMargins(qreal margins)
void QQuickPopup::resetMargins()
{
- setMargins(0);
+ setMargins(-1);
}
/*!
@@ -1065,6 +1062,9 @@ void QQuickPopup::resetMargins()
This property holds the top margin around the popup.
+ A popup with a negative top margin is not pushed within the top edge
+ of the enclosing window. The default value is \c -1.
+
\sa margins, bottomMargin
*/
qreal QQuickPopup::topMargin() const
@@ -1084,7 +1084,7 @@ void QQuickPopup::setTopMargin(qreal margin)
void QQuickPopup::resetTopMargin()
{
Q_D(QQuickPopup);
- d->setTopMargin(0, true);
+ d->setTopMargin(-1, true);
}
/*!
@@ -1092,6 +1092,9 @@ void QQuickPopup::resetTopMargin()
This property holds the left margin around the popup.
+ A popup with a negative left margin is not pushed within the left edge
+ of the enclosing window. The default value is \c -1.
+
\sa margins, rightMargin
*/
qreal QQuickPopup::leftMargin() const
@@ -1111,7 +1114,7 @@ void QQuickPopup::setLeftMargin(qreal margin)
void QQuickPopup::resetLeftMargin()
{
Q_D(QQuickPopup);
- d->setLeftMargin(0, true);
+ d->setLeftMargin(-1, true);
}
/*!
@@ -1119,6 +1122,9 @@ void QQuickPopup::resetLeftMargin()
This property holds the right margin around the popup.
+ A popup with a negative right margin is not pushed within the right edge
+ of the enclosing window. The default value is \c -1.
+
\sa margins, leftMargin
*/
qreal QQuickPopup::rightMargin() const
@@ -1138,7 +1144,7 @@ void QQuickPopup::setRightMargin(qreal margin)
void QQuickPopup::resetRightMargin()
{
Q_D(QQuickPopup);
- d->setRightMargin(0, true);
+ d->setRightMargin(-1, true);
}
/*!
@@ -1146,6 +1152,9 @@ void QQuickPopup::resetRightMargin()
This property holds the bottom margin around the popup.
+ A popup with a negative bottom margin is not pushed within the bottom edge
+ of the enclosing window. The default value is \c -1.
+
\sa margins, topMargin
*/
qreal QQuickPopup::bottomMargin() const
@@ -1165,7 +1174,7 @@ void QQuickPopup::setBottomMargin(qreal margin)
void QQuickPopup::resetBottomMargin()
{
Q_D(QQuickPopup);
- d->setBottomMargin(0, true);
+ d->setBottomMargin(-1, true);
}
/*!