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 | |
4 | #include "qquickstyleitemslider.h" |
5 | |
6 | QT_BEGIN_NAMESPACE |
7 | |
8 | QFont QQuickStyleItemSlider::styleFont(QQuickItem *control) const |
9 | { |
10 | return style()->font(element: QStyle::CE_ProgressBarLabel, state: controlSize(item: control)); |
11 | } |
12 | |
13 | void QQuickStyleItemSlider::connectToControl() const |
14 | { |
15 | QQuickStyleItem::connectToControl(); |
16 | auto slider = control<QQuickSlider>(); |
17 | connect(sender: slider, signal: &QQuickSlider::fromChanged, context: this, slot: &QQuickStyleItem::markImageDirty); |
18 | connect(sender: slider, signal: &QQuickSlider::toChanged, context: this, slot: &QQuickStyleItem::markImageDirty); |
19 | connect(sender: slider, signal: &QQuickSlider::positionChanged, context: this, slot: &QQuickStyleItem::markImageDirty); |
20 | connect(sender: slider, signal: &QQuickSlider::valueChanged, context: this, slot: &QQuickStyleItem::markImageDirty); |
21 | connect(sender: slider, signal: &QQuickSlider::stepSizeChanged, context: this, slot: &QQuickStyleItem::markImageDirty); |
22 | connect(sender: slider, signal: &QQuickSlider::pressedChanged, context: this, slot: &QQuickStyleItem::markImageDirty); |
23 | connect(sender: slider, signal: &QQuickSlider::orientationChanged, context: this, slot: &QQuickStyleItem::markImageDirty); |
24 | } |
25 | |
26 | StyleItemGeometry QQuickStyleItemSlider::calculateGeometry() |
27 | { |
28 | QStyleOptionSlider styleOption; |
29 | initStyleOption(styleOption); |
30 | |
31 | StyleItemGeometry geometry; |
32 | geometry.minimumSize = style()->sizeFromContents(ct: QStyle::CT_Slider, opt: &styleOption, contentsSize: QSize(0, 0)); |
33 | geometry.implicitSize = geometry.minimumSize; |
34 | styleOption.rect = QRect(QPoint(0, 0), geometry.implicitSize); |
35 | geometry.layoutRect = style()->subElementRect(subElement: QStyle::SE_SliderLayoutItem, option: &styleOption); |
36 | geometry.ninePatchMargins = style()->ninePatchMargins(cc: QStyle::CC_Slider, opt: &styleOption, imageSize: geometry.minimumSize); |
37 | geometry.focusFrameRadius = style()->pixelMetric(metric: QStyle::PM_SliderFocusFrameRadius, option: &styleOption); |
38 | |
39 | return geometry; |
40 | } |
41 | |
42 | void QQuickStyleItemSlider::paintEvent(QPainter *painter) const |
43 | { |
44 | QStyleOptionSlider styleOption; |
45 | initStyleOption(styleOption); |
46 | style()->drawComplexControl(cc: QStyle::CC_Slider, opt: &styleOption, p: painter); |
47 | } |
48 | |
49 | void QQuickStyleItemSlider::initStyleOption(QStyleOptionSlider &styleOption) const |
50 | { |
51 | initStyleOptionBase(styleOption); |
52 | auto slider = control<QQuickSlider>(); |
53 | |
54 | styleOption.subControls = QStyle::SC_None; |
55 | if (m_subControl & Groove) |
56 | styleOption.subControls |= QStyle::SC_SliderGroove; |
57 | if (m_subControl & Handle) |
58 | styleOption.subControls |= QStyle::SC_SliderHandle; |
59 | styleOption.activeSubControls = QStyle::SC_None; |
60 | styleOption.orientation = slider->orientation(); |
61 | |
62 | if (slider->isPressed()) |
63 | styleOption.state |= QStyle::State_Sunken; |
64 | |
65 | qreal min = 0; |
66 | qreal max = 1; |
67 | if (!qFuzzyIsNull(d: slider->stepSize())) { |
68 | min = slider->from(); |
69 | max = slider->to(); |
70 | |
71 | // TODO: add proper API for tickmarks |
72 | const int index = slider->metaObject()->indexOfProperty(name: "qqc2_style_tickPosition" ); |
73 | if (index != -1) { |
74 | const int tickPosition = slider->metaObject()->property(index).read(obj: slider).toInt(); |
75 | styleOption.tickPosition = QStyleOptionSlider::TickPosition(tickPosition); |
76 | if (styleOption.tickPosition != QStyleOptionSlider::NoTicks) |
77 | styleOption.subControls |= QStyle::SC_SliderTickmarks; |
78 | } |
79 | } |
80 | |
81 | // Since the [from, to] interval in QQuickSlider is floating point, users can |
82 | // specify very small ranges and step sizes, (e.g. [0.., 0.25], step size 0.05). |
83 | // Since the style operates on ints, we cannot pass these values directly to the style, |
84 | // so we normalize all values to the range [0, 10000] |
85 | static const qreal Scale = 10000; |
86 | const qreal normalizeMultiplier = Scale/(max - min); |
87 | styleOption.tickInterval = int(slider->stepSize() * normalizeMultiplier); |
88 | styleOption.minimum = 0; |
89 | styleOption.maximum = int(Scale); |
90 | styleOption.sliderValue = int((slider->value() - min) * normalizeMultiplier); |
91 | styleOption.sliderPosition = int(slider->position() * styleOption.maximum); |
92 | } |
93 | |
94 | QT_END_NAMESPACE |
95 | |
96 | #include "moc_qquickstyleitemslider.cpp" |
97 | |