aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@qt.io>2019-02-18 11:28:58 +0100
committerMitch Curtis <mitch.curtis@qt.io>2019-03-15 10:23:01 +0000
commit8b78d9cea3091b0bd94d1ae0c71a000f8e7e1903 (patch)
tree8e9247dca2d2cd18cc37ae1d244c1609411eb742 /src
parent9a7c88bf7c225897751e6e3abdff8e30aa442bce (diff)
Fix DialogButtonBox content size calculation
Some history: - f1f884d3 worked around an issue in DialogButtonBox. - c2fd8f7d fixed it by using contentWidth; i.e. the implicit width of the contentItem. It caused QTBUG-72372. - I tried to fix QTBUG-72372 with 6476de0b, but created (or exposed) QTBUG-73860. The problem in QTBUG-73860 can be seen with the following example: Dialog { id: dialog visible: true standardButtons: Dialog.Ok } The single 'Ok' button here will go outside of the dialog. The underlying issue can be seen by looking into DialogButtonBox.qml: implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, (control.count === 1 ? contentWidth * 2 : contentWidth) + leftPadding + rightPadding) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, contentHeight + topPadding + bottomPadding) The implicit width of the box in this case is contentWidth * 2 (there is one button, so control.count === 1). This should result in the button taking half the width of the box and being aligned to the right: alignment: count === 1 ? Qt.AlignRight : undefined ... delegate: Button { width: control.count === 1 ? control.availableWidth / 2 : undefined } What actually happens is that the contentItem (ListView) is temporarily 0 until it gets its final size of 100. However, QQuickDialogButtonBox doesn't respond to this change in the ListView's contentWidth. This problem can be fixed by returning to c2fd8f7d's resizeContent() implementation, which uses contentWidth. Then, there is a second issue: Dialog { id: dialog visible: true standardButtons: Dialog.Ok width: 300 } The button here is also positioned outside of the box. The problem is that the contentWidth is based on implicitContentWidth: QQuickContainerPrivate::updateContentWidth() { // ... contentWidth = implicitContentWidth; // ... } implicitContentWidth is calculated by calling getContentWidth(): void QQuickControlPrivate::updateImplicitContentWidth() { // ... implicitContentWidth = getContentWidth(); // ... } In the case of horizontal alignment, QQuickDialogButtonBoxPrivate::getContentWidth() uses the implicit width of the largest button: for (int i = 0; i < count; ++i) { QQuickItem *item = q->itemAt(i); if (item) { totalWidth += item->implicitWidth(); maxWidth = qMax(maxWidth, item->implicitWidth()); } } // ... if ((alignment & Qt::AlignHorizontal_Mask) == 0) totalWidth = qMax(totalWidth, count * maxWidth + totalSpacing); The Default style button has an implicitWidth of 100. The DialogButtonBox in the example above is 300 pixels wide, so the button should be 150, and it is, thanks to its width binding. However, the DialogButtonBox uses contentWidth to size its contentItem (ListView), and the contentWidth is, as mentioned, 100: the implicit width of the button. So, the button ends up hanging over the side of the box, as it's larger than the box thinks it is. This problem is fixed by setting DialogButtonBox's contentWidth to the contentWidth of the contentItem (ListView). This makes DialogButtonBox use the explicit widths of the buttons rather than their implicit widths. Since the contentWidth is no longer implicit, we must also change any use of contentWidth in the implicitWidth binding to implicitContentWidth. While writing auto tests for this, they caught an issue where contentWidth wasn't updated, so now we call resizeContent() in QQuickContainer::setContentWidth(). Change-Id: I99ffda21b47aeb14d4382e453e87c4312f343a1c Fixes: QTBUG-72886 Fixes: QTBUG-73860 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/imports/controls/DialogButtonBox.qml5
-rw-r--r--src/imports/controls/universal/DialogButtonBox.qml5
-rw-r--r--src/quicktemplates2/qquickcontainer.cpp2
-rw-r--r--src/quicktemplates2/qquickdialogbuttonbox.cpp7
4 files changed, 10 insertions, 9 deletions
diff --git a/src/imports/controls/DialogButtonBox.qml b/src/imports/controls/DialogButtonBox.qml
index 1b783b3b..3c9d5b48 100644
--- a/src/imports/controls/DialogButtonBox.qml
+++ b/src/imports/controls/DialogButtonBox.qml
@@ -41,9 +41,10 @@ T.DialogButtonBox {
id: control
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
- (control.count === 1 ? contentWidth * 2 : contentWidth) + leftPadding + rightPadding)
+ (control.count === 1 ? implicitContentWidth * 2 : implicitContentWidth) + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
- contentHeight + topPadding + bottomPadding)
+ implicitContentHeight + topPadding + bottomPadding)
+ contentWidth: contentItem.contentWidth
spacing: 1
padding: 12
diff --git a/src/imports/controls/universal/DialogButtonBox.qml b/src/imports/controls/universal/DialogButtonBox.qml
index ac2dc541..0458c39d 100644
--- a/src/imports/controls/universal/DialogButtonBox.qml
+++ b/src/imports/controls/universal/DialogButtonBox.qml
@@ -43,9 +43,10 @@ T.DialogButtonBox {
id: control
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
- (control.count === 1 ? contentWidth * 2 : contentWidth) + leftPadding + rightPadding)
+ (control.count === 1 ? implicitContentWidth * 2 : implicitContentWidth) + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
- contentHeight + topPadding + bottomPadding)
+ implicitContentHeight + topPadding + bottomPadding)
+ contentWidth: contentItem.contentWidth
spacing: 4
padding: 24
diff --git a/src/quicktemplates2/qquickcontainer.cpp b/src/quicktemplates2/qquickcontainer.cpp
index c4af6151..2c357f82 100644
--- a/src/quicktemplates2/qquickcontainer.cpp
+++ b/src/quicktemplates2/qquickcontainer.cpp
@@ -793,6 +793,7 @@ void QQuickContainer::setContentWidth(qreal width)
return;
d->contentWidth = width;
+ d->resizeContent();
emit contentWidthChanged();
}
@@ -832,6 +833,7 @@ void QQuickContainer::setContentHeight(qreal height)
return;
d->contentHeight = height;
+ d->resizeContent();
emit contentHeightChanged();
}
diff --git a/src/quicktemplates2/qquickdialogbuttonbox.cpp b/src/quicktemplates2/qquickdialogbuttonbox.cpp
index 8559ad15..03f5f8e8 100644
--- a/src/quicktemplates2/qquickdialogbuttonbox.cpp
+++ b/src/quicktemplates2/qquickdialogbuttonbox.cpp
@@ -241,11 +241,8 @@ void QQuickDialogButtonBoxPrivate::resizeContent()
return;
QRectF geometry = q->boundingRect().adjusted(q->leftPadding(), q->topPadding(), -q->rightPadding(), -q->bottomPadding());
- if (alignment != 0) {
- qreal cw = (alignment & Qt::AlignHorizontal_Mask) == 0 ? q->availableWidth() : contentItem->property("contentWidth").toReal();
- qreal ch = (alignment & Qt::AlignVertical_Mask) == 0 ? q->availableHeight() : contentItem->property("contentHeight").toReal();
- geometry = alignedRect(q->isMirrored() ? Qt::RightToLeft : Qt::LeftToRight, alignment, QSizeF(cw, ch), geometry);
- }
+ if (alignment != 0)
+ geometry = alignedRect(q->isMirrored() ? Qt::RightToLeft : Qt::LeftToRight, alignment, QSizeF(contentWidth, contentHeight), geometry);
contentItem->setPosition(geometry.topLeft());
contentItem->setSize(geometry.size());