Qt Utilities  5.8.1
Common Qt related C++ classes and routines used by my applications such as dialogs, widgets and models
colorbutton.cpp
Go to the documentation of this file.
1 #include "./colorbutton.h"
2 
3 #include <QApplication>
4 #include <QColorDialog>
5 #include <QDrag>
6 #include <QDragEnterEvent>
7 #include <QMimeData>
8 #include <QPainter>
9 
10 namespace Widgets {
11 
16 class ColorButtonPrivate {
17  ColorButton *q_ptr;
18  Q_DECLARE_PUBLIC(ColorButton)
19 public:
20  QColor m_color;
21 #ifndef QT_NO_DRAGANDDROP
22  QColor m_dragColor;
23  QPoint m_dragStart;
24  bool m_dragging;
25 #endif
26  bool m_backgroundCheckered;
27 
28  void slotEditColor();
29  QColor shownColor() const;
30  QPixmap generatePixmap() const;
31 };
32 
33 void ColorButtonPrivate::slotEditColor()
34 {
35  const QColor newColor = QColorDialog::getColor(m_color, q_ptr, QString(), QColorDialog::ShowAlphaChannel);
36  if (!newColor.isValid() || newColor == q_ptr->color())
37  return;
38  q_ptr->setColor(newColor);
39  emit q_ptr->colorChanged(m_color);
40 }
41 
42 QColor ColorButtonPrivate::shownColor() const
43 {
44 #ifndef QT_NO_DRAGANDDROP
45  if (m_dragging)
46  return m_dragColor;
47 #endif
48  return m_color;
49 }
50 
51 QPixmap ColorButtonPrivate::generatePixmap() const
52 {
53  QPixmap pix(24, 24);
54 
55  int pixSize = 20;
56  QBrush br(shownColor());
57 
58  QPixmap pm(2 * pixSize, 2 * pixSize);
59  QPainter pmp(&pm);
60  pmp.fillRect(0, 0, pixSize, pixSize, Qt::lightGray);
61  pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::lightGray);
62  pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::darkGray);
63  pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::darkGray);
64  pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, shownColor());
65  br = QBrush(pm);
66 
67  QPainter p(&pix);
68  int corr = 1;
69  QRect r = pix.rect().adjusted(corr, corr, -corr, -corr);
70  p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
71  p.fillRect(r, br);
72 
73  p.fillRect(r.width() / 4 + corr, r.height() / 4 + corr, r.width() / 2, r.height() / 2, QColor(shownColor().rgb()));
74  p.drawRect(pix.rect().adjusted(0, 0, -1, -1));
75 
76  return pix;
77 }
78 
83 ColorButton::ColorButton(QWidget *parent)
84  : QToolButton(parent)
85  , d_ptr(new ColorButtonPrivate)
86 {
87  d_ptr->q_ptr = this;
88  d_ptr->m_dragging = false;
89  d_ptr->m_backgroundCheckered = true;
90 
91  setAcceptDrops(true);
92 
93  connect(this, SIGNAL(clicked()), this, SLOT(slotEditColor()));
94  setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
95 }
96 
98 {
99 }
100 
101 void ColorButton::setColor(const QColor &color)
102 {
103  if (d_ptr->m_color == color)
104  return;
105  d_ptr->m_color = color;
106  update();
107 }
108 
109 QColor ColorButton::color() const
110 {
111  return d_ptr->m_color;
112 }
113 
115 {
116  if (d_ptr->m_backgroundCheckered == checkered)
117  return;
118  d_ptr->m_backgroundCheckered = checkered;
119  update();
120 }
121 
123 {
124  return d_ptr->m_backgroundCheckered;
125 }
126 
127 void ColorButton::paintEvent(QPaintEvent *event)
128 {
129  QToolButton::paintEvent(event);
130  if (!isEnabled())
131  return;
132 
133  const int pixSize = 10;
134  QBrush br(d_ptr->shownColor());
135  if (d_ptr->m_backgroundCheckered) {
136  QPixmap pm(2 * pixSize, 2 * pixSize);
137  QPainter pmp(&pm);
138  pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
139  pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
140  pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
141  pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
142  pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, d_ptr->shownColor());
143  br = QBrush(pm);
144  }
145 
146  QPainter p(this);
147  const int corr = 4;
148  QRect r = rect().adjusted(corr, corr, -corr, -corr);
149  p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
150  p.fillRect(r, br);
151 
152  // const int adjX = qRound(r.width() / 4.0);
153  // const int adjY = qRound(r.height() / 4.0);
154  // p.fillRect(r.adjusted(adjX, adjY, -adjX, -adjY),
155  // QColor(d_ptr->shownColor().rgb()));
156  /*
157  p.fillRect(r.adjusted(0, r.height() * 3 / 4, 0, 0),
158  QColor(d_ptr->shownColor().rgb()));
159  p.fillRect(r.adjusted(0, 0, 0, -r.height() * 3 / 4),
160  QColor(d_ptr->shownColor().rgb()));
161  */
162  /*
163  const QColor frameColor0(0, 0, 0, qRound(0.2 * (0xFF -
164  d_ptr->shownColor().alpha())));
165  p.setPen(frameColor0);
166  p.drawRect(r.adjusted(adjX, adjY, -adjX - 1, -adjY - 1));
167  */
168 
169  const QColor frameColor1(0, 0, 0, 26);
170  p.setPen(frameColor1);
171  p.drawRect(r.adjusted(1, 1, -2, -2));
172  const QColor frameColor2(0, 0, 0, 51);
173  p.setPen(frameColor2);
174  p.drawRect(r.adjusted(0, 0, -1, -1));
175 }
176 
177 void ColorButton::mousePressEvent(QMouseEvent *event)
178 {
179 #ifndef QT_NO_DRAGANDDROP
180  if (event->button() == Qt::LeftButton)
181  d_ptr->m_dragStart = event->pos();
182 #endif
183  QToolButton::mousePressEvent(event);
184 }
185 
186 void ColorButton::mouseMoveEvent(QMouseEvent *event)
187 {
188 #ifndef QT_NO_DRAGANDDROP
189  if (event->buttons() & Qt::LeftButton && (d_ptr->m_dragStart - event->pos()).manhattanLength() > QApplication::startDragDistance()) {
190  QMimeData *mime = new QMimeData;
191  mime->setColorData(color());
192  QDrag *drg = new QDrag(this);
193  drg->setMimeData(mime);
194  drg->setPixmap(d_ptr->generatePixmap());
195  setDown(false);
196  event->accept();
197  drg->start();
198  return;
199  }
200 #endif
201  QToolButton::mouseMoveEvent(event);
202 }
203 
204 #ifndef QT_NO_DRAGANDDROP
205 void ColorButton::dragEnterEvent(QDragEnterEvent *event)
206 {
207  const QMimeData *mime = event->mimeData();
208  if (!mime->hasColor())
209  return;
210 
211  event->accept();
212  d_ptr->m_dragColor = qvariant_cast<QColor>(mime->colorData());
213  d_ptr->m_dragging = true;
214  update();
215 }
216 
217 void ColorButton::dragLeaveEvent(QDragLeaveEvent *event)
218 {
219  event->accept();
220  d_ptr->m_dragging = false;
221  update();
222 }
223 
224 void ColorButton::dropEvent(QDropEvent *event)
225 {
226  event->accept();
227  d_ptr->m_dragging = false;
228  if (d_ptr->m_dragColor == color())
229  return;
230  setColor(d_ptr->m_dragColor);
231  emit colorChanged(color());
232 }
233 #endif
234 } // namespace Widgets
235 
236 #include "moc_colorbutton.cpp"
void setColor(const QColor &color)
void dropEvent(QDropEvent *event)
void colorChanged(const QColor &color)
ColorButton(QWidget *parent=nullptr)
Definition: colorbutton.cpp:83
bool isBackgroundCheckered() const
QColor color() const
void mouseMoveEvent(QMouseEvent *event)
void mousePressEvent(QMouseEvent *event)
void dragLeaveEvent(QDragLeaveEvent *event)
void paintEvent(QPaintEvent *event)
Provides a set of extended widgets such as ClearLineEdit and ClearComboBox.
Definition: buttonoverlay.h:13
void setBackgroundCheckered(bool checkered)
void dragEnterEvent(QDragEnterEvent *event)