1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qtdesignsystemstyle.h"
#include "stylehelper.h"
#include "utilsicons.h"
#include <QGuiApplication>
#include <QPaintEvent>
#include <QPainter>
#include <QPainterPath>
#include <QPixmapCache>
#include <QWidget>
#include <QStyleOption>
#include <QTabBar>
namespace Utils {
using namespace StyleHelper;
using namespace StyleHelper::SpacingTokens;
constexpr TextFormat TabBarTf
{Theme::Token_Text_Muted, StyleHelper::UiElementH5};
constexpr TextFormat TabBarTfActive
{Theme::Token_Text_Default, TabBarTf.uiElement};
constexpr TextFormat TabBarTfDisabled
{Theme::Token_Text_Subtle, TabBarTf.uiElement};
QtDesignSystemStyle::QtDesignSystemStyle()
{
}
QtDesignSystemStyle::~QtDesignSystemStyle() = default;
void QtDesignSystemStyle::drawControl(ControlElement element, const QStyleOption *opt,
QPainter *painter, const QWidget *widget) const
{
switch (element) {
case CE_TabBarTabLabel: {
auto tabOpt = qstyleoption_cast<const QStyleOptionTab*>(opt);
QStyleOptionTab myTabOpt = *tabOpt;
const QColor c = ((myTabOpt.state & QStyle::State_Enabled) ?
(myTabOpt.state & QStyle::State_Selected) ? TabBarTfActive
: TabBarTf
: TabBarTfDisabled).color();
myTabOpt.palette.setColor(widget->foregroundRole(), c);
myTabOpt.state = myTabOpt.state & ~QStyle::State_HasFocus; // Avoid extra focus rect
QCommonStyle::drawControl(element, &myTabOpt, painter, widget);
break;
}
case CE_TabBarTabShape: {
const bool selected = opt->state & QStyle::State_Selected;
const bool enabled = opt->state & QStyle::State_Enabled;
const bool hovered = !selected && opt->rect.contains(widget->mapFromGlobal(QCursor::pos()));
auto tabOpt = qstyleoption_cast<const QStyleOptionTab*>(opt);
const int paddingL = tabOpt->position == QStyleOptionTab::Beginning ? 0 : PaddingHXxs;
const int paddingR = tabOpt->position == QStyleOptionTab::End ? 0 : PaddingHXxs;
const QRect shapeR = opt->rect.adjusted(paddingL, 0, -paddingR, 0);
if (selected || (hovered && enabled)) {
if (hovered || tabOpt->position == QStyleOptionTab::Moving) {
StyleHelper::drawCardBg(painter, shapeR.adjusted(0, 0, 0, +SpacingTokens::RadiusS),
creatorColor(Theme::Token_Foreground_Subtle));
}
QRect highLightRect = shapeR;
highLightRect.moveTop(highLightRect.height() - StyleHelper::HighlightThickness);
const QColor color = creatorColor(enabled ? hovered ? Theme::Token_Text_Subtle
: Theme::Token_Accent_Default
: Theme::Token_Foreground_Subtle);
painter->fillRect(highLightRect, color);
}
break;
}
default:
QCommonStyle::drawControl(element, opt, painter, widget);
break;
}
}
void QtDesignSystemStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *opt,
QPainter *painter, const QWidget *widget) const
{
switch (element) {
case PE_FrameTabBarBase: {
QRectF borderR = opt->rect.toRectF();
const int lineWidth = 1;
borderR.setTop(borderR.bottom() - lineWidth);
const bool enabled = opt->state & QStyle::State_Enabled;
const QColor color = creatorColor(enabled ? Theme::Token_Stroke_Subtle
: Theme::Token_Foreground_Subtle);
painter->fillRect(borderR, color);
break;
}
default:
QCommonStyle::drawPrimitive(element, opt, painter, widget);
break;
}
}
int QtDesignSystemStyle::pixelMetric(PixelMetric m, const QStyleOption *opt,
const QWidget *widget) const
{
switch (m) {
case PM_TabBarTabShiftVertical:
case PM_TabBarTabShiftHorizontal:
return 0;
case PM_TabBarTabHSpace:
return PaddingHL + PaddingHL;
case PM_TabBarTabVSpace: {
const int textHeight = opt->fontMetrics.height();
return PaddingVM + TabBarTf.lineHeight() + PaddingVM - textHeight;
}
default:
return QCommonStyle::pixelMetric(m, opt, widget);
}
}
QIcon QtDesignSystemStyle::standardIcon(StandardPixmap sp, const QStyleOption *opt,
const QWidget *widget) const
{
QIcon icon;
switch (sp) {
case SP_TabCloseButton: {
static const QIcon tabClose = Icons::CLOSE_FOREGROUND.icon();
icon = tabClose;
break;
}
default:
icon = QCommonStyle::standardIcon(sp, opt, widget);
break;
}
return icon;
}
void QtDesignSystemStyle::polish(QWidget *widget)
{
QCommonStyle::polish(widget);
if (auto tabBar = qobject_cast<QTabBar*>(widget)) {
tabBar->setFont(TabBarTf.font());
for (int count = tabBar->count(), i = 0; i < count; ++i ) {
for (const QTabBar::ButtonPosition pos : {QTabBar::LeftSide, QTabBar::RightSide}) {
if (QWidget *tabButton = tabBar->tabButton(i, pos))
tabButton->setStyle(this);
}
}
}
}
QStyle *QtDesignSystemStyle::instance()
{
static QtDesignSystemStyle style;
return &style;
}
} // namespace Utils
|