diff options
Diffstat (limited to 'src/plugins/styles')
4 files changed, 153 insertions, 46 deletions
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp index 0ed8e2890d9..c8cd7c26f61 100644 --- a/src/plugins/styles/modernwindows/qwindows11style.cpp +++ b/src/plugins/styles/modernwindows/qwindows11style.cpp @@ -109,6 +109,7 @@ inline ControlState calcControlState(const QStyleOption *option) #define More u"\uE712"_s #define Help u"\uE897"_s +#define Clear u"\uE894"_s template <typename R, typename P, typename B> static inline void drawRoundedRect(QPainter *p, R &&rect, P &&pen, B &&brush) @@ -580,21 +581,18 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt if (combobox->frame) drawLineEditFrame(painter, frameRect, combobox, combobox->editable); - const bool isMouseOver = state & State_MouseOver; const bool hasFocus = state & State_HasFocus; - if (isMouseOver && !hasFocus && !highContrastTheme) - drawRoundedRect(painter, frameRect, Qt::NoPen, winUI3Color(subtleHighlightColor)); + QStyleOption opt(*option); + opt.state.setFlag(QStyle::State_On, false); + drawRoundedRect(painter, frameRect, Qt::NoPen, controlFillBrush(&opt, ControlType::Control)); if (sub & SC_ComboBoxArrow) { QRectF rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget).adjusted(4, 0, -4, 1); painter->setFont(d->assetFont); - painter->setPen(combobox->palette.text().color()); + painter->setPen(controlTextColor(option)); painter->drawText(rect, Qt::AlignCenter, ChevronDownMed); } - if (state & State_HasFocus) { - drawPrimitive(PE_FrameFocusRect, option, painter, widget); - } - if (state & State_KeyboardFocusChange && state & State_HasFocus) { + if (state & State_KeyboardFocusChange && hasFocus) { QStyleOptionFocusRect fropt; fropt.QStyleOption::operator=(*option); proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); @@ -1048,12 +1046,27 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption if (rect.width() <= 0) break; - painter->setPen(Qt::NoPen); - if (vopt->features & QStyleOptionViewItem::Alternate) - painter->setBrush(vopt->palette.alternateBase()); - else - painter->setBrush(vopt->palette.base()); - painter->drawRect(rect); + if (vopt->features & QStyleOptionViewItem::Alternate) { + QPalette::ColorGroup cg = + (widget ? widget->isEnabled() : (vopt->state & QStyle::State_Enabled)) + ? QPalette::Normal + : QPalette::Disabled; + if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active)) + cg = QPalette::Inactive; + painter->fillRect(rect, option->palette.brush(cg, QPalette::AlternateBase)); + } + + if (option->state & State_Selected && !highContrastTheme) { + // keep in sync with CE_ItemViewItem QListView indicator painting + const auto col = option->palette.accent().color(); + painter->setBrush(col); + painter->setPen(col); + const auto xPos = isRtl ? rect.right() - 4.5f : rect.left() + 3.5f; + const auto yOfs = rect.height() / 4.; + QRectF r(QPointF(xPos, rect.y() + yOfs), + QPointF(xPos + 1, rect.y() + rect.height() - yOfs)); + painter->drawRoundedRect(r, 1, 1); + } const bool isTreeDecoration = vopt->features.testFlag( QStyleOptionViewItem::IsDecorationForRootColumn); @@ -1182,11 +1195,14 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op painter->setRenderHint(QPainter::Antialiasing); switch (element) { case QStyle::CE_ComboBoxLabel: +#if QT_CONFIG(combobox) if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { + painter->setPen(controlTextColor(option)); QStyleOptionComboBox newOption = *cb; newOption.rect.adjust(4,0,-4,0); QCommonStyle::drawControl(element, &newOption, painter, widget); } +#endif // QT_CONFIG(combobox) break; case QStyle::CE_TabBarTabShape: #if QT_CONFIG(tabbar) @@ -1705,9 +1721,10 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op } case CE_ItemViewItem: { if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option)) { - QRect checkRect = proxy()->subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget); - QRect iconRect = proxy()->subElementRect(SE_ItemViewItemDecoration, vopt, widget); - QRect textRect = proxy()->subElementRect(SE_ItemViewItemText, vopt, widget); + const auto p = proxy(); + QRect checkRect = p->subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget); + QRect iconRect = p->subElementRect(SE_ItemViewItemDecoration, vopt, widget); + QRect textRect = p->subElementRect(SE_ItemViewItemText, vopt, widget); // draw the background proxy()->drawPrimitive(PE_PanelItemViewItem, option, painter, widget); @@ -1808,16 +1825,17 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op d->viewItemDrawText(painter, vopt, textRect); // paint a vertical marker for QListView - if (vopt->state & State_Selected) { + if (vopt->state & State_Selected && !highContrastTheme) { if (const QListView *lv = qobject_cast<const QListView *>(widget); - lv && lv->viewMode() != QListView::IconMode && !highContrastTheme) { - painter->setPen(vopt->palette.accent().color()); - const auto xPos = isRtl ? rect.right() - 1 : rect.left(); - const QLineF lines[2] = { - QLineF(xPos, rect.y() + 2, xPos, rect.y() + rect.height() - 2), - QLineF(xPos + 1, rect.y() + 2, xPos + 1, rect.y() + rect.height() - 2), - }; - painter->drawLines(lines, 2); + lv && lv->viewMode() != QListView::IconMode) { + const auto col = vopt->palette.accent().color(); + painter->setBrush(col); + painter->setPen(col); + const auto xPos = isRtl ? rect.right() - 4.5f : rect.left() + 3.5f; + const auto yOfs = rect.height() / 4.; + QRectF r(QPointF(xPos, rect.y() + yOfs), + QPointF(xPos + 1, rect.y() + rect.height() - yOfs)); + painter->drawRoundedRect(r, 1, 1); } } } @@ -1857,7 +1875,7 @@ QRect QWindows11Style::subElementRect(QStyle::SubElement element, const QStyleOp case QStyle::SE_RadioButtonIndicator: case QStyle::SE_CheckBoxIndicator: ret = QWindowsVistaStyle::subElementRect(element, option, widget); - ret.moveLeft(contentItemHMargin); + ret.moveLeft(ret.left() + contentItemHMargin); break; case QStyle::SE_ComboBoxFocusRect: case QStyle::SE_CheckBoxFocusRect: @@ -1868,22 +1886,29 @@ QRect QWindows11Style::subElementRect(QStyle::SubElement element, const QStyleOp case QStyle::SE_LineEditContents: ret = option->rect.adjusted(4,0,-4,0); break; - case QStyle::SE_ItemViewItemText: - if (const auto *item = qstyleoption_cast<const QStyleOptionViewItem *>(option)) { - const int decorationOffset = item->features.testFlag(QStyleOptionViewItem::HasDecoration) ? item->decorationSize.width() : 0; - const int checkboxOffset = item->features.testFlag(QStyleOptionViewItem::HasCheckIndicator) ? 16 : 0; - if (widget && qobject_cast<QComboBoxPrivateContainer *>(widget->parentWidget())) { - if (option->direction == Qt::LeftToRight) - ret = option->rect.adjusted(decorationOffset + checkboxOffset + 5, 0, -5, 0); - else - ret = option->rect.adjusted(5, 0, decorationOffset - checkboxOffset - 5, 0); + case SE_ItemViewItemCheckIndicator: + case SE_ItemViewItemDecoration: + case SE_ItemViewItemText: { + ret = QWindowsVistaStyle::subElementRect(element, option, widget); + if (!ret.isValid() || highContrastTheme) + return ret; + + if (const QListView *lv = qobject_cast<const QListView *>(widget); + lv && lv->viewMode() != QListView::IconMode) { + const int xOfs = contentHMargin; + const bool isRtl = option->direction == Qt::RightToLeft; + if (isRtl) { + ret.moveRight(ret.right() - xOfs); + if (ret.left() < option->rect.left()) + ret.setLeft(option->rect.left()); } else { - ret = QWindowsVistaStyle::subElementRect(element, option, widget); + ret.moveLeft(ret.left() + xOfs); + if (ret.right() > option->rect.right()) + ret.setRight(option->rect.right()); } - } else { - ret = QWindowsVistaStyle::subElementRect(element, option, widget); } break; + } #if QT_CONFIG(progressbar) case SE_ProgressBarGroove: case SE_ProgressBarContents: @@ -2062,6 +2087,33 @@ QRect QWindows11Style::subControlRect(ComplexControl control, const QStyleOption } break; } + case CC_ComboBox: { + if (subControl == SC_ComboBoxArrow) { + const auto indicatorWidth = + proxy()->pixelMetric(PM_MenuButtonIndicator, option, widget); + const int endX = option->rect.right() - contentHMargin - 2; + const int startX = endX - indicatorWidth; + const QRect rect(QPoint(startX, option->rect.top()), + QPoint(endX, option->rect.bottom())); + ret = visualRect(option->direction, option->rect, rect); + } else { + ret = QWindowsVistaStyle::subControlRect(control, option, subControl, widget); + } + break; + } +#if QT_CONFIG(groupbox) + case CC_GroupBox: { + ret = QWindowsVistaStyle::subControlRect(control, option, subControl, widget); + switch (subControl) { + case SC_GroupBoxCheckBox: + ret.moveTop(1); + break; + default: + break; + } + break; + } +#endif // QT_CONFIG(groupbox) default: ret = QWindowsVistaStyle::subControlRect(control, option, subControl, widget); } @@ -2152,14 +2204,18 @@ QSize QWindows11Style::sizeFromContents(ContentsType type, const QStyleOption *o break; } #endif +#if QT_CONFIG(combobox) case CT_ComboBox: if (const auto *comboBoxOpt = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { contentSize = QWindowsStyle::sizeFromContents(type, option, size, widget); // don't rely on QWindowsThemeData contentSize += QSize(4, 4); // default win11 style margins - if (comboBoxOpt->subControls & SC_ComboBoxArrow) - contentSize += QSize(8, 0); // arrow margins + if (comboBoxOpt->subControls & SC_ComboBoxArrow) { + const auto w = proxy()->pixelMetric(PM_MenuButtonIndicator, option, widget); + contentSize.rwidth() += w + contentItemHMargin; + } } break; +#endif case CT_HeaderSection: // windows vista does not honor the indicator (as it was drawn above the text, not on the // side) so call QWindowsStyle::styleHint directly to get the correct size hint @@ -2201,6 +2257,25 @@ QSize QWindows11Style::sizeFromContents(ContentsType type, const QStyleOption *o contentSize.rwidth() += 2 * contentHMargin - oldMargin; break; } + case CT_ItemViewItem: { + if (const auto *viewItemOpt = qstyleoption_cast<const QStyleOptionViewItem *>(option)) { + if (const QListView *lv = qobject_cast<const QListView *>(widget); + lv && lv->viewMode() != QListView::IconMode) { + QStyleOptionViewItem vOpt(*viewItemOpt); + // viewItemSize only takes PM_FocusFrameHMargin into account but no additional + // margin, therefore adjust it here for a correct width during layouting when + // WrapText is enabled + vOpt.rect.setRight(vOpt.rect.right() - contentHMargin); + contentSize = QWindowsVistaStyle::sizeFromContents(type, &vOpt, size, widget); + contentSize.rwidth() += contentHMargin; + contentSize.rheight() += 2 * contentHMargin; + + } else { + contentSize = QWindowsVistaStyle::sizeFromContents(type, option, size, widget); + } + } + break; + } default: contentSize = QWindowsVistaStyle::sizeFromContents(type, option, size, widget); break; @@ -2290,6 +2365,9 @@ int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option, case PM_ButtonShiftVertical: res = 0; break; + case PM_TreeViewIndentation: + res = 30; + break; default: res = QWindowsVistaStyle::pixelMetric(metric, option, widget); } @@ -2377,6 +2455,13 @@ void QWindows11Style::unpolish(QWidget *widget) widget->setProperty("_q_original_menubar_maxheight", QVariant()); } #endif + const auto comboBoxContainer = qobject_cast<const QComboBoxPrivateContainer *>(widget); + if (comboBoxContainer) { + widget->setAttribute(Qt::WA_OpaquePaintEvent, true); + widget->setAttribute(Qt::WA_TranslucentBackground, false); + widget->setWindowFlag(Qt::FramelessWindowHint, false); + widget->setWindowFlag(Qt::NoDropShadowWindowHint, false); + } if (const auto *scrollarea = qobject_cast<QAbstractScrollArea *>(widget); scrollarea @@ -2501,6 +2586,7 @@ void QWindows11Style::polish(QPalette& result) d->m_titleBarCloseIcon = QIcon(); d->m_titleBarNormalIcon = QIcon(); d->m_toolbarExtensionButton = QIcon(); + d->m_lineEditClearButton = QIcon(); } QPixmap QWindows11Style::standardPixmap(StandardPixmap standardPixmap, @@ -2525,10 +2611,17 @@ QIcon QWindows11Style::standardIcon(StandardPixmap standardIcon, { auto *d = const_cast<QWindows11StylePrivate*>(d_func()); switch (standardIcon) { + case SP_LineEditClearButton: { + if (d->m_lineEditClearButton.isNull()) { + auto e = new WinFontIconEngine(Clear.at(0), d->assetFont); + d->m_lineEditClearButton = QIcon(e); + } + return d->m_lineEditClearButton; + } case SP_ToolBarHorizontalExtensionButton: case SP_ToolBarVerticalExtensionButton: { if (d->m_toolbarExtensionButton.isNull()) { - auto e = new WinFontIconEngine(More.at(0), d->assetFont); + auto e = new WinFontIconEngine(More, d->assetFont); e->setScale(1.0); d->m_toolbarExtensionButton = QIcon(e); } diff --git a/src/plugins/styles/modernwindows/qwindows11style_p.h b/src/plugins/styles/modernwindows/qwindows11style_p.h index 736caae956c..a51a93ddd9b 100644 --- a/src/plugins/styles/modernwindows/qwindows11style_p.h +++ b/src/plugins/styles/modernwindows/qwindows11style_p.h @@ -123,6 +123,7 @@ class QWindows11StylePrivate : public QWindowsVistaStylePrivate { protected: QIcon m_toolbarExtensionButton; + QIcon m_lineEditClearButton; }; QT_END_NAMESPACE diff --git a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp index abe0bde540f..fa0d0260f3c 100644 --- a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp +++ b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp @@ -1626,6 +1626,12 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt break; case PE_Frame: + if (widget && widget->inherits("QComboBoxPrivateContainer")){ + QStyleOption copy = *option; + copy.state |= State_Raised; + proxy()->drawPrimitive(PE_PanelMenu, ©, painter, widget); + break; + } #if QT_CONFIG(accessibility) if (QStyleHelper::isInstanceOf(option->styleObject, QAccessible::EditableText) || QStyleHelper::isInstanceOf(option->styleObject, QAccessible::StaticText) || @@ -1704,6 +1710,14 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt return; } + case PE_PanelMenu: + if (widget && widget->inherits("QComboBoxPrivateContainer")){ + //fill combobox popup background + QWindowsThemeData popupbackgroundTheme(widget, painter, QWindowsVistaStylePrivate::MenuTheme, + MENU_POPUPBACKGROUND, stateId, option->rect); + d->drawBackground(popupbackgroundTheme); + } + case PE_PanelMenuBar: break; @@ -4945,8 +4959,7 @@ QIcon QWindowsVistaStyle::standardIcon(StandardPixmap standardIcon, return QWindowsStyle::standardIcon(standardIcon, option, widget); } - -WinFontIconEngine::WinFontIconEngine(const QChar &glyph, const QFont &font) +WinFontIconEngine::WinFontIconEngine(const QString &glyph, const QFont &font) : QFontIconEngine({}, font) , m_font(font) , m_glyph(glyph) diff --git a/src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h b/src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h index cf982ceb133..23b34547faa 100644 --- a/src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h +++ b/src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h @@ -184,7 +184,7 @@ private: class WinFontIconEngine : public QFontIconEngine { public: - WinFontIconEngine(const QChar &glyph, const QFont &font); + WinFontIconEngine(const QString &glyph, const QFont &font); QString key() const override; QIconEngine *clone() const override; @@ -194,7 +194,7 @@ public: protected: QFont m_font; - QChar m_glyph; + QString m_glyph; double m_scale = 0.7; }; |
