KProperty

KColorCombo.cpp
1 /* This file is part of the KDE libraries
2  Copyright (C) 1997 Martin Jones ([email protected])
3  Copyright (C) 2007 Pino Toscano ([email protected])
4  Copyright (c) 2007 David Jarvie ([email protected])
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include "KColorCombo.h"
23 
24 #include <QAbstractItemDelegate>
25 #include <QApplication>
26 #include <QColorDialog>
27 #include <QStylePainter>
28 
29 class KColorComboDelegate : public QAbstractItemDelegate
30 {
31 public:
32  enum ItemRoles {
34  };
35 
36  enum LayoutMetrics {
37  FrameMargin = 3
38  };
39 
40  KColorComboDelegate(QObject *parent = 0);
41  virtual ~KColorComboDelegate();
42 
43  void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
44  QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
45 };
46 
47 static QBrush k_colorcombodelegate_brush(const QModelIndex &index, int role)
48 {
49  QBrush brush;
50  QVariant v = index.data(role);
51  if (v.type() == QVariant::Brush) {
52  brush = v.value<QBrush>();
53  } else if (v.type() == QVariant::Color) {
54  brush = QBrush(v.value<QColor>());
55  }
56  return brush;
57 }
58 
59 KColorComboDelegate::KColorComboDelegate(QObject *parent)
60  : QAbstractItemDelegate(parent)
61 {
62 }
63 
64 KColorComboDelegate::~KColorComboDelegate()
65 {
66 }
67 
68 void KColorComboDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
69 {
70  // background
71  QColor innercolor(Qt::white);
72  bool isSelected = (option.state & QStyle::State_Selected);
73  bool paletteBrush = (k_colorcombodelegate_brush(index, Qt::BackgroundRole).style() == Qt::NoBrush);
74  if (isSelected) {
75  innercolor = option.palette.color(QPalette::Highlight);
76  } else {
77  innercolor = option.palette.color(QPalette::Base);
78  }
79  // highlight selected item
80  QStyleOptionViewItem opt(option);
81  opt.showDecorationSelected = true;
82  QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
83  style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
84  QRect innerrect = option.rect.adjusted(FrameMargin, FrameMargin, -FrameMargin, -FrameMargin);
85  // inner color
86  QVariant cv = index.data(ColorRole);
87  if (cv.type() == QVariant::Color) {
88  QColor tmpcolor = cv.value<QColor>();
89  if (tmpcolor.isValid()) {
90  innercolor = tmpcolor;
91  paletteBrush = false;
92  painter->setPen(Qt::transparent);
93  painter->setBrush(innercolor);
94  QPainter::RenderHints tmpHint = painter->renderHints();
96  painter->drawRoundedRect(innerrect, 2, 2);
97  painter->setRenderHints(tmpHint);
98  painter->setBrush(Qt::NoBrush);
99  }
100  }
101  // text
102  QVariant tv = index.data(Qt::DisplayRole);
103  if (tv.type() == QVariant::String) {
104  QString text = tv.toString();
105  QColor textColor;
106  if (paletteBrush) {
107  if (isSelected) {
108  textColor = option.palette.color(QPalette::HighlightedText);
109  } else {
110  textColor = option.palette.color(QPalette::Text);
111  }
112  } else {
113  int unused, v;
114  innercolor.getHsv(&unused, &unused, &v);
115  if (v > 128) {
116  textColor = Qt::black;
117  } else {
118  textColor = Qt::white;
119  }
120  }
121  painter->setPen(textColor);
122  painter->drawText(innerrect.adjusted(1, 1, -1, -1), text);
123  }
124 }
125 
126 QSize KColorComboDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
127 {
128  Q_UNUSED(index)
129 
130  // the width does not matter, as the view will always use the maximum width available
131  return QSize(100, option.fontMetrics.height() + 2 * FrameMargin);
132 }
133 
134 static const uchar standardPalette[][4] = {
135  { 255, 255, 255 }, // white
136  { 192, 192, 192 }, // light gray
137  { 160, 160, 160 }, // gray
138  { 128, 128, 128 }, // dark gray
139  { 0, 0, 0 }, // black
140 
141  { 255, 128, 128 }, //light red
142  { 255, 192, 128 }, //light orange
143  { 255, 255, 128 }, //light yellow
144  { 128, 255, 128 }, //light green
145  { 128, 255, 255 }, //cyan blue
146  { 128, 128, 255 }, //light blue
147  { 255, 128, 255 }, //light violet
148  { 255, 0, 0 }, //red
149  { 255, 128, 0 }, //orange
150  { 255, 255, 0 }, //yellow
151  { 0, 255, 0 }, //green
152  { 0, 255, 255 }, //light blue
153  { 0, 0, 255 }, //blue
154  { 255, 0, 255 }, //violet
155  { 128, 0, 0 }, //dark red
156  { 128, 64, 0 }, //dark orange
157  { 128, 128, 0 }, //dark yellow
158  { 0, 128, 0 }, //dark green
159  { 0, 128, 128 }, //dark light blue
160  { 0, 0, 128 }, //dark blue
161  { 128, 0, 128 } //dark violet
162 };
163 
164 #define STANDARD_PALETTE_SIZE (int(sizeof(standardPalette) / sizeof(*standardPalette)))
165 
166 static inline QColor standardColor(int i)
167 {
168  const uchar *entry = standardPalette[i];
169  return QColor(entry[0], entry[1], entry[2]);
170 }
171 
172 class KColorComboPrivate
173 {
174 public:
175  KColorComboPrivate(KColorCombo *qq);
176 
177  void addColors();
178  void setCustomColor(const QColor &color, bool lookupInPresets = true);
179 
180  // slots
181  void _k_slotActivated(int index);
182  void _k_slotHighlighted(int index);
183 
184  KColorCombo *q;
185  QList<QColor> colorList;
186  QColor customColor;
187  QColor internalcolor;
188 };
189 
190 KColorComboPrivate::KColorComboPrivate(KColorCombo *qq)
191  : q(qq), customColor(Qt::white)
192 {
193 }
194 
195 void KColorComboPrivate::setCustomColor(const QColor &color, bool lookupInPresets)
196 {
197  if (lookupInPresets) {
198  if (colorList.isEmpty()) {
199  for (int i = 0; i < STANDARD_PALETTE_SIZE; ++i) {
200  if (standardColor(i) == color) {
201  q->setCurrentIndex(i + 1);
202  internalcolor = color;
203  return;
204  }
205  }
206  } else {
207  int i = colorList.indexOf(color);
208  if (i >= 0) {
209  q->setCurrentIndex(i + 1);
210  internalcolor = color;
211  return;
212  }
213  }
214  }
215 
216  internalcolor = color;
217  customColor = color;
218  q->setItemData(0, customColor, KColorComboDelegate::ColorRole);
219 }
220 
222  : QComboBox(parent), d(new KColorComboPrivate(this))
223 {
224  setItemDelegate(new KColorComboDelegate(this));
225  d->addColors();
226 
227  connect(this, SIGNAL(activated(int)), SLOT(_k_slotActivated(int)));
228  connect(this, SIGNAL(highlighted(int)), SLOT(_k_slotHighlighted(int)));
229 
230  // select the white color
231  setCurrentIndex(1);
232  d->_k_slotActivated(1);
233 
234  setMaxVisibleItems(13);
235 }
236 
237 KColorCombo::~KColorCombo()
238 {
239  delete d;
240 }
241 
242 void KColorCombo::setColors(const QList<QColor> &colors)
243 {
244  clear();
245  d->colorList = colors;
246  d->addColors();
247 }
248 
250 {
251  if (d->colorList.isEmpty()) {
253  for (int i = 0; i < STANDARD_PALETTE_SIZE; ++i) {
254  list += standardColor(i);
255  }
256  return list;
257  } else {
258  return d->colorList;
259  }
260 }
261 
262 void KColorCombo::setColor(const QColor &col)
263 {
264  if (!col.isValid()) {
265  return;
266  }
267 
268  if (count() == 0) {
269  d->addColors();
270  }
271 
272  d->setCustomColor(col, true);
273 }
274 
276 {
277  return d->internalcolor;
278 }
279 
280 bool KColorCombo::isCustomColor() const
281 {
282  return d->internalcolor == d->customColor;
283 }
284 
285 void KColorCombo::paintEvent(QPaintEvent *event)
286 {
287  Q_UNUSED(event)
288  QStylePainter painter(this);
289  painter.setPen(palette().color(QPalette::Text));
290 
292  initStyleOption(&opt);
293  painter.drawComplexControl(QStyle::CC_ComboBox, opt);
294 
295  QRect frame = style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField, this);
296  painter.setRenderHint(QPainter::Antialiasing);
297  painter.setPen(Qt::transparent);
298  painter.setBrush(QBrush(d->internalcolor));
299  painter.drawRoundedRect(frame.adjusted(1, 1, -1, -1), 2, 2);
300 }
301 
302 void KColorCombo::showEmptyList()
303 {
304  clear();
305 }
306 
307 void KColorComboPrivate::_k_slotActivated(int index)
308 {
309  if (index == 0) {
310  QColor c = QColorDialog::getColor(customColor, q);
311  if (c.isValid()) {
312  customColor = c;
313  setCustomColor(customColor, false);
314  }
315  } else if (colorList.isEmpty()) {
316  internalcolor = standardColor(index - 1);
317  } else {
318  internalcolor = colorList[index - 1];
319  }
320 
321  emit q->activated(internalcolor);
322 }
323 
324 void KColorComboPrivate::_k_slotHighlighted(int index)
325 {
326  if (index == 0) {
327  internalcolor = customColor;
328  } else if (colorList.isEmpty()) {
329  internalcolor = standardColor(index - 1);
330  } else {
331  internalcolor = colorList[index - 1];
332  }
333 
334  emit q->highlighted(internalcolor);
335 }
336 
337 void KColorComboPrivate::addColors()
338 {
339  q->addItem(KColorCombo::tr("Custom...", "Custom color"));
340 
341  if (colorList.isEmpty()) {
342  for (int i = 0; i < STANDARD_PALETTE_SIZE; ++i) {
343  q->addItem(QString());
344  q->setItemData(i + 1, standardColor(i), KColorComboDelegate::ColorRole);
345  }
346  } else {
347  for (int i = 0, count = colorList.count(); i < count; ++i) {
348  q->addItem(QString());
349  q->setItemData(i + 1, colorList[i], KColorComboDelegate::ColorRole);
350  }
351  }
352 }
353 
354 #include "moc_KColorCombo.cpp"
QColor color() const
const QPalette & palette() const const
void setRenderHint(QPainter::RenderHint hint, bool on)
Qt::BrushStyle style() const const
QPainter::RenderHints renderHints() const const
QStyle * style() const const
T value() const const
KColorCombo(QWidget *parent=nullptr)
QString tr(const char *sourceText, const char *disambiguation, int n)
void setColors(const QList< QColor > &colors)
Combobox for colors.
Definition: KColorCombo.h:42
void setPen(const QColor &color)
void drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode)
UserRole
void setBrush(const QBrush &brush)
void drawText(const QPointF &position, const QString &text)
void setColor(const QColor &col)
PE_PanelItemViewItem
QRect adjusted(int dx1, int dy1, int dx2, int dy2) const const
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const const =0
QColor getColor(const QColor &initial, QWidget *parent, const QString &title, QColorDialog::ColorDialogOptions options)
void setRenderHints(QPainter::RenderHints hints, bool on)
bool isCustomColor() const
QList< QColor > colors() const
QFontMetrics fontMetrics() const const
QVariant data(int role) const const
QStyle * style()
virtual void drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const =0
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const const =0
QVariant::Type type() const const
typedef RenderHints
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
QString toString() const const
virtual bool event(QEvent *event) override
int height() const const
bool isValid() const const
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sun Aug 9 2020 23:10:56 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.