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