Krita Source Code Documentation
Loading...
Searching...
No Matches
KoDualColorButton.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 SPDX-FileCopyrightText: 1999 Daniel M. Duley <mosfet@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-only
5*/
6
7#include "KoDualColorButton.h"
8#include "KoColor.h"
10#include <kcolormimedata.h>
11#include <kconfiggroup.h>
12#include <ksharedconfig.h>
13
14#include "dcolorarrow.xbm"
15#include "dcolorreset.xpm"
16
17#include <QColorDialog>
19
20#include "kis_signals_blocker.h"
21
22#include <QBrush>
23#include <QDrag>
24#include <QDragEnterEvent>
25#include <QPainter>
26#include <QPointer>
27#include <qdrawutil.h>
28#include <QApplication>
29
30class Q_DECL_HIDDEN KoDualColorButton::Private
31{
32public:
33 Private(const KoColor &fgColor, const KoColor &bgColor,
34 QWidget *_dialogParent,
35 const KoColorDisplayRendererInterface *_displayRenderer)
36 : dialogParent(_dialogParent)
37 , dragFlag( false )
38 , miniCtlFlag( false )
39 , foregroundColor(fgColor)
40 , backgroundColor(bgColor)
41
42 , displayRenderer(_displayRenderer)
43 {
44 updateArrows();
45 resetPixmap = QPixmap( (const char **)dcolorreset_xpm );
46
47 popDialog = true;
48 }
49
50 void updateArrows() {
51 arrowBitmap = QPixmap(12,12);
52 arrowBitmap.fill(Qt::transparent);
53
54 QPainter p(&arrowBitmap);
55 p.setPen(dialogParent->palette().windowText().color());
56
57 // arrow pointing left
58 p.drawLine(0, 3, 7, 3);
59 p.drawLine(1, 2, 1, 4);
60 p.drawLine(2, 1, 2, 5);
61 p.drawLine(3, 0, 3, 6);
62
63 // arrow pointing down
64 p.drawLine(8, 4, 8, 11);
65 p.drawLine(5, 8, 11, 8);
66 p.drawLine(6, 9, 10, 9);
67 p.drawLine(7, 10, 9, 10);
68 }
69
70 QWidget* dialogParent;
71
72 QPixmap arrowBitmap;
73 QPixmap resetPixmap;
74 bool dragFlag, miniCtlFlag;
82
84};
85
86void KoDualColorButton::Private::init(KoDualColorButton *q)
87{
88 if ( q->sizeHint().isValid() )
89 q->setMinimumSize( q->sizeHint() );
90
91 q->setAcceptDrops( true );
92 QString caption = i18n("Select a Color");
94 config.modal = false;
95 colorSelectorDialog = new KisDlgInternalColorSelector(q, foregroundColor, config, caption, displayRenderer);
96 connect(colorSelectorDialog, SIGNAL(signalForegroundColorChosen(KoColor)), q, SLOT(slotSetForeGroundColorFromDialog(KoColor)));
97 connect(q, SIGNAL(foregroundColorChanged(KoColor)), colorSelectorDialog, SLOT(slotColorUpdated(KoColor)));
98}
99
100KoDualColorButton::KoDualColorButton(const KoColor &foregroundColor, const KoColor &backgroundColor, QWidget *parent, QWidget* dialogParent )
101 : QWidget( parent ),
102 d( new Private(foregroundColor, backgroundColor,
103 dialogParent,
105{
106 d->init(this);
107}
108
109KoDualColorButton::KoDualColorButton(const KoColor &foregroundColor, const KoColor &backgroundColor,
110 const KoColorDisplayRendererInterface *displayRenderer,
111 QWidget *parent, QWidget* dialogParent)
112 : QWidget( parent ),
113 d( new Private(foregroundColor, backgroundColor,
114 dialogParent,
115 displayRenderer) )
116{
117 d->init(this);
118}
119
124
126{
127 return d->foregroundColor;
128}
129
131{
132 return d->backgroundColor;
133}
134
136{
137 return d->popDialog;
138}
139
141{
142 return QSize(34, 34);
143}
144
146{
147 d->foregroundColor = color;
148 {
153 KisSignalsBlocker b(d->colorSelectorDialog);
154 d->colorSelectorDialog->slotColorUpdated(color);
155 }
156 update();
157}
158
160{
161 d->backgroundColor = color;
162 update();
163}
164
166{
167 if (d->displayRenderer && d->displayRenderer != KoDumbColorDisplayRenderer::instance()) {
168 d->displayRenderer->disconnect(this);
169 }
170 if (displayRenderer) {
171 d->displayRenderer = displayRenderer;
172 d->colorSelectorDialog->setDisplayRenderer(displayRenderer);
173 connect(d->displayRenderer, SIGNAL(destroyed()), this, SLOT(setDisplayRenderer()), Qt::UniqueConnection);
174 connect(d->displayRenderer, SIGNAL(displayConfigurationChanged()), this, SLOT(update()));
175 } else {
176 d->displayRenderer = KoDumbColorDisplayRenderer::instance();
177 }
178}
179
181{
182 d->colorSelectorDialog->lockUsedColorSpace(cs);
183}
184
186{
187 QColor col;
188 if (d->displayRenderer) {
189 c.convertTo(d->displayRenderer->getPaintingColorSpace());
190 col = d->displayRenderer->toQColor(c);
191 } else {
192 col = c.toQColor();
193 }
194 return col;
195}
196
198{
199 d->popDialog = popDialog;
200}
201
202void KoDualColorButton::metrics( QRect &foregroundRect, QRect &backgroundRect )
203{
204 foregroundRect = QRect( 0, 0, width() - 14, height() - 14 );
205 backgroundRect = QRect( 14, 14, width() - 14, height() - 14 );
206}
207
209{
210 QRect foregroundRect;
211 QRect backgroundRect;
212
213 QPainter painter( this );
214
215 metrics( foregroundRect, backgroundRect );
216
217 QBrush defBrush = palette().brush( QPalette::Button );
218 QBrush foregroundBrush( getColorFromDisplayRenderer(d->foregroundColor), Qt::SolidPattern );
219 QBrush backgroundBrush( getColorFromDisplayRenderer(d->backgroundColor), Qt::SolidPattern );
220
221 qDrawShadeRect( &painter, backgroundRect, palette(), false, 1, 0,
222 isEnabled() ? &backgroundBrush : &defBrush );
223
224 qDrawShadeRect( &painter, foregroundRect, palette(), false, 1, 0,
225 isEnabled() ? &foregroundBrush : &defBrush );
226
227 painter.setPen( palette().color( QPalette::Shadow ) );
228
229 painter.drawPixmap( foregroundRect.right() + 2, 1, d->arrowBitmap );
230 painter.drawPixmap( 1, foregroundRect.bottom() + 2, d->resetPixmap );
231}
232
233void KoDualColorButton::dragEnterEvent( QDragEnterEvent *event )
234{
235 event->setAccepted( isEnabled() && KColorMimeData::canDecode( event->mimeData() ) );
236}
237
238void KoDualColorButton::dropEvent( QDropEvent *event )
239{
240 Q_UNUSED(event);
241 /* QColor color = KColorMimeData::fromMimeData( event->mimeData() );
242
243 if ( color.isValid() ) {
244 if ( d->selection == Foreground ) {
245 d->foregroundColor = color;
246 Q_EMIT foregroundColorChanged( color );
247 } else {
248 d->backgroundColor = color;
249 Q_EMIT backgroundColorChanged( color );
250 }
251
252 update();
253 }
254*/
255}
256
258{
259 d->foregroundColor = color;
260 update();
261 Q_EMIT foregroundColorChanged(d->foregroundColor);
262}
263
264
266 d->colorSelectorDialog->setPreviousColor(d->foregroundColor);
267 d->colorSelectorDialog->show();
268 update();
269}
270
272 KoColor c = d->backgroundColor;
273 c = KisDlgInternalColorSelector::getModalColorDialog(c, this, d->colorSelectorDialog->windowTitle());
274 d->backgroundColor = c;
275 Q_EMIT backgroundColorChanged(d->backgroundColor);
276}
277
278void KoDualColorButton::mousePressEvent( QMouseEvent *event )
279{
280 QRect foregroundRect;
281 QRect backgroundRect;
282
283 metrics( foregroundRect, backgroundRect );
284
285 d->dragPosition = event->pos();
286
287 d->dragFlag = false;
288
289 if ( foregroundRect.contains( d->dragPosition ) ) {
290 d->tmpSelection = Foreground;
291 d->miniCtlFlag = false;
292 }
293 else if( backgroundRect.contains( d->dragPosition ) ) {
294 d->tmpSelection = Background;
295 d->miniCtlFlag = false;
296 }
297 else if ( event->pos().x() > foregroundRect.width() ) {
298 // We handle the swap and reset controls as soon as the mouse is
299 // is pressed and ignore further events on this click (mosfet).
300
301 KoColor tmp = d->foregroundColor;
302 d->foregroundColor = d->backgroundColor;
303 d->backgroundColor = tmp;
304
305 Q_EMIT backgroundColorChanged( d->backgroundColor );
306 Q_EMIT foregroundColorChanged( d->foregroundColor );
307
308 d->miniCtlFlag = true;
309 }
310 else if ( event->pos().x() < backgroundRect.x() ) {
311 d->foregroundColor = d->displayRenderer->approximateFromRenderedQColor(Qt::black);
312 d->backgroundColor = d->displayRenderer->approximateFromRenderedQColor(Qt::white);
313
314 Q_EMIT backgroundColorChanged( d->backgroundColor );
315 Q_EMIT foregroundColorChanged( d->foregroundColor );
316
317 d->miniCtlFlag = true;
318 }
319 update();
320}
321
322
323void KoDualColorButton::mouseMoveEvent( QMouseEvent *event )
324{
325 if ( !d->miniCtlFlag ) {
326 int delay = QApplication::startDragDistance();
327
328 if ( event->x() >= d->dragPosition.x() + delay || event->x() <= d->dragPosition.x() - delay ||
329 event->y() >= d->dragPosition.y() + delay || event->y() <= d->dragPosition.y() - delay ) {
330 KColorMimeData::createDrag( d->tmpSelection == Foreground ?
331 getColorFromDisplayRenderer(d->foregroundColor) :
332 getColorFromDisplayRenderer(d->backgroundColor),
333 this )->exec();
334 d->dragFlag = true;
335 }
336 }
337}
338
339void KoDualColorButton::mouseReleaseEvent( QMouseEvent *event )
340{
341 d->dragFlag = false;
342
343 if ( d->miniCtlFlag )
344 return;
345
346 d->miniCtlFlag = false;
347
348 QRect foregroundRect;
349 QRect backgroundRect;
350 metrics( foregroundRect, backgroundRect );
351
352 KConfigGroup cfg = KSharedConfig::openConfig()->group("colorselector");
353 bool usePlatformDialog = cfg.readEntry("UsePlatformColorDialog", false);
354
355 if (foregroundRect.contains( event->pos())) {
356 if (d->tmpSelection == Foreground) {
357 if (d->popDialog) {
358 if (usePlatformDialog) {
359 QColor c = d->foregroundColor.toQColor();
360 c = QColorDialog::getColor(c, this);
361 if (c.isValid()) {
362 d->foregroundColor = d->displayRenderer->approximateFromRenderedQColor(c);
363 Q_EMIT foregroundColorChanged(d->foregroundColor);
364 }
365 }
366 else {
367 d->colorSelectorDialog->setPreviousColor(d->foregroundColor);
368 d->colorSelectorDialog->show();
369 }
370 }
371 }
372 else {
373 d->foregroundColor = d->backgroundColor;
374 Q_EMIT foregroundColorChanged( d->foregroundColor );
375 }
376 }
377 else if (backgroundRect.contains( event->pos())) {
378 if(d->tmpSelection == Background ) {
379 if( d->popDialog) {
380 if (usePlatformDialog) {
381 QColor c = d->backgroundColor.toQColor();
382 c = QColorDialog::getColor(c, this);
383 if (c.isValid()) {
384 d->backgroundColor = d->displayRenderer->approximateFromRenderedQColor(c);
385 Q_EMIT backgroundColorChanged(d->backgroundColor);
386 }
387 }
388 else {
389 KoColor c = d->backgroundColor;
390 c = KisDlgInternalColorSelector::getModalColorDialog(c, this, d->colorSelectorDialog->windowTitle());
391 d->backgroundColor = c;
392 Q_EMIT backgroundColorChanged(d->backgroundColor);
393 }
394 }
395 } else {
396 d->backgroundColor = d->foregroundColor;
397 Q_EMIT backgroundColorChanged( d->backgroundColor );
398 }
399 }
400
401 update();
402}
403
405{
406 QWidget::changeEvent(event);
407
408 switch (event->type()) {
409 case QEvent::StyleChange:
410 case QEvent::PaletteChange:
411 d->updateArrows();
412 default:
413 break;
414 }
415}
416
417bool KoDualColorButton::event(QEvent *event)
418{
419 if (event->type() == QEvent::ToolTip) {
420 QRect foregroundRect;
421 QRect backgroundRect;
422 metrics( foregroundRect, backgroundRect );
423
424 if (this->mapFromGlobal(QCursor::pos()).x() < backgroundRect.x() ) {
425 if (this->mapFromGlobal(QCursor::pos()).y() < backgroundRect.y()){
426 this->setToolTip(i18n("Foreground color selector"));
427 }
428 else{
429 this->setToolTip(i18n("Set foreground and background colors to black and white"));
430 }
431 }
432 else {
433 if (this->mapFromGlobal(QCursor::pos()).y() < backgroundRect.y() ) {
434 this->setToolTip(i18n("Swap foreground and background colors"));
435 }
436 else{
437 this->setToolTip(i18n("Background color selector"));
438 }
439 }
440 }
441 return QWidget::event(event);
442
443}
const Params2D p
PythonPluginManager * instance
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
The KisInternalColorSelector class.
static KoColor getModalColorDialog(const KoColor color, QWidget *parent=0, QString caption=QString())
getModalColorDialog Execute this dialog modally. The function returns the KoColor you want.
void convertTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
Definition KoColor.cpp:136
void toQColor(QColor *c) const
a convenience method for the above.
Definition KoColor.cpp:198
A widget for selecting two related colors.
void setForegroundColor(const KoColor &color)
void slotSetForeGroundColorFromDialog(const KoColor color)
void mouseMoveEvent(QMouseEvent *event) override
bool event(QEvent *event) override
void paintEvent(QPaintEvent *event) override
void setPopDialog(bool popDialog)
QSize sizeHint() const override
void dragEnterEvent(QDragEnterEvent *event) override
KoDualColorButton(const KoColor &foregroundColor, const KoColor &backgroundColor, QWidget *parent=0, QWidget *dialogParent=0)
Private(const KoColor &fgColor, const KoColor &bgColor, QWidget *_dialogParent, const KoColorDisplayRendererInterface *_displayRenderer)
void init(KoDualColorButton *q)
void foregroundColorChanged(const KoColor &color)
void setColorSpace(const KoColorSpace *cs)
setColorSpace set ColorSpace so we can lock the selector. Right now this'll be changed per view-chang...
KisDlgInternalColorSelector * colorSelectorDialog
QColor getColorFromDisplayRenderer(KoColor c)
getColorFromDisplayRenderer convenience function to get the right qcolor from the display renderer,...
virtual void metrics(QRect &foregroundRect, QRect &backgroundRect)
void mousePressEvent(QMouseEvent *event) override
void backgroundColorChanged(const KoColor &color)
void mouseReleaseEvent(QMouseEvent *event) override
void setDisplayRenderer(const KoColorDisplayRendererInterface *displayRenderer=KoDumbColorDisplayRenderer::instance())
void setBackgroundColor(const KoColor &color)
QPointer< const KoColorDisplayRendererInterface > displayRenderer
void dropEvent(QDropEvent *event) override
void changeEvent(QEvent *event) override
static KoColorDisplayRendererInterface * instance()
rgba palette[MAX_PALETTE]
Definition palette.c:35