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