summaryrefslogtreecommitdiffstats
path: root/src/widgets/styles/qstylesheetstyle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/styles/qstylesheetstyle.cpp')
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp317
1 files changed, 191 insertions, 126 deletions
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index 0437561d13..7602217f24 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -59,7 +59,7 @@
#include <private/qstyleanimation_p.h>
#endif
#if QT_CONFIG(tabbar)
-#include <qtabbar.h>
+#include <private/qtabbar_p.h>
#endif
#include <QMetaProperty>
#if QT_CONFIG(mainwindow)
@@ -138,8 +138,6 @@ class QStyleSheetStyleRecursionGuard
if (globalStyleSheetStyle != 0 && globalStyleSheetStyle != this) { RETURN; } \
QStyleSheetStyleRecursionGuard recursion_guard(this);
-#define ceil(x) ((int)(x) + ((x) > 0 && (x) != (int)(x)))
-
enum PseudoElement {
PseudoElement_None,
PseudoElement_DownArrow,
@@ -436,15 +434,26 @@ struct QStyleSheetBoxData : public QSharedData
struct QStyleSheetPaletteData : public QSharedData
{
- QStyleSheetPaletteData(const QBrush &fg, const QBrush &sfg, const QBrush &sbg,
- const QBrush &abg)
- : foreground(fg), selectionForeground(sfg), selectionBackground(sbg),
- alternateBackground(abg) { }
+ QStyleSheetPaletteData(const QBrush &foreground,
+ const QBrush &selectedForeground,
+ const QBrush &selectedBackground,
+ const QBrush &alternateBackground,
+ const QBrush &placeHolderTextForeground,
+ const QBrush &accent)
+ : foreground(foreground)
+ , selectionForeground(selectedForeground)
+ , selectionBackground(selectedBackground)
+ , alternateBackground(alternateBackground)
+ , placeholderForeground(placeHolderTextForeground)
+ , accent(accent)
+ { }
QBrush foreground;
QBrush selectionForeground;
QBrush selectionBackground;
QBrush alternateBackground;
+ QBrush placeholderForeground;
+ QBrush accent;
};
struct QStyleSheetGeometryData : public QSharedData
@@ -616,7 +625,7 @@ public:
Q_DECLARE_TYPEINFO(QRenderRule, Q_RELOCATABLE_TYPE);
///////////////////////////////////////////////////////////////////////////////////////////
-static const char knownStyleHints[][45] = {
+static constexpr std::array<const char*, 90> knownStyleHints = {
"activate-on-singleclick",
"alignment",
"arrow-keys-navigate-into-children",
@@ -709,13 +718,10 @@ static const char knownStyleHints[][45] = {
"widget-animation-duration"
};
-static const int numKnownStyleHints = sizeof(knownStyleHints)/sizeof(knownStyleHints[0]);
-
-static QList<QVariant> subControlLayout(const QString& layout)
+static QList<QVariant> subControlLayout(QByteArrayView layout)
{
QList<QVariant> buttons;
- for (int i = 0; i < layout.length(); i++) {
- int button = layout[i].toLatin1();
+ for (int button : layout) {
switch (button) {
case 'm':
buttons.append(PseudoElement_MdiMinButton);
@@ -777,10 +783,9 @@ QHash<QStyle::SubControl, QRect> QStyleSheetStyle::titleBarLayout(const QWidget
int offsets[3] = { 0, 0, 0 };
enum Where { Left, Right, Center, NoWhere } where = Left;
QList<ButtonInfo> infos;
- const int numLayouts = layout.size();
- infos.reserve(numLayouts);
- for (int i = 0; i < numLayouts; i++) {
- const int element = layout[i].toInt();
+ infos.reserve(layout.size());
+ for (const QVariant &val : std::as_const(layout)) {
+ const int element = val.toInt();
if (element == '(') {
where = Center;
} else if (element == ')') {
@@ -839,8 +844,7 @@ QHash<QStyle::SubControl, QRect> QStyleSheetStyle::titleBarLayout(const QWidget
}
}
- for (int i = 0; i < infos.size(); i++) {
- const ButtonInfo &info = infos[i];
+ for (const ButtonInfo &info : std::as_const(infos)) {
QRect lr = cr;
switch (info.where) {
case Center: {
@@ -956,10 +960,17 @@ QRenderRule::QRenderRule(const QList<Declaration> &declarations, const QObject *
bg = new QStyleSheetBackgroundData(brush, pixmap, repeat, alignment, origin, attachment, clip);
}
- QBrush sfg, fg;
- QBrush sbg, abg;
- if (v.extractPalette(&fg, &sfg, &sbg, &abg))
- pal = new QStyleSheetPaletteData(fg, sfg, sbg, abg);
+ QBrush foreground;
+ QBrush selectedForeground;
+ QBrush selectedBackground;
+ QBrush alternateBackground;
+ QBrush placeHolderTextForeground;
+ QBrush accent;
+ if (v.extractPalette(&foreground, &selectedForeground, &selectedBackground,
+ &alternateBackground, &placeHolderTextForeground, &accent)) {
+ pal = new QStyleSheetPaletteData(foreground, selectedForeground, selectedBackground,
+ alternateBackground, placeHolderTextForeground, accent);
+ }
QIcon imgIcon;
alignment = Qt::AlignCenter;
@@ -980,7 +991,7 @@ QRenderRule::QRenderRule(const QList<Declaration> &declarations, const QObject *
palette = QToolTip::palette();
#endif
- for (int i = 0; i < declarations.count(); i++) {
+ for (int i = 0; i < declarations.size(); i++) {
const Declaration& decl = declarations.at(i);
if (decl.d->propertyId == BorderImage) {
QString uri;
@@ -1014,8 +1025,8 @@ QRenderRule::QRenderRule(const QList<Declaration> &declarations, const QObject *
// intentionally left blank...
} else if (decl.d->propertyId == UnknownProperty) {
bool knownStyleHint = false;
- for (int i = 0; i < numKnownStyleHints; i++) {
- QLatin1StringView styleHint(knownStyleHints[i]);
+ for (const auto sh : knownStyleHints) {
+ QLatin1StringView styleHint(sh);
if (decl.d->property.compare(styleHint) == 0) {
QString hintName = QString(styleHint);
QVariant hintValue;
@@ -1055,9 +1066,9 @@ QRenderRule::QRenderRule(const QList<Declaration> &declarations, const QObject *
}
} else if (hintName.endsWith("icon"_L1)) {
hintValue = decl.iconValue();
- } else if (hintName == "button-layout"_L1
- && decl.d->values.count() != 0 && decl.d->values.at(0).type == Value::String) {
- hintValue = subControlLayout(decl.d->values.at(0).variant.toString());
+ } else if (hintName == "button-layout"_L1 && decl.d->values.size() != 0
+ && decl.d->values.at(0).type == QCss::Value::String) {
+ hintValue = subControlLayout(decl.d->values.at(0).variant.toString().toLatin1());
} else {
int integer;
decl.intValue(&integer);
@@ -1449,6 +1460,16 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorRole fr, QPalette
p->setBrush(QPalette::AlternateBase, pal->alternateBackground);
}
+void setDefault(QPalette *palette, QPalette::ColorGroup group, QPalette::ColorRole role,
+ const QBrush &defaultBrush, const QWidget *widget)
+{
+ const QPalette &widgetPalette = widget->palette();
+ if (widgetPalette.isBrushSet(group, role))
+ palette->setBrush(group, role, widgetPalette.brush(group, role));
+ else
+ palette->setBrush(group, role, defaultBrush);
+}
+
void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const QWidget *w, bool embedded)
{
if (bg && bg->brush.style() != Qt::NoBrush) {
@@ -1470,11 +1491,15 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const Q
return;
if (pal->foreground.style() != Qt::NoBrush) {
- p->setBrush(cg, QPalette::ButtonText, pal->foreground);
- p->setBrush(cg, w->foregroundRole(), pal->foreground);
- p->setBrush(cg, QPalette::WindowText, pal->foreground);
- p->setBrush(cg, QPalette::Text, pal->foreground);
- p->setBrush(cg, QPalette::PlaceholderText, pal->foreground);
+ setDefault(p, cg, QPalette::ButtonText, pal->foreground, w);
+ setDefault(p, cg, w->foregroundRole(), pal->foreground, w);
+ setDefault(p, cg, QPalette::WindowText, pal->foreground, w);
+ setDefault(p, cg, QPalette::Text, pal->foreground, w);
+ QColor phColor(pal->foreground.color());
+ phColor.setAlpha((phColor.alpha() + 1) / 2);
+ QBrush placeholder = pal->foreground;
+ placeholder.setColor(phColor);
+ setDefault(p, cg, QPalette::PlaceholderText, placeholder, w);
}
if (pal->selectionBackground.style() != Qt::NoBrush)
p->setBrush(cg, QPalette::Highlight, pal->selectionBackground);
@@ -1482,6 +1507,10 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorGroup cg, const Q
p->setBrush(cg, QPalette::HighlightedText, pal->selectionForeground);
if (pal->alternateBackground.style() != Qt::NoBrush)
p->setBrush(cg, QPalette::AlternateBase, pal->alternateBackground);
+ if (pal->placeholderForeground.style() != Qt::NoBrush)
+ p->setBrush(cg, QPalette::PlaceholderText, pal->placeholderForeground);
+ if (pal->accent.style() != Qt::NoBrush)
+ p->setBrush(cg, QPalette::Accent, pal->accent);
}
bool QRenderRule::hasModification() const
@@ -1596,8 +1625,8 @@ public:
return nodeName == "QToolTip"_L1;
#endif
do {
- const ushort *uc = (const ushort *)nodeName.constData();
- const ushort *e = uc + nodeName.length();
+ const auto *uc = reinterpret_cast<const char16_t *>(nodeName.constData());
+ const auto *e = uc + nodeName.size();
const uchar *c = (const uchar *)metaObject->className();
while (*c && uc != e && (*uc == *c || (*c == ':' && *uc == '-'))) {
++uc;
@@ -1647,7 +1676,8 @@ QList<QCss::StyleRule> QStyleSheetStyle::styleRules(const QObject *obj) const
defaultSs = getDefaultStyleSheet();
QStyle *bs = baseStyle();
styleSheetCaches->styleSheetCache.insert(bs, defaultSs);
- QObject::connect(bs, SIGNAL(destroyed(QObject*)), styleSheetCaches, SLOT(styleDestroyed(QObject*)), Qt::UniqueConnection);
+ QObject::connect(bs, &QStyle::destroyed, styleSheetCaches,
+ &QStyleSheetStyleCaches::styleDestroyed);
} else {
defaultSs = defaultCacheIt.value();
}
@@ -1694,8 +1724,8 @@ QList<QCss::StyleRule> QStyleSheetStyle::styleRules(const QObject *obj) const
objectSs.append(ss);
}
- for (int i = 0; i < objectSs.count(); i++)
- objectSs[i].depth = objectSs.count() - i + 2;
+ for (int i = 0; i < objectSs.size(); i++)
+ objectSs[i].depth = objectSs.size() - i + 2;
styleSelector.styleSheets += objectSs;
@@ -1712,7 +1742,7 @@ static QList<Declaration> declarations(const QList<StyleRule> &styleRules, const
quint64 pseudoClass = PseudoClass_Unspecified)
{
QList<Declaration> decls;
- for (int i = 0; i < styleRules.count(); i++) {
+ for (int i = 0; i < styleRules.size(); i++) {
const Selector& selector = styleRules.at(i).selectors.at(0);
// Rules with pseudo elements don't cascade. This is an intentional
// diversion for CSS
@@ -1842,7 +1872,7 @@ QRenderRule QStyleSheetStyle::renderRule(const QObject *obj, int element, quint6
quint64 stateMask = 0;
const QList<StyleRule> rules = styleRules(obj);
- for (int i = 0; i < rules.count(); i++) {
+ for (int i = 0; i < rules.size(); i++) {
const Selector& selector = rules.at(i).selectors.at(0);
quint64 negated = 0;
stateMask |= selector.pseudoClass(&negated);
@@ -2163,8 +2193,8 @@ bool QStyleSheetStyle::hasStyleRule(const QObject *obj, int part) const
return result;
}
- QString pseudoElement = QLatin1StringView(knownPseudoElements[part].name);
- for (int i = 0; i < rules.count(); i++) {
+ auto pseudoElement = QLatin1StringView(knownPseudoElements[part].name);
+ for (int i = 0; i < rules.size(); i++) {
const Selector& selector = rules.at(i).selectors.at(0);
if (pseudoElement.compare(selector.pseudoElement(), Qt::CaseInsensitive) == 0) {
cache[part] = true;
@@ -2564,8 +2594,9 @@ static quint64 extendedPseudoClass(const QWidget *w)
} else
if (const QPlainTextEdit *edit = qobject_cast<const QPlainTextEdit *>(w)) {
pc |= (edit->isReadOnly() ? PseudoClass_ReadOnly : PseudoClass_Editable);
- }
+ } else
#endif
+ {}
return pc;
}
@@ -2635,7 +2666,7 @@ void QStyleSheetStyle::setProperties(QWidget *w)
{
// scan decls for final occurrence of each "qproperty"
QDuplicateTracker<QString> propertySet(decls.size());
- for (int i = decls.count() - 1; i >= 0; --i) {
+ for (int i = decls.size() - 1; i >= 0; --i) {
const QString property = decls.at(i).d->property;
if (!property.startsWith("qproperty-"_L1, Qt::CaseInsensitive))
continue;
@@ -2644,7 +2675,7 @@ void QStyleSheetStyle::setProperties(QWidget *w)
}
}
- for (int i = finals.count() - 1; i >= 0; --i) {
+ for (int i = finals.size() - 1; i >= 0; --i) {
const Declaration &decl = decls.at(finals[i]);
QStringView property = decl.d->property;
property = property.mid(10); // strip "qproperty-"
@@ -2801,7 +2832,7 @@ static void updateObjects(const QList<const QObject *>& objects)
QCoreApplication::sendEvent(widget, &event);
QList<const QObject *> children;
children.reserve(widget->children().size() + 1);
- for (auto child: qAsConst(widget->children()))
+ for (auto child: std::as_const(widget->children()))
children.append(child);
updateObjects(children);
}
@@ -2869,7 +2900,9 @@ bool QStyleSheetStyle::initObject(const QObject *obj) const
const_cast<QWidget *>(w)->setAttribute(Qt::WA_StyleSheet, true);
}
- QObject::connect(obj, SIGNAL(destroyed(QObject*)), styleSheetCaches, SLOT(objectDestroyed(QObject*)), Qt::UniqueConnection);
+ connect(obj, &QObject::destroyed,
+ styleSheetCaches, &QStyleSheetStyleCaches::objectDestroyed,
+ Qt::UniqueConnection);
return true;
}
@@ -2896,7 +2929,7 @@ void QStyleSheetStyle::polish(QWidget *w)
//set the WA_Hover attribute if one of the selector depends of the hover state
QList<StyleRule> rules = styleRules(w);
- for (int i = 0; i < rules.count(); i++) {
+ for (int i = 0; i < rules.size(); i++) {
const Selector& selector = rules.at(i).selectors.at(0);
quint64 negated = 0;
quint64 cssClass = selector.pseudoClass(&negated);
@@ -2913,10 +2946,10 @@ void QStyleSheetStyle::polish(QWidget *w)
QRenderRule rule = renderRule(sa, PseudoElement_None, PseudoClass_Enabled);
if ((rule.hasBorder() && rule.border()->hasBorderImage())
|| (rule.hasBackground() && !rule.background()->pixmap.isNull())) {
- QObject::connect(sa->horizontalScrollBar(), SIGNAL(valueChanged(int)),
- sa, SLOT(update()), Qt::UniqueConnection);
- QObject::connect(sa->verticalScrollBar(), SIGNAL(valueChanged(int)),
- sa, SLOT(update()), Qt::UniqueConnection);
+ connect(sa->horizontalScrollBar(), &QScrollBar::valueChanged,
+ sa, QOverload<>::of(&QAbstractScrollArea::update), Qt::UniqueConnection);
+ connect(sa->verticalScrollBar(), &QScrollBar::valueChanged,
+ sa, QOverload<>::of(&QAbstractScrollArea::update), Qt::UniqueConnection);
}
}
#endif
@@ -2986,7 +3019,7 @@ void QStyleSheetStyle::repolish(QWidget *w)
{
QList<const QObject *> children;
children.reserve(w->children().size() + 1);
- for (auto child: qAsConst(w->children()))
+ for (auto child: std::as_const(w->children()))
children.append(child);
children.append(w);
styleSheetCaches->styleSheetCache.remove(w);
@@ -3019,13 +3052,13 @@ void QStyleSheetStyle::unpolish(QWidget *w)
setGeometry(w);
w->setAttribute(Qt::WA_StyleSheetTarget, false);
w->setAttribute(Qt::WA_StyleSheet, false);
- QObject::disconnect(w, nullptr, this, nullptr);
+ w->disconnect(this);
#if QT_CONFIG(scrollarea)
if (QAbstractScrollArea *sa = qobject_cast<QAbstractScrollArea *>(w)) {
- QObject::disconnect(sa->horizontalScrollBar(), SIGNAL(valueChanged(int)),
- sa, SLOT(update()));
- QObject::disconnect(sa->verticalScrollBar(), SIGNAL(valueChanged(int)),
- sa, SLOT(update()));
+ disconnect(sa->horizontalScrollBar(), &QScrollBar::valueChanged,
+ sa, QOverload<>::of(&QAbstractScrollArea::update));
+ disconnect(sa->verticalScrollBar(), &QScrollBar::valueChanged,
+ sa, QOverload<>::of(&QAbstractScrollArea::update));
}
#endif
baseStyle()->unpolish(w);
@@ -3041,16 +3074,6 @@ void QStyleSheetStyle::unpolish(QApplication *app)
styleSheetCaches->styleSheetCache.remove(qApp);
}
-#if QT_CONFIG(tabbar)
-inline static bool verticalTabs(QTabBar::Shape shape)
-{
- return shape == QTabBar::RoundedWest
- || shape == QTabBar::RoundedEast
- || shape == QTabBar::TriangularWest
- || shape == QTabBar::TriangularEast;
-}
-#endif // QT_CONFIG(tabbar)
-
void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
const QWidget *w) const
{
@@ -3480,12 +3503,12 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
|| hasStyleRule(w, PseudoElement_MdiMinButton)) {
QList<QVariant> layout = rule.styleHint("button-layout"_L1).toList();
if (layout.isEmpty())
- layout = subControlLayout("mNX"_L1);
+ layout = subControlLayout("mNX");
QStyleOptionComplex optCopy(*opt);
optCopy.subControls = { };
- for (int i = 0; i < layout.count(); i++) {
- int layoutButton = layout[i].toInt();
+ for (const QVariant &val : std::as_const(layout)) {
+ int layoutButton = val.toInt();
if (layoutButton < PseudoElement_MdiCloseButton
|| layoutButton > PseudoElement_MdiNormalButton)
continue;
@@ -3516,6 +3539,7 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
break;
subRule.drawRule(p, opt->rect);
QHash<QStyle::SubControl, QRect> layout = titleBarLayout(w, tb);
+ const auto paintDeviceDpr = p->device()->devicePixelRatio();
QRect ir;
ir = layout[SC_TitleBarLabel];
@@ -3526,8 +3550,6 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
p->drawText(ir.x(), ir.y(), ir.width(), ir.height(), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, tb->text);
}
- QPixmap pm;
-
ir = layout[SC_TitleBarSysMenu];
if (ir.isValid()) {
QRenderRule subSubRule = renderRule(w, opt, PseudoElement_TitleBarSysMenu);
@@ -3537,7 +3559,9 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
tb->icon.paint(p, ir);
} else {
int iconSize = pixelMetric(PM_SmallIconSize, tb, w);
- pm = standardIcon(SP_TitleBarMenuButton, nullptr, w).pixmap(iconSize, iconSize);
+ const QSize sz(iconSize, iconSize);
+ const auto pm = standardIcon(SP_TitleBarMenuButton, nullptr, w)
+ .pixmap(sz, paintDeviceDpr);
drawItemPixmap(p, ir, Qt::AlignCenter, pm);
}
}
@@ -3547,15 +3571,14 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
QRenderRule subSubRule = renderRule(w, opt, PseudoElement_TitleBarCloseButton);
subSubRule.drawRule(p, ir);
- QSize sz = subSubRule.contentsRect(ir).size();
- if ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool)
- pm = standardIcon(SP_DockWidgetCloseButton, nullptr, w).pixmap(sz);
- else
- pm = standardIcon(SP_TitleBarCloseButton, nullptr, w).pixmap(sz);
+ const QSize sz = subSubRule.contentsRect(ir).size();
+ const auto type = ((tb->titleBarFlags & Qt::WindowType_Mask) == Qt::Tool)
+ ? SP_DockWidgetCloseButton : SP_TitleBarCloseButton;
+ const auto pm = standardIcon(type, nullptr, w).pixmap(sz, paintDeviceDpr);
drawItemPixmap(p, ir, Qt::AlignCenter, pm);
}
- int pes[] = {
+ constexpr std::array<int, 6> pes = {
PseudoElement_TitleBarMaxButton,
PseudoElement_TitleBarMinButton,
PseudoElement_TitleBarNormalButton,
@@ -3564,15 +3587,15 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
PseudoElement_TitleBarContextHelpButton
};
- for (unsigned int i = 0; i < sizeof(pes)/sizeof(int); i++) {
- int pe = pes[i];
+ for (int pe : pes) {
QStyle::SubControl sc = knownPseudoElements[pe].subControl;
ir = layout[sc];
if (!ir.isValid())
continue;
QRenderRule subSubRule = renderRule(w, opt, pe);
subSubRule.drawRule(p, ir);
- pm = standardIcon(subControlIcon(pe), nullptr, w).pixmap(subSubRule.contentsRect(ir).size());
+ const QSize sz = subSubRule.contentsRect(ir).size();
+ const auto pm = standardIcon(subControlIcon(pe), nullptr, w).pixmap(sz, paintDeviceDpr);
drawItemPixmap(p, ir, Qt::AlignCenter, pm);
}
@@ -3595,7 +3618,9 @@ void QStyleSheetStyle::renderMenuItemIcon(const QStyleOptionMenuItem *mi, QPaint
? (mi->state & QStyle::State_Selected ? QIcon::Active : QIcon::Normal)
: QIcon::Disabled;
const bool checked = mi->checkType != QStyleOptionMenuItem::NotCheckable && mi->checked;
- const QPixmap pixmap(mi->icon.pixmap(pixelMetric(PM_SmallIconSize), mode,
+ const auto iconSize = pixelMetric(PM_SmallIconSize, mi, w);
+ const QSize sz(iconSize, iconSize);
+ const QPixmap pixmap(mi->icon.pixmap(sz, p->device()->devicePixelRatio(), mode,
checked ? QIcon::On : QIcon::Off));
const int pixw = pixmap.width() / pixmap.devicePixelRatio();
const int pixh = pixmap.height() / pixmap.devicePixelRatio();
@@ -3730,7 +3755,8 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
if (button->state & State_On)
state = QIcon::On;
- QPixmap pixmap = icon.pixmap(button->iconSize, mode, state);
+ const auto paintDeviceDpr = p->device()->devicePixelRatio();
+ QPixmap pixmap = icon.pixmap(button->iconSize, paintDeviceDpr, mode, state);
int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio();
int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio();
int labelWidth = pixmapWidth;
@@ -4032,7 +4058,8 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
if (spacing == -1)
spacing = 6;
QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
- QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
+ const auto paintDeviceDpr = p->device()->devicePixelRatio();
+ QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, paintDeviceDpr, mode);
QRect iconRect(editRect);
iconRect.setWidth(cb->iconSize.width());
iconRect = alignedRect(cb->direction,
@@ -4093,15 +4120,22 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
case CE_HeaderLabel:
if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
- QStyleOptionHeader hdr(*header);
+ QStyleOptionHeaderV2 hdr;
+ QStyleOptionHeader &v1Copy = hdr;
+ if (auto v2 = qstyleoption_cast<const QStyleOptionHeaderV2 *>(opt))
+ hdr = *v2;
+ else
+ v1Copy = *header;
QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
if (hasStyleRule(w, PseudoElement_HeaderViewUpArrow)
|| hasStyleRule(w, PseudoElement_HeaderViewDownArrow)) {
- const QRect arrowRect = subElementRect(SE_HeaderArrow, opt, w);
- if (hdr.orientation == Qt::Horizontal)
- hdr.rect.setWidth(hdr.rect.width() - arrowRect.width());
- else
- hdr.rect.setHeight(hdr.rect.height() - arrowRect.height());
+ if (hdr.sortIndicator != QStyleOptionHeader::None) {
+ const QRect arrowRect = subElementRect(SE_HeaderArrow, opt, w);
+ if (hdr.orientation == Qt::Horizontal)
+ hdr.rect.setWidth(hdr.rect.width() - arrowRect.width());
+ else
+ hdr.rect.setHeight(hdr.rect.height() - arrowRect.height());
+ }
}
subRule.configurePalette(&hdr.palette, QPalette::ButtonText, QPalette::Button);
if (subRule.hasFont) {
@@ -4201,6 +4235,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
--chunkCount;
};
} else if (chunkWidth > 0) {
+ const auto ceil = [](qreal x) { return int(x) + (x > 0 && x != int(x)); };
const int chunkCount = ceil(qreal(fillWidth)/chunkWidth);
int x = reverse ? r.left() + r.width() - chunkWidth : r.x();
@@ -4241,12 +4276,11 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
if (rule.hasDrawable()) {
rule.drawFrame(p, opt->rect);
p->save();
- switch (sgOpt->corner) {
- case Qt::BottomRightCorner: break;
- case Qt::BottomLeftCorner: p->rotate(90); break;
- case Qt::TopLeftCorner: p->rotate(180); break;
- case Qt::TopRightCorner: p->rotate(270); break;
- default: break;
+ static constexpr int rotation[] = { 180, 270, 90, 0 };
+ if (rotation[sgOpt->corner]) {
+ p->translate(opt->rect.center());
+ p->rotate(rotation[sgOpt->corner]);
+ p->translate(-opt->rect.center());
}
rule.drawImage(p, opt->rect);
p->restore();
@@ -4349,19 +4383,23 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
vopt->state & QStyle::State_Selected
? QPalette::Highlight
: QPalette::Base);
- // only draw the indicator; no text or background
+ // only draw the indicator; no text, icon or background
optIndicator.backgroundBrush = Qt::NoBrush; // no background
optIndicator.text.clear();
+ optIndicator.icon = QIcon();
QWindowsStyle::drawControl(ce, &optIndicator, p, w);
- // Now draw text, background, and highlight, but not the indicator with the
- // base style. Since we can't turn off HasCheckIndicator to prevent the base
+
+ // Now draw text, background,icon, and highlight, but not the indicator with
+ // the base style. Since we can't turn off HasCheckIndicator to prevent the base
// style from drawing the check indicator again (it would change how the item
// gets laid out) we have to clip the indicator that's already been painted.
- const QRect checkRect = subElementRect(QStyle::SE_ItemViewItemCheckIndicator,
- &optIndicator, w);
+ const QRect crStyle = subElementRect(QStyle::SE_ItemViewItemCheckIndicator,
+ &optIndicator, w);
+ const QRect crBase = baseStyle()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator,
+ &optIndicator, w);
const QRegion clipRegion = QRegion(p->hasClipping() ? p->clipRegion()
: QRegion(optIndicator.rect))
- - checkRect;
+ - crStyle.united(crBase);
p->setClipRegion(clipRegion);
}
subRule.configurePalette(&optCopy.palette, QPalette::Text, QPalette::NoRole);
@@ -4450,7 +4488,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
QString titleText = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, r.width());
drawItemText(p, r,
- alignment, dwOpt->palette,
+ alignment | Qt::TextHideMnemonic, dwOpt->palette,
dwOpt->state & State_Enabled, titleText,
QPalette::WindowText);
@@ -4612,11 +4650,14 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
case PE_PanelLineEdit:
if (const QStyleOptionFrame *frm = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
- if (QWidget *container = containerWidget(w); container != w) {
- QRenderRule containerRule = renderRule(container, opt);
- if (!containerRule.hasNativeBorder() || !containerRule.baseStyleCanDraw())
- return;
- rule = containerRule;
+ // Fall back to container widget's render rule
+ if (w) {
+ if (QWidget *container = containerWidget(w); container != w) {
+ QRenderRule containerRule = renderRule(container, opt);
+ if (!containerRule.hasNativeBorder() || !containerRule.baseStyleCanDraw())
+ return;
+ rule = containerRule;
+ }
}
if (rule.hasNativeBorder()) {
@@ -4727,10 +4768,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
QRenderRule subRule = renderRule(w, opt, PseudoElement_TreeViewBranch);
if (subRule.hasDrawable()) {
- if ((vopt->state & QStyle::State_Selected) && vopt->showDecorationSelected)
- p->fillRect(vopt->rect, vopt->palette.highlight());
- else if (vopt->features & QStyleOptionViewItem::Alternate)
- p->fillRect(vopt->rect, vopt->palette.alternateBase());
+ proxy()->drawPrimitive(PE_PanelItemViewRow, vopt, p, w);
subRule.drawRule(p, opt->rect);
} else {
baseStyle()->drawPrimitive(pe, vopt, p, w);
@@ -4798,6 +4836,17 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
pseudoElement = PseudoElement_DockWidgetSeparator;
break;
+ case PE_PanelItemViewRow:
+ // For compatibility reasons, QTreeView draws different parts of
+ // the background of an item row separately, before calling the
+ // delegate to draw the item. The row background of an item is
+ // however not separately styleable through a style sheet, but
+ // only indirectly through the background of the item. To get the
+ // same background for all parts drawn by QTreeView, we have to
+ // use the background rule for the item here.
+ if (renderRule(w, opt, PseudoElement_ViewItem).hasBackground())
+ pseudoElement = PseudoElement_ViewItem;
+ break;
case PE_PanelItemViewItem:
pseudoElement = PseudoElement_ViewItem;
break;
@@ -4824,6 +4873,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
w = w->parentWidget(); //match on the QTabBar instead of the CloseButton
}
pseudoElement = PseudoElement_TabBarTabCloseButton;
+ break;
#endif
default:
@@ -5084,7 +5134,7 @@ int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const
break;
case PM_ScrollView_ScrollBarOverlap:
- if (!rule.hasNativeBorder() || rule.hasBox())
+ if (!proxy()->styleHint(SH_ScrollBar_Transient, opt, w))
return 0;
break;
#endif // QT_CONFIG(scrollbar)
@@ -5451,11 +5501,11 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op
QList<QVariant> layout = rule.styleHint("button-layout"_L1).toList();
if (layout.isEmpty())
- layout = subControlLayout("mNX"_L1);
+ layout = subControlLayout("mNX");
int width = 0, height = 0;
- for (int i = 0; i < layout.count(); i++) {
- int layoutButton = layout[i].toInt();
+ for (const QVariant &val : std::as_const(layout)) {
+ int layoutButton = val.toInt();
if (layoutButton < PseudoElement_MdiCloseButton
|| layoutButton > PseudoElement_MdiNormalButton)
continue;
@@ -5582,7 +5632,8 @@ QPixmap QStyleSheetStyle::standardPixmap(StandardPixmap standardPixmap, const QS
QRenderRule rule = renderRule(w, opt);
if (rule.hasStyleHint(s)) {
QIcon icon = qvariant_cast<QIcon>(rule.styleHint(s));
- return icon.pixmap(16, 16); // ###: unhard-code this if someone complains
+ const auto dpr = w ? w->devicePixelRatio() : qApp->devicePixelRatio();
+ return icon.pixmap(QSize(16, 16), dpr);
}
}
return baseStyle()->standardPixmap(standardPixmap, opt, w);
@@ -5694,7 +5745,7 @@ int QStyleSheetStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWi
case SH_TitleBar_ShowToolTipsOnButtons: s = "titlebar-show-tooltips-on-buttons"_L1; break;
case SH_Widget_Animation_Duration: s = "widget-animation-duration"_L1; break;
case SH_ScrollBar_Transient:
- if (!rule.hasNativeBorder() || rule.hasBox())
+ if (!rule.hasNativeBorder() || rule.hasBox() || rule.hasDrawable())
return 0;
break;
default: break;
@@ -6017,12 +6068,12 @@ QRect QStyleSheetStyle::subControlRect(ComplexControl cc, const QStyleOptionComp
|| hasStyleRule(w, PseudoElement_MdiMinButton)) {
QList<QVariant> layout = rule.styleHint("button-layout"_L1).toList();
if (layout.isEmpty())
- layout = subControlLayout("mNX"_L1);
+ layout = subControlLayout("mNX");
int x = 0, width = 0;
QRenderRule subRule;
- for (int i = 0; i < layout.count(); i++) {
- int layoutButton = layout[i].toInt();
+ for (const QVariant &val : std::as_const(layout)) {
+ int layoutButton = val.toInt();
if (layoutButton < PseudoElement_MdiCloseButton
|| layoutButton > PseudoElement_MdiNormalButton)
continue;
@@ -6178,8 +6229,22 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c
case SE_HeaderLabel: {
QRenderRule subRule = renderRule(w, opt, PseudoElement_HeaderViewSection);
- if (subRule.hasBox() || !subRule.hasNativeBorder())
- return subRule.contentsRect(opt->rect);
+ if (subRule.hasBox() || !subRule.hasNativeBorder()) {
+ auto r = subRule.contentsRect(opt->rect);
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
+ // Subtract width needed for arrow, if there is one
+ if (header->sortIndicator != QStyleOptionHeader::None) {
+ const auto arrowRect = subElementRect(SE_HeaderArrow, opt, w);
+ if (arrowRect.isValid()) {
+ if (opt->state & State_Horizontal)
+ r.setWidth(r.width() - arrowRect.width());
+ else
+ r.setHeight(r.height() - arrowRect.height());
+ }
+ }
+ }
+ return r;
+ }
}
break;