DialogButtonBox: workaround implicit size calculation with one button

When there's only one button in the dialog button box, the Default and
Universal styles resize the button to cover half of the button box.
This works in typical scenarios when the dialog button box is assigned
as a footer of a dialog, and thus, gets resized together with the
dialog. However, if the dialog button box is placed into a layout, or
otherwise not given an explicit size, the implicit size calculation
loops until it reaches zero.

 1) button box gets the implicit size of the content (one button)
 2) button box resizes the button to cover half of the box width
 3) button box re-calculates its implicit size => step 1

Avoid the problem by providing a reasonable hard-coded implicit size
for this special case.

Notice that this is just a temporary workaround to avoid the problem.
This can be fixed properly in dev by providing separate contentWidth
and contentHeight properties that cleanly propagate the content size
to QML.

Task-number: QTBUG-59719
Change-Id: I552e0824ae6bff26b570c699252a3e4f09bd3397
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
This commit is contained in:
J-P Nurmi 2017-11-08 14:56:29 +01:00
parent e80d273e6f
commit f1f884d353
5 changed files with 33 additions and 5 deletions

View File

@ -54,7 +54,7 @@ T.DialogButtonBox {
}
contentItem: ListView {
implicitWidth: contentWidth
implicitWidth: control.count === 1 ? 200 : contentWidth
implicitHeight: 40
model: control.contentModel

View File

@ -60,7 +60,7 @@ T.DialogButtonBox {
}
contentItem: ListView {
implicitWidth: contentWidth
implicitWidth: control.count === 1 ? 200 : contentWidth
implicitHeight: 32
model: control.contentModel

View File

@ -58,7 +58,7 @@ T.DialogButtonBox {
}
contentItem: ListView {
implicitWidth: contentWidth
implicitWidth: control.count === 1 ? 200 : contentWidth
implicitHeight: 32
model: control.contentModel

View File

@ -215,8 +215,8 @@ void QQuickDialogButtonBoxPrivate::resizeContent()
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->implicitWidth();
qreal ch = (alignment & Qt::AlignVertical_Mask) == 0 ? q->availableHeight() : contentItem->implicitHeight();
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);
}

View File

@ -195,4 +195,32 @@ TestCase {
compare(clickedSpy.signalArguments[0][0], button)
compare(roleSpy.count, 1)
}
function test_implicitSize_data() {
return [
{ tag: "Ok", standardButtons: DialogButtonBox.Ok },
{ tag: "Yes|No", standardButtons: DialogButtonBox.Yes | DialogButtonBox.No }
]
}
// QTBUG-59719
function test_implicitSize(data) {
var control = createTemporaryObject(buttonBox, testCase, {standardButtons: data.standardButtons})
verify(control)
var listView = control.contentItem
verify(listView && listView.hasOwnProperty("contentWidth"))
waitForRendering(listView)
var implicitContentWidth = control.leftPadding + control.rightPadding
for (var i = 0; i < listView.contentItem.children.length; ++i) {
var button = listView.contentItem.children[i]
if (!button.hasOwnProperty("text"))
continue
implicitContentWidth += button.implicitWidth
}
verify(implicitContentWidth > control.leftPadding + control.rightPadding)
verify(control.implicitWidth >= implicitContentWidth, qsTr("implicit width (%1) is less than content width (%2)").arg(control.implicitWidth).arg(implicitContentWidth))
}
}