1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the tools applications of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include "qtcolorline.h" |
41 | #include "qdrawutil.h" |
42 | |
43 | #include <QtGui/QPainter> |
44 | #include <QtGui/QPaintEvent> |
45 | #include <QtWidgets/QStyleOption> |
46 | #include <QtGui/QRegion> |
47 | |
48 | QT_BEGIN_NAMESPACE |
49 | |
50 | class QtColorLinePrivate |
51 | { |
52 | QtColorLine *q_ptr; |
53 | Q_DECLARE_PUBLIC(QtColorLine) |
54 | public: |
55 | QtColorLinePrivate(); |
56 | |
57 | QColor color() const; |
58 | void setColor(const QColor &color); |
59 | |
60 | QtColorLine::ColorComponent colorComponent() const; |
61 | void setColorComponent(QtColorLine::ColorComponent component); |
62 | |
63 | void setIndicatorSize(int size); |
64 | int indicatorSize() const; |
65 | |
66 | void setIndicatorSpace(int space); |
67 | int indicatorSpace() const; |
68 | |
69 | void setFlip(bool flip); |
70 | bool flip() const; |
71 | |
72 | void setBackgroundCheckered(bool checkered); |
73 | bool isBackgroundCheckered() const; |
74 | |
75 | void setOrientation(Qt::Orientation orientation); |
76 | Qt::Orientation orientation() const; |
77 | |
78 | void resizeEvent(QResizeEvent *event); |
79 | void paintEvent(QPaintEvent *event); |
80 | void mousePressEvent(QMouseEvent *event); |
81 | void mouseMoveEvent(QMouseEvent *event); |
82 | void mouseReleaseEvent(QMouseEvent *event); |
83 | void mouseDoubleClickEvent(QMouseEvent *event); |
84 | private: |
85 | void checkColor(); |
86 | bool isMainPixmapValid() const; |
87 | void validate(); |
88 | void recreateMainPixmap(); |
89 | QSize pixmapSizeFromGeometrySize(const QSize &geometrySize) const; |
90 | QPixmap gradientPixmap(int size, Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped = false) const; |
91 | QPixmap gradientPixmap(Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped = false) const; |
92 | QPixmap hueGradientPixmap(int size, Qt::Orientation orientation, bool flipped = false, |
93 | int saturation = 0xFF, int value = 0xFF, int alpha = 0xFF) const; |
94 | QPixmap hueGradientPixmap(Qt::Orientation orientation, bool flipped = false, |
95 | int saturation = 0xFF, int value = 0xFF, int alpha = 0xFF) const; |
96 | |
97 | QVector<QRect> rects(const QPointF &point) const; |
98 | |
99 | QColor colorFromPoint(const QPointF &point) const; |
100 | QPointF pointFromColor(const QColor &color) const; |
101 | |
102 | QColor m_color; |
103 | QtColorLine::ColorComponent m_component; |
104 | bool m_flipped; |
105 | bool m_backgroundCheckered; |
106 | Qt::Orientation m_orientation; |
107 | bool m_dragging; |
108 | bool m_combiningAlpha; |
109 | int m_indicatorSize; |
110 | int m_indicatorSpace; |
111 | QPointF m_point; |
112 | QPoint m_clickOffset; |
113 | |
114 | QPixmap m_mainPixmap; |
115 | QPixmap m_alphalessPixmap; |
116 | QPixmap m_semiAlphaPixmap; |
117 | QSize m_pixmapSize; |
118 | |
119 | struct PixData { |
120 | QSize size; |
121 | QColor color; |
122 | QtColorLine::ColorComponent component; |
123 | bool flipped; |
124 | Qt::Orientation orientation; |
125 | }; |
126 | |
127 | PixData m_lastValidMainPixmapData; |
128 | }; |
129 | |
130 | QtColorLinePrivate::QtColorLinePrivate() |
131 | : m_color(Qt::black), m_component(QtColorLine::Value), |
132 | m_flipped(false), m_backgroundCheckered(true), m_orientation(Qt::Horizontal), m_dragging(false), m_combiningAlpha(false) |
133 | { |
134 | m_indicatorSize = 22; |
135 | m_indicatorSpace = 0; |
136 | m_pixmapSize = QSize(0, 0); |
137 | m_point = pointFromColor(color: m_color); |
138 | } |
139 | |
140 | void QtColorLinePrivate::setColor(const QColor &color) |
141 | { |
142 | if (m_color == color) |
143 | return; |
144 | if (!color.isValid()) |
145 | return; |
146 | if (m_dragging) // Warning perhaps here, recursive call |
147 | return; |
148 | m_color = color; |
149 | checkColor(); |
150 | m_point = pointFromColor(color: m_color); |
151 | q_ptr->update(); |
152 | } |
153 | |
154 | QColor QtColorLinePrivate::color() const |
155 | { |
156 | return m_color; |
157 | } |
158 | |
159 | void QtColorLinePrivate::setColorComponent(QtColorLine::ColorComponent component) |
160 | { |
161 | if (m_component == component) |
162 | return; |
163 | if (m_dragging) // Warning perhaps here, recursive call |
164 | return; |
165 | m_component = component; |
166 | checkColor(); |
167 | m_point = pointFromColor(color: m_color); |
168 | q_ptr->update(); |
169 | } |
170 | |
171 | QtColorLine::ColorComponent QtColorLinePrivate::colorComponent() const |
172 | { |
173 | return m_component; |
174 | } |
175 | |
176 | void QtColorLinePrivate::setIndicatorSize(int size) |
177 | { |
178 | if (size <= 0) |
179 | return; |
180 | if (m_dragging) // Warning perhaps here, recursive call |
181 | return; |
182 | if (m_indicatorSize == size) |
183 | return; |
184 | m_indicatorSize = size; |
185 | m_pixmapSize = pixmapSizeFromGeometrySize(geometrySize: q_ptr->contentsRect().size()); |
186 | q_ptr->update(); |
187 | q_ptr->updateGeometry(); |
188 | } |
189 | |
190 | int QtColorLinePrivate::indicatorSize() const |
191 | { |
192 | return m_indicatorSize; |
193 | } |
194 | |
195 | void QtColorLinePrivate::setIndicatorSpace(int space) |
196 | { |
197 | if (space < 0) |
198 | return; |
199 | if (m_dragging) // Warning perhaps here, recursive call |
200 | return; |
201 | if (m_indicatorSpace == space) |
202 | return; |
203 | m_indicatorSpace = space; |
204 | m_pixmapSize = pixmapSizeFromGeometrySize(geometrySize: q_ptr->contentsRect().size()); |
205 | q_ptr->update(); |
206 | } |
207 | |
208 | int QtColorLinePrivate::indicatorSpace() const |
209 | { |
210 | return m_indicatorSpace; |
211 | } |
212 | |
213 | void QtColorLinePrivate::setFlip(bool flip) |
214 | { |
215 | if (m_dragging) // Warning perhaps here, recursive call |
216 | return; |
217 | if (m_flipped == flip) |
218 | return; |
219 | m_flipped = flip; |
220 | m_point = pointFromColor(color: m_color); |
221 | q_ptr->update(); |
222 | } |
223 | |
224 | bool QtColorLinePrivate::flip() const |
225 | { |
226 | return m_flipped; |
227 | } |
228 | |
229 | void QtColorLinePrivate::setBackgroundCheckered(bool checkered) |
230 | { |
231 | if (m_backgroundCheckered == checkered) |
232 | return; |
233 | m_backgroundCheckered = checkered; |
234 | q_ptr->update(); |
235 | } |
236 | |
237 | bool QtColorLinePrivate::isBackgroundCheckered() const |
238 | { |
239 | return m_backgroundCheckered; |
240 | } |
241 | |
242 | void QtColorLinePrivate::setOrientation(Qt::Orientation orientation) |
243 | { |
244 | if (m_dragging) // Warning perhaps here, recursive call |
245 | return; |
246 | if (m_orientation == orientation) |
247 | return; |
248 | |
249 | m_orientation = orientation; |
250 | if (!q_ptr->testAttribute(attribute: Qt::WA_WState_OwnSizePolicy)) { |
251 | QSizePolicy sp = q_ptr->sizePolicy(); |
252 | sp.transpose(); |
253 | q_ptr->setSizePolicy(sp); |
254 | q_ptr->setAttribute(Qt::WA_WState_OwnSizePolicy, on: false); |
255 | } |
256 | m_point = pointFromColor(color: m_color); |
257 | q_ptr->update(); |
258 | q_ptr->updateGeometry(); |
259 | } |
260 | |
261 | Qt::Orientation QtColorLinePrivate::orientation() const |
262 | { |
263 | return m_orientation; |
264 | } |
265 | |
266 | void QtColorLinePrivate::checkColor() |
267 | { |
268 | switch (m_component) { |
269 | case QtColorLine::Red: |
270 | case QtColorLine::Green: |
271 | case QtColorLine::Blue: |
272 | if (m_color.spec() != QColor::Rgb) |
273 | m_color = m_color.toRgb(); |
274 | break; |
275 | case QtColorLine::Hue: |
276 | case QtColorLine::Saturation: |
277 | case QtColorLine::Value: |
278 | if (m_color.spec() != QColor::Hsv) |
279 | m_color = m_color.toHsv(); |
280 | break; |
281 | default: |
282 | break; |
283 | } |
284 | if (m_color.spec() == QColor::Hsv) { |
285 | if (m_color.hue() == 360 || m_color.hue() == -1) { |
286 | m_color.setHsvF(h: 0.0, s: m_color.saturationF(), v: m_color.valueF(), a: m_color.alphaF()); |
287 | } |
288 | } |
289 | } |
290 | |
291 | bool QtColorLinePrivate::isMainPixmapValid() const |
292 | { |
293 | if (m_mainPixmap.isNull()) { |
294 | if (m_pixmapSize.isEmpty()) |
295 | return true; |
296 | else |
297 | return false; |
298 | } |
299 | if (m_lastValidMainPixmapData.component != m_component) |
300 | return false; |
301 | if (m_lastValidMainPixmapData.size != m_pixmapSize) |
302 | return false; |
303 | if (m_lastValidMainPixmapData.flipped != m_flipped) |
304 | return false; |
305 | if (m_lastValidMainPixmapData.orientation != m_orientation) |
306 | return false; |
307 | if (m_lastValidMainPixmapData.color == m_color) |
308 | return true; |
309 | switch (m_component) { |
310 | case QtColorLine::Red: |
311 | if (m_color.green() == m_lastValidMainPixmapData.color.green() && |
312 | m_color.blue() == m_lastValidMainPixmapData.color.blue() && |
313 | (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha())) |
314 | return true; |
315 | break; |
316 | case QtColorLine::Green: |
317 | if (m_color.red() == m_lastValidMainPixmapData.color.red() && |
318 | m_color.blue() == m_lastValidMainPixmapData.color.blue() && |
319 | (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha())) |
320 | return true; |
321 | break; |
322 | case QtColorLine::Blue: |
323 | if (m_color.red() == m_lastValidMainPixmapData.color.red() && |
324 | m_color.green() == m_lastValidMainPixmapData.color.green() && |
325 | (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha())) |
326 | return true; |
327 | break; |
328 | case QtColorLine::Hue: |
329 | if (m_color.saturation() == m_lastValidMainPixmapData.color.saturation() && |
330 | m_color.value() == m_lastValidMainPixmapData.color.value() && |
331 | (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha())) |
332 | return true; |
333 | break; |
334 | case QtColorLine::Saturation: |
335 | if (m_color.hue() == m_lastValidMainPixmapData.color.hue() && |
336 | m_color.value() == m_lastValidMainPixmapData.color.value() && |
337 | (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha())) |
338 | return true; |
339 | break; |
340 | case QtColorLine::Value: |
341 | if (m_color.hue() == m_lastValidMainPixmapData.color.hue() && |
342 | m_color.saturation() == m_lastValidMainPixmapData.color.saturation() && |
343 | (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha())) |
344 | return true; |
345 | break; |
346 | case QtColorLine::Alpha: |
347 | if (m_color.hue() == m_lastValidMainPixmapData.color.hue() && |
348 | m_color.saturation() == m_lastValidMainPixmapData.color.saturation() && |
349 | m_color.value() == m_lastValidMainPixmapData.color.value()) |
350 | return true; |
351 | } |
352 | return false; |
353 | } |
354 | |
355 | void QtColorLinePrivate::validate() |
356 | { |
357 | if (isMainPixmapValid()) |
358 | return; |
359 | |
360 | recreateMainPixmap(); |
361 | } |
362 | |
363 | QPixmap QtColorLinePrivate::gradientPixmap(Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped) const |
364 | { |
365 | int size = m_pixmapSize.width(); |
366 | if (orientation == Qt::Vertical) |
367 | size = m_pixmapSize.height(); |
368 | return gradientPixmap(size, orientation, begin, end, flipped); |
369 | } |
370 | |
371 | QPixmap QtColorLinePrivate::gradientPixmap(int size, Qt::Orientation orientation, |
372 | const QColor &begin, const QColor &end, bool flipped) const |
373 | { |
374 | int gradW = size; |
375 | int gradH = size; |
376 | int w = size; |
377 | int h = size; |
378 | if (orientation == Qt::Horizontal) { |
379 | gradH = 0; |
380 | h = 1; |
381 | } else { |
382 | gradW = 0; |
383 | w = 1; |
384 | } |
385 | QColor c1 = begin; |
386 | QColor c2 = end; |
387 | if (flipped) { |
388 | c1 = end; |
389 | c2 = begin; |
390 | } |
391 | QLinearGradient lg(0, 0, gradW, gradH); |
392 | lg.setColorAt(pos: 0, color: c1); |
393 | lg.setColorAt(pos: 1, color: c2); |
394 | QImage img(w, h, QImage::Format_ARGB32); |
395 | QPainter p(&img); |
396 | p.setCompositionMode(QPainter::CompositionMode_Source); |
397 | p.fillRect(QRect(0, 0, w, h), lg); |
398 | return QPixmap::fromImage(image: img); |
399 | } |
400 | |
401 | QPixmap QtColorLinePrivate::hueGradientPixmap(Qt::Orientation orientation, bool flipped, |
402 | int saturation, int value, int alpha) const |
403 | { |
404 | int size = m_pixmapSize.width(); |
405 | if (orientation == Qt::Vertical) |
406 | size = m_pixmapSize.height(); |
407 | return hueGradientPixmap(size, orientation, flipped, saturation, value, alpha); |
408 | } |
409 | |
410 | QPixmap QtColorLinePrivate::hueGradientPixmap(int size, Qt::Orientation orientation, bool flipped, |
411 | int saturation, int value, int alpha) const |
412 | { |
413 | int gradW = size + 1; |
414 | int gradH = size + 1; |
415 | int w = size; |
416 | int h = size; |
417 | if (orientation == Qt::Horizontal) { |
418 | gradH = 0; |
419 | h = 1; |
420 | } else { |
421 | gradW = 0; |
422 | w = 1; |
423 | } |
424 | QList<QColor> colorList; |
425 | colorList << QColor::fromHsv(h: 0, s: saturation, v: value, a: alpha); |
426 | colorList << QColor::fromHsv(h: 60, s: saturation, v: value, a: alpha); |
427 | colorList << QColor::fromHsv(h: 120, s: saturation, v: value, a: alpha); |
428 | colorList << QColor::fromHsv(h: 180, s: saturation, v: value, a: alpha); |
429 | colorList << QColor::fromHsv(h: 240, s: saturation, v: value, a: alpha); |
430 | colorList << QColor::fromHsv(h: 300, s: saturation, v: value, a: alpha); |
431 | colorList << QColor::fromHsv(h: 0, s: saturation, v: value, a: alpha); |
432 | QLinearGradient lg(0, 0, gradW, gradH); |
433 | for (int i = 0; i <= 6; i++) |
434 | lg.setColorAt(pos: double(i) / 6.0, color: flipped ? colorList.at(i: 6 - i) : colorList.at(i)); |
435 | QImage img(w, h, QImage::Format_ARGB32); |
436 | QPainter p(&img); |
437 | p.setCompositionMode(QPainter::CompositionMode_Source); |
438 | p.fillRect(QRect(0, 0, w, h), lg); |
439 | return QPixmap::fromImage(image: img); |
440 | } |
441 | |
442 | void QtColorLinePrivate::recreateMainPixmap() |
443 | { |
444 | m_lastValidMainPixmapData.size = m_pixmapSize; |
445 | m_lastValidMainPixmapData.component = m_component; |
446 | m_lastValidMainPixmapData.color = m_color; |
447 | m_lastValidMainPixmapData.flipped = m_flipped; |
448 | m_lastValidMainPixmapData.orientation = m_orientation; |
449 | |
450 | if (m_pixmapSize.isEmpty()) { |
451 | m_mainPixmap = QPixmap(); |
452 | m_alphalessPixmap = QPixmap(); |
453 | m_semiAlphaPixmap = QPixmap(); |
454 | return; |
455 | } |
456 | |
457 | if (m_mainPixmap.size() != m_pixmapSize) { |
458 | m_mainPixmap = QPixmap(m_pixmapSize); |
459 | m_alphalessPixmap = QPixmap(m_pixmapSize); |
460 | m_semiAlphaPixmap = QPixmap(m_pixmapSize); |
461 | } |
462 | |
463 | Qt::Orientation orient = m_orientation; |
464 | const bool flip = m_flipped; |
465 | |
466 | const int r = m_color.red(); |
467 | const int g = m_color.green(); |
468 | const int b = m_color.blue(); |
469 | const int h = m_color.hue(); |
470 | const int s = m_color.saturation(); |
471 | const int v = m_color.value(); |
472 | const int a = m_color.alpha(); |
473 | const double coef = 0.5; |
474 | const int semi = qRound(d: a * coef + 0xFF * (1.0 - coef)); |
475 | |
476 | if (m_component == QtColorLine::Hue) { |
477 | m_alphalessPixmap = hueGradientPixmap(orientation: orient, flipped: flip, saturation: s, value: v, alpha: 0xFF); |
478 | if (m_combiningAlpha) { |
479 | m_mainPixmap = hueGradientPixmap(orientation: orient, flipped: flip, saturation: s, value: v, alpha: a); |
480 | m_semiAlphaPixmap = hueGradientPixmap(orientation: orient, flipped: flip, saturation: s, value: v, alpha: semi); |
481 | } |
482 | } else if (m_component == QtColorLine::Saturation) { |
483 | m_alphalessPixmap = gradientPixmap(orientation: orient, begin: QColor::fromHsv(h, s: 0, v, a: 0xFF), end: QColor::fromHsv(h, s: 0xFF, v, a: 0xFF), flipped: flip); |
484 | if (m_combiningAlpha) { |
485 | m_mainPixmap = gradientPixmap(orientation: orient, begin: QColor::fromHsv(h, s: 0, v, a), end: QColor::fromHsv(h, s: 0xFF, v, a), flipped: flip); |
486 | m_semiAlphaPixmap = gradientPixmap(orientation: orient, begin: QColor::fromHsv(h, s: 0, v, a: semi), end: QColor::fromHsv(h, s: 0xFF, v, a: semi), flipped: flip); |
487 | } |
488 | } else if (m_component == QtColorLine::Value) { |
489 | m_alphalessPixmap = gradientPixmap(orientation: orient, begin: QColor::fromRgb(r: 0, g: 0, b: 0, a: 0xFF), end: QColor::fromHsv(h, s, v: 0xFF, a: 0xFF), flipped: flip); |
490 | if (m_combiningAlpha) { |
491 | m_mainPixmap = gradientPixmap(orientation: orient, begin: QColor::fromRgb(r: 0, g: 0, b: 0, a), end: QColor::fromHsv(h, s, v: 0xFF, a), flipped: flip); |
492 | m_semiAlphaPixmap = gradientPixmap(orientation: orient, begin: QColor::fromRgb(r: 0, g: 0, b: 0, a: semi), end: QColor::fromHsv(h, s, v: 0xFF, a: semi), flipped: flip); |
493 | } |
494 | } else if (m_component == QtColorLine::Red) { |
495 | m_alphalessPixmap = gradientPixmap(orientation: orient, begin: QColor::fromRgb(r: 0, g, b, a: 0xFF), end: QColor::fromRgb(r: 0xFF, g, b, a: 0xFF), flipped: flip); |
496 | if (m_combiningAlpha) { |
497 | m_mainPixmap = gradientPixmap(orientation: orient, begin: QColor::fromRgb(r: 0, g, b, a), end: QColor::fromRgb(r: 0xFF, g, b, a), flipped: flip); |
498 | m_semiAlphaPixmap = gradientPixmap(orientation: orient, begin: QColor::fromRgb(r: 0, g, b, a: semi), end: QColor::fromRgb(r: 0xFF, g, b, a: semi), flipped: flip); |
499 | } |
500 | } else if (m_component == QtColorLine::Green) { |
501 | m_alphalessPixmap = gradientPixmap(orientation: orient, begin: QColor::fromRgb(r, g: 0, b, a: 0xFF), end: QColor::fromRgb(r, g: 0xFF, b, a: 0xFF), flipped: flip); |
502 | if (m_combiningAlpha) { |
503 | m_mainPixmap = gradientPixmap(orientation: orient, begin: QColor::fromRgb(r, g: 0, b, a), end: QColor::fromRgb(r, g: 0xFF, b, a), flipped: flip); |
504 | m_semiAlphaPixmap = gradientPixmap(orientation: orient, begin: QColor::fromRgb(r, g: 0, b, a: semi), end: QColor::fromRgb(r, g: 0xFF, b, a: semi), flipped: flip); |
505 | } |
506 | } else if (m_component == QtColorLine::Blue) { |
507 | m_alphalessPixmap = gradientPixmap(orientation: orient, begin: QColor::fromRgb(r, g, b: 0, a: 0xFF), end: QColor::fromRgb(r, g, b: 0xFF, a: 0xFF), flipped: flip); |
508 | if (m_combiningAlpha) { |
509 | m_mainPixmap = gradientPixmap(orientation: orient, begin: QColor::fromRgb(r, g, b: 0, a), end: QColor::fromRgb(r, g, b: 0xFF, a), flipped: flip); |
510 | m_semiAlphaPixmap = gradientPixmap(orientation: orient, begin: QColor::fromRgb(r, g, b: 0, a: semi), end: QColor::fromRgb(r, g, b: 0xFF, a: semi), flipped: flip); |
511 | } |
512 | } else if (m_component == QtColorLine::Alpha) { |
513 | m_mainPixmap = gradientPixmap(orientation: orient, begin: QColor::fromRgb(r, g, b, a: 0), end: QColor::fromRgb(r, g, b, a: 0xFF), flipped: flip); |
514 | |
515 | // m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, 0xFF), QColor::fromRgb(r, g, b, 0xFF), flip); |
516 | // m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, semi), QColor::fromRgb(r, g, b, semi), flip); |
517 | } |
518 | if (!m_combiningAlpha && m_component != QtColorLine::Alpha) |
519 | m_mainPixmap = m_alphalessPixmap; |
520 | } |
521 | |
522 | QSize QtColorLinePrivate::pixmapSizeFromGeometrySize( |
523 | const QSize &geometrySize) const |
524 | { |
525 | QSize size(m_indicatorSize + 2 * m_indicatorSpace - 1, |
526 | m_indicatorSize + 2 * m_indicatorSpace - 1); |
527 | if (m_orientation == Qt::Horizontal) |
528 | size.setHeight(0); |
529 | else |
530 | size.setWidth(0); |
531 | return geometrySize - size; |
532 | } |
533 | |
534 | QColor QtColorLinePrivate::colorFromPoint(const QPointF &point) const |
535 | { |
536 | QPointF p = point; |
537 | if (p.x() < 0) |
538 | p.setX(0.0); |
539 | else if (p.x() > 1) |
540 | p.setX(1.0); |
541 | if (p.y() < 0) |
542 | p.setY(0.0); |
543 | else if (p.y() > 1) |
544 | p.setY(1.0); |
545 | |
546 | double pos = p.x(); |
547 | if (m_orientation == Qt::Vertical) |
548 | pos = p.y(); |
549 | if (m_flipped) |
550 | pos = 1.0 - pos; |
551 | QColor c; |
552 | qreal hue; |
553 | switch (m_component) { |
554 | case QtColorLine::Red: |
555 | c.setRgbF(r: pos, g: m_color.greenF(), b: m_color.blueF(), a: m_color.alphaF()); |
556 | break; |
557 | case QtColorLine::Green: |
558 | c.setRgbF(r: m_color.redF(), g: pos, b: m_color.blueF(), a: m_color.alphaF()); |
559 | break; |
560 | case QtColorLine::Blue: |
561 | c.setRgbF(r: m_color.redF(), g: m_color.greenF(), b: pos, a: m_color.alphaF()); |
562 | break; |
563 | case QtColorLine::Hue: |
564 | hue = pos; |
565 | hue *= 35999.0 / 36000.0; |
566 | c.setHsvF(h: hue, s: m_color.saturationF(), v: m_color.valueF(), a: m_color.alphaF()); |
567 | break; |
568 | case QtColorLine::Saturation: |
569 | c.setHsvF(h: m_color.hueF(), s: pos, v: m_color.valueF(), a: m_color.alphaF()); |
570 | break; |
571 | case QtColorLine::Value: |
572 | c.setHsvF(h: m_color.hueF(), s: m_color.saturationF(), v: pos, a: m_color.alphaF()); |
573 | break; |
574 | case QtColorLine::Alpha: |
575 | c.setHsvF(h: m_color.hueF(), s: m_color.saturationF(), v: m_color.valueF(), a: pos); |
576 | break; |
577 | } |
578 | return c; |
579 | } |
580 | |
581 | QPointF QtColorLinePrivate::pointFromColor(const QColor &color) const |
582 | { |
583 | qreal hue = color.hueF(); |
584 | if (color.hue() == 360) |
585 | hue = 0.0; |
586 | else |
587 | hue *= 36000.0 / 35999.0; |
588 | |
589 | double pos = 0.0; |
590 | switch (m_component) { |
591 | case QtColorLine::Red: |
592 | pos = color.redF(); |
593 | break; |
594 | case QtColorLine::Green: |
595 | pos = color.greenF(); |
596 | break; |
597 | case QtColorLine::Blue: |
598 | pos = color.blueF(); |
599 | break; |
600 | case QtColorLine::Hue: |
601 | pos = hue; |
602 | break; |
603 | case QtColorLine::Saturation: |
604 | pos = color.saturationF(); |
605 | break; |
606 | case QtColorLine::Value: |
607 | pos = color.valueF(); |
608 | break; |
609 | case QtColorLine::Alpha: |
610 | pos = color.alphaF(); |
611 | break; |
612 | } |
613 | if (m_flipped) |
614 | pos = 1.0 - pos; |
615 | QPointF p(pos, pos); |
616 | if (m_orientation == Qt::Horizontal) |
617 | p.setY(0); |
618 | else |
619 | p.setX(0); |
620 | return p; |
621 | } |
622 | |
623 | QVector<QRect> QtColorLinePrivate::rects(const QPointF &point) const |
624 | { |
625 | QRect r = q_ptr->geometry(); |
626 | r.moveTo(ax: 0, ay: 0); |
627 | |
628 | int x1 = (int)((r.width() - m_indicatorSize - 2 * m_indicatorSpace) * point.x() + 0.5); |
629 | int x2 = x1 + m_indicatorSize + 2 * m_indicatorSpace; |
630 | int y1 = (int)((r.height() - m_indicatorSize - 2 * m_indicatorSpace) * point.y() + 0.5); |
631 | int y2 = y1 + m_indicatorSize + 2 * m_indicatorSpace; |
632 | |
633 | QVector<QRect> rects; |
634 | if (m_orientation == Qt::Horizontal) { |
635 | // r0 r1 r2 |
636 | QRect r0(0, 0, x1, r.height()); |
637 | QRect r1(x1 + m_indicatorSpace, 0, m_indicatorSize, r.height()); |
638 | QRect r2(x2, 0, r.width() - x2, r.height()); |
639 | |
640 | rects << r0 << r1 << r2; |
641 | } else { |
642 | // r0 |
643 | // r1 |
644 | // r2 |
645 | QRect r0(0, 0, r.width(), y1); |
646 | QRect r1(0, y1 + m_indicatorSpace, r.width(), m_indicatorSize); |
647 | QRect r2(0, y2, r.width(), r.height() - y2); |
648 | |
649 | rects << r0 << r1 << r2; |
650 | } |
651 | return rects; |
652 | } |
653 | |
654 | void QtColorLinePrivate::resizeEvent(QResizeEvent *event) |
655 | { |
656 | m_pixmapSize = pixmapSizeFromGeometrySize(geometrySize: event->size()); |
657 | } |
658 | |
659 | void QtColorLinePrivate::paintEvent(QPaintEvent *) |
660 | { |
661 | QRect rect = q_ptr->rect(); |
662 | |
663 | QVector<QRect> r = rects(point: m_point); |
664 | |
665 | QColor c = colorFromPoint(point: m_point); |
666 | if (!m_combiningAlpha && m_component != QtColorLine::Alpha) |
667 | c.setAlpha(0xFF); |
668 | |
669 | QPainter p(q_ptr); |
670 | if (q_ptr->isEnabled()) { |
671 | if (m_backgroundCheckered) { |
672 | int pixSize = 20; |
673 | QPixmap pm(2 * pixSize, 2 * pixSize); |
674 | QPainter pmp(&pm); |
675 | pmp.fillRect(x: 0, y: 0, w: pixSize, h: pixSize, c: Qt::white); |
676 | pmp.fillRect(x: pixSize, y: pixSize, w: pixSize, h: pixSize, c: Qt::white); |
677 | pmp.fillRect(x: 0, y: pixSize, w: pixSize, h: pixSize, c: Qt::black); |
678 | pmp.fillRect(x: pixSize, y: 0, w: pixSize, h: pixSize, c: Qt::black); |
679 | pmp.end(); |
680 | |
681 | p.setBrushOrigin(x: (rect.width() % pixSize + pixSize) / 2, y: (rect.height() % pixSize + pixSize) / 2); |
682 | |
683 | QRegion region(r[1].adjusted(xp1: 4, yp1: 4, xp2: -4, yp2: -4)); |
684 | region += QRect(rect.topLeft(), QPoint(r[1].left() + 0, rect.bottom())); |
685 | region += QRect(QPoint(r[1].right() - 0, rect.top()), rect.bottomRight()); |
686 | region += QRect(rect.topLeft(), QPoint(rect.right(), r[1].top() + 0)); |
687 | region += QRect(QPoint(rect.left(), r[1].bottom() - 0), rect.bottomRight()); |
688 | p.setClipRegion(region); |
689 | p.fillRect(rect, pm); |
690 | p.setBrushOrigin(x: 0, y: 0); |
691 | p.setClipping(false); |
692 | } |
693 | |
694 | validate(); |
695 | |
696 | QSize fieldSize = pixmapSizeFromGeometrySize(geometrySize: q_ptr->geometry().size()); |
697 | |
698 | QPoint posOnField = r[1].topLeft() - QPoint(m_indicatorSpace, m_indicatorSpace); |
699 | int x = posOnField.x(); |
700 | int y = posOnField.y(); |
701 | int w = fieldSize.width(); |
702 | int h = fieldSize.height(); |
703 | |
704 | QRect r0, r2; |
705 | if (m_orientation == Qt::Horizontal) { |
706 | r0 = QRect(0, 0, x, m_pixmapSize.height()); |
707 | r2 = QRect(x + 1, 0, w - x - 1, m_pixmapSize.height()); |
708 | } else { |
709 | r0 = QRect(0, 0, m_pixmapSize.width(), y); |
710 | r2 = QRect(0, y + 1, m_pixmapSize.width(), h - y - 1); |
711 | } |
712 | |
713 | p.setBrush(m_mainPixmap); |
714 | p.setPen(Qt::NoPen); |
715 | if (r[0].isValid()) { |
716 | p.drawRect(r: r[0]); |
717 | } |
718 | if (r[2].isValid()) { |
719 | p.setBrushOrigin(r[2].topLeft() - r2.topLeft()); |
720 | p.drawRect(r: r[2]); |
721 | } |
722 | if (m_indicatorSpace) { |
723 | p.setBrush(c); |
724 | if (m_orientation == Qt::Horizontal) { |
725 | p.drawRect(r: r[1].adjusted(xp1: -m_indicatorSpace, yp1: 0, xp2: -r[1].width(), yp2: 0)); |
726 | p.drawRect(r: r[1].adjusted(xp1: r[1].width(), yp1: 0, xp2: m_indicatorSpace, yp2: 0)); |
727 | } else { |
728 | p.drawRect(r: r[1].adjusted(xp1: 0, yp1: -m_indicatorSpace, xp2: 0, yp2: -r[1].height())); |
729 | p.drawRect(r: r[1].adjusted(xp1: 0, yp1: r[1].height(), xp2: 0, yp2: m_indicatorSpace)); |
730 | } |
731 | } |
732 | |
733 | QPen pen(c); |
734 | p.setPen(pen); |
735 | p.setBrush(Qt::NoBrush); |
736 | if (r[1].isValid()) { |
737 | p.drawRect(r: r[1].adjusted(xp1: 0, yp1: 0, xp2: -1, yp2: -1)); |
738 | // p.drawRect(r[1].adjusted(1, 1, -2, -2)); |
739 | } |
740 | double coef = 9.0 / 10; |
741 | p.setPen(Qt::NoPen); |
742 | if (m_component != QtColorLine::Alpha && m_combiningAlpha) { |
743 | p.setBrush(m_alphalessPixmap); |
744 | if (r[0].isValid()) { |
745 | p.setBrushOrigin(QPoint(0, 0)); |
746 | QRect thinRect1 = r[0]; |
747 | QRect thinRect2 = r[0]; |
748 | QRect thinRect = r[0]; |
749 | if (m_orientation == Qt::Horizontal) { |
750 | thinRect1.adjust(dx1: 0, dy1: qRound(d: thinRect1.height() * coef), dx2: 0, dy2: 0); |
751 | thinRect2.adjust(dx1: 0, dy1: 0, dx2: 0, dy2: -qRound(d: thinRect2.height() * coef)); |
752 | thinRect.adjust(dx1: 0, dy1: qRound(d: thinRect.height() * coef), dx2: 0, dy2: -qRound(d: thinRect.height() * coef)); |
753 | } else { |
754 | thinRect1.adjust(dx1: qRound(d: thinRect1.width() * coef), dy1: 0, dx2: 0, dy2: 0); |
755 | thinRect2.adjust(dx1: 0, dy1: 0, dx2: -qRound(d: thinRect2.width() * coef), dy2: 0); |
756 | thinRect.adjust(dx1: qRound(d: thinRect.width() * coef), dy1: 0, dx2: -qRound(d: thinRect.width() * coef), dy2: 0); |
757 | } |
758 | p.drawRect(r: thinRect1); |
759 | p.drawRect(r: thinRect2); |
760 | //p.drawRect(thinRect); |
761 | } |
762 | if (r[2].isValid()) { |
763 | p.setBrushOrigin(r[2].topLeft() - r2.topLeft()); |
764 | QRect thinRect1 = r[2]; |
765 | QRect thinRect2 = r[2]; |
766 | QRect thinRect = r[2]; |
767 | if (m_orientation == Qt::Horizontal) { |
768 | thinRect1.adjust(dx1: 0, dy1: qRound(d: thinRect1.height() * coef), dx2: 0, dy2: 0); |
769 | thinRect2.adjust(dx1: 0, dy1: 0, dx2: 0, dy2: -qRound(d: thinRect2.height() * coef)); |
770 | thinRect.adjust(dx1: 0, dy1: qRound(d: thinRect.height() * coef), dx2: 0, dy2: -qRound(d: thinRect.height() * coef)); |
771 | } else { |
772 | thinRect1.adjust(dx1: qRound(d: thinRect1.width() * coef), dy1: 0, dx2: 0, dy2: 0); |
773 | thinRect2.adjust(dx1: 0, dy1: 0, dx2: -qRound(d: thinRect2.width() * coef), dy2: 0); |
774 | thinRect.adjust(dx1: qRound(d: thinRect.width() * coef), dy1: 0, dx2: -qRound(d: thinRect.width() * coef), dy2: 0); |
775 | } |
776 | p.drawRect(r: thinRect1); |
777 | p.drawRect(r: thinRect2); |
778 | //p.drawRect(thinRect); |
779 | } |
780 | /* |
781 | |
782 | */ |
783 | |
784 | |
785 | |
786 | |
787 | |
788 | p.setPen(Qt::NoPen); |
789 | |
790 | p.setBrush(m_semiAlphaPixmap); |
791 | if (r[0].isValid()) { |
792 | p.setBrushOrigin(QPoint(0, 0)); |
793 | QRect thinRect1 = r[0]; |
794 | QRect thinRect2 = r[0]; |
795 | QRect thinRect = r[0]; |
796 | if (m_orientation == Qt::Horizontal) { |
797 | thinRect1.adjust(dx1: 0, dy1: qRound(d: thinRect1.height() * coef) - 1, dx2: 0, dy2: 0); |
798 | thinRect1.setBottom(thinRect1.top()); |
799 | thinRect2.adjust(dx1: 0, dy1: 0, dx2: 0, dy2: -qRound(d: thinRect2.height() * coef) + 1); |
800 | thinRect2.setTop(thinRect2.bottom()); |
801 | thinRect.adjust(dx1: 0, dy1: qRound(d: thinRect.height() * coef), dx2: 0, dy2: -qRound(d: thinRect.height() * coef)); |
802 | } else { |
803 | thinRect1.adjust(dx1: qRound(d: thinRect1.width() * coef) - 1, dy1: 0, dx2: 0, dy2: 0); |
804 | thinRect1.setRight(thinRect1.left()); |
805 | thinRect2.adjust(dx1: 0, dy1: 0, dx2: -qRound(d: thinRect2.width() * coef) + 1, dy2: 0); |
806 | thinRect2.setLeft(thinRect2.right()); |
807 | thinRect.adjust(dx1: qRound(d: thinRect.width() * coef), dy1: 0, dx2: -qRound(d: thinRect.width() * coef), dy2: 0); |
808 | } |
809 | p.drawRect(r: thinRect1); |
810 | p.drawRect(r: thinRect2); |
811 | //p.drawRect(thinRect); |
812 | } |
813 | if (r[2].isValid()) { |
814 | p.setBrushOrigin(r[2].topLeft() - r2.topLeft()); |
815 | QRect thinRect1 = r[2]; |
816 | QRect thinRect2 = r[2]; |
817 | QRect thinRect = r[2]; |
818 | if (m_orientation == Qt::Horizontal) { |
819 | thinRect1.adjust(dx1: 0, dy1: qRound(d: thinRect1.height() * coef) - 1, dx2: 0, dy2: 0); |
820 | thinRect1.setBottom(thinRect1.top()); |
821 | thinRect2.adjust(dx1: 0, dy1: 0, dx2: 0, dy2: -qRound(d: thinRect2.height() * coef) + 1); |
822 | thinRect2.setTop(thinRect2.bottom()); |
823 | thinRect.adjust(dx1: 0, dy1: qRound(d: thinRect.height() * coef), dx2: 0, dy2: -qRound(d: thinRect.height() * coef)); |
824 | } else { |
825 | thinRect1.adjust(dx1: qRound(d: thinRect1.width() * coef) - 1, dy1: 0, dx2: 0, dy2: 0); |
826 | thinRect1.setRight(thinRect1.left()); |
827 | thinRect2.adjust(dx1: 0, dy1: 0, dx2: -qRound(d: thinRect2.width() * coef) + 1, dy2: 0); |
828 | thinRect2.setLeft(thinRect2.right()); |
829 | thinRect.adjust(dx1: qRound(d: thinRect.width() * coef), dy1: 0, dx2: -qRound(d: thinRect.width() * coef), dy2: 0); |
830 | } |
831 | p.drawRect(r: thinRect1); |
832 | p.drawRect(r: thinRect2); |
833 | //p.drawRect(thinRect); |
834 | } |
835 | p.setBrush(m_alphalessPixmap); |
836 | QRegion region; |
837 | if (m_orientation == Qt::Horizontal) { |
838 | region += r[1].adjusted(xp1: 0, yp1: qRound(d: r[1].height() * coef), xp2: 0, yp2: 0); |
839 | region += r[1].adjusted(xp1: 0, yp1: 0, xp2: 0, yp2: -qRound(d: r[1].height() * coef)); |
840 | p.setClipRegion(region); |
841 | } else { |
842 | region += r[1].adjusted(xp1: qRound(d: r[1].width() * coef), yp1: 0, xp2: 0, yp2: 0); |
843 | region += r[1].adjusted(xp1: 0, yp1: 0, xp2: -qRound(d: r[1].width() * coef), yp2: 0); |
844 | p.setClipRegion(region); |
845 | } |
846 | p.setClipRegion(region); |
847 | p.setBrush(Qt::NoBrush); |
848 | p.setPen(QPen(QColor(c.rgb()))); |
849 | |
850 | p.drawRect(r: r[1].adjusted(xp1: 0, yp1: 0, xp2: -1, yp2: -1)); |
851 | // p.drawRect(r[1].adjusted(1, 1, -2, -2)); |
852 | /* |
853 | p.setBrush(m_semiAlphaPixmap); |
854 | if (m_orientation == Qt::Horizontal) { |
855 | QRect top = r[1].adjusted(0, 0, 0, -qRound(r[1].height() * coef) + 1); |
856 | top.setTop(top.bottom()); |
857 | QRect bottom = r[1].adjusted(0, qRound(r[1].height() * coef) - 1, 0, 0); |
858 | top.setBottom(bottom.top()); |
859 | p.setClipRect(top); |
860 | p.setClipRect(bottom, Qt::UniteClip); |
861 | } else { |
862 | |
863 | } |
864 | QColor semiColor(c.rgb()); |
865 | semiColor.setAlpha((c.alpha() + 0xFF) / 2); |
866 | p.setPen(QPen(semiColor)); |
867 | p.drawRect(r[1].adjusted(0, 0, -1, -1)); |
868 | // p.drawRect(r[1].adjusted(1, 1, -2, -2)); |
869 | */ |
870 | p.setClipping(false); |
871 | } |
872 | } |
873 | |
874 | p.setBrush(Qt::NoBrush); |
875 | int lw = 4; |
876 | //int br = 1; |
877 | int br = 0; |
878 | r[1].adjust(dx1: br, dy1: br, dx2: -br, dy2: -br); |
879 | if (r[1].adjusted(xp1: lw, yp1: lw, xp2: -lw, yp2: -lw).isValid()) { |
880 | QStyleOptionFrame opt; |
881 | opt.init(w: q_ptr); |
882 | opt.rect = r[1]; |
883 | opt.lineWidth = 2; |
884 | opt.midLineWidth = 1; |
885 | if (m_dragging) |
886 | opt.state |= QStyle::State_Sunken; |
887 | else |
888 | opt.state |= QStyle::State_Raised; |
889 | q_ptr->style()->drawPrimitive(pe: QStyle::PE_Frame, opt: &opt, p: &p, w: q_ptr); |
890 | QRect colorRect = r[1].adjusted(xp1: lw, yp1: lw, xp2: -lw, yp2: -lw); |
891 | if (q_ptr->isEnabled()) { |
892 | p.fillRect(colorRect, color: c); |
893 | const QColor frameColor(0, 0, 0, 38); |
894 | p.setPen(frameColor); |
895 | p.drawRect(r: colorRect.adjusted(xp1: 0, yp1: 0, xp2: -1, yp2: -1)); |
896 | /* |
897 | p.fillRect(colorRect.width() / 4 + colorRect.left(), |
898 | colorRect.height() / 4 + colorRect.top(), |
899 | colorRect.width() / 2, |
900 | colorRect.height() / 2, |
901 | QColor(c.rgb())); |
902 | */ |
903 | /* |
904 | if (m_component != QtColorLine::Alpha) { |
905 | p.fillRect(colorRect.adjusted(0, colorRect.height() * 4 / 5, 0, 0), QColor(c.rgb())); |
906 | p.fillRect(colorRect.adjusted(0, 0, 0, -colorRect.height() * 4 / 5), QColor(c.rgb())); |
907 | } |
908 | */ |
909 | } |
910 | } |
911 | } |
912 | |
913 | void QtColorLinePrivate::mousePressEvent(QMouseEvent *event) |
914 | { |
915 | if (event->button() != Qt::LeftButton) |
916 | return; |
917 | |
918 | QVector<QRect> r = rects(point: m_point); |
919 | QPoint clickPos = event->pos(); |
920 | |
921 | QPoint posOnField = r[1].topLeft() - QPoint(m_indicatorSpace, m_indicatorSpace); |
922 | m_clickOffset = posOnField - clickPos; |
923 | |
924 | if (!r[1].contains(p: clickPos)) |
925 | return; |
926 | m_dragging = true; |
927 | q_ptr->update(); |
928 | } |
929 | |
930 | void QtColorLinePrivate::mouseMoveEvent(QMouseEvent *event) |
931 | { |
932 | if (!m_dragging) |
933 | return; |
934 | QPoint newPos = event->pos(); |
935 | |
936 | QSize fieldSize = q_ptr->geometry().size() - |
937 | QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1); |
938 | QPoint newPosOnField = newPos + m_clickOffset; |
939 | if (newPosOnField.x() < 0) |
940 | newPosOnField.setX(0); |
941 | else if (newPosOnField.x() > fieldSize.width()) |
942 | newPosOnField.setX(fieldSize.width()); |
943 | if (newPosOnField.y() < 0) |
944 | newPosOnField.setY(0); |
945 | else if (newPosOnField.y() > fieldSize.height()) |
946 | newPosOnField.setY(fieldSize.height()); |
947 | |
948 | const double x = double(newPosOnField.x()) / fieldSize.width(); |
949 | const double y = double(newPosOnField.y()) / fieldSize.height(); |
950 | m_point = QPointF(x, y); |
951 | QColor color = colorFromPoint(point: m_point); |
952 | if (m_color == color) |
953 | return; |
954 | m_color = color; |
955 | emit q_ptr->colorChanged(color); // maybe before internal set, 1 line above |
956 | q_ptr->update(); |
957 | } |
958 | |
959 | void QtColorLinePrivate::mouseReleaseEvent(QMouseEvent *event) |
960 | { |
961 | if (event->button() != Qt::LeftButton) |
962 | return; |
963 | m_dragging = false; |
964 | q_ptr->update(); |
965 | } |
966 | |
967 | void QtColorLinePrivate::mouseDoubleClickEvent(QMouseEvent *event) |
968 | { |
969 | if (event->button() != Qt::LeftButton) |
970 | return; |
971 | |
972 | QVector<QRect> r = rects(point: m_point); |
973 | QPoint clickPos = event->pos(); |
974 | if (!r[0].contains(p: clickPos) && !r[2].contains(p: clickPos)) |
975 | return; |
976 | QPoint newPosOnField = clickPos; |
977 | if (r[2].contains(p: clickPos)) |
978 | newPosOnField -= QPoint(m_indicatorSize + 2 * m_indicatorSpace - 2, m_indicatorSize + 2 * m_indicatorSpace - 2); |
979 | QSize fieldSize = q_ptr->geometry().size() - |
980 | QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1); |
981 | |
982 | const double x = double(newPosOnField.x()) / fieldSize.width(); |
983 | const double y = double(newPosOnField.y()) / fieldSize.height(); |
984 | m_point = QPointF(x, y); |
985 | QColor color = colorFromPoint(point: m_point); |
986 | if (m_color == color) |
987 | return; |
988 | m_color = color; |
989 | emit q_ptr->colorChanged(color); // maybe before internal set, 1 line above |
990 | q_ptr->update(); |
991 | } |
992 | |
993 | //////////////////////////////////////////////////// |
994 | |
995 | QtColorLine::QtColorLine(QWidget *parent) |
996 | : QWidget(parent), d_ptr(new QtColorLinePrivate) |
997 | { |
998 | d_ptr->q_ptr = this; |
999 | |
1000 | setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); |
1001 | } |
1002 | |
1003 | QtColorLine::~QtColorLine() |
1004 | { |
1005 | } |
1006 | |
1007 | QSize QtColorLine::minimumSizeHint() const |
1008 | { |
1009 | return QSize(d_ptr->m_indicatorSize, d_ptr->m_indicatorSize); |
1010 | } |
1011 | |
1012 | QSize QtColorLine::sizeHint() const |
1013 | { |
1014 | return QSize(d_ptr->m_indicatorSize, d_ptr->m_indicatorSize); |
1015 | } |
1016 | |
1017 | void QtColorLine::setColor(const QColor &color) |
1018 | { |
1019 | d_ptr->setColor(color); |
1020 | } |
1021 | |
1022 | QColor QtColorLine::color() const |
1023 | { |
1024 | return d_ptr->color(); |
1025 | } |
1026 | |
1027 | void QtColorLine::setColorComponent(QtColorLine::ColorComponent component) |
1028 | { |
1029 | d_ptr->setColorComponent(component); |
1030 | } |
1031 | |
1032 | QtColorLine::ColorComponent QtColorLine::colorComponent() const |
1033 | { |
1034 | return d_ptr->colorComponent(); |
1035 | } |
1036 | |
1037 | void QtColorLine::setIndicatorSize(int size) |
1038 | { |
1039 | d_ptr->setIndicatorSize(size); |
1040 | } |
1041 | |
1042 | int QtColorLine::indicatorSize() const |
1043 | { |
1044 | return d_ptr->indicatorSize(); |
1045 | } |
1046 | |
1047 | void QtColorLine::setIndicatorSpace(int space) |
1048 | { |
1049 | d_ptr->setIndicatorSpace(space); |
1050 | } |
1051 | |
1052 | int QtColorLine::indicatorSpace() const |
1053 | { |
1054 | return d_ptr->indicatorSpace(); |
1055 | } |
1056 | |
1057 | void QtColorLine::setFlip(bool flip) |
1058 | { |
1059 | d_ptr->setFlip(flip); |
1060 | } |
1061 | |
1062 | bool QtColorLine::flip() const |
1063 | { |
1064 | return d_ptr->flip(); |
1065 | } |
1066 | |
1067 | void QtColorLine::setBackgroundCheckered(bool checkered) |
1068 | { |
1069 | d_ptr->setBackgroundCheckered(checkered); |
1070 | } |
1071 | |
1072 | bool QtColorLine::isBackgroundCheckered() const |
1073 | { |
1074 | return d_ptr->isBackgroundCheckered(); |
1075 | } |
1076 | |
1077 | void QtColorLine::setOrientation(Qt::Orientation orientation) |
1078 | { |
1079 | d_ptr->setOrientation(orientation); |
1080 | } |
1081 | |
1082 | Qt::Orientation QtColorLine::orientation() const |
1083 | { |
1084 | return d_ptr->orientation(); |
1085 | } |
1086 | void QtColorLine::resizeEvent(QResizeEvent *event) |
1087 | { |
1088 | d_ptr->resizeEvent(event); |
1089 | } |
1090 | |
1091 | void QtColorLine::paintEvent(QPaintEvent *event) |
1092 | { |
1093 | d_ptr->paintEvent(event); |
1094 | } |
1095 | |
1096 | void QtColorLine::mousePressEvent(QMouseEvent *event) |
1097 | { |
1098 | d_ptr->mousePressEvent(event); |
1099 | } |
1100 | |
1101 | void QtColorLine::mouseMoveEvent(QMouseEvent *event) |
1102 | { |
1103 | d_ptr->mouseMoveEvent(event); |
1104 | } |
1105 | |
1106 | void QtColorLine::mouseReleaseEvent(QMouseEvent *event) |
1107 | { |
1108 | d_ptr->mouseReleaseEvent(event); |
1109 | } |
1110 | |
1111 | void QtColorLine::mouseDoubleClickEvent(QMouseEvent *event) |
1112 | { |
1113 | d_ptr->mouseDoubleClickEvent(event); |
1114 | } |
1115 | |
1116 | QT_END_NAMESPACE |
1117 | |