From aa8d3f90a440575deef914916299b792105d7209 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 21 Apr 2019 13:09:07 +0200 Subject: QAbstractSpinBox: fix some ui glitches Fix some ui glitches for QAbstractSpinBox: - update geometry when buttons are toggled on/off - calc button size with subControlRect instead hardcoded 20px - when buttons are not shown, don't add the button size in sizeFromContents for common and macOS style Fixes: QTBUG-39713 Fixes: QTBUG-75303 Task-number: QTBUG-67126 Change-Id: Ibf330c76deb16358a481bba6bd429fff6a5d57ae Reviewed-by: Richard Moe Gustavsen --- src/plugins/styles/mac/qmacstyle_mac.mm | 5 ++-- src/widgets/styles/qcommonstyle.cpp | 3 ++- src/widgets/styles/qstylesheetstyle.cpp | 30 +++++++++++++--------- src/widgets/widgets/qabstractspinbox.cpp | 1 + .../widgets/qdoublespinbox/tst_qdoublespinbox.cpp | 12 +++++---- .../auto/widgets/widgets/qspinbox/tst_qspinbox.cpp | 14 ++++++---- 6 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 094ac3cc1d..392368a40b 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -6166,8 +6166,9 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, switch (ct) { #if QT_CONFIG(spinbox) case CT_SpinBox: - if (qstyleoption_cast(opt)) { - const int buttonWidth = 20; // FIXME Use subControlRect() + if (const QStyleOptionSpinBox *vopt = qstyleoption_cast(opt)) { + const bool hasButtons = (vopt->buttonSymbols != QAbstractSpinBox::NoButtons); + const int buttonWidth = hasButtons ? proxy()->subControlRect(CC_SpinBox, vopt, SC_SpinBoxUp, widget).width() : 0; sz += QSize(buttonWidth, 0); } break; diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index a3461d8848..35b630cde2 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -5029,7 +5029,8 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, case CT_SpinBox: if (const QStyleOptionSpinBox *vopt = qstyleoption_cast(opt)) { // Add button + frame widths - const int buttonWidth = (vopt->subControls & (QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown)) != 0 ? 20 : 0; + const bool hasButtons = (vopt->buttonSymbols != QAbstractSpinBox::NoButtons); + const int buttonWidth = hasButtons ? proxy()->subControlRect(CC_SpinBox, vopt, SC_SpinBoxUp, widget).width() : 0; const int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0; sz += QSize(buttonWidth + 2*fw, 2*fw); } diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 2118bad9d6..84299263d7 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -4987,17 +4987,19 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op switch (ct) { #if QT_CONFIG(spinbox) - case CT_SpinBox: // ### hopelessly broken QAbstractSpinBox (part 1) + case CT_SpinBox: if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast(opt)) { - // Add some space for the up/down buttons - QRenderRule subRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton); - if (subRule.hasDrawable()) { - QRect r = positionRect(w, rule, subRule, PseudoElement_SpinBoxUpButton, - opt->rect, opt->direction); - sz += QSize(r.width(), 0); - } else { - QSize defaultUpSize = defaultSize(w, subRule.size(), spinbox->rect, PseudoElement_SpinBoxUpButton); - sz += QSize(defaultUpSize.width(), 0); + if (spinbox->buttonSymbols != QAbstractSpinBox::NoButtons) { + // Add some space for the up/down buttons + QRenderRule subRule = renderRule(w, opt, PseudoElement_SpinBoxUpButton); + if (subRule.hasDrawable()) { + QRect r = positionRect(w, rule, subRule, PseudoElement_SpinBoxUpButton, + opt->rect, opt->direction); + sz.rwidth() += r.width(); + } else { + QSize defaultUpSize = defaultSize(w, subRule.size(), spinbox->rect, PseudoElement_SpinBoxUpButton); + sz.rwidth() += defaultUpSize.width(); + } } if (rule.hasBox() || rule.hasBorder() || !rule.hasNativeBorder()) sz = rule.boxSize(sz); @@ -5498,8 +5500,12 @@ QRect QStyleSheetStyle::subControlRect(ComplexControl cc, const QStyleOptionComp : Qt::Alignment(Qt::AlignRight); downAlign = resolveAlignment(opt->direction, downAlign); - int upSize = subControlRect(CC_SpinBox, opt, SC_SpinBoxUp, w).width(); - int downSize = subControlRect(CC_SpinBox, opt, SC_SpinBoxDown, w).width(); + const bool hasButtons = (spin->buttonSymbols != QAbstractSpinBox::NoButtons); + const int upSize = hasButtons + ? subControlRect(CC_SpinBox, opt, SC_SpinBoxUp, w).width() : 0; + const int downSize = hasButtons + ? subControlRect(CC_SpinBox, opt, SC_SpinBoxDown, w).width() : 0; + int widestL = qMax((upAlign & Qt::AlignLeft) ? upSize : 0, (downAlign & Qt::AlignLeft) ? downSize : 0); int widestR = qMax((upAlign & Qt::AlignRight) ? upSize : 0, diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index 6edefaa311..f30ea35303 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -212,6 +212,7 @@ void QAbstractSpinBox::setButtonSymbols(ButtonSymbols buttonSymbols) if (d->buttonSymbols != buttonSymbols) { d->buttonSymbols = buttonSymbols; d->updateEditFieldGeometry(); + updateGeometry(); update(); } } diff --git a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp index b101f47bcd..954ee6471d 100644 --- a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp +++ b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp @@ -324,7 +324,9 @@ void tst_QDoubleSpinBox::setPrefixSuffix() QFETCH(QString, expectedCleanText); QFETCH(bool, show); - QDoubleSpinBox spin(0); + QDoubleSpinBox spin; + if (show) + spin.show(); spin.setDecimals(decimals); const QSize size1 = spin.sizeHint(); spin.setPrefix(prefix); @@ -332,17 +334,17 @@ void tst_QDoubleSpinBox::setPrefixSuffix() spin.setSuffix(suffix); const QSize size3 = spin.sizeHint(); spin.setValue(value); - if (show) - spin.show(); QCOMPARE(spin.text(), expectedText); QCOMPARE(spin.cleanText(), expectedCleanText); - if (!prefix.isEmpty() && !suffix.isEmpty()) { - QVERIFY(size1.width() < size2.width()); + if (!suffix.isEmpty()) { QVERIFY(size2.width() < size3.width()); spin.setSuffix(QString()); QCOMPARE(spin.sizeHint(), size2); + } + if (!prefix.isEmpty()) { + QVERIFY(size1.width() < size2.width()); spin.setPrefix(QString()); QCOMPARE(spin.sizeHint(), size1); } diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp index 803b72f36e..52d7dad7cf 100644 --- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp @@ -461,26 +461,30 @@ void tst_QSpinBox::setPrefixSuffix() QFETCH(QString, expectedCleanText); QFETCH(bool, show); - QSpinBox spin(0); + QSpinBox spin; + if (show) { + spin.show(); + spin.setPrefix(QString()); // trigger a recalc of sizeHint + } const QSize size1 = spin.sizeHint(); spin.setPrefix(prefix); const QSize size2 = spin.sizeHint(); spin.setSuffix(suffix); const QSize size3 = spin.sizeHint(); spin.setValue(value); - if (show) - spin.show(); QCOMPARE(spin.prefix(), prefix); QCOMPARE(spin.suffix(), suffix); QCOMPARE(spin.text(), expectedText); QCOMPARE(spin.cleanText(), expectedCleanText); - if (!prefix.isEmpty() && !suffix.isEmpty()) { - QVERIFY(size1.width() < size2.width()); + if (!suffix.isEmpty()) { QVERIFY(size2.width() < size3.width()); spin.setSuffix(QString()); QCOMPARE(spin.sizeHint(), size2); + } + if (!prefix.isEmpty()) { + QVERIFY(size1.width() < size2.width()); spin.setPrefix(QString()); QCOMPARE(spin.sizeHint(), size1); } -- cgit v1.2.3