KProperty

KColorCombo.cpp
1/* This file is part of the KDE libraries
2 Copyright (C) 1997 Martin Jones (mjones@kde.org)
3 Copyright (C) 2007 Pino Toscano (pino@kde.org)
4 Copyright (c) 2007 David Jarvie (software@astrojar.org.uk)
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
29class KColorComboDelegate : public QAbstractItemDelegate
30{
31public:
32 enum ItemRoles {
33 ColorRole = Qt::UserRole + 1
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
47static 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
59KColorComboDelegate::KColorComboDelegate(QObject *parent)
60 : QAbstractItemDelegate(parent)
61{
62}
63
64KColorComboDelegate::~KColorComboDelegate()
65{
66}
67
68void 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
126QSize 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
134static 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
166static inline QColor standardColor(int i)
167{
168 const uchar *entry = standardPalette[i];
169 return QColor(entry[0], entry[1], entry[2]);
170}
171
172class KColorComboPrivate
173{
174public:
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
190KColorComboPrivate::KColorComboPrivate(KColorCombo *qq)
191 : q(qq), customColor(Qt::white)
192{
193}
194
195void 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
237KColorCombo::~KColorCombo()
238{
239 delete d;
240}
241
242void KColorCombo::setColors(const QList<QColor> &colors)
243{
244 clear();
245 d->colorList = colors;
246 d->addColors();
247}
248
249QList<QColor> KColorCombo::colors() const
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
262void 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
275QColor KColorCombo::color() const
276{
277 return d->internalcolor;
278}
279
281{
282 return d->internalcolor == d->customColor;
283}
284
285void 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
297 painter.setPen(Qt::transparent);
298 painter.setBrush(QBrush(d->internalcolor));
299 painter.drawRoundedRect(frame.adjusted(1, 1, -1, -1), 2, 2);
300}
301
303{
304 clear();
305}
306
307void 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
324void 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
337void 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"
void setColors(const QList< QColor > &colors)
void showEmptyList()
KColorCombo(QWidget *parent=nullptr)
void activated(const QColor &col)
void setColor(const QColor &col)
bool isCustomColor() const
void highlighted(const QColor &col)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QStyle * style()
Qt::BrushStyle style() const const
bool isValid() const const
QColor getColor(const QColor &initial, QWidget *parent, const QString &title, QColorDialog::ColorDialogOptions options)
void addItem(const QString &text, const QVariant &userData)
void clear()
void setCurrentIndex(int index)
virtual bool event(QEvent *event) override
void initStyleOption(QStyleOptionComboBox *option) const const
void setItemData(int index, const QVariant &value, int role)
int count(const T &value) const const
int indexOf(const T &value, int from) const const
bool isEmpty() const const
QVariant data(int role) const const
QObject * parent() const const
QString tr(const char *sourceText, const char *disambiguation, int n)
typedef RenderHints
void drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode)
void drawText(const QPointF &position, const QString &text)
QPainter::RenderHints renderHints() const const
void setBrush(const QBrush &brush)
void setPen(const QColor &color)
void setRenderHint(QPainter::RenderHint hint, bool on)
void setRenderHints(QPainter::RenderHints hints, bool on)
QRect adjusted(int dx1, int dy1, int dx2, int dy2) const const
PE_PanelItemViewItem
SC_ComboBoxEditField
virtual void drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const=0
virtual QRect subControlRect(QStyle::ComplexControl control, const QStyleOptionComplex *option, QStyle::SubControl subControl, const QWidget *widget) const const=0
UserRole
QString toString() const const
QVariant::Type type() const const
T value() const const
QStyle * style() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Feb 25 2024 18:41:55 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.