Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_color_button.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 SPDX-FileCopyrightText: 1997 Martin Jones (mjones@kde.org)
3 SPDX-FileCopyrightText: 1999 Cristian Tibirna (ctibirna@kde.org)
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "kis_color_button.h"
9
10#include <QPointer>
11#include <QPainter>
12#include <qdrawutil.h>
13#include <QApplication>
14#include <QColorDialog>
15#include <QClipboard>
16#include <QMimeData>
17#include <QDrag>
18#include <QStyle>
19#include <QMouseEvent>
20#include <QStyleOptionButton>
21
22#include <KoColor.h>
24#include <kconfiggroup.h>
25#include <ksharedconfig.h>
26
28{
29public:
32 if(m_dialog) {
33 m_dialog->close();
34 }
35 }
36
37 void _k_chooseColor();
38
43 bool m_palette : 1;
44
46 QPoint mPos;
48
49 void initStyleOption(QStyleOptionButton *opt) const;
50};
51
53// Functions duplicated from KColorMimeData
54// Should be kept in sync
55void _k_populateMimeData(QMimeData *mimeData, const KoColor &color)
56{
57 mimeData->setColorData(color.toQColor());
58 mimeData->setText(color.toQColor().name());
59}
60
61bool _k_canDecode(const QMimeData *mimeData)
62{
63 if (mimeData->hasColor()) {
64 return true;
65 }
66 if (mimeData->hasText()) {
67 const QString colorName = mimeData->text();
68 if ((colorName.length() >= 4) && (colorName[0] == QLatin1Char('#'))) {
69 return true;
70 }
71 }
72 return false;
73}
74
75QColor _k_fromMimeData(const QMimeData *mimeData)
76{
77 if (mimeData->hasColor()) {
78 return mimeData->colorData().value<QColor>();
79 }
80 if (_k_canDecode(mimeData)) {
81 return QColor(mimeData->text());
82 }
83 return QColor();
84}
85
86QDrag *_k_createDrag(const KoColor &color, QObject *dragsource)
87{
88 QDrag *drag = new QDrag(dragsource);
89 QMimeData *mime = new QMimeData;
90 _k_populateMimeData(mime, color);
91 drag->setMimeData(mime);
92 QPixmap colorpix(25, 20);
93 colorpix.fill(color.toQColor());
94 QPainter p(&colorpix);
95 p.setPen(Qt::black);
96 p.drawRect(0, 0, 24, 19);
97 p.end();
98 drag->setPixmap(colorpix);
99 drag->setHotSpot(QPoint(-5, -7));
100 return drag;
101}
103
105 : q(q)
106{
107 m_bdefaultColor = false;
108 m_alphaChannel = false;
109 m_palette = true;
110 q->setAcceptDrops(true);
111
112 connect(q, SIGNAL(clicked()), q, SLOT(_k_chooseColor()));
113}
114
116 : QPushButton(parent)
117 , d(new KisColorButtonPrivate(this))
118{
119}
120
121KisColorButton::KisColorButton(const KoColor &c, QWidget *parent)
122 : QPushButton(parent)
123 , d(new KisColorButtonPrivate(this))
124{
125 d->col = c;
126}
127
128KisColorButton::KisColorButton(const KoColor &c, const KoColor &defaultColor, QWidget *parent)
129 : QPushButton(parent)
130 , d(new KisColorButtonPrivate(this))
131{
132 d->col = c;
134}
135
137{
138 delete d;
139}
140
142{
143 return d->col;
144}
145
147{
148 d->col = c;
149 update();
150 Q_EMIT changed(d->col);
151}
152
154{
155 d->m_alphaChannel = alpha;
156}
157
159{
160 return d->m_alphaChannel;
161}
162
164{
165 d->m_palette = enable;
166}
167
169{
170 return d->m_palette;
171}
172
177
179{
180 d->m_bdefaultColor = true;
181 d->m_defaultColor = c;
182}
183
185{
186 opt->initFrom(q);
187 opt->state |= q->isDown() ? QStyle::State_Sunken : QStyle::State_Raised;
188 opt->features = QStyleOptionButton::None;
189 if (q->isDefault()) {
190 opt->features |= QStyleOptionButton::DefaultButton;
191 }
192 opt->text.clear();
193 opt->icon = QIcon();
194}
195
196void KisColorButton::paintEvent(QPaintEvent *)
197{
198 QPainter painter(this);
199 QStyle *style = QWidget::style();
200
201 //First, we need to draw the bevel.
202 QStyleOptionButton butOpt;
203 d->initStyleOption(&butOpt);
204 style->drawControl(QStyle::CE_PushButtonBevel, &butOpt, &painter, this);
205
206 //OK, now we can muck around with drawing out pretty little color box
207 //First, sort out where it goes
208 QRect labelRect = style->subElementRect(QStyle::SE_PushButtonContents,
209 &butOpt, this);
210 int shift = style->pixelMetric(QStyle::PM_ButtonMargin, &butOpt, this) / 2;
211 labelRect.adjust(shift, shift, -shift, -shift);
212 int x, y, w, h;
213 labelRect.getRect(&x, &y, &w, &h);
214
215 if (isChecked() || isDown()) {
216 x += style->pixelMetric(QStyle::PM_ButtonShiftHorizontal, &butOpt, this);
217 y += style->pixelMetric(QStyle::PM_ButtonShiftVertical, &butOpt, this);
218 }
219
220 QColor fillCol = isEnabled() ? d->col.toQColor() : palette().color(backgroundRole());
221 qDrawShadePanel(&painter, x, y, w, h, palette(), true, 1, NULL);
222 if (fillCol.isValid()) {
223 const QRect rect(x + 1, y + 1, w - 2, h - 2);
224 if (fillCol.alpha() < 255) {
225 QPixmap chessboardPattern(16, 16);
226 QPainter patternPainter(&chessboardPattern);
227 patternPainter.fillRect(0, 0, 8, 8, Qt::black);
228 patternPainter.fillRect(8, 8, 8, 8, Qt::black);
229 patternPainter.fillRect(0, 8, 8, 8, Qt::white);
230 patternPainter.fillRect(8, 0, 8, 8, Qt::white);
231 patternPainter.end();
232 painter.fillRect(rect, QBrush(chessboardPattern));
233 }
234 painter.fillRect(rect, fillCol);
235 }
236
237 if (hasFocus()) {
238 QRect focusRect = style->subElementRect(QStyle::SE_PushButtonFocusRect, &butOpt, this);
239 QStyleOptionFocusRect focusOpt;
240 focusOpt.initFrom(this);
241 focusOpt.rect = focusRect;
242 focusOpt.backgroundColor = palette().window().color();
243 style->drawPrimitive(QStyle::PE_FrameFocusRect, &focusOpt, &painter, this);
244 }
245}
246
248{
249 QStyleOptionButton opt;
250 d->initStyleOption(&opt);
251 return style()->sizeFromContents(QStyle::CT_PushButton, &opt, QSize(40, 15), this);
252}
253
255{
256 QStyleOptionButton opt;
257 d->initStyleOption(&opt);
258 return style()->sizeFromContents(QStyle::CT_PushButton, &opt, QSize(3, 3), this);
259}
260
261void KisColorButton::dragEnterEvent(QDragEnterEvent *event)
262{
263 event->setAccepted(_k_canDecode(event->mimeData()) && isEnabled());
264}
265
266void KisColorButton::dropEvent(QDropEvent *event)
267{
268 QColor c = _k_fromMimeData(event->mimeData());
269 if (c.isValid()) {
270 KoColor col;
271 col.fromQColor(c);
272 setColor(col);
273 }
274}
275
277{
278 int key = e->key() | e->modifiers();
279
280 if (QKeySequence::keyBindings(QKeySequence::Copy).contains(key)) {
281 QMimeData *mime = new QMimeData;
282 _k_populateMimeData(mime, color());
283 QApplication::clipboard()->setMimeData(mime, QClipboard::Clipboard);
284 } else if (QKeySequence::keyBindings(QKeySequence::Paste).contains(key)) {
285 QColor color = _k_fromMimeData(QApplication::clipboard()->mimeData(QClipboard::Clipboard));
286 KoColor col;
287 col.fromQColor(color);
288 setColor(col);
289 } else {
290 QPushButton::keyPressEvent(e);
291 }
292}
293
295{
296 d->mPos = e->pos();
297 QPushButton::mousePressEvent(e);
298}
299
301{
302 if ((e->buttons() & Qt::LeftButton) &&
303 (e->pos() - d->mPos).manhattanLength() > QApplication::startDragDistance()) {
304 _k_createDrag(color(), this)->exec();
305 setDown(false);
306 }
307}
308
310{
311 KConfigGroup cfg = KSharedConfig::openConfig()->group("colorselector");
312 bool usePlatformDialog = cfg.readEntry("UsePlatformColorDialog", false);
313
314 if (!usePlatformDialog) {
316 cfg.paletteBox = q->paletteViewEnabled();
317 KisDlgInternalColorSelector *dialog = new KisDlgInternalColorSelector(q, q->color(), cfg, i18n("Choose a color"));
318 dialog->setPreviousColor(q->color());
319 auto setColorFn = [this, dialog]() { q->setColor(dialog->getCurrentColor()); };
321 connect(dialog, &QDialog::accepted, setColorFn);
322 m_dialog = dialog;
323 } else{
324 QColorDialog *dialog = new QColorDialog(q);
325 dialog->setOption(QColorDialog::ShowAlphaChannel, m_alphaChannel);
326 dialog->setCurrentColor(q->color().toQColor());
327 auto setColorFn = [this, dialog]()
328 {
329 KoColor c;
330 c.fromQColor(dialog->currentColor());
331 q->setColor(c);
332 };
333 connect(dialog, &QColorDialog::currentColorChanged, setColorFn);
334 connect(dialog, &QDialog::accepted, setColorFn);
335 m_dialog = dialog;
336 }
337 // common functionality
338 KoColor colorBeforeColorDialogChanges = col;
339 connect(m_dialog, &QDialog::rejected, [colorBeforeColorDialogChanges, this](){ q->setColor(colorBeforeColorDialogChanges); });
340 m_dialog->setAttribute(Qt::WA_DeleteOnClose);
341 m_dialog->show();
342 m_dialog->raise();
343 m_dialog->activateWindow();
344}
345
346#include "moc_kis_color_button.cpp"
const Params2D p
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void initStyleOption(QStyleOptionButton *opt) const
A pushbutton to display or allow user selection of a color.
QSize sizeHint() const override
void mousePressEvent(QMouseEvent *e) override
void dropEvent(QDropEvent *) override
void paintEvent(QPaintEvent *pe) override
void setPaletteViewEnabled(bool enable)
void setAlphaChannelEnabled(bool alpha)
void setColor(const KoColor &c)
void dragEnterEvent(QDragEnterEvent *) override
QSize minimumSizeHint() const override
void changed(const KoColor &newColor)
~KisColorButton() override
bool paletteViewEnabled() const
paletteViewEnabled
void mouseMoveEvent(QMouseEvent *e) override
KisColorButtonPrivate *const d
void setDefaultColor(const KoColor &c)
KisColorButton(QWidget *parent=0)
bool isAlphaChannelEnabled() const
void keyPressEvent(QKeyEvent *e) override
The KisInternalColorSelector class.
void signalForegroundColorChosen(KoColor color)
signalForegroundColorChosen The most important signal. This will sent out when a color has been chose...
void fromQColor(const QColor &c)
Convenient function for converting from a QColor.
Definition KoColor.cpp:213
void toQColor(QColor *c) const
a convenience method for the above.
Definition KoColor.cpp:198
QColor _k_fromMimeData(const QMimeData *mimeData)
void _k_populateMimeData(QMimeData *mimeData, const KoColor &color)
bool _k_canDecode(const QMimeData *mimeData)
QDrag * _k_createDrag(const KoColor &color, QObject *dragsource)
rgba palette[MAX_PALETTE]
Definition palette.c:35