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