From 01ec11507d7ef3de09bad9d1ef8e6d4a3d6c4428 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 10 Oct 2019 14:33:53 +0200 Subject: QStyleSheetStyle: add new property to QPushButton: icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is currently no proper way to change the icon of a pushbutton from css. But there is a need for doing so (QTBUG-2982), and the typical work-around is to instead use the css property 'qproperty-icon'. But setting qproperties from the style is not a good idea in the first place, since it modifies the state of the widget it draws. Moreover, such properties are only set once (in QStyle::polish()), and will not have any effect on pseudo states, like hover. To close this gap, this patch will add a css property 'icon' that can be set on a QPushButton. This property will follow normal css cascading, and respect pseudo states, equal to any other css property. [ChangeLog][QtWidgets][QStyle] You can now set the CSS property 'icon' on a QPushButton to override which icon to draw. Fixes: QTBUG-79137 Change-Id: Ie7e0b0fa4f19471f51108cd4ca931356219d562e Reviewed-by: Christian Ehrlicher Reviewed-by: Jan Arve Sæther --- src/widgets/styles/qstylesheetstyle.cpp | 51 ++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 16 deletions(-) (limited to 'src/widgets/styles/qstylesheetstyle.cpp') diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 3f57992311..0568d749c8 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -534,6 +534,7 @@ public: const QStyleSheetOutlineData *outline() const { return ou; } const QStyleSheetGeometryData *geometry() const { return geo; } const QStyleSheetPositionData *position() const { return p; } + const QStyleSheetImageData *icon() const { return iconPtr; } bool hasModification() const; @@ -569,6 +570,7 @@ public: bool hasGeometry() const { return geo != 0; } bool hasDrawable() const { return !hasNativeBorder() || hasBackground() || hasImage(); } bool hasImage() const { return img != 0; } + bool hasIcon() const { return iconPtr != 0; } QSize minimumContentsSize() const { return geo ? QSize(geo->minWidth, geo->minHeight) : QSize(0, 0); } @@ -628,6 +630,7 @@ public: QSharedDataPointer geo; QSharedDataPointer p; QSharedDataPointer img; + QSharedDataPointer iconPtr; int clipset; QPainterPath clipPath; @@ -969,11 +972,16 @@ QRenderRule::QRenderRule(const QVector &declarations, const QObject if (v.extractPalette(&fg, &sfg, &sbg, &abg)) pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg); - QIcon icon; + QIcon imgIcon; alignment = Qt::AlignCenter; + QSize imgSize; + if (v.extractImage(&imgIcon, &alignment, &imgSize)) + img = new QStyleSheetImageData(imgIcon, alignment, imgSize); + + QIcon icon; QSize size; - if (v.extractImage(&icon, &alignment, &size)) - img = new QStyleSheetImageData(icon, alignment, size); + if (v.extractIcon(&icon, &size)) + iconPtr = new QStyleSheetImageData(icon, Qt::AlignCenter, size); int adj = -255; hasFont = v.extractFont(&font, &adj); @@ -3521,15 +3529,25 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if (rule.hasFont) p->setFont(rule.font.resolve(p->font())); - if (rule.hasPosition() && rule.position()->textAlignment != 0) { - Qt::Alignment textAlignment = rule.position()->textAlignment; - QRect textRect = button->rect; + if (rule.hasPosition() || rule.hasIcon()) { uint tf = Qt::TextShowMnemonic; + QRect textRect = button->rect; + + const uint horizontalAlignMask = Qt::AlignHCenter | Qt::AlignLeft | Qt::AlignRight; const uint verticalAlignMask = Qt::AlignVCenter | Qt::AlignTop | Qt::AlignLeft; - tf |= (textAlignment & verticalAlignMask) ? (textAlignment & verticalAlignMask) : Qt::AlignVCenter; - if (!styleHint(SH_UnderlineShortcut, button, w)) - tf |= Qt::TextHideMnemonic; - if (!button->icon.isNull()) { + + if (rule.hasPosition() && rule.position()->textAlignment != 0) { + Qt::Alignment textAlignment = rule.position()->textAlignment; + tf |= (textAlignment & verticalAlignMask) ? (textAlignment & verticalAlignMask) : Qt::AlignVCenter; + tf |= (textAlignment & horizontalAlignMask) ? (textAlignment & horizontalAlignMask) : Qt::AlignHCenter; + if (!styleHint(SH_UnderlineShortcut, button, w)) + tf |= Qt::TextHideMnemonic; + } else { + tf |= Qt::AlignVCenter | Qt::AlignHCenter; + } + + QIcon icon = rule.hasIcon() ? rule.icon()->icon : button->icon; + if (!icon.isNull()) { //Group both icon and text QRect iconRect; QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; @@ -3539,7 +3557,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if (button->state & State_On) state = QIcon::On; - QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state); + QPixmap pixmap = icon.pixmap(button->iconSize, mode, state); int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio(); int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio(); int labelWidth = pixmapWidth; @@ -3550,10 +3568,10 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q labelWidth += (textWidth + iconSpacing); //Determine label alignment: - if (textAlignment & Qt::AlignLeft) { /*left*/ + if (tf & Qt::AlignLeft) { /*left*/ iconRect = QRect(textRect.x(), textRect.y() + (textRect.height() - labelHeight) / 2, pixmapWidth, pixmapHeight); - } else if (textAlignment & Qt::AlignHCenter) { /* center */ + } else if (tf & Qt::AlignHCenter) { /* center */ iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2, textRect.y() + (textRect.height() - labelHeight) / 2, pixmapWidth, pixmapHeight); @@ -3565,7 +3583,9 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q iconRect = visualRect(button->direction, textRect, iconRect); - tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead + // Left align, adjust the text-rect according to the icon instead + tf &= ~horizontalAlignMask; + tf |= Qt::AlignLeft; if (button->direction == Qt::RightToLeft) textRect.setRight(iconRect.left() - iconSpacing); @@ -3576,9 +3596,8 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q iconRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, w), pixelMetric(PM_ButtonShiftVertical, opt, w)); p->drawPixmap(iconRect, pixmap); - } else { - tf |= textAlignment; } + if (button->state & (State_On | State_Sunken)) textRect.translate(pixelMetric(PM_ButtonShiftHorizontal, opt, w), pixelMetric(PM_ButtonShiftVertical, opt, w)); -- cgit v1.2.3 From af2daafde72db02454d24b7d691aa6861525ab99 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 18 Nov 2019 17:01:26 +0100 Subject: Deprecate constructing QFlags from a pointer This was used to support QFlags f = 0 initialization, but with 0 used as a pointer literal now considered bad form, it had been changed many places to QFlags f = nullptr, which is meaningless and confusing. Change-Id: I4bc592151c255dc5cab1a232615caecc520f02e8 Reviewed-by: Thiago Macieira --- src/widgets/styles/qstylesheetstyle.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/widgets/styles/qstylesheetstyle.cpp') diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 0568d749c8..24a397a274 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -479,7 +479,7 @@ struct QStyleSheetGeometryData : public QSharedData struct QStyleSheetPositionData : public QSharedData { - QStyleSheetPositionData(int l, int t, int r, int b, Origin o, Qt::Alignment p, QCss::PositionMode m, Qt::Alignment a = 0) + QStyleSheetPositionData(int l, int t, int r, int b, Origin o, Qt::Alignment p, QCss::PositionMode m, Qt::Alignment a = { }) : left(l), top(t), bottom(b), right(r), origin(o), position(p), mode(m), textAlignment(a) { } int left, top, bottom, right; @@ -922,9 +922,9 @@ QRenderRule::QRenderRule(const QVector &declarations, const QObject int left = 0, top = 0, right = 0, bottom = 0; Origin origin = Origin_Unknown; - Qt::Alignment position = 0; + Qt::Alignment position; QCss::PositionMode mode = PositionMode_Unknown; - Qt::Alignment textAlignment = 0; + Qt::Alignment textAlignment; if (v.extractPosition(&left, &top, &right, &bottom, &origin, &position, &mode, &textAlignment)) p = new QStyleSheetPositionData(left, top, right, bottom, origin, position, mode, textAlignment); @@ -2231,7 +2231,7 @@ static Qt::Alignment defaultPosition(int pe) return Qt::AlignRight | Qt::AlignVCenter; default: - return 0; + return { }; } } @@ -3341,7 +3341,7 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC layout = subControlLayout(QLatin1String("mNX")); QStyleOptionComplex optCopy(*opt); - optCopy.subControls = 0; + optCopy.subControls = { }; for (int i = 0; i < layout.count(); i++) { int layoutButton = layout[i].toInt(); if (layoutButton < PseudoElement_MdiCloseButton @@ -4242,7 +4242,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q } r = subRule.contentsRect(r); - Qt::Alignment alignment = 0; + Qt::Alignment alignment; if (subRule.hasPosition()) alignment = subRule.position()->textAlignment; if (alignment == 0) -- cgit v1.2.3 From 97ac281c1d70dcfbb137e5a83e24a747e9510116 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Wed, 4 Dec 2019 17:15:30 +0100 Subject: QStyleSheetStyle: properly honor checkmark size when drawing a QMenu When drawing a QMenu which is checkable but does not have an icon somewhere, the width of the (possible) checkmark was not considered during drawing and the text was drawn over the checkmark. Also the wrong state was checked for drawing the checked icon (if one was given). Fixes: QTBUG-80506 Task-number: QTBUG-78238 Change-Id: Icf8aa37aab424564054d3549defee93eb0d7c1a4 Reviewed-by: Eirik Aavitsland --- src/widgets/styles/qstylesheetstyle.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/widgets/styles/qstylesheetstyle.cpp') diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 3f57992311..aab4b74c4b 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -3711,6 +3711,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q bool dis = !(opt->state & QStyle::State_Enabled), act = opt->state & QStyle::State_Selected; + int textRectOffset = m->maxIconWidth; if (!mi.icon.isNull()) { QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal; if (act && !dis) @@ -3736,19 +3737,21 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q p->drawPixmap(pmr.topLeft(), pixmap); } else if (checkable) { QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark); + const QRect cmRect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction); if (subSubRule.hasDrawable() || checked) { QStyleOptionMenuItem newMi = mi; if (!dis) newMi.state |= State_Enabled; - if (act) + if (mi.checked) newMi.state |= State_On; - newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction); + newMi.rect = cmRect; drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w); } + textRectOffset = std::max(textRectOffset, cmRect.width()); } QRect textRect = subRule.contentsRect(opt->rect); - textRect.setLeft(textRect.left() + m->maxIconWidth); + textRect.setLeft(textRect.left() + textRectOffset); textRect.setWidth(textRect.width() - mi.tabWidth); const QRect vTextRect = visualRect(opt->direction, m->rect, textRect); -- cgit v1.2.3 From ece0c0a5e7e0b18beb58ccd868bde54c7be64f78 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 22 Nov 2019 14:46:58 +0100 Subject: Tidy nullptr usage Move away from using 0 as pointer literal. Done using clang-tidy. This is not complete as run-clang-tidy can't handle all of qtbase in one go. Change-Id: I1076a21f32aac0dab078af6f175f7508145eece0 Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll --- src/widgets/styles/qstylesheetstyle.cpp | 110 ++++++++++++++++---------------- 1 file changed, 55 insertions(+), 55 deletions(-) (limited to 'src/widgets/styles/qstylesheetstyle.cpp') diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 24a397a274..c40bbbc96c 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -133,7 +133,7 @@ public: }; -static QStyleSheetStyleCaches *styleSheetCaches = 0; +static QStyleSheetStyleCaches *styleSheetCaches = nullptr; /* RECURSION_GUARD: * the QStyleSheetStyle is a proxy. If used with others proxy style, we may end up with something like: @@ -144,16 +144,16 @@ static QStyleSheetStyleCaches *styleSheetCaches = 0; * The first instance of QStyleSheetStyle will set globalStyleSheetStyle to itself. The second one * will notice the globalStyleSheetStyle is not istelf and call its base style directly. */ -static const QStyleSheetStyle *globalStyleSheetStyle = 0; +static const QStyleSheetStyle *globalStyleSheetStyle = nullptr; class QStyleSheetStyleRecursionGuard { public: QStyleSheetStyleRecursionGuard(const QStyleSheetStyle *that) - : guarded(globalStyleSheetStyle == 0) + : guarded(globalStyleSheetStyle == nullptr) { if (guarded) globalStyleSheetStyle = that; } - ~QStyleSheetStyleRecursionGuard() { if (guarded) globalStyleSheetStyle = 0; } + ~QStyleSheetStyleRecursionGuard() { if (guarded) globalStyleSheetStyle = nullptr; } bool guarded; }; #define RECURSION_GUARD(RETURN) \ @@ -371,7 +371,7 @@ struct QStyleSheetBackgroundData : public QSharedData struct QStyleSheetBorderData : public QSharedData { - QStyleSheetBorderData() : bi(0) + QStyleSheetBorderData() : bi(nullptr) { for (int i = 0; i < 4; i++) { borders[i] = 0; @@ -379,7 +379,7 @@ struct QStyleSheetBorderData : public QSharedData } } - QStyleSheetBorderData(int *b, QBrush *c, QCss::BorderStyle *s, QSize *r) : bi(0) + QStyleSheetBorderData(int *b, QBrush *c, QCss::BorderStyle *s, QSize *r) : bi(nullptr) { for (int i = 0; i < 4; i++) { borders[i] = b[i]; @@ -396,7 +396,7 @@ struct QStyleSheetBorderData : public QSharedData const QStyleSheetBorderImageData *borderImage() const { return bi; } - bool hasBorderImage() const { return bi!=0; } + bool hasBorderImage() const { return bi!=nullptr; } QSharedDataPointer bi; @@ -413,7 +413,7 @@ struct QStyleSheetBorderData : public QSharedData if (!radii[i].isEmpty()) return false; } - if (bi != 0 && bi->pixmap.hasAlpha()) + if (bi != nullptr && bi->pixmap.hasAlpha()) return false; return true; } @@ -502,7 +502,7 @@ struct QStyleSheetImageData : public QSharedData class QRenderRule { public: - QRenderRule() : features(0), hasFont(false), pal(0), b(0), bg(0), bd(0), ou(0), geo(0), p(0), img(0), clipset(0) { } + QRenderRule() : features(0), hasFont(false), pal(nullptr), b(nullptr), bg(nullptr), bd(nullptr), ou(nullptr), geo(nullptr), p(nullptr), img(nullptr), clipset(0) { } QRenderRule(const QVector &, const QObject *); QRect borderRect(const QRect &r) const; @@ -538,18 +538,18 @@ public: bool hasModification() const; - bool hasPalette() const { return pal != 0; } - bool hasBackground() const { return bg != 0 && (!bg->pixmap.isNull() || bg->brush.style() != Qt::NoBrush); } + bool hasPalette() const { return pal != nullptr; } + bool hasBackground() const { return bg != nullptr && (!bg->pixmap.isNull() || bg->brush.style() != Qt::NoBrush); } bool hasGradientBackground() const { return bg && bg->brush.style() >= Qt::LinearGradientPattern && bg->brush.style() <= Qt::ConicalGradientPattern; } bool hasNativeBorder() const { - return bd == 0 + return bd == nullptr || (!bd->hasBorderImage() && bd->styles[0] == BorderStyle_Native); } bool hasNativeOutline() const { - return (ou == 0 + return (ou == nullptr || (!ou->hasBorderImage() && ou->styles[0] == BorderStyle_Native)); } @@ -563,14 +563,14 @@ public: return features & StyleFeature_BackgroundColor; } - bool hasBox() const { return b != 0; } - bool hasBorder() const { return bd != 0; } - bool hasOutline() const { return ou != 0; } - bool hasPosition() const { return p != 0; } - bool hasGeometry() const { return geo != 0; } + bool hasBox() const { return b != nullptr; } + bool hasBorder() const { return bd != nullptr; } + bool hasOutline() const { return ou != nullptr; } + bool hasPosition() const { return p != nullptr; } + bool hasGeometry() const { return geo != nullptr; } bool hasDrawable() const { return !hasNativeBorder() || hasBackground() || hasImage(); } - bool hasImage() const { return img != 0; } - bool hasIcon() const { return iconPtr != 0; } + bool hasImage() const { return img != nullptr; } + bool hasIcon() const { return iconPtr != nullptr; } QSize minimumContentsSize() const { return geo ? QSize(geo->minWidth, geo->minHeight) : QSize(0, 0); } @@ -910,7 +910,7 @@ static QStyle::StandardPixmap subControlIcon(int pe) } QRenderRule::QRenderRule(const QVector &declarations, const QObject *object) -: features(0), hasFont(false), pal(0), b(0), bg(0), bd(0), ou(0), geo(0), p(0), img(0), clipset(0) +: features(0), hasFont(false), pal(nullptr), b(nullptr), bg(nullptr), bd(nullptr), ou(nullptr), geo(nullptr), p(nullptr), img(nullptr), clipset(0) { QPalette palette = QGuiApplication::palette(); // ###: ideally widget's palette ValueExtractor v(declarations, palette); @@ -1134,11 +1134,11 @@ QSize QRenderRule::boxSize(const QSize &cs, int flags) const void QRenderRule::fixupBorder(int nativeWidth) { - if (bd == 0) + if (bd == nullptr) return; if (!bd->hasBorderImage() || bd->bi->pixmap.isNull()) { - bd->bi = 0; + bd->bi = nullptr; // ignore the color, border of edges that have none border-style QBrush color = pal ? pal->foreground : QBrush(); const bool hasRadius = bd->radii[0].isValid() || bd->radii[1].isValid() @@ -1515,7 +1515,7 @@ public: do { result += QString::fromLatin1(metaObject->className()).replace(QLatin1Char(':'), QLatin1Char('-')); metaObject = metaObject->superClass(); - } while (metaObject != 0); + } while (metaObject != nullptr); return result; } QString attribute(NodePtr node, const QString& name) const override @@ -1539,7 +1539,7 @@ public: return className; } else if (name == QLatin1String("style")) { QWidget *w = qobject_cast(obj); - QStyleSheetStyle *proxy = w ? qt_styleSheet(w->style()) : 0; + QStyleSheetStyle *proxy = w ? qt_styleSheet(w->style()) : nullptr; if (proxy) { QString styleName = QString::fromLatin1(proxy->baseStyle()->metaObject()->className()); cache[name] = styleName; @@ -1575,7 +1575,7 @@ public: if (uc == e && !*c) return true; metaObject = metaObject->superClass(); - } while (metaObject != 0); + } while (metaObject != nullptr); return false; } bool hasAttributes(NodePtr) const override @@ -1583,11 +1583,11 @@ public: QStringList nodeIds(NodePtr node) const override { return isNullNode(node) ? QStringList() : QStringList(OBJECT_PTR(node)->objectName()); } bool isNullNode(NodePtr node) const override - { return node.ptr == 0; } + { return node.ptr == nullptr; } NodePtr parentNode(NodePtr node) const override - { NodePtr n; n.ptr = isNullNode(node) ? 0 : parentObject(OBJECT_PTR(node)); return n; } + { NodePtr n; n.ptr = isNullNode(node) ? nullptr : parentObject(OBJECT_PTR(node)); return n; } NodePtr previousSiblingNode(NodePtr) const override - { NodePtr n; n.ptr = 0; return n; } + { NodePtr n; n.ptr = nullptr; return n; } NodePtr duplicateNode(NodePtr node) const override { return node; } void freeNode(NodePtr) const override @@ -1700,22 +1700,22 @@ int QStyleSheetStyle::nativeFrameWidth(const QWidget *w) #if QT_CONFIG(spinbox) if (qobject_cast(w)) - return base->pixelMetric(QStyle::PM_SpinBoxFrameWidth, 0, w); + return base->pixelMetric(QStyle::PM_SpinBoxFrameWidth, nullptr, w); #endif #if QT_CONFIG(combobox) if (qobject_cast(w)) - return base->pixelMetric(QStyle::PM_ComboBoxFrameWidth, 0, w); + return base->pixelMetric(QStyle::PM_ComboBoxFrameWidth, nullptr, w); #endif #if QT_CONFIG(menu) if (qobject_cast(w)) - return base->pixelMetric(QStyle::PM_MenuPanelWidth, 0, w); + return base->pixelMetric(QStyle::PM_MenuPanelWidth, nullptr, w); #endif #if QT_CONFIG(menubar) if (qobject_cast(w)) - return base->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, w); + return base->pixelMetric(QStyle::PM_MenuBarPanelWidth, nullptr, w); #endif #ifndef QT_NO_FRAME if (const QFrame *frame = qobject_cast(w)) { @@ -1725,9 +1725,9 @@ int QStyleSheetStyle::nativeFrameWidth(const QWidget *w) #endif if (qstrcmp(w->metaObject()->className(), "QTipLabel") == 0) - return base->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, w); + return base->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, nullptr, w); - return base->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, w); + return base->pixelMetric(QStyle::PM_DefaultFrameWidth, nullptr, w); } static quint64 pseudoClass(QStyle::State state) @@ -2243,21 +2243,21 @@ QSize QStyleSheetStyle::defaultSize(const QWidget *w, QSize sz, const QRect& rec case PseudoElement_Indicator: case PseudoElement_MenuCheckMark: if (sz.width() == -1) - sz.setWidth(base->pixelMetric(PM_IndicatorWidth, 0, w)); + sz.setWidth(base->pixelMetric(PM_IndicatorWidth, nullptr, w)); if (sz.height() == -1) - sz.setHeight(base->pixelMetric(PM_IndicatorHeight, 0, w)); + sz.setHeight(base->pixelMetric(PM_IndicatorHeight, nullptr, w)); break; case PseudoElement_ExclusiveIndicator: case PseudoElement_GroupBoxIndicator: if (sz.width() == -1) - sz.setWidth(base->pixelMetric(PM_ExclusiveIndicatorWidth, 0, w)); + sz.setWidth(base->pixelMetric(PM_ExclusiveIndicatorWidth, nullptr, w)); if (sz.height() == -1) - sz.setHeight(base->pixelMetric(PM_ExclusiveIndicatorHeight, 0, w)); + sz.setHeight(base->pixelMetric(PM_ExclusiveIndicatorHeight, nullptr, w)); break; case PseudoElement_PushButtonMenuIndicator: { - int pm = base->pixelMetric(PM_MenuButtonIndicator, 0, w); + int pm = base->pixelMetric(PM_MenuButtonIndicator, nullptr, w); if (sz.width() == -1) sz.setWidth(pm); if (sz.height() == -1) @@ -2291,12 +2291,12 @@ QSize QStyleSheetStyle::defaultSize(const QWidget *w, QSize sz, const QRect& rec case PseudoElement_ToolButtonMenu: if (sz.width() == -1) - sz.setWidth(base->pixelMetric(PM_MenuButtonIndicator, 0, w)); + sz.setWidth(base->pixelMetric(PM_MenuButtonIndicator, nullptr, w)); break; case PseudoElement_HeaderViewUpArrow: case PseudoElement_HeaderViewDownArrow: { - int pm = base->pixelMetric(PM_HeaderMargin, 0, w); + int pm = base->pixelMetric(PM_HeaderMargin, nullptr, w); if (sz.width() == -1) sz.setWidth(pm); if (sz.height() == 1) @@ -2309,7 +2309,7 @@ QSize QStyleSheetStyle::defaultSize(const QWidget *w, QSize sz, const QRect& rec case PseudoElement_ScrollBarAddLine: case PseudoElement_ScrollBarSubLine: case PseudoElement_ScrollBarSlider: { - int pm = pixelMetric(QStyle::PM_ScrollBarExtent, 0, w); + int pm = pixelMetric(QStyle::PM_ScrollBarExtent, nullptr, w); if (sz.width() == -1) sz.setWidth(pm); if (sz.height() == -1) @@ -2319,7 +2319,7 @@ QSize QStyleSheetStyle::defaultSize(const QWidget *w, QSize sz, const QRect& rec case PseudoElement_DockWidgetCloseButton: case PseudoElement_DockWidgetFloatButton: { - int iconSize = pixelMetric(PM_SmallIconSize, 0, w); + int iconSize = pixelMetric(PM_SmallIconSize, nullptr, w); return QSize(iconSize, iconSize); } @@ -2956,7 +2956,7 @@ void QStyleSheetStyle::unpolish(QWidget *w) setGeometry(w); w->setAttribute(Qt::WA_StyleSheetTarget, false); w->setAttribute(Qt::WA_StyleSheet, false); - QObject::disconnect(w, 0, this, 0); + QObject::disconnect(w, nullptr, this, nullptr); #if QT_CONFIG(scrollarea) if (QAbstractScrollArea *sa = qobject_cast(w)) { QObject::disconnect(sa->horizontalScrollBar(), SIGNAL(valueChanged(int)), @@ -3395,7 +3395,7 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC tb->icon.paint(p, ir); } else { int iconSize = pixelMetric(PM_SmallIconSize, tb, w); - pm = standardIcon(SP_TitleBarMenuButton, 0, w).pixmap(iconSize, iconSize); + pm = standardIcon(SP_TitleBarMenuButton, nullptr, w).pixmap(iconSize, iconSize); drawItemPixmap(p, ir, Qt::AlignCenter, pm); } } @@ -3407,9 +3407,9 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC QSize sz = subSubRule.contentsRect(ir).size(); if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool) - pm = standardIcon(SP_DockWidgetCloseButton, 0, w).pixmap(sz); + pm = standardIcon(SP_DockWidgetCloseButton, nullptr, w).pixmap(sz); else - pm = standardIcon(SP_TitleBarCloseButton, 0, w).pixmap(sz); + pm = standardIcon(SP_TitleBarCloseButton, nullptr, w).pixmap(sz); drawItemPixmap(p, ir, Qt::AlignCenter, pm); } @@ -3430,7 +3430,7 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC continue; QRenderRule subSubRule = renderRule(w, opt, pe); subSubRule.drawRule(p, ir); - pm = standardIcon(subControlIcon(pe), 0, w).pixmap(subSubRule.contentsRect(ir).size()); + pm = standardIcon(subControlIcon(pe), nullptr, w).pixmap(subSubRule.contentsRect(ir).size()); drawItemPixmap(p, ir, Qt::AlignCenter, pm); } @@ -4280,7 +4280,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if (pe1 != PseudoElement_None) { QRenderRule subRule = renderRule(w, opt, pe1); - if (subRule.bg != 0 || subRule.hasDrawable()) { + if (subRule.bg != nullptr || subRule.hasDrawable()) { //We test subRule.bg directly because hasBackground() would return false for background:none. //But we still don't want the default drawning in that case (example for QScrollBar::add-page) (task 198926) subRule.drawRule(p, opt->rect); @@ -5088,7 +5088,7 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op case CT_GroupBox: case CT_LineEdit: #if QT_CONFIG(spinbox) - if (qobject_cast(w ? w->parentWidget() : 0)) + if (qobject_cast(w ? w->parentWidget() : nullptr)) return csz; // we only care about the size hint of the line edit #endif if (rule.hasBox() || !rule.hasNativeBorder()) { @@ -5729,7 +5729,7 @@ QRect QStyleSheetStyle::subControlRect(ComplexControl cc, const QStyleOptionComp QRenderRule subRule = renderRule(w, opt, PseudoElement_SliderGroove); if (!subRule.hasDrawable()) break; - subRule.img = 0; + subRule.img = nullptr; QRect gr = positionRect(w, rule, subRule, PseudoElement_SliderGroove, opt->rect, opt->direction); switch (sc) { case SC_SliderGroove: @@ -5739,8 +5739,8 @@ QRect QStyleSheetStyle::subControlRect(ComplexControl cc, const QStyleOptionComp QRect cr = subRule.contentsRect(gr); QRenderRule subRule2 = renderRule(w, opt, PseudoElement_SliderHandle); int len = horizontal ? subRule2.size().width() : subRule2.size().height(); - subRule2.img = 0; - subRule2.geo = 0; + subRule2.img = nullptr; + subRule2.geo = nullptr; cr = positionRect(w, subRule2, PseudoElement_SliderHandle, cr, opt->direction); int thickness = horizontal ? cr.height() : cr.width(); int sliderPos = sliderPositionFromValue(slider->minimum, slider->maximum, slider->sliderPosition, @@ -5848,7 +5848,7 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c QRect ir = subElementRect(isRadio ? SE_RadioButtonIndicator : SE_CheckBoxIndicator, opt, w); ir = visualRect(opt->direction, opt->rect, ir); - int spacing = pixelMetric(isRadio ? PM_RadioButtonLabelSpacing : PM_CheckBoxLabelSpacing, 0, w); + int spacing = pixelMetric(isRadio ? PM_RadioButtonLabelSpacing : PM_CheckBoxLabelSpacing, nullptr, w); QRect cr = rule.contentsRect(opt->rect); ir.setRect(ir.left() + ir.width() + spacing, cr.y(), cr.width() - ir.width() - spacing, cr.height()); -- cgit v1.2.3 From 03dc30acca4976c716c723ff46d503d35459b2a0 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 3 Dec 2019 13:39:08 +0100 Subject: Fix QPushButton style sheet style for overlay (content) image Unlike comparable widgets like QLabel or QFrame, QPushButton would not render a content image specified in the stylesheet, unless a border style was also specified. Fix by explicitly rendering the content image, if set, in the native-border codepath also. Although the doc warns about the QPushButton border style having to be set in order for the background styling to take effect (since the native border painting otherwise hides it), the previous behavior does seem unexpected. Fixes: QTBUG-72029 Change-Id: I8b979b010515dab4dcf2f00344a187c87eeec096 Reviewed-by: Friedemann Kleint Reviewed-by: Christian Ehrlicher --- src/widgets/styles/qstylesheetstyle.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/widgets/styles/qstylesheetstyle.cpp') diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index aab4b74c4b..98c85684ae 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -3493,6 +3493,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q } else { QWindowsStyle::drawControl(ce, &btnOpt, p, w); } + rule.drawImage(p, rule.contentsRect(opt->rect)); if (!customMenu) return; } else { -- cgit v1.2.3 From 56674dca36f113369d3ed598192a392ceb723605 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Wed, 25 Dec 2019 19:37:53 +0100 Subject: QSS/QComboBox: set correct palette when drawing SC_ComboBoxArrow When the dropdown button of a combobox is drawn with QStyleSheetStyle, not only the background color is used for drawing but also QPalette::Light/Dark/Shadow. Since the palette was not properly set up in some cases, the shaded frame around the button was drawn with the default colors instead the ones derived from the given background. Therefore we have to properly set up the palette before drawing the drop down button by calling QRenderRule::configurePalette() Fixes: QTBUG-80950 Change-Id: Ibf98fa28612b5c7527ef9dd6ae06c417315f2632 Reviewed-by: Friedemann Kleint Reviewed-by: Timur Pocheptsov --- src/widgets/styles/qstylesheetstyle.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/widgets/styles/qstylesheetstyle.cpp') diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 98c85684ae..c694e9db97 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -3019,6 +3019,7 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC r = positionRect(w, subRule, subRule2, PseudoElement_ComboBoxArrow, r, opt->direction); subRule2.drawRule(p, r); } else { + rule.configurePalette(&cmbOpt.palette, QPalette::ButtonText, QPalette::Button); cmbOpt.subControls = QStyle::SC_ComboBoxArrow; QWindowsStyle::drawComplexControl(cc, &cmbOpt, p, w); } -- cgit v1.2.3 From 24b8b2cb6ccd3704545ef44519f567edb3da5d5d Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 3 Jan 2020 13:39:04 +0100 Subject: Stylesheet: Handle tabs with elide mode set correctly In order for SE_TabBarTabText to correctly calculate the space available for the text it needs to get the rectangle of the tab directly instead of relying on the option's rectangle as this may have been modified before this point. Therefore we introduce QStyleOptionTabV4 to be able to store the index as part of the option so it can be queried directly. [ChangeLog][QtWidgets] Added QStyleOptionTabV4 as a subclass of QStyleOptionTab so that the tab's index information can be obtained. Fixes: QTBUG-50637 Change-Id: If705f5069fdd14eeccf06bc63dba4e8d2e704359 Reviewed-by: Volker Hilsheimer Reviewed-by: Christian Ehrlicher --- src/widgets/styles/qstylesheetstyle.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/widgets/styles/qstylesheetstyle.cpp') diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 7e8c9a6050..7fe46e24b6 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -6009,6 +6009,16 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c case SE_TabBarTabRightButton: { QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab); if (subRule.hasBox() || !subRule.hasNativeBorder()) { + if (se == SE_TabBarTabText) { + if (const QStyleOptionTabV4 *tab = qstyleoption_cast(opt)) { + const QTabBar *bar = qobject_cast(w); + const QRect optRect = bar && tab->tabIndex != -1 ? bar->tabRect(tab->tabIndex) : opt->rect; + const QRect r = positionRect(w, subRule, PseudoElement_TabBarTab, optRect, opt->direction); + QStyleOptionTabV4 tabCopy(*tab); + tabCopy.rect = subRule.contentsRect(r); + return ParentStyle::subElementRect(se, &tabCopy, w); + } + } return ParentStyle::subElementRect(se, opt, w); } break; -- cgit v1.2.3