Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickabstractcolorpicker.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 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// Qt-Security score:significant reason:default
4
6
8
9#include <QtQuickTemplates2/private/qquickcontrol_p_p.h>
10#include <QtQuickTemplates2/private/qquickdeferredexecute_p_p.h>
11
12#include <qpa/qplatformintegration.h>
13#include <private/qguiapplication_p.h>
14
15QQuickAbstractColorPickerPrivate::QQuickAbstractColorPickerPrivate() = default;
16
17bool QQuickAbstractColorPickerPrivate::handlePress(const QPointF &point, ulong timestamp)
18{
19 Q_Q(QQuickAbstractColorPicker);
20 QQuickControlPrivate::handlePress(point, timestamp);
21 m_pressPoint = point;
22 q->setPressed(true);
23 q->updateColor(point);
24 return true;
25}
26
27bool QQuickAbstractColorPickerPrivate::handleMove(const QPointF &point, ulong timestamp)
28{
29 Q_Q(QQuickAbstractColorPicker);
30 QQuickControlPrivate::handleMove(point, timestamp);
31 if (point != m_pressPoint)
32 q->updateColor(point);
33 return true;
34}
35
36bool QQuickAbstractColorPickerPrivate::handleRelease(const QPointF &point, ulong timestamp)
37{
38 Q_Q(QQuickAbstractColorPicker);
39 QQuickControlPrivate::handleRelease(point, timestamp);
40 m_pressPoint = QPointF();
41 q->setKeepMouseGrab(false);
42 q->setKeepTouchGrab(false);
43 q->setPressed(false);
44 q->updateColor(point);
45 return true;
46}
47
49{
50 Q_Q(QQuickAbstractColorPicker);
51 QQuickControlPrivate::handleUngrab();
52 m_pressPoint = QPointF();
53 q->setPressed(false);
54}
55
57{
58 Q_Q(QQuickAbstractColorPicker);
59 quickCancelDeferred(q, handleName());
60}
61
63{
64 Q_Q(QQuickAbstractColorPicker);
65 if (m_handle.wasExecuted())
66 return;
67
68 if (!m_handle || complete)
69 quickBeginDeferred(q, handleName(), m_handle);
70 if (complete)
71 quickCompleteDeferred(q, handleName(), m_handle);
72}
73
75{
76 Q_Q(QQuickAbstractColorPicker);
77 QQuickControlPrivate::itemImplicitWidthChanged(item);
78 if (item == m_handle)
79 emit q->implicitHandleWidthChanged();
80}
81
83{
84 Q_Q(QQuickAbstractColorPicker);
85 QQuickControlPrivate::itemImplicitHeightChanged(item);
86 if (item == m_handle)
87 emit q->implicitHandleHeightChanged();
88}
89
90QQuickAbstractColorPicker::QQuickAbstractColorPicker(QQuickAbstractColorPickerPrivate &dd,
91 QQuickItem *parent)
92 : QQuickControl(dd, parent)
93{
94 setActiveFocusOnTab(true);
95 setAcceptedMouseButtons(Qt::LeftButton);
96}
97
98QQuickAbstractColorPicker::~QQuickAbstractColorPicker()
99{
100 Q_D(QQuickAbstractColorPicker);
101 if (d->m_handle)
102 d->removeImplicitSizeListener(d->m_handle);
103}
104
105QColor QQuickAbstractColorPicker::color() const
106{
107 Q_D(const QQuickAbstractColorPicker);
108 return d->m_hsl ? QColor::fromHslF(d->m_hsva.h, d->m_hsva.s, d->m_hsva.l, d->m_hsva.a)
109 : QColor::fromHsvF(d->m_hsva.h, d->m_hsva.s, d->m_hsva.v, d->m_hsva.a);
110}
111
112void QQuickAbstractColorPicker::setColor(const QColor &c)
113{
114 Q_D(QQuickAbstractColorPicker);
115 // QColor represents a theoretical color, rather than simply an rgba value.
116 // Therefore, two QColor objects can be different,
117 // and yet translate to the same rgba value.
118 // Since the color picker can reuse the same rgba value for multiple pixels,
119 // we should not return early if the rgba() values are equal,
120 // but only if the QColor objects are exactly the same.
121
122 if (color() == c)
123 return;
124
125 // When called from QQuickColorDialogImpl, it might not have the same spec as the current color
126 // picker.
127 if (d->m_hsl && c.spec() == QColor::Spec::Hsv) {
128 const auto sl = getSaturationAndLightness(c.hsvSaturationF(), c.valueF());
129 d->m_hsva.h = qBound(.0, c.hsvHueF(), 1.0);
130 d->m_hsva.s = qBound(.0, sl.first, 1.0);
131 d->m_hsva.l = qBound(.0, sl.second, 1.0);
132 } else if (!d->m_hsl && c.spec() == QColor::Spec::Hsl) {
133 const auto sv = getSaturationAndValue(c.hslSaturationF(), c.lightnessF());
134 d->m_hsva.h = qBound(.0, c.hslHueF(), 1.0);
135 d->m_hsva.s = qBound(.0, sv.first, 1.0);
136 d->m_hsva.v = qBound(.0, sv.second, 1.0);
137 } else {
138 d->m_hsva.h = qBound(.0, d->m_hsl ? c.hslHueF() : c.hsvHueF(), 1.0);
139 d->m_hsva.s = qBound(.0, d->m_hsl ? c.hslSaturationF() : c.hsvSaturationF(), 1.0);
140 d->m_hsva.v = qBound(.0, d->m_hsl ? c.lightnessF() : c.valueF(), 1.0);
141 }
142
143 d->m_hsva.a = qBound(.0, c.alphaF(), 1.0);
144
145 emit colorChanged(color());
146}
147
148qreal QQuickAbstractColorPicker::alpha() const
149{
150 Q_D(const QQuickAbstractColorPicker);
151 return d->m_hsva.a;
152}
153
154void QQuickAbstractColorPicker::setAlpha(qreal alpha)
155{
156 Q_D(QQuickAbstractColorPicker);
157
158 if (!qt_is_finite(alpha))
159 return;
160
161 alpha = qBound(.0, alpha, 1.0);
162
163 if (qFuzzyCompare(d->m_hsva.a, alpha))
164 return;
165
166 d->m_hsva.a = alpha;
167
168 emit colorChanged(color());
169}
170
171qreal QQuickAbstractColorPicker::hue() const
172{
173 Q_D(const QQuickAbstractColorPicker);
174 return d->m_hsva.h;
175}
176void QQuickAbstractColorPicker::setHue(qreal hue)
177{
178 Q_D(QQuickAbstractColorPicker);
179
180 if (!qt_is_finite(hue))
181 return;
182
183 d->m_hsva.h = hue;
184
185 emit colorChanged(color());
186}
187
188qreal QQuickAbstractColorPicker::saturation() const
189{
190 Q_D(const QQuickAbstractColorPicker);
191 return d->m_hsva.s;
192}
193
194void QQuickAbstractColorPicker::setSaturation(qreal saturation)
195{
196 Q_D(QQuickAbstractColorPicker);
197 if (!qt_is_finite(saturation))
198 return;
199
200 d->m_hsva.s = saturation;
201
202 emit colorChanged(color());
203}
204qreal QQuickAbstractColorPicker::value() const
205{
206 Q_D(const QQuickAbstractColorPicker);
207 return d->m_hsl ? getSaturationAndValue(d->m_hsva.s, d->m_hsva.l).second : d->m_hsva.v;
208}
209void QQuickAbstractColorPicker::setValue(qreal value)
210{
211 Q_D(QQuickAbstractColorPicker);
212 if (!qt_is_finite(value))
213 return;
214
215 const auto sv = d->m_hsl ? getSaturationAndValue(d->m_hsva.s, d->m_hsva.l)
216 : std::pair<qreal, qreal>(d->m_hsva.s, value);
217 d->m_hsva.s = sv.first;
218 d->m_hsva.v = sv.second;
219
220 emit colorChanged(color());
221}
222
223qreal QQuickAbstractColorPicker::lightness() const
224{
225 Q_D(const QQuickAbstractColorPicker);
226 return d->m_hsl ? d->m_hsva.l : getSaturationAndLightness(d->m_hsva.s, d->m_hsva.v).second;
227}
228void QQuickAbstractColorPicker::setLightness(qreal lightness)
229{
230 Q_D(QQuickAbstractColorPicker);
231 if (!qt_is_finite(lightness))
232 return;
233
234 const auto sl = !d->m_hsl ? getSaturationAndLightness(d->m_hsva.s, d->m_hsva.v)
235 : std::pair<qreal, qreal>(d->m_hsva.s, lightness);
236 d->m_hsva.s = sl.first;
237 d->m_hsva.l = sl.second;
238
239 emit colorChanged(color());
240}
241
242/*!
243 \internal
244
245 This property holds whether the slider is pressed.
246*/
247bool QQuickAbstractColorPicker::isPressed() const
248{
249 Q_D(const QQuickAbstractColorPicker);
250 return d->m_pressed;
251}
252
253void QQuickAbstractColorPicker::setPressed(bool pressed)
254{
255 Q_D(QQuickAbstractColorPicker);
256 if (pressed == d->m_pressed)
257 return;
258
259 d->m_pressed = pressed;
260 emit pressedChanged();
261}
262
263/*!
264 \internal
265
266 This property holds the handle item.
267*/
268QQuickItem *QQuickAbstractColorPicker::handle() const
269{
270 QQuickAbstractColorPickerPrivate *d = const_cast<QQuickAbstractColorPickerPrivate *>(d_func());
271 if (!d->m_handle)
272 d->executeHandle();
273 return d->m_handle;
274}
275
276void QQuickAbstractColorPicker::setHandle(QQuickItem *handle)
277{
278 Q_D(QQuickAbstractColorPicker);
279 if (handle == d->m_handle)
280 return;
281
282 if (!d->m_handle.isExecuting())
283 d->cancelHandle();
284
285 const qreal oldImplicitHandleWidth = implicitHandleWidth();
286 const qreal oldImplicitHandleHeight = implicitHandleHeight();
287
288 d->removeImplicitSizeListener(d->m_handle);
289 QQuickControlPrivate::hideOldItem(d->m_handle);
290 d->m_handle = handle;
291
292 if (handle) {
293 if (!handle->parentItem())
294 handle->setParentItem(this);
295 d->addImplicitSizeListener(handle);
296 }
297
298 if (!qFuzzyCompare(oldImplicitHandleWidth, implicitHandleWidth()))
299 emit implicitHandleWidthChanged();
300 if (!qFuzzyCompare(oldImplicitHandleHeight, implicitHandleHeight()))
301 emit implicitHandleHeightChanged();
302 if (!d->m_handle.isExecuting())
303 emit handleChanged();
304}
305
306/*!
307 \internal
308 \readonly
309
310 This property holds the implicit handle width.
311
312 The value is equal to \c {handle ? handle.implicitWidth : 0}.
313
314 This is typically used, together with \l {Control::}{implicitContentWidth} and
315 \l {Control::}{implicitBackgroundWidth}, to calculate the \l {Item::}{implicitWidth}.
316
317 \sa implicitHandleHeight
318*/
319qreal QQuickAbstractColorPicker::implicitHandleWidth() const
320{
321 Q_D(const QQuickAbstractColorPicker);
322 if (!d->m_handle)
323 return 0;
324 return d->m_handle->implicitWidth();
325}
326
327/*!
328 \internal
329 \readonly
330
331 This property holds the implicit handle height.
332
333 The value is equal to \c {handle ? handle.implicitHeight : 0}.
334
335 This is typically used, together with \l {Control::}{implicitContentHeight} and
336 \l {Control::}{implicitBackgroundHeight}, to calculate the \l {Item::}{implicitHeight}.
337
338 \sa implicitHandleWidth
339*/
340qreal QQuickAbstractColorPicker::implicitHandleHeight() const
341{
342 Q_D(const QQuickAbstractColorPicker);
343 if (!d->m_handle)
344 return 0;
345 return d->m_handle->implicitHeight();
346}
347
348void QQuickAbstractColorPicker::componentComplete()
349{
350 Q_D(QQuickAbstractColorPicker);
351 d->executeHandle(true);
352 QQuickControl::componentComplete();
353}
354
355void QQuickAbstractColorPicker::updateColor(const QPointF &pos)
356{
357 QColor c = colorAt(pos);
358 c.setAlphaF(alpha());
359 setColor(c);
360
361 emit colorPicked(c);
362}
bool handleRelease(const QPointF &point, ulong timestamp) override
void itemImplicitHeightChanged(QQuickItem *item) override
void itemImplicitWidthChanged(QQuickItem *item) override
bool handlePress(const QPointF &point, ulong timestamp) override
bool handleMove(const QPointF &point, ulong timestamp) override