Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickstylehelper.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include "qquickstyleoption.h"
6#include "qquickstyle_p.h"
7
8#include <QtCore/qmath.h>
9#include <QtGui/qpainter.h>
10#include <QtGui/qpixmapcache.h>
11#include <QtGui/qwindow.h>
12#include <QtGui/private/qhighdpiscaling_p.h>
13#include <QtGui/private/qguiapplication_p.h>
14#include <QtGui/private/qmath_p.h>
15#include <QtGui/private/qhexstring_p.h>
16
17#include <qmetaobject.h>
18#include <qstringbuilder.h>
19
21
22Q_GUI_EXPORT int qt_defaultDpiX();
23
24namespace QQC2 {
25
26namespace QStyleHelper {
27
29{
30 const QStyleOptionComplex *complexOption = qstyleoption_cast<const QStyleOptionComplex *>(option);
31 QString tmp = key % HexString<uint>(option->state)
32 % HexString<uint>(option->direction)
33 % HexString<uint>(complexOption ? uint(complexOption->activeSubControls) : 0u)
34 % HexString<quint64>(option->palette.cacheKey())
35 % HexString<uint>(size.width())
36 % HexString<uint>(size.height());
37
38 if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
39 tmp = tmp % HexString<uint>(spinBox->buttonSymbols)
40 % HexString<uint>(spinBox->stepEnabled)
41 % QLatin1Char(spinBox->frame ? '1' : '0'); ;
42 }
43
44 return tmp;
45}
46
47#ifdef Q_OS_DARWIN
48static const qreal qstyleBaseDpi = 72;
49#else
50static const qreal qstyleBaseDpi = 96;
51#endif
52
54{
55#ifndef Q_OS_DARWIN
56 // Prioritize the application override, except for on macOS where
57 // we have historically not supported the AA_Use96Dpi flag.
59 return 96;
60#endif
61
62 // Expect that QStyleOption::QFontMetrics::QFont has the correct DPI set
63 if (option)
64 return option->fontMetrics.fontDpi();
65
66 return qstyleBaseDpi;
67}
68
73
75{
76 return dpiScaled(value, device->logicalDpiX());
77}
78
83
84#if QT_CONFIG(accessibility)
85bool isInstanceOf(QObject *obj, QAccessible::Role role)
86{
87 bool match = false;
88 QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(obj);
89 match = iface && iface->role() == role;
90 return match;
91}
92
93// Searches for an ancestor of a particular accessible role
94bool hasAncestor(QObject *obj, QAccessible::Role role)
95{
96 bool found = false;
97 QObject *parent = obj ? obj->parent() : nullptr;
98 while (parent && !found) {
99 if (isInstanceOf(parent, role))
100 found = true;
101 parent = parent->parent();
102 }
103 return found;
104}
105#endif
106
107int calcBigLineSize(int radius)
108{
109 int bigLineSize = radius / 6;
110 if (bigLineSize < 4)
111 bigLineSize = 4;
112 if (bigLineSize > radius / 2)
113 bigLineSize = radius / 2;
114 return bigLineSize;
115}
116
118{
119 const int width = dial->rect.width();
120 const int height = dial->rect.height();
121 const int r = qMin(width, height) / 2;
122 const int currentSliderPosition = dial->upsideDown ? dial->sliderPosition : (dial->maximum - dial->sliderPosition);
123 qreal a = 0;
124 qreal startAngle = (90. - dial->startAngle) * Q_PI / 180.;
125 qreal spanAngle = (dial->endAngle - dial->startAngle) * Q_PI / 180.;
126 if (dial->maximum == dial->minimum)
127 a = Q_PI / 2;
128 else
129 a = (startAngle - (currentSliderPosition - dial->minimum) * spanAngle
130 / (dial->maximum - dial->minimum));
131 qreal xc = width / 2.0;
132 qreal yc = height / 2.0;
134 qreal back = offset * len;
135 QPointF pos(QPointF(xc + back * qCos(a), yc - back * qSin(a)));
136 return pos;
137}
138
140{
141 static const qreal rad_factor = 180 / Q_PI;
142 qreal _angle = 0;
143
144 if (p1.x() == p2.x()) {
145 if (p1.y() < p2.y())
146 _angle = 270;
147 else
148 _angle = 90;
149 } else {
150 qreal x1, x2, y1, y2;
151
152 if (p1.x() <= p2.x()) {
153 x1 = p1.x(); y1 = p1.y();
154 x2 = p2.x(); y2 = p2.y();
155 } else {
156 x2 = p1.x(); y2 = p1.y();
157 x1 = p2.x(); y1 = p2.y();
158 }
159
160 qreal m = -(y2 - y1) / (x2 - x1);
161 _angle = qAtan(m) * rad_factor;
162
163 if (p1.x() < p2.x())
164 _angle = 180 - _angle;
165 else
166 _angle = -_angle;
167 }
168 return _angle;
169}
170
172{
173 QPolygonF poly;
174 int width = dial->rect.width();
175 int height = dial->rect.height();
176 qreal r = qMin(width, height) / 2;
177 int bigLineSize = calcBigLineSize(int(r));
178
179 qreal xc = width / 2 + 0.5;
180 qreal yc = height / 2 + 0.5;
181 const int ns = dial->tickInterval;
182 if (!ns) // Invalid values may be set by Qt Designer.
183 return poly;
184 int notches = (dial->maximum + ns - 1 - dial->minimum) / ns;
185 if (notches <= 0)
186 return poly;
187 if (dial->maximum < dial->minimum || dial->maximum - dial->minimum > 1000) {
188 int maximum = dial->minimum + 1000;
189 notches = (maximum + ns - 1 - dial->minimum) / ns;
190 }
191
192 poly.resize(2 + 2 * notches);
193 int smallLineSize = bigLineSize / 2;
194 for (int i = 0; i <= notches; ++i) {
195 qreal angle = dial->dialWrapping ? Q_PI * 3 / 2 - i * 2 * Q_PI / notches
196 : (Q_PI * 8 - i * 10 * Q_PI / notches) / 6;
197 qreal s = qSin(angle);
198 qreal c = qCos(angle);
199 if (i == 0 || (((ns * i) % (dial->pageStep ? dial->pageStep : 1)) == 0)) {
200 poly[2 * i] = QPointF(xc + (r - bigLineSize) * c,
201 yc - (r - bigLineSize) * s);
202 poly[2 * i + 1] = QPointF(xc + r * c, yc - r * s);
203 } else {
204 poly[2 * i] = QPointF(xc + (r - 1 - smallLineSize) * c,
205 yc - (r - 1 - smallLineSize) * s);
206 poly[2 * i + 1] = QPointF(xc + (r - 1) * c, yc -(r - 1) * s);
207 }
208 }
209 return poly;
210}
211
212// This will draw a nice and shiny QDial for us. We don't want
213// all the shinyness in QWindowsStyle, hence we place it here
214
216{
217 QPalette pal = option->palette;
218 const int width = option->rect.width();
219 const int height = option->rect.height();
220 const bool enabled = option->state & QStyle::State_Enabled;
221 qreal r = qMin(width, height) / 2;
222 r -= r/50;
223 const qreal penSize = r/20.0;
224
225 painter->save();
227
228 // Draw notches
229 if (option->subControls & QStyle::SC_DialTickmarks) {
230 painter->setPen(option->palette.dark().color().darker(120));
232 }
233
234 // setting color before BEGIN_STYLE_PIXMAPCACHE since
235 // otherwise it is not set when the image is in the cache
236 QColor buttonColor = pal.button().color().toHsv();
237 buttonColor.setHsv(buttonColor .hue(),
238 qMin(140, buttonColor .saturation()),
239 qMax(180, buttonColor.value()));
240
241 // Cache dial background
243 p->setRenderHint(QPainter::Antialiasing);
244
245 const qreal d_ = r / 6;
246 const qreal dx = option->rect.x() + d_ + (width - 2 * r) / 2 + 1;
247 const qreal dy = option->rect.y() + d_ + (height - 2 * r) / 2 + 1;
248
249 QRectF br = QRectF(dx + 0.5, dy + 0.5,
250 int(r * 2 - 2 * d_ - 2),
251 int(r * 2 - 2 * d_ - 2));
252
253 if (enabled) {
254 // Drop shadow
255 qreal shadowSize = qMax(1.0, penSize/2.0);
256 QRectF shadowRect= br.adjusted(-2*shadowSize, -2*shadowSize,
257 2*shadowSize, 2*shadowSize);
258 QRadialGradient shadowGradient(shadowRect.center().x(),
259 shadowRect.center().y(), shadowRect.width()/2.0,
260 shadowRect.center().x(), shadowRect.center().y());
261 shadowGradient.setColorAt(qreal(0.91), QColor(0, 0, 0, 40));
262 shadowGradient.setColorAt(qreal(1.0), Qt::transparent);
263 p->setBrush(shadowGradient);
264 p->setPen(Qt::NoPen);
265 p->translate(shadowSize, shadowSize);
266 p->drawEllipse(shadowRect);
267 p->translate(-shadowSize, -shadowSize);
268
269 // Main gradient
270 QRadialGradient gradient(br.center().x() - br.width()/3, dy,
271 br.width()*1.3, br.center().x(),
272 br.center().y() - br.height()/2);
273 gradient.setColorAt(0, buttonColor.lighter(110));
274 gradient.setColorAt(qreal(0.5), buttonColor);
275 gradient.setColorAt(qreal(0.501), buttonColor.darker(102));
276 gradient.setColorAt(1, buttonColor.darker(115));
277 p->setBrush(gradient);
278 } else {
279 p->setBrush(Qt::NoBrush);
280 }
281
282 p->setPen(QPen(buttonColor.darker(280)));
283 p->drawEllipse(br);
284 p->setBrush(Qt::NoBrush);
285 p->setPen(buttonColor.lighter(110));
286 p->drawEllipse(br.adjusted(1, 1, -1, -1));
287
288 if (option->state & QStyle::State_HasFocus) {
289 QColor highlight = pal.highlight().color().toHsv();
290 highlight.setHsv(highlight.hue(),
291 qMin(160, highlight.saturation()),
292 qMax(230, highlight.value()));
293 highlight.setAlpha(127);
294 p->setPen(QPen(highlight, 2.0));
295 p->setBrush(Qt::NoBrush);
296 p->drawEllipse(br.adjusted(-1, -1, 1, 1));
297 }
298
300
301 QPointF dp = calcRadialPos(option, qreal(0.70));
302 buttonColor = buttonColor.lighter(104);
303 buttonColor.setAlphaF(0.8f);
304 const qreal ds = r/qreal(7.0);
305 QRectF dialRect(dp.x() - ds, dp.y() - ds, 2*ds, 2*ds);
306 QRadialGradient dialGradient(dialRect.center().x() + dialRect.width()/2,
307 dialRect.center().y() + dialRect.width(),
308 dialRect.width()*2,
309 dialRect.center().x(), dialRect.center().y());
310 dialGradient.setColorAt(1, buttonColor.darker(140));
311 dialGradient.setColorAt(qreal(0.4), buttonColor.darker(120));
312 dialGradient.setColorAt(0, buttonColor.darker(110));
313 if (penSize > 3.0) {
314 painter->setPen(QPen(QColor(0, 0, 0, 25), penSize));
316 }
317
318 painter->setBrush(dialGradient);
319 painter->setPen(QColor(255, 255, 255, 150));
320 painter->drawEllipse(dialRect.adjusted(-1, -1, 1, 1));
321 painter->setPen(QColor(0, 0, 0, 80));
322 painter->drawEllipse(dialRect);
323 painter->restore();
324}
325
327 int left, int top, int right,
328 int bottom)
329{
330 QSize size = pixmap.size();
331 //painter->setRenderHint(QPainter::SmoothPixmapTransform);
332
333 //top
334 if (top > 0) {
335 painter->drawPixmap(QRect(rect.left() + left, rect.top(), rect.width() -right - left, top), pixmap,
336 QRect(left, 0, size.width() -right - left, top));
337
338 //top-left
339 if(left > 0)
340 painter->drawPixmap(QRect(rect.left(), rect.top(), left, top), pixmap,
341 QRect(0, 0, left, top));
342
343 //top-right
344 if (right > 0)
345 painter->drawPixmap(QRect(rect.left() + rect.width() - right, rect.top(), right, top), pixmap,
346 QRect(size.width() - right, 0, right, top));
347 }
348
349 //left
350 if (left > 0)
351 painter->drawPixmap(QRect(rect.left(), rect.top()+top, left, rect.height() - top - bottom), pixmap,
352 QRect(0, top, left, size.height() - bottom - top));
353
354 //center
355 painter->drawPixmap(QRect(rect.left() + left, rect.top()+top, rect.width() -right - left,
356 rect.height() - bottom - top), pixmap,
357 QRect(left, top, size.width() -right -left,
358 size.height() - bottom - top));
359 //right
360 if (right > 0)
361 painter->drawPixmap(QRect(rect.left() +rect.width() - right, rect.top()+top, right, rect.height() - top - bottom), pixmap,
362 QRect(size.width() - right, top, right, size.height() - bottom - top));
363
364 //bottom
365 if (bottom > 0) {
366 painter->drawPixmap(QRect(rect.left() +left, rect.top() + rect.height() - bottom,
367 rect.width() - right - left, bottom), pixmap,
368 QRect(left, size.height() - bottom,
369 size.width() - right - left, bottom));
370 //bottom-left
371 if (left > 0)
372 painter->drawPixmap(QRect(rect.left(), rect.top() + rect.height() - bottom, left, bottom), pixmap,
373 QRect(0, size.height() - bottom, left, bottom));
374
375 //bottom-right
376 if (right > 0)
377 painter->drawPixmap(QRect(rect.left() + rect.width() - right, rect.top() + rect.height() - bottom, right, bottom), pixmap,
378 QRect(size.width() - right, size.height() - bottom, right, bottom));
379
380 }
381}
382
384{
386 return SizeMini;
387 else if (opt && opt->state & QStyle::State_Small)
388 return SizeSmall;
389
390 return SizeDefault;
391}
392
394{
395// if (qobject_cast<const QScrollBar *>(widget) && widget->parent() &&
396// qobject_cast<const QAbstractScrollArea *>(widget->parent()->parent()))
397// return widget->parentWidget()->parentWidget()->palette().color(QPalette::Base);
398 return pal.color(QPalette::Base);
399}
400
401}
402
403} // namespace QQC2
404
IOBluetoothDevice * device
bool frame
whether the spin box draws itself with a frame
ButtonSymbols buttonSymbols
the current button symbol mode
virtual StepEnabled stepEnabled() const
Virtual function that determines whether stepping up and down is legal at any given time.
const QColor & color() const
Returns the brush color.
Definition qbrush.h:121
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
int saturation() const noexcept
Returns the HSV saturation color component of this color.
Definition qcolor.cpp:1734
void setAlphaF(float alpha)
Sets the alpha of this color to alpha.
Definition qcolor.cpp:1511
QColor darker(int f=200) const noexcept
Definition qcolor.cpp:2857
QColor toHsv() const noexcept
Creates and returns an HSV QColor based on this color.
Definition qcolor.cpp:2188
int hue() const noexcept
Returns the HSV hue color component of this color.
Definition qcolor.cpp:1708
void setAlpha(int alpha)
Sets the alpha of this color to alpha.
Definition qcolor.cpp:1481
void setHsv(int h, int s, int v, int a=255)
Sets a HSV color value; h is the hue, s is the saturation, v is the value and a is the alpha componen...
Definition qcolor.cpp:1099
int value() const noexcept
Returns the value color component of this color.
Definition qcolor.cpp:1756
QColor lighter(int f=150) const noexcept
Definition qcolor.cpp:2812
static bool testAttribute(Qt::ApplicationAttribute attribute)
Returns true if attribute attribute is set; otherwise returns false.
void setColorAt(qreal pos, const QColor &color)
Creates a stop point at the given position with the given color.
Definition qbrush.cpp:1563
\inmodule QtCore
Definition qobject.h:103
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
void setPen(const QColor &color)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void drawLine(const QLineF &line)
Draws a line defined by line.
Definition qpainter.h:442
void restore()
Restores the current painter state (pops a saved state off the stack).
void drawLines(const QLineF *lines, int lineCount)
Draws the first lineCount lines in the array lines using the current pen.
void save()
Saves the current painter state (pushes the state onto a stack).
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device.
void drawEllipse(const QRectF &r)
Draws the ellipse defined by the given rectangle.
void setBrush(const QBrush &brush)
Sets the painter's brush to the given brush.
@ Antialiasing
Definition qpainter.h:52
void setRenderHint(RenderHint hint, bool on=true)
Sets the given render hint on the painter if on is true; otherwise clears the render hint.
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
const QBrush & highlight() const
Returns the highlight brush of the current color group.
Definition qpalette.h:98
const QBrush & button() const
Returns the button brush of the current color group.
Definition qpalette.h:84
const QColor & color(ColorGroup cg, ColorRole cr) const
Returns the color in the specified color group, used for the given color role.
Definition qpalette.h:67
\inmodule QtGui
Definition qpen.h:28
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
\inmodule QtCore\reentrant
Definition qpoint.h:217
The QPolygonF class provides a list of points using floating point precision.
Definition qpolygon.h:96
\inmodule QtGui
Definition qbrush.h:412
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore\reentrant
Definition qrect.h:30
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
QStyle::State state
QPixmap p2
QPixmap p1
[0]
rect
[4]
QStyleOptionButton opt
QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size)
int calcBigLineSize(int radius)
QPolygonF calcLines(const QStyleOptionSlider *dial)
static QPointF calcRadialPos(const QStyleOptionSlider *dial, qreal offset)
qreal dpi(const QStyleOption *option)
void drawBorderPixmap(const QPixmap &pixmap, QPainter *painter, const QRect &rect, int left, int top, int right, int bottom)
WidgetSizePolicy widgetSizePolicy(const QStyleOption *opt)
QColor backgroundColor(const QPalette &pal)
static const qreal qstyleBaseDpi
qreal dpiScaled(qreal value, qreal dpi)
void drawDial(const QStyleOptionSlider *option, QPainter *painter)
Combined button and popup list for selecting options.
@ transparent
Definition qnamespace.h:47
@ NoPen
@ AA_Use96Dpi
Definition qnamespace.h:433
@ NoBrush
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
auto qCos(T v)
Definition qmath.h:60
auto qAtan(T v)
Definition qmath.h:84
auto qSin(T v)
Definition qmath.h:54
static QT_BEGIN_NAMESPACE const qreal Q_PI
Definition qmath_p.h:24
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
const GLfloat * m
GLuint64 key
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLuint GLfloat GLfloat GLfloat x1
GLdouble GLdouble GLdouble GLdouble top
GLdouble GLdouble right
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLint GLsizei width
GLint left
GLint GLint bottom
GLfloat angle
GLenum GLuint GLintptr offset
GLhandleARB obj
[2]
GLdouble s
[6]
Definition qopenglext.h:235
const GLubyte * c
GLfixed GLfixed GLfixed y2
GLfixed GLfixed x2
GLfloat GLfloat p
[1]
GLuint GLenum option
GLenum GLsizei len
QT_BEGIN_NAMESPACE Q_GUI_EXPORT int qt_defaultDpiX()
Definition qfont.cpp:110
#define BEGIN_STYLE_PIXMAPCACHE(a)
Definition qstyle_p.h:46
#define END_STYLE_PIXMAPCACHE
Definition qstyle_p.h:66
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
unsigned int uint
Definition qtypes.h:34
double qreal
Definition qtypes.h:187
widget render & pixmap
QPainter painter(this)
[7]
QSpinBox * spinBox
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18