dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
qtcolorbutton.cpp
Go to the documentation of this file.
1 
13 /*
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful, but
20  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  * for more details.
23  *
24  * You should have received a copy of the GNU General Public License along
25  * with this program; if not, see <http://www.gnu.org/licenses/>
26  */
27 
28 #include "qtcolorbutton.h"
29 
30 #include <QtCore/QMimeData>
31 #include <QApplication>
32 #include <QColorDialog>
33 #include <QDragEnterEvent>
34 #include <QDrag>
35 #include <QPainter>
36 
37 namespace Utils {
38 
40 {
41  QtColorButton *q_ptr;
42  Q_DECLARE_PUBLIC(QtColorButton)
43 public:
44  QColor m_color;
45 #ifndef QT_NO_DRAGANDDROP
46  QColor m_dragColor;
47  QPoint m_dragStart;
48  bool m_dragging;
49 #endif
50  bool m_backgroundCheckered;
51  bool m_alphaAllowed;
52 
53  void slotEditColor();
54  QColor shownColor() const;
55  QPixmap generatePixmap() const;
56 };
57 
58 void QtColorButtonPrivate::slotEditColor()
59 {
60  QColor newColor;
61  if (m_alphaAllowed) {
62  bool ok;
63  const QRgb rgba = QColorDialog::getRgba(m_color.rgba(), &ok, q_ptr);
64  if (!ok)
65  return;
66  newColor = QColor::fromRgba(rgba);
67  } else {
68  newColor = QColorDialog::getColor(m_color, q_ptr);
69  if (!newColor.isValid())
70  return;
71  }
72  if (newColor == q_ptr->color())
73  return;
74  q_ptr->setColor(newColor);
75  emit q_ptr->colorChanged(m_color);
76 }
77 
78 QColor QtColorButtonPrivate::shownColor() const
79 {
80 #ifndef QT_NO_DRAGANDDROP
81  if (m_dragging)
82  return m_dragColor;
83 #endif
84  return m_color;
85 }
86 
87 QPixmap QtColorButtonPrivate::generatePixmap() const
88 {
89  QPixmap pix(24, 24);
90 
91  int pixSize = 20;
92  QBrush br(shownColor());
93 
94  QPixmap pm(2 * pixSize, 2 * pixSize);
95  QPainter pmp(&pm);
96  pmp.fillRect(0, 0, pixSize, pixSize, Qt::lightGray);
97  pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::lightGray);
98  pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::darkGray);
99  pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::darkGray);
100  pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, shownColor());
101  br = QBrush(pm);
102 
103  QPainter p(&pix);
104  int corr = 1;
105  QRect r = pix.rect().adjusted(corr, corr, -corr, -corr);
106  p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
107  p.fillRect(r, br);
108 
109  p.fillRect(r.width() / 4 + corr, r.height() / 4 + corr,
110  r.width() / 2, r.height() / 2,
111  QColor(shownColor().rgb()));
112  p.drawRect(pix.rect().adjusted(0, 0, -1, -1));
113 
114  return pix;
115 }
116 
118 
120  : QToolButton(parent)
121 {
122  d_ptr = new QtColorButtonPrivate;
123  d_ptr->q_ptr = this;
124  d_ptr->m_dragging = false;
125  d_ptr->m_backgroundCheckered = true;
126  d_ptr->m_alphaAllowed = true;
127 
128  setAcceptDrops(true);
129 
130  connect(this, SIGNAL(clicked()), this, SLOT(slotEditColor()));
131  setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
132 }
133 
135 {
136  delete d_ptr;
137 }
138 
139 void QtColorButton::setColor(const QColor &color)
140 {
141  if (d_ptr->m_color == color)
142  return;
143  d_ptr->m_color = color;
144  update();
145 }
146 
147 QColor QtColorButton::color() const
148 {
149  return d_ptr->m_color;
150 }
151 
153 {
154  if (d_ptr->m_backgroundCheckered == checkered)
155  return;
156  d_ptr->m_backgroundCheckered = checkered;
157  update();
158 }
159 
161 {
162  return d_ptr->m_backgroundCheckered;
163 }
164 
166 {
167  d_ptr->m_alphaAllowed = allowed;
168 }
169 
171 {
172  return d_ptr->m_alphaAllowed;
173 }
174 
175 void QtColorButton::paintEvent(QPaintEvent *event)
176 {
177  QToolButton::paintEvent(event);
178  if (!isEnabled())
179  return;
180 
181  const int pixSize = 10;
182  QBrush br(d_ptr->shownColor());
183  if (d_ptr->m_backgroundCheckered) {
184  QPixmap pm(2 * pixSize, 2 * pixSize);
185  QPainter pmp(&pm);
186  pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
187  pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
188  pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
189  pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
190  pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, d_ptr->shownColor());
191  br = QBrush(pm);
192  }
193 
194  QPainter p(this);
195  const int corr = 5;
196  QRect r = rect().adjusted(corr, corr, -corr, -corr);
197  p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
198  p.fillRect(r, br);
199 
200  //const int adjX = qRound(r.width() / 4.0);
201  //const int adjY = qRound(r.height() / 4.0);
202  //p.fillRect(r.adjusted(adjX, adjY, -adjX, -adjY),
203  // QColor(d_ptr->shownColor().rgb()));
204  /*
205  p.fillRect(r.adjusted(0, r.height() * 3 / 4, 0, 0),
206  QColor(d_ptr->shownColor().rgb()));
207  p.fillRect(r.adjusted(0, 0, 0, -r.height() * 3 / 4),
208  QColor(d_ptr->shownColor().rgb()));
209  */
210  /*
211  const QColor frameColor0(0, 0, 0, qRound(0.2 * (0xFF - d_ptr->shownColor().alpha())));
212  p.setPen(frameColor0);
213  p.drawRect(r.adjusted(adjX, adjY, -adjX - 1, -adjY - 1));
214  */
215 
216  const QColor frameColor1(0, 0, 0, 26);
217  p.setPen(frameColor1);
218  p.drawRect(r.adjusted(1, 1, -2, -2));
219  const QColor frameColor2(0, 0, 0, 51);
220  p.setPen(frameColor2);
221  p.drawRect(r.adjusted(0, 0, -1, -1));
222 }
223 
224 void QtColorButton::mousePressEvent(QMouseEvent *event)
225 {
226 #ifndef QT_NO_DRAGANDDROP
227  if (event->button() == Qt::LeftButton)
228  d_ptr->m_dragStart = event->pos();
229 #endif
230  QToolButton::mousePressEvent(event);
231 }
232 
233 void QtColorButton::mouseMoveEvent(QMouseEvent *event)
234 {
235 #ifndef QT_NO_DRAGANDDROP
236  if (event->buttons() & Qt::LeftButton &&
237  (d_ptr->m_dragStart - event->pos()).manhattanLength() > QApplication::startDragDistance()) {
238  QMimeData *mime = new QMimeData;
239  mime->setColorData(color());
240  QDrag *drg = new QDrag(this);
241  drg->setMimeData(mime);
242  drg->setPixmap(d_ptr->generatePixmap());
243  setDown(false);
244  event->accept();
245  drg->start();
246  return;
247  }
248 #endif
249  QToolButton::mouseMoveEvent(event);
250 }
251 
252 #ifndef QT_NO_DRAGANDDROP
253 void QtColorButton::dragEnterEvent(QDragEnterEvent *event)
254 {
255  const QMimeData *mime = event->mimeData();
256  if (!mime->hasColor())
257  return;
258 
259  event->accept();
260  d_ptr->m_dragColor = qvariant_cast<QColor>(mime->colorData());
261  d_ptr->m_dragging = true;
262  update();
263 }
264 
265 void QtColorButton::dragLeaveEvent(QDragLeaveEvent *event)
266 {
267  event->accept();
268  d_ptr->m_dragging = false;
269  update();
270 }
271 
272 void QtColorButton::dropEvent(QDropEvent *event)
273 {
274  event->accept();
275  d_ptr->m_dragging = false;
276  if (d_ptr->m_dragColor == color())
277  return;
278  setColor(d_ptr->m_dragColor);
279  emit colorChanged(color());
280 }
281 #endif
282 
283 } // namespace Utils
284 
285 #include "moc_qtcolorbutton.cpp"
friend class QtColorButtonPrivate
Definition: qtcolorbutton.h:70
void dragLeaveEvent(QDragLeaveEvent *event)
void setBackgroundCheckered(bool checkered)
void setColor(const QColor &color)
void paintEvent(QPaintEvent *event)
QtColorButton(QWidget *parent=nullptr)
void mouseMoveEvent(QMouseEvent *event)
QColor color() const
void mousePressEvent(QMouseEvent *event)
void colorChanged(const QColor &color)
void dropEvent(QDropEvent *event)
void dragEnterEvent(QDragEnterEvent *event)
void setAlphaAllowed(bool allowed)
bool isAlphaAllowed() const
bool isBackgroundCheckered() const