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
92 }
93
94 switch (m_configuration.mainType) {
97 break;
100 break;
103 break;
104 default:
105 Q_ASSERT(false);
106 }
107
108 switch (m_configuration.subType) {
111 break;
114 break;
115 default:
116 Q_ASSERT(false);
117 }
118
119 connect(m_mainComponent, SIGNAL(paramChanged(qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal)),
120 m_subComponent, SLOT(setParam(qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal)), Qt::UniqueConnection);
121 connect(m_subComponent, SIGNAL(paramChanged(qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal)),
122 m_mainComponent, SLOT(setParam(qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal,qreal)), Qt::UniqueConnection);
123
124 connect(m_mainComponent, SIGNAL(update()), m_signalCompressor, SLOT(start()), Qt::UniqueConnection);
125 connect(m_subComponent, SIGNAL(update()), m_signalCompressor, SLOT(start()), Qt::UniqueConnection);
126
128
129 // Use Hluma as subType when the main type uses hsy'.
132
134 QResizeEvent event(QSize(width(), height()), QSize());
135 resizeEvent(&event);
136}
137
142
144{
146 KConfigGroup cfg = KSharedConfig::openConfig()->group("advancedColorSelector");
147
148 setConfiguration(KisColorSelectorConfiguration::fromString(cfg.readEntry("colorSelectorConfiguration", KisColorSelectorConfiguration().toString())));
149
150 if (m_canvas && m_canvas->viewManager() && m_canvas->viewManager()->canvasResourceProvider()) {
151 bool gamutMaskActive = m_canvas->viewManager()->canvasResourceProvider()->gamutMaskActive();
152
153 if (gamutMaskActive) {
154 KoGamutMaskSP currentMask = m_canvas->viewManager()->canvasResourceProvider()->currentGamutMask();
155 if (currentMask) {
156 slotGamutMaskSet(currentMask);
157 }
158 } else {
159 slotGamutMaskToggle(false);
160 }
161 }
162}
163
171
179
185
190
196
198 if (m_button) {
199 m_button->setIcon(KisIconUtils::loadIcon("configure"));
200 }
201}
202
207
209{
210 if (m_mainComponent) {
212 }
213
214 if (m_subComponent) {
216 }
217
219}
220
222{
223 Q_UNUSED(e);
224 QPainter p(this);
225 KConfigGroup cfg = KSharedConfig::openConfig()->group("advancedColorSelector");
226
227 // If checked, use theme colors for background of selector
228 if (cfg.readEntry("useCustomColorForBackground", false)) {
229 p.fillRect(0,0,width(), height(), cfg.readEntry("customSelectorBackgroundColor", QColor(Qt::gray)));
230 } else {
231 p.fillRect(0,0,width(), height(), qApp->palette().window().color());
232 }
233
234 p.setRenderHint(QPainter::Antialiasing);
235
236 // this variable name isn't entirely accurate to what always happens. see definition in header file to understand it better
238 p.setOpacity(0.2);
239 }
240
243
244 p.setOpacity(1.0);
245}
246
247inline int iconSize(qreal width, qreal height) {
248 qreal radius = qMin(width, height)/2.;
249 qreal xm = width/2.;
250 qreal ym = height/2.;
251 if(xm>=2*ym || ym>=2*xm)
252 return qBound<qreal>(5., radius, 32.);
253
254 qreal a=-2;
255 qreal b=2.*(xm+ym);
256 qreal c=radius*radius-xm*xm-ym*ym;
257 return qBound<qreal>(5., ((-b+sqrt(b*b-4*a*c))/(2*a)), 32.);
258}
259
260void KisColorSelector::resizeEvent(QResizeEvent* e) {
262
263 m_ring->setGeometry(0,0,width(), height());
264
265 if (displaySettingsButton()) {
266 int size = iconSize(width(), height());
267 m_button->setGeometry(0, 0, size, size);
268 }
269
272 height()/2-m_ring->innerRadius(),
273 m_ring->innerRadius()*2,
274 m_ring->innerRadius()*2);
275 }
276 else {
277 int size = m_ring->innerRadius()*2/sqrt(2.);
278 m_square->setGeometry(width()/2-size/2,
279 height()/2-size/2,
280 size,
281 size);
282 }
283 }
284 else {
285 // type wheel and square
288 int size = iconSize(width(), height()*0.9);
289 m_button->setGeometry(0, height()*0.1, size, size);
290 }
291 m_mainComponent->setGeometry(0, height()*0.1, width(), height()*0.9);
292 m_subComponent->setGeometry( 0, 0, width(), height()*0.1);
293 }
294 else {
295 int buttonSize = 0;
297 buttonSize = qBound(20, int(0.1*height()), 32);
298 m_button->setGeometry(0, 0, buttonSize, buttonSize);
299 }
300
301 if(height()>width()) {
302 int selectorHeight=height()-buttonSize;
303 m_mainComponent->setGeometry(0, buttonSize+selectorHeight*0.1, width(), selectorHeight*0.9);
304 m_subComponent->setGeometry( 0, buttonSize, width(), selectorHeight*0.1);
305 }
306 else {
307 int selectorWidth=width()-buttonSize;
308 m_mainComponent->setGeometry(buttonSize, height()*0.1, selectorWidth, height()*0.9);
309 m_subComponent->setGeometry( buttonSize, 0, selectorWidth, height()*0.1);
310 }
311 }
312 }
313
314 // reset the correct color after resizing the widget
316
317 KisColorSelectorBase::resizeEvent(e);
318}
319
321{
322 e->setAccepted(false);
324
325 if(!e->isAccepted()) {
326 if(m_mainComponent->wantsGrab(e->x(), e->y()))
328 else if(m_subComponent->wantsGrab(e->x(), e->y()))
330
331 mouseEvent(e);
333 e->accept();
334 }
335}
336
338{
340
341 mouseEvent(e);
342 e->accept();
343}
344
346{
347 e->setAccepted(false);
349
350 if(!e->isAccepted() &&
352
354 m_lastColorRole = Acs::buttonToRole(e->button());
355
358 e->accept();
359 }
360
362}
363
365{
366 return dynamic_cast<KisColorSelectorContainer*>(parent());
367}
368
370{
372 m_subComponent->setColor(color);
373 m_lastRealColor = color;
374
376}
377
379{
380 if (m_grabbingComponent && (e->buttons() & Qt::LeftButton || e->buttons() & Qt::RightButton)) {
381
382 m_grabbingComponent->mouseEvent(e->x(), e->y());
383
385 Acs::ColorRole role = Acs::buttonsToRole(e->button(), e->buttons());
386 m_currentRealColor = color;
387
388 requestUpdateColorAndPreview(color, role);
389 }
390}
391
393{
394 setAcceptDrops(true);
395
397 m_ring = new KisColorSelectorRing(this);
401 m_wheel = new KisColorSelectorWheel(this);
402
404 m_button = new QToolButton(this);
405 m_button->setIcon(KisIconUtils::loadIcon("configure-thicker"));
406 m_button->setAutoRaise(true);
407 connect(m_button, SIGNAL(clicked()), SIGNAL(settingsButtonClicked()));
408 }
409
410 // a tablet can send many more signals, than a mouse
411 // this causes many repaints, if updating after every signal.
413 connect(m_signalCompressor, SIGNAL(timeout()), SLOT(update()));
414
415 setMinimumSize(40, 40);
416}
float value(const T *src, size_t ch)
const Params2D p
static int buttonSize(int screen)
Definition KoToolBox.cpp:41
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)