From a317ee0a6fa76d1166f6da8593d39eaf7afce83c Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Tue, 5 Feb 2013 13:04:01 +0100 Subject: Fix sizeHint for QAbstractSpinBox The current size hint is not correct and the text is truncated when using prefix/suffix. Update QCommonStyle::sizeFromContents() to get the button and frame widths into account for the QSpinBox width. Update sizeFromContents() in the different styles to be consistent with the change in QCommonStyle. Update minimumSizeHint(), calculate it using the prefix and data range. The SpinBox can shrunk over the suffix if any. Task-number: QTBUG-28863 Change-Id: Ia742232edf8b11d0283e8136c2818928f8755103 Reviewed-by: J-P Nurmi --- src/widgets/styles/qcommonstyle.cpp | 10 +++++++++ src/widgets/styles/qgtkstyle.cpp | 2 +- src/widgets/styles/qmacstyle_mac.mm | 5 +++-- src/widgets/styles/qwindowsstyle.cpp | 1 - src/widgets/widgets/qabstractspinbox.cpp | 38 +++++++++++++++++--------------- src/widgets/widgets/qdatetimeedit.cpp | 16 +++----------- src/widgets/widgets/qspinbox.cpp | 1 + 7 files changed, 38 insertions(+), 35 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 969e31d881..1a41b6dbaa 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -4808,6 +4808,16 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, } break; #endif // QT_NO_ITEMVIEWS +#ifndef QT_NO_SPINBOX + case CT_SpinBox: + if (const QStyleOptionSpinBox *vopt = qstyleoption_cast(opt)) { + // Add button + frame widths + int buttonWidth = 20; + int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0; + sz += QSize(buttonWidth + 2*fw, 2*fw); + } + break; +#endif case CT_ScrollBar: case CT_MenuBar: case CT_Menu: diff --git a/src/widgets/styles/qgtkstyle.cpp b/src/widgets/styles/qgtkstyle.cpp index da9c13b97f..52c1e2376c 100644 --- a/src/widgets/styles/qgtkstyle.cpp +++ b/src/widgets/styles/qgtkstyle.cpp @@ -3910,7 +3910,7 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option, break; case CT_SpinBox: // QSpinBox does some nasty things that depends on CT_LineEdit - newSize = size + QSize(0, -d->gtk_widget_get_style(d->gtkWidget("GtkSpinButton"))->ythickness * 2); + newSize = newSize + QSize(0, -d->gtk_widget_get_style(d->gtkWidget("GtkSpinButton"))->ythickness * 2); break; case CT_RadioButton: case CT_CheckBox: diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index dddeb97f32..a58f6e710b 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -5985,10 +5985,11 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, switch (ct) { case QStyle::CT_SpinBox: - // hack to work around horrible sizeHint() code in QAbstractSpinBox + // hack to work around horrible sizeHint() code in QAbstractSpinBox + sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget); sz.setHeight(sz.height() - 3); break; - case QStyle::CT_TabWidget: + case QStyle::CT_TabWidget: // the size between the pane and the "contentsRect" (+4,+4) // (the "contentsRect" is on the inside of the pane) sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget); diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index 2b48096a7b..e288b1854d 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -2358,7 +2358,6 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, sz += QSize(QWindowsStylePrivate::windowsItemHMargin * 4, QWindowsStylePrivate::windowsItemVMargin * 2); break; #endif - // Otherwise, fall through case CT_ToolButton: if (qstyleoption_cast(opt)) return sz += QSize(7, 6); diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index 14d22c458b..c2b04ce461 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -825,14 +825,13 @@ QSize QAbstractSpinBox::sizeHint() const ensurePolished(); const QFontMetrics fm(fontMetrics()); - int h = d->edit->sizeHint().height() + 4; + int h = d->edit->sizeHint().height(); int w = 0; QString s; - s = d->prefix + d->textFromValue(d->minimum) + d->suffix + QLatin1Char(' '); - s.truncate(18); + QString fixedContent = d->prefix + d->suffix + QLatin1Char(' '); + s = d->textFromValue(d->minimum) + fixedContent; w = qMax(w, fm.width(s)); - s = d->prefix + d->textFromValue(d->maximum) + d->suffix + QLatin1Char(' '); - s.truncate(18); + s = d->textFromValue(d->maximum) + fixedContent; w = qMax(w, fm.width(s)); if (d->specialValueText.size()) { s = d->specialValueText; @@ -857,27 +856,29 @@ QSize QAbstractSpinBox::minimumSizeHint() const { Q_D(const QAbstractSpinBox); if (d->cachedMinimumSizeHint.isEmpty()) { + //Use the prefix and range to calculate the minimumSizeHint ensurePolished(); const QFontMetrics fm(fontMetrics()); int h = d->edit->minimumSizeHint().height(); - int w = fm.width(QLatin1String("1000")); + int w = 0; + + QString s; + QString fixedContent = d->prefix + QLatin1Char(' '); + s = d->textFromValue(d->minimum) + fixedContent; + w = qMax(w, fm.width(s)); + s = d->textFromValue(d->maximum) + fixedContent; + w = qMax(w, fm.width(s)); + + if (d->specialValueText.size()) { + s = d->specialValueText; + w = qMax(w, fm.width(s)); + } w += 2; // cursor blinking space QStyleOptionSpinBox opt; initStyleOption(&opt); QSize hint(w, h); - QSize extra(35, 6); - opt.rect.setSize(hint + extra); - extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt, - QStyle::SC_SpinBoxEditField, this).size(); - // get closer to final result by repeating the calculation - opt.rect.setSize(hint + extra); - extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt, - QStyle::SC_SpinBoxEditField, this).size(); - hint += extra; - - opt.rect = rect(); d->cachedMinimumSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this) .expandedTo(QApplication::globalStrut()); @@ -1724,7 +1725,8 @@ void QAbstractSpinBoxPrivate::setRange(const QVariant &min, const QVariant &max) clearCache(); minimum = min; maximum = (variantCompare(min, max) < 0 ? max : min); - cachedSizeHint = QSize(); // minimumSizeHint doesn't care about min/max + cachedSizeHint = QSize(); + cachedMinimumSizeHint = QSize(); // minimumSizeHint cares about min/max reset(); if (!(bound(value) == value)) { diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index fb64850923..7ee2bf64fb 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -981,9 +981,9 @@ QSize QDateTimeEdit::sizeHint() const int h = d->edit->sizeHint().height(); int w = 0; QString s; - s = d->textFromValue(d->minimum) + QLatin1String(" "); + s = d->textFromValue(d->minimum) + QLatin1Char(' '); w = qMax(w, fm.width(s)); - s = d->textFromValue(d->maximum) + QLatin1String(" "); + s = d->textFromValue(d->maximum) + QLatin1Char(' '); w = qMax(w, fm.width(s)); if (d->specialValueText.size()) { s = d->specialValueText; @@ -1000,19 +1000,8 @@ QSize QDateTimeEdit::sizeHint() const } else #endif { - QSize extra(35, 6); QStyleOptionSpinBox opt; initStyleOption(&opt); - opt.rect.setSize(hint + extra); - extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt, - QStyle::SC_SpinBoxEditField, this).size(); - // get closer to final result by repeating the calculation - opt.rect.setSize(hint + extra); - extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt, - QStyle::SC_SpinBoxEditField, this).size(); - hint += extra; - - opt.rect = rect(); d->cachedSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this) .expandedTo(QApplication::globalStrut()); } @@ -1023,6 +1012,7 @@ QSize QDateTimeEdit::sizeHint() const return d->cachedSizeHint; } + /*! \reimp */ diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp index e61c1c877a..b51bf4c078 100644 --- a/src/widgets/widgets/qspinbox.cpp +++ b/src/widgets/widgets/qspinbox.cpp @@ -268,6 +268,7 @@ void QSpinBox::setPrefix(const QString &prefix) d->updateEdit(); d->cachedSizeHint = QSize(); + d->cachedMinimumSizeHint = QSize(); // minimumSizeHint cares about the prefix updateGeometry(); } -- cgit v1.2.3