From 51499e7a17d71fd7e489a157766f35f75ecf1475 Mon Sep 17 00:00:00 2001 From: Wladimir Leuschner Date: Thu, 22 Jun 2023 15:49:32 +0300 Subject: Introduce rounded plain frames, group boxes in QWindows11Style Plain frames and group boxes are now drawn with rounded edges. In QWindows11Style. Change-Id: I576873d31c2252b7a22d84e8e86c64e09e2e5023 Reviewed-by: Oliver Wolff --- .../styles/modernwindows/qwindows11style.cpp | 49 +++++++++++ src/widgets/styles/qdrawutil.cpp | 97 +++++++++++++++++++++- src/widgets/styles/qdrawutil.h | 6 ++ 3 files changed, 150 insertions(+), 2 deletions(-) diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp index 2bb9a4eed8..2c040104d2 100644 --- a/src/plugins/styles/modernwindows/qwindows11style.cpp +++ b/src/plugins/styles/modernwindows/qwindows11style.cpp @@ -438,6 +438,20 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption } switch (element) { + case PE_FrameGroupBox: + if (const QStyleOptionFrame *frame = qstyleoption_cast(option)) { + painter->setPen(frameColorStrong); + painter->setBrush(Qt::NoBrush); + if (frame->features & QStyleOptionFrame::Flat) { + QRect fr = frame->rect; + QPoint p1(fr.x(), fr.y() + 1); + QPoint p2(fr.x() + fr.width(), p1.y()); + painter->drawLine(p1,p2); + } else { + painter->drawRoundedRect(frame->rect.marginsRemoved(QMargins(1,1,1,1)), secondLevelRoundingRadius, secondLevelRoundingRadius); + } + } + break; case PE_IndicatorCheckBox: { QNumberStyleAnimation* animation = qobject_cast(d->animation(option->styleObject)); @@ -720,6 +734,36 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op } } break; + case QStyle::CE_ShapedFrame: + if (const QStyleOptionFrame *f = qstyleoption_cast(option)) { + int frameShape = f->frameShape; + int frameShadow = QFrame::Plain; + if (f->state & QStyle::State_Sunken) + frameShadow = QFrame::Sunken; + else if (f->state & QStyle::State_Raised) + frameShadow = QFrame::Raised; + + int lw = f->lineWidth; + int mlw = f->midLineWidth; + + switch (frameShape) { + case QFrame::Box: + if (frameShadow == QFrame::Plain) + qDrawPlainRoundedRect(painter, f->rect, secondLevelRoundingRadius, secondLevelRoundingRadius, frameColorStrong, lw); + else + qDrawShadeRect(painter, f->rect, f->palette, frameShadow == QFrame::Sunken, lw, mlw); + break; + case QFrame::Panel: + if (frameShadow == QFrame::Plain) + qDrawPlainRoundedRect(painter, f->rect, secondLevelRoundingRadius, secondLevelRoundingRadius, frameColorStrong, lw); + else + qDrawShadePanel(painter, f->rect, f->palette, frameShadow == QFrame::Sunken, lw); + break; + default: + QWindowsVistaStyle::drawControl(element, option, painter, widget); + } + } + break; case QStyle::CE_ProgressBarGroove:{ if (const QStyleOptionProgressBar* progbaropt = qstyleoption_cast(option)) { const QProgressBar* bar = qobject_cast(widget); @@ -1182,6 +1226,10 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op int QWindows11Style::styleHint(StyleHint hint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *returnData) const { switch (hint) { + case SH_GroupBox_TextLabelColor: + if (opt!=nullptr && widget!=nullptr) + return opt->palette.text().color().rgba(); + return 0; case QStyle::SH_ItemView_ShowDecorationSelected: return 1; default: @@ -1242,6 +1290,7 @@ int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option, return res; } + void QWindows11Style::polish(QWidget* widget) { QWindowsVistaStyle::polish(widget); diff --git a/src/widgets/styles/qdrawutil.cpp b/src/widgets/styles/qdrawutil.cpp index d04ed74dd0..80494d85af 100644 --- a/src/widgets/styles/qdrawutil.cpp +++ b/src/widgets/styles/qdrawutil.cpp @@ -297,7 +297,6 @@ void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, p->setPen(oldPen); // restore pen } - /*! \fn void qDrawShadePanel(QPainter *painter, int x, int y, int width, int height, const QPalette &palette, bool sunken, @@ -409,7 +408,6 @@ void qDrawShadePanel(QPainter *p, int x, int y, int w, int h, p->setPen(oldPen); // restore pen } - /*! \internal This function draws a rectangle with two pixel line width. @@ -611,6 +609,69 @@ void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c, p->setBrush(oldBrush); } +/*! + \fn void qDrawPlainRoundedRect(QPainter *painter, int x, int y, + int width, int height, qreal rx, qreal ry, + const QColor &lineColor, int lineWidth, + const QBrush *fill) + \relates + + Draws the plain rounded rectangle beginning at (\a x, \a y) + with the given \a width and \a height, + using the horizontal \a rx and vertical radius \a ry, + specified \a painter, \a lineColor and \a lineWidth. + The rectangle's interior is filled with the \a + fill brush unless \a fill is \nullptr. + + \warning This function does not look at QWidget::style() or + QApplication::style(). Use the drawing functions in QStyle to make + widgets that follow the current GUI style. + + Alternatively you can use a QFrame widget and apply the + QFrame::setFrameStyle() function to display a plain rectangle: + + \snippet code/src_gui_painting_qdrawutil.cpp 4 + + \sa qDrawShadeRect(), QStyle +*/ + +void qDrawPlainRoundedRect(QPainter *p, int x, int y, int w, int h, + qreal rx, qreal ry, const QColor &c, + int lineWidth, const QBrush *fill) +{ + if (w == 0 || h == 0) + return; + if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) { + qWarning("qDrawPlainRect: Invalid parameters"); + } + + PainterStateGuard painterGuard(p); + const qreal devicePixelRatio = p->device()->devicePixelRatio(); + if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { + painterGuard.save(); + const qreal inverseScale = qreal(1) / devicePixelRatio; + p->scale(inverseScale, inverseScale); + x = qRound(devicePixelRatio * x); + y = qRound(devicePixelRatio * y); + w = devicePixelRatio * w; + h = devicePixelRatio * h; + lineWidth = qRound(devicePixelRatio * lineWidth); + p->translate(0.5, 0.5); + } + + p->save(); + p->setPen(c); + p->setBrush(Qt::NoBrush); + for (int i=0; idrawRoundedRect(x+i, y+i, w-i*2 - 1, h-i*2 - 1, rx, ry); + if (fill) { // fill with fill color + p->setPen(Qt::NoPen); + p->setBrush(*fill); + p->drawRoundedRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, rx, ry); + } + p->restore(); +} + /***************************************************************************** Overloaded functions. *****************************************************************************/ @@ -819,6 +880,38 @@ void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &c, lineWidth, fill); } +/*! + \fn void qDrawPlainRoundedRect(QPainter *painter, const QRect &rect, + qreal rx, qreal ry, + const QColor &lineColor, int lineWidth, + const QBrush *fill) + \relates + \overload + + Draws the plain rectangle specified by \a rect using + the horizontal \a rx and vertical radius \a ry, + the given \a painter, \a lineColor and \a lineWidth. + The rectangle's interior is filled with the + \a fill brush unless \a fill is \nullptr. + + \warning This function does not look at QWidget::style() or + QApplication::style(). Use the drawing functions in QStyle to make + widgets that follow the current GUI style. + + Alternatively you can use a QFrame widget and apply the + QFrame::setFrameStyle() function to display a plain rectangle: + + \snippet code/src_gui_painting_qdrawutil.cpp 9 + + \sa qDrawShadeRect(), QStyle +*/ + +void qDrawPlainRoundedRect(QPainter *p, const QRect &r, qreal rx, qreal ry, + const QColor &c, int lineWidth, const QBrush *fill) +{ + qDrawPlainRoundedRect(p, r.x(), r.y(), r.width(), r.height(), rx, ry, c, + lineWidth, fill); +} /*! \class QTileRules diff --git a/src/widgets/styles/qdrawutil.h b/src/widgets/styles/qdrawutil.h index 2fc957d493..a4732e014e 100644 --- a/src/widgets/styles/qdrawutil.h +++ b/src/widgets/styles/qdrawutil.h @@ -71,6 +71,12 @@ Q_WIDGETS_EXPORT void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, co Q_WIDGETS_EXPORT void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &, int lineWidth = 1, const QBrush *fill = nullptr); +Q_WIDGETS_EXPORT void qDrawPlainRoundedRect(QPainter *p, int x, int y, int w, int h, + qreal rx, qreal ry, const QColor &, int lineWidth = 1, + const QBrush *fill = nullptr); + +Q_WIDGETS_EXPORT void qDrawPlainRoundedRect(QPainter *p, const QRect& r, qreal rx, qreal ry, + const QColor &, int lineWidth = 1, const QBrush *fill = nullptr); struct QTileRules -- cgit v1.2.3