Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_color_selector.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2010 Adam Celarek <kdedev at xibo dot at>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
8
9#include <cmath>
10
11#include <QHBoxLayout>
12#include <QColor>
13#include <QPainter>
14#include <QMouseEvent>
15#include <QToolButton>
16#include <QApplication>
17
18#include <kconfig.h>
19#include <kconfiggroup.h>
20#include <ksharedconfig.h>
21
22#include <kis_debug.h>
23
26#include <kis_icon.h>
27
33#include "kis_canvas2.h"
35#include "KisViewManager.h"
36
37
39 : KisColorSelectorBase(parent),
40 m_ring(0),
41 m_triangle(0),
42 m_slider(0),
43 m_square(0),
44 m_wheel(0),
45 m_mainComponent(0),
46 m_subComponent(0),
47 m_grabbingComponent(0),
48 m_blipDisplay(true)
49{
50 init();
52 setConfiguration(conf);
53}
54
56 : KisColorSelectorBase(parent),
57 m_ring(0),
58 m_triangle(0),
59 m_slider(0),
60 m_square(0),
61 m_wheel(0),
62 m_button(0),
63 m_mainComponent(0),
64 m_subComponent(0),
65 m_grabbingComponent(0),
66 m_blipDisplay(true)
67{
68 init();
70}
71
78
80{
81 m_configuration = conf;
82
83 if(m_mainComponent!=0) {
84 Q_ASSERT(m_subComponent!=0);
85 m_mainComponent->setGeometry(0, 0, 0, 0);
86 m_subComponent->setGeometry(0, 0, 0, 0);
87
88 m_mainComponent->disconnect();
89 m_subComponent->disconnect();
90 }
91
92 switch (m_configuration.mainType) {
95 break;
98 break;
101 break;
102 default:
103 Q_ASSERT(false);
104 }
105
106 switch (m_configuration.subType) {
109 break;
112 break;
113 default:
114 Q_ASSERT(false);
115 }
116
117 connect(m_mainComponent, SIGNAL(paramChanged(qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal)),
118 m_subComponent, SLOT(setParam(qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal)), Qt::UniqueConnection);
119 connect(m_subComponent, SIGNAL(paramChanged(qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal)),
120 m_mainComponent, SLOT(setParam(qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal)), Qt::UniqueConnection);
121
122 connect(m_mainComponent, SIGNAL(update()), m_signalCompressor, SLOT(start()), Qt::UniqueConnection);
123 connect(m_subComponent, SIGNAL(update()), m_signalCompressor, SLOT(start()), Qt::UniqueConnection);
124
126
127 // Use Hluma as subType when the main type uses hsy'.
130
132 QResizeEvent event(QSize(width(), height()), QSize());
133 resizeEvent(&event);
134}
135
140
142{
144 KConfigGroup cfg = KSharedConfig::openConfig()->group("advancedColorSelector");
145
146 setConfiguration(KisColorSelectorConfiguration::fromString(cfg.readEntry("colorSelectorConfiguration", KisColorSelectorConfiguration().toString())));
147
148 if (m_canvas && m_canvas->viewManager() && m_canvas->viewManager()->canvasResourceProvider()) {
149 bool gamutMaskActive = m_canvas->viewManager()->canvasResourceProvider()->gamutMaskActive();
150
151 if (gamutMaskActive) {
152 KoGamutMaskSP currentMask = m_canvas->viewManager()->canvasResourceProvider()->currentGamutMask();
153 if (currentMask) {
154 slotGamutMaskSet(currentMask);
155 }
156 } else {
157 slotGamutMaskToggle(false);
158 }
159 }
160}
161
169
177
183
188
194
196 if (m_button) {
197 m_button->setIcon(KisIconUtils::loadIcon("configure"));
198 }
199}
200
205
207{
208 if (m_mainComponent) {
210 }
211
212 if (m_subComponent) {
214 }
215
217}
218
220{
221 Q_UNUSED(e);
222 QPainter p(this);
223 KConfigGroup cfg = KSharedConfig::openConfig()->group("advancedColorSelector");
224
225 // If checked, use theme colors for background of selector
226 if (cfg.readEntry("useCustomColorForBackground", false)) {
227 p.fillRect(0,0,width(), height(), cfg.readEntry("customSelectorBackgroundColor", QColor(Qt::gray)));
228 } else {
229 p.fillRect(0,0,width(), height(), qApp->palette().window().color());
230 }
231
232 p.setRenderHint(QPainter::Antialiasing);
233
234 // this variable name isn't entirely accurate to what always happens. see definition in header file to understand it better
236 p.setOpacity(0.2);
237 }
238
241
242 p.setOpacity(1.0);
243}
244
245inline int iconSize(qreal width, qreal height) {
246 qreal radius = qMin(width, height)/2.;
247 qreal xm = width/2.;
248 qreal ym = height/2.;
249 if(xm>=2*ym || ym>=2*xm)
250 return qBound<qreal>(5., radius, 32.);
251
252 qreal a=-2;
253 qreal b=2.*(xm+ym);
254 qreal c=radius*radius-xm*xm-ym*ym;
255 return qBound<qreal>(5., ((-b+sqrt(b*b-4*a*c))/(2*a)), 32.);
256}
257
258void KisColorSelector::resizeEvent(QResizeEvent* e) {
260
261 m_ring->setGeometry(0,0,width(), height());
262
263 if (displaySettingsButton()) {
264 int size = iconSize(width(), height());
265 m_button->setGeometry(0, 0, size, size);
266 }
267
270 height()/2-m_ring->innerRadius(),
271 m_ring->innerRadius()*2,
272 m_ring->innerRadius()*2);
273 }
274 else {
275 int size = m_ring->innerRadius()*2/sqrt(2.);
276 m_square->setGeometry(width()/2-size/2,
277 height()/2-size/2,
278 size,
279 size);
280 }
281 }
282 else {
283 // type wheel and square
286 int size = iconSize(width(), height()*0.9);
287 m_button->setGeometry(0, height()*0.1, size, size);
288 }
289 m_mainComponent->setGeometry(0, height()*0.1, width(), height()*0.9);
290 m_subComponent->setGeometry( 0, 0, width(), height()*0.1);
291 }
292 else {
293 int buttonSize = 0;
295 buttonSize = qBound(20, int(0.1*height()), 32);
296 m_button->setGeometry(0, 0, buttonSize, buttonSize);
297 }
298
299 if(height()>width()) {
300 int selectorHeight=height()-buttonSize;
301 m_mainComponent->setGeometry(0, buttonSize+selectorHeight*0.1, width(), selectorHeight*0.9);
302 m_subComponent->setGeometry( 0, buttonSize, width(), selectorHeight*0.1);
303 }
304 else {
305 int selectorWidth=width()-buttonSize;
306 m_mainComponent->setGeometry(buttonSize, height()*0.1, selectorWidth, height()*0.9);
307 m_subComponent->setGeometry( buttonSize, 0, selectorWidth, height()*0.1);
308 }
309 }
310 }
311
312 // reset the correct color after resizing the widget
314
315 KisColorSelectorBase::resizeEvent(e);
316}
317
319{
320 e->setAccepted(false);
322
323 if(!e->isAccepted()) {
324 if(m_mainComponent->wantsGrab(e->x(), e->y()))
326 else if(m_subComponent->wantsGrab(e->x(), e->y()))
328
329 mouseEvent(e);
331 e->accept();
332 }
333}
334
336{
338
339 mouseEvent(e);
340 e->accept();
341}
342
344{
345 e->setAccepted(false);
347
348 if(!e->isAccepted() &&
350
352 m_lastColorRole = Acs::buttonToRole(e->button());
353
356 e->accept();
357 }
358
360}
361
363{
364 return dynamic_cast<KisColorSelectorContainer*>(parent());
365}
366
368{
370 m_subComponent->setColor(color);
371 m_lastRealColor = color;
372
374}
375
377{
378 if (m_grabbingComponent && (e->buttons() & Qt::LeftButton || e->buttons() & Qt::RightButton)) {
379
380 m_grabbingComponent->mouseEvent(e->x(), e->y());
381
383 Acs::ColorRole role = Acs::buttonsToRole(e->button(), e->buttons());
384 m_currentRealColor = color;
385
386 requestUpdateColorAndPreview(color, role);
387 }
388}
389
391{
392 setAcceptDrops(true);
393
395 m_ring = new KisColorSelectorRing(this);
399 m_wheel = new KisColorSelectorWheel(this);
400
402 m_button = new QToolButton(this);
403 m_button->setIcon(KisIconUtils::loadIcon("configure-thicker"));
404 m_button->setAutoRaise(true);
405 connect(m_button, SIGNAL(clicked()), SIGNAL(settingsButtonClicked()));
406 }
407
408 // a tablet can send many more signals, than a mouse
409 // this causes many repaints, if updating after every signal.
411 connect(m_signalCompressor, SIGNAL(timeout()), SLOT(update()));
412
413 setMinimumSize(40, 40);
414}
float value(const T *src, size_t ch)
const Params2D p
static int buttonSize(int screen)
Definition KoToolBox.cpp:41
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
int iconSize(qreal width, qreal height)
Base class for all color selectors, that should support color management and zooming.
virtual void setColor(const KoColor &color)
void mouseReleaseEvent(QMouseEvent *) override
void mousePressEvent(QMouseEvent *) override
void mouseMoveEvent(QMouseEvent *event) override
QPointer< KisCanvas2 > m_canvas
void updateBaseColorPreview(const KoColor &color)
void updateColor(const KoColor &color, Acs::ColorRole role, bool needsExplicitColorReset)
bool wantsGrab(int x, int y)
returns true, if this component wants to grab the mouse (normally true, if containsPoint returns true...
virtual void mouseEvent(int x, int y)
saves the mouse position, so that a blip can be created.
void setDirty()
force subsequent redraw of the component
virtual void setColor(const KoColor &color)
set the color, blibs etc
void setConfiguration(Parameter param, Type type)
setConfiguration can be ignored (for instance ring and triangle, as they can have only one config)
void setGamutMask(KoGamutMaskSP gamutMask)
KoColor currentColor()
return the color, that was selected by calling mouseEvent
void setGeometry(int x, int y, int width, int height)
static KisColorSelectorConfiguration fromString(QString string)
KisColorSelectorComponent * m_triangle
void updateSettings() override
KisColorSelectorSimple * m_square
KisColorSelectorSimple * m_slider
Acs::ColorRole m_lastColorRole
void hasAtLeastOneDocument(bool value)
void mouseEvent(QMouseEvent *e)
void setColor(const KoColor &color) override
void mouseMoveEvent(QMouseEvent *) override
KoGamutMaskSP gamutMask()
KisColorSelector(KisColorSelectorConfiguration conf, QWidget *parent=0)
KisColorSelectorConfiguration configuration() const
QToolButton * m_button
void settingsButtonClicked()
KisSignalCompressor * m_signalCompressor
void resizeEvent(QResizeEvent *) override
KisColorSelectorWheel * m_wheel
void requestUpdateColorAndPreview(const KisColor &color, Acs::ColorRole role)
void slotGamutMaskToggle(bool state)
void mousePressEvent(QMouseEvent *) override
KisColorSelectorComponent * m_subComponent
void slotGamutMaskSet(KoGamutMaskSP gamutMask)
KisColorSelectorComponent * m_mainComponent
KisColorSelectorRing * m_ring
KisColorSelectorConfiguration m_configuration
void mouseReleaseEvent(QMouseEvent *) override
KisColorSelectorBase * createPopup() const override
void paintEvent(QPaintEvent *) override
void setConfiguration(KisColorSelectorConfiguration conf)
KisColorSelectorComponent * m_grabbingComponent
void updateIcons()
update icons when a theme update happens
ColorRole buttonsToRole(Qt::MouseButton button, Qt::MouseButtons buttons)
ColorRole buttonToRole(Qt::MouseButton button)
@ Foreground
QIcon loadIcon(const QString &name)