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