Introduce progressbar in QWindows11Style

Introduces Windows 11 styled progressbar to QWindows11Style drawn by QPainter.
The progress is indicated by a thicker line in accent color on a grey track.
Animation for indetermined progress is changed to follow the animation of Windows 11
progress bars.

Change-Id: Icac79fdbe40b82b10e1fd0e59b389890a7de6683
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
bb10
Wladimir Leuschner 2023-06-21 14:15:55 +03:00
parent c0b5c1567b
commit 6723515e5b
2 changed files with 76 additions and 1 deletions

View File

@ -10,6 +10,8 @@
#include <QGraphicsDropShadowEffect>
#include "qdrawutil.h"
#include <chrono>
QT_BEGIN_NAMESPACE
const static int topLevelRoundingRadius = 8; //Radius for toplevel items like popups for round corners
@ -718,6 +720,80 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
}
}
break;
case QStyle::CE_ProgressBarGroove:{
if (const QStyleOptionProgressBar* progbaropt = qstyleoption_cast<const QStyleOptionProgressBar*>(option)) {
const QProgressBar* bar = qobject_cast<const QProgressBar*>(widget);
QRectF rect = subElementRect(SE_ProgressBarContents, progbaropt, widget);
QPointF center = rect.center();
if (bar->orientation() & Qt::Horizontal) {
rect.setHeight(1);
rect.moveTop(center.y());
} else {
rect.setWidth(1);
rect.moveLeft(center.x());
}
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::gray);
painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius);
}
break;
}
case QStyle::CE_ProgressBarContents:
if (const QStyleOptionProgressBar* progbaropt = qstyleoption_cast<const QStyleOptionProgressBar*>(option)) {
const QProgressBar* bar = qobject_cast<const QProgressBar*>(widget);
QRectF rect = subElementRect(SE_ProgressBarContents, progbaropt, widget);
QRectF originalRect = rect;
QPointF center = rect.center();
bool isIndeterminate = progbaropt->maximum == 0 && progbaropt->minimum == 0;
float fillPercentage = 0;
if (!isIndeterminate) {
fillPercentage = ((float(progbaropt->progress) - float(progbaropt->minimum)) / (float(progbaropt->maximum) - float(progbaropt->minimum)));
if (bar->orientation() == Qt::Horizontal) {
rect.setHeight(4);
rect.moveTop(center.y() - 1.5);
rect.setWidth(rect.width() * fillPercentage);
} else {
float oldHeight = rect.height();
rect.setWidth(4);
rect.moveLeft(center.x() - 1.5);
rect.moveTop(oldHeight * (1.0f - fillPercentage));
rect.setHeight(oldHeight * fillPercentage);
}
} else {
auto elapsedTime = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
fillPercentage = (elapsedTime.time_since_epoch().count() % 5000)/(5000.0f*0.75);
if (bar->orientation() == Qt::Horizontal) {
float barBegin = qMin(qMax(fillPercentage-0.25,0.0) * rect.width(), float(rect.width()));
float barEnd = qMin(fillPercentage * rect.width(), float(rect.width()));
rect = QRect(QPoint(rect.left() + barBegin, rect.top()), QPoint(rect.left() + barEnd, rect.bottom()));
rect.setHeight(4);
rect.moveTop(center.y() - 1.5);
} else {
float barBegin = qMin(qMax(fillPercentage-0.25,0.0) * rect.height(), float(rect.height()));
float barEnd = qMin(fillPercentage * rect.height(), float(rect.height()));
rect = QRect(QPoint(rect.left(), rect.bottom() - barEnd), QPoint(rect.right(), rect.bottom() - barBegin));
rect.setWidth(4);
rect.moveLeft(center.x() - 1.5);
}
const_cast<QWidget*>(widget)->update();
}
if (progbaropt->invertedAppearance && bar->orientation() == Qt::Horizontal)
rect.moveLeft(originalRect.width() * (1.0 - fillPercentage));
else if (progbaropt->invertedAppearance && bar->orientation() == Qt::Vertical)
rect.moveBottom(originalRect.height() * fillPercentage);
painter->setPen(Qt::NoPen);
painter->setBrush(progbaropt->palette.accent());
painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius);
}
break;
case QStyle::CE_ProgressBarLabel:
if (const QStyleOptionProgressBar* progbaropt = qstyleoption_cast<const QStyleOptionProgressBar*>(option)) {
QRect rect = subElementRect(SE_ProgressBarLabel, progbaropt, widget);
painter->setPen(progbaropt->palette.text().color());
painter->drawText(rect, progbaropt->text,Qt::AlignVCenter|Qt::AlignLeft);
}
break;
case CE_PushButtonLabel:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
QRect textRect = btn->rect;

View File

@ -29,7 +29,6 @@ class QWindows11Style : public QWindowsVistaStyle
public:
QWindows11Style();
~QWindows11Style() override;
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
QPainter *painter, const QWidget *widget) const override;
void drawPrimitive(PrimitiveElement element, const QStyleOption *option,