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 <richard.gustavsen@qt.io>
This commit is contained in:
Christian Ehrlicher 2019-04-21 13:09:07 +02:00
parent 12ebdf0281
commit aa8d3f90a4
6 changed files with 40 additions and 25 deletions

View File

@ -6166,8 +6166,9 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
switch (ct) {
#if QT_CONFIG(spinbox)
case CT_SpinBox:
if (qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
const int buttonWidth = 20; // FIXME Use subControlRect()
if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(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;

View File

@ -5029,7 +5029,8 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
case CT_SpinBox:
if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(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);
}

View File

@ -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<const QStyleOptionSpinBox *>(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,

View File

@ -212,6 +212,7 @@ void QAbstractSpinBox::setButtonSymbols(ButtonSymbols buttonSymbols)
if (d->buttonSymbols != buttonSymbols) {
d->buttonSymbols = buttonSymbols;
d->updateEditFieldGeometry();
updateGeometry();
update();
}
}

View File

@ -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);
}

View File

@ -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);
}