Introduce Windows 11 styled ComboBox in QWindows11Style

QComboBox is adapted to use the WinUI3 style.

Task-number: QTBUG-113513
Change-Id: I300157a7ce9162be73ccd4acfc50b12f7166dc2d
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
bb10
Wladimir Leuschner 2023-06-01 14:45:47 +03:00
parent 64db4042d4
commit 9da8d67b3b
2 changed files with 69 additions and 3 deletions

View File

@ -8,6 +8,8 @@
#include <qstyleoption.h>
#include <qpainter.h>
#include <qglobal.h>
#include <QGraphicsDropShadowEffect>
#include "qdrawutil.h"
QT_BEGIN_NAMESPACE
@ -80,6 +82,30 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
switch (control) {
#if QT_CONFIG(combobox)
case CC_ComboBox:
if (const QStyleOptionComboBox *sb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
QBrush fillColor = state & State_MouseOver && !(state & State_HasFocus) ? QBrush(subtleHighlightColor) : option->palette.brush(QPalette::Base);
QRectF rect = option->rect.adjusted(2,2,-2,-2);
painter->setBrush(fillColor);
painter->setPen(frameColorLight);
painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius);
if (sub & SC_ComboBoxArrow) {
QRectF rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget).adjusted(0, 0, 0, 1);
painter->setFont(assetFont);
painter->setPen(sb->palette.text().color());
painter->drawText(rect,"\uE019", Qt::AlignVCenter | Qt::AlignHCenter);
}
if (sb->editable) {
QColor lineColor = state & State_HasFocus ? option->palette.accent().color() : QColor(0,0,0);
painter->setPen(QPen(lineColor));
painter->drawLine(rect.bottomLeft() + QPoint(2,1), rect.bottomRight() + QPoint(-2,1));
if (state & State_HasFocus)
painter->drawLine(rect.bottomLeft() + QPoint(3,2), rect.bottomRight() + QPoint(-3,2));
}
}
break;
#endif // QT_CONFIG(combobox)
case QStyle::CC_ScrollBar:
if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
QRectF rect = scrollbar->rect;
@ -186,6 +212,12 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
if (frame->frameShape == QFrame::NoFrame)
break;
QRect rect = option->rect.adjusted(2,2,-2,-2);
if (widget && widget->inherits("QComboBoxPrivateContainer")) {
painter->setPen(Qt::NoPen);
painter->setBrush(menuPanelFill);
painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius);
}
painter->setBrush(option->palette.base());
painter->setPen(QPen(frameColorLight));
painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius);
@ -353,7 +385,7 @@ int QWindows11Style::styleHint(StyleHint hint, const QStyleOption *opt,
void QWindows11Style::polish(QWidget* widget)
{
QWindowsVistaStyle::polish(widget);
if (widget->inherits("QScrollBar")) {
if (widget->inherits("QScrollBar") || widget->inherits("QComboBoxPrivateContainer")) {
bool wasCreated = widget->testAttribute(Qt::WA_WState_Created);
widget->setAttribute(Qt::WA_OpaquePaintEvent,false);
widget->setAttribute(Qt::WA_TranslucentBackground);
@ -364,6 +396,21 @@ void QWindows11Style::polish(QWidget* widget)
pal.setColor(widget->backgroundRole(), Qt::transparent);
widget->setPalette(pal);
}
if (widget->inherits("QComboBoxPrivateContainer")) {
QGraphicsDropShadowEffect* dropshadow = new QGraphicsDropShadowEffect(widget);
dropshadow->setBlurRadius(3);
dropshadow->setXOffset(3);
dropshadow->setYOffset(3);
widget->setGraphicsEffect(dropshadow);
}
if (widget->inherits("QComboBox")) {
QComboBox* cb = qobject_cast<QComboBox*>(widget);
if (cb->isEditable()) {
QLineEdit *le = cb->lineEdit();
le->setFrame(false);
}
}
if (widget->inherits("QGraphicsView") && !widget->inherits("QTextEdit")) {
QPalette pal = widget->palette();
pal.setColor(QPalette::Base, pal.window().color());

View File

@ -761,7 +761,9 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
QModelIndex indexUnderMouse = view->indexAt(m->position().toPoint());
if (indexUnderMouse.isValid()
&& !QComboBoxDelegate::isSeparator(indexUnderMouse)) {
view->setCurrentIndex(indexUnderMouse);
// Request for comments: To show selected item with AccentColor bar indicator and hovered
// items in the flyout, the next line needs to be removed.
//view->setCurrentIndex(indexUnderMouse);
}
}
break;
@ -2969,9 +2971,26 @@ void QComboBox::changeEvent(QEvent *e)
Q_D(QComboBox);
switch (e->type()) {
case QEvent::StyleChange:
if (d->container)
if (d->container) {
// If on Windows, force recreation of ComboBox container, since
// windows11 style depends on WA_TranslucentBackground
#ifdef Q_OS_WIN
auto delegate = itemDelegate();
d->container->deleteLater();
// d->container needs to be set explicitly to nullptr
// since QComboBoxPrivate::viewContainer() only
// creates a new QComboBoxPrivateContainer when
// d->container has the value of nullptr
d->container = nullptr;
d->container = d->viewContainer();
delegate->setParent(d->container);
setItemDelegate(delegate);
#endif
d->container->updateStyleSettings();
}
d->updateDelegate();
#ifdef Q_OS_MAC
case QEvent::MacSizeChange:
#endif