Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_specific_color_selector_widget.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2008 Cyrille Berger <cberger@cberger.net>
3 * SPDX-FileCopyrightText: 2015 Moritz Molch <kde@moritzmolch.de>
4 *
5 * SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
9#include <QLabel>
10#include <QVBoxLayout>
11#include <QButtonGroup>
12#include <QRadioButton>
13#include <QSpacerItem>
14
15#include <klocalizedstring.h>
16#include <kconfiggroup.h>
17#include <kconfig.h>
18#include <ksharedconfig.h>
19
20#include <KoChannelInfo.h>
21#include <KoColorSpace.h>
25
26#include <kis_color_input.h>
27#include <KoColorProfile.h>
28#include <kis_debug.h>
32#include <KisPopupButton.h>
33#include <kis_icon_utils.h>
34
35#include "ui_wdgSpecificColorSelectorWidget.h"
36
38 : QWidget(parent)
39 , m_inputs()
40 , m_hexInput(nullptr)
41 , m_hsvSlider(nullptr)
42 , m_rgbButton(nullptr)
43 , m_hsxButton(nullptr)
44 , m_hsvSelector(nullptr)
45 , m_colorSpace(nullptr)
46 , m_color()
47 , m_FGColor()
48 , m_updateAllowed(true)
49 , m_updateCompressor(new KisSignalCompressor(10, KisSignalCompressor::POSTPONE, this))
50 , m_colorspaceSelector(nullptr)
51 , m_ui(nullptr)
52 , m_displayConverter(nullptr)
53 , m_converterConnection()
54{
55
56 m_ui.reset(new Ui_wdgSpecificColorSelectorWidget());
57 m_ui->setupUi(this);
58
59 // Set up "RGB/HSV" button group
60 m_hsvSelector = new QButtonGroup(this);
61 m_rgbButton = new QRadioButton("RGB", this);
62 m_hsxButton = new QRadioButton("HSV", this);
63 m_hsxModeComboBox = new QComboBox(this);
64
65 m_hsxButton->setText("");
66 m_rgbButton->setChecked(true);
67 m_hsxModeComboBox->addItem(i18n("HSV"));
68 m_hsxModeComboBox->addItem(i18n("HSL"));
69 m_hsxModeComboBox->addItem(i18n("HSI"));
70 m_hsxModeComboBox->addItem(i18n("HSY"));
71
72 connect(m_hsvSelector, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(hsvSelectorClicked(QAbstractButton*)));
73 connect(m_hsxModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeHsxMode(int)));
74
75 m_hsvSelector->addButton(m_rgbButton);
76 m_hsvSelector->addButton(m_hsxButton);
77 m_hsvSelector->setExclusive(true);
78 m_rgbButton->setVisible(false);
79 m_hsxButton->setVisible(false);
80 m_hsxModeComboBox->setVisible(false);
81
82 QSpacerItem *hsvButtonSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding);
83 m_ui->hsvButtonsLayout->addWidget(m_rgbButton);
84 m_ui->hsvButtonsLayout->addWidget(m_hsxButton);
85 m_ui->hsvButtonsLayout->addWidget(m_hsxModeComboBox);
86 m_ui->hsvButtonsLayout->addItem(hsvButtonSpacer);
87
88 // Set up HSV sliders
90 m_hsvSlider->setVisible(false);
91
92 connect(m_hsvSlider, SIGNAL(updated()), this, SLOT(update()));
93 connect(this, SIGNAL(updated()), m_hsvSlider, SLOT(update()));
94
95 m_ui->hsvSlidersLayout->addWidget(m_hsvSlider);
96
97 connect(m_updateCompressor, SIGNAL(timeout()), SLOT(updateTimeout()));
98
100 connect(m_colorspaceSelector, SIGNAL(colorSpaceChanged(const KoColorSpace*)), this, SLOT(setCustomColorSpace(const KoColorSpace*)));
101
102 m_ui->colorspacePopupButton->setPopupWidget(m_colorspaceSelector);
103
104 m_ui->useSameColorSpace->setChecked(true);
105 setUseSameColorSpace(m_ui->useSameColorSpace->isChecked(), false);
106 connect(m_ui->useSameColorSpace, SIGNAL(toggled(bool)), this, SLOT(setUseSameColorSpace(bool)));
107
108 connect(m_ui->chkUsePercentage, SIGNAL(toggled(bool)), this, SLOT(onChkUsePercentageChanged(bool)));
109
110 KConfigGroup cfg = KSharedConfig::openConfig()->group(QString());
111 m_ui->chkUsePercentage->setChecked(cfg.readEntry("SpecificColorSelector/UsePercentage", false));
112 m_ui->chkUsePercentage->setIcon(KisIconUtils::loadIcon("ratio"));
113 m_hsxModeComboBox->setCurrentIndex(cfg.readEntry("SpecificColorSelector/HsxMode", 0));
114 m_hsxButton->setChecked(cfg.readEntry("SpecificColorSelector/UseHsx", false));
115
117
118 QSpacerItem *bottomSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding);
119 m_ui->spacerLayout->addItem(bottomSpacer);
120}
121
123{
124 KConfigGroup cfg = KSharedConfig::openConfig()->group(QString());
125 cfg.writeEntry("SpecificColorSelector/UsePercentage", m_ui->chkUsePercentage->isChecked());
126 cfg.writeEntry("SpecificColorSelector/HsxMode", m_hsxModeComboBox->currentIndex());
127 cfg.writeEntry("SpecificColorSelector/UseHsx", m_hsxButton->isChecked());
128}
129
130void KisSpecificColorSelectorWidget::setUseSameColorSpace(bool locked, bool reloadColorSpace)
131{
132 m_ui->useSameColorSpace->setIcon(locked ? KisIconUtils::loadIcon("chain-icon") : KisIconUtils::loadIcon("chain-broken-icon"));
133 if (locked && reloadColorSpace) {
135 }
136}
137
139{
140 QWidget::resizeEvent(event);
141
142 if (m_colorSpace) {
143 QString elidedColorspaceName = m_ui->colorspacePopupButton->fontMetrics().elidedText(
144 m_colorSpace->name(), Qt::ElideRight,
145 m_ui->colorspacePopupButton->width()
146 );
147 m_ui->colorspacePopupButton->setText(elidedColorspaceName);
148 }
149}
150
152{
153 const bool needsForceUpdate = m_displayConverter != displayConverter;
154
155 m_displayConverter = displayConverter;
156
157 if (m_displayConverter) {
159 m_converterConnection.addConnection(m_displayConverter, SIGNAL(displayConfigurationChanged()), this, SLOT(rereadCurrentColorSpace()), Qt::UniqueConnection);
160 }
161
162 rereadCurrentColorSpace(needsForceUpdate);
163}
164
166{
167 if (m_displayConverter && m_ui->useSameColorSpace->isChecked()) {
169 } else {
171 }
172
174}
175
177{
178 Q_ASSERT(cs);
179 dbgPlugins << cs->id() << " " << cs->profile()->name();
180
181 if (m_colorSpace && *m_colorSpace == *cs && !force) {
182 Q_FOREACH (KisColorInput* input, m_inputs) {
183 input->update();
184 }
185
186 return;
187 }
188
190 m_ui->chkUsePercentage->setVisible(true);
191 } else {
192 m_ui->chkUsePercentage->setVisible(false);
193 }
194
196 Q_ASSERT(m_colorSpace);
197 Q_ASSERT(*m_colorSpace == *cs);
198
199 QString elidedColorspaceName = m_ui->colorspacePopupButton->fontMetrics().elidedText(
200 m_colorSpace->name(), Qt::ElideRight,
201 m_ui->colorspacePopupButton->width()
202 );
203 m_ui->colorspacePopupButton->setText(elidedColorspaceName);
204
206 Q_FOREACH (KisColorInput* input, m_inputs) {
207 delete input;
208 }
209 if (m_hexInput) {
210 delete m_hexInput;
211 m_hexInput = nullptr;
212 }
213 m_inputs.clear();
214
216
217 KoColorDisplayRendererInterface *displayRenderer =
221
222 Q_FOREACH (KoChannelInfo* channel, channels) {
223 if (channel->channelType() == KoChannelInfo::COLOR) {
224 KisColorInput* input = 0;
225 switch (channel->channelValueType()) {
229 input = new KisIntegerColorInput(this, channel, &m_color, displayRenderer, m_ui->chkUsePercentage->isChecked());
230 }
231 break;
234 input = new KisFloatColorInput(this, channel, &m_color, displayRenderer);
235 }
236 break;
237 default:
238 Q_ASSERT(false);
239 input = 0;
240 }
241 if (input) {
242 connect(input, SIGNAL(updated()), this, SLOT(update()));
243 connect(this, SIGNAL(updated()), input, SLOT(update()));
244
245 m_inputs.append(input);
246 m_ui->slidersLayout->addWidget(input);
247 }
248 }
249 }
250
251 QList<QLabel*> labels;
252 int labelWidth = 0;
253
254 Q_FOREACH (KisColorInput* input, m_inputs) {
255 Q_FOREACH (QLabel* label, input->findChildren<QLabel*>()) {
256 labels.append(label);
257 labelWidth = qMax(labelWidth, label->sizeHint().width());
258 }
259 }
260
261 Q_FOREACH (QLabel *label, labels) {
262 label->setMinimumWidth(labelWidth);
263 }
264
265 bool allChannels8Bit = true;
266 Q_FOREACH (KoChannelInfo* channel, channels) {
267 if (channel->channelType() == KoChannelInfo::COLOR && channel->channelValueType() != KoChannelInfo::UINT8) {
268 allChannels8Bit = false;
269 }
270 }
271 if (allChannels8Bit) {
272 // Set up the Hex input
273 m_hexInput = new KisHexColorInput(this, &m_color, displayRenderer, false, true);
274 m_ui->hexSelectorLayout->addWidget(m_hexInput);
275 connect(m_hexInput, SIGNAL(updated()), this, SLOT(update()));
276 connect(this, SIGNAL(updated()), m_hexInput, SLOT(update()));
277 }
278
280
281 m_colorspaceSelector->blockSignals(true);
283 m_colorspaceSelector->blockSignals(false);
284
285 m_updateAllowed = false;
286 emit(updated());
287 m_updateAllowed = true;
288}
289
297{
298 m_updateAllowed = false;
300 emit(updated());
301 m_updateAllowed = true;
302}
303
308
309
314
316{
317 m_ui->useSameColorSpace->setChecked(false);
318 setColorSpace(colorSpace);
320}
321
323{
324 for (auto input: m_inputs) {
325 input->setPercentageWise(isChecked);
326 }
327 emit(updated());
328}
329
334
338
340{
341 m_rgbButton->setVisible(isRgbColorSpace);
342 m_hsxButton->setVisible(isRgbColorSpace);
343 m_hsxModeComboBox->setVisible(isRgbColorSpace);
344
345 if (!isRgbColorSpace) {
346 // Force to be RGB only
347 m_hsvSlider->setVisible(false);
348 Q_FOREACH (KisColorInput* input, m_inputs) {
349 input->setVisible(true);
350 }
351 m_ui->chkUsePercentage->setEnabled(true);
352
353 return;
354 }
355
356 Q_FOREACH (KisColorInput* input, m_inputs) {
357 input->setVisible(m_rgbButton->isChecked());
358 }
359 m_ui->chkUsePercentage->setEnabled(m_rgbButton->isChecked());
360
361 m_hsvSlider->setVisible(m_hsxButton->isChecked());
362}
363
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void setCurrentColorSpace(const KoColorSpace *colorSpace)
void showColorBrowserButton(bool showButton)
KoColorDisplayRendererInterface * displayRendererInterface() const
const KoColorSpace * paintingColorSpace() const
static KisDisplayColorConverter * dumbConverterInstance()
void setMixMode(KisHsvColorSlider::MIX_MODE mixMode)
void addConnection(Sender sender, Signal signal, Receiver receiver, Method method, Qt::ConnectionType type=Qt::AutoConnection)
void colorChanged(const KoColor &)
void setColorSpace(const KoColorSpace *cs, bool force=false)
void resizeEvent(QResizeEvent *event) override
QScopedPointer< Ui_wdgSpecificColorSelectorWidget > m_ui
KisSignalAutoConnectionsStore m_converterConnection
void setUseSameColorSpace(bool locked, bool reloadColorSpace=true)
void setDisplayConverter(KisDisplayColorConverter *colorConverter)
@ COLOR
The channel represents a color.
@ UINT8
use this for an unsigned integer 8bits channel
@ UINT16
use this for an integer 16bits channel
@ FLOAT32
use this for a float 32bits channel
@ FLOAT16
use this for a float 16bits channel
@ UINT32
use this for an unsigned integer 21bits channel
enumChannelType channelType() const
enumChannelValueType channelValueType() const
static QList< KoChannelInfo * > displayOrderSorted(const QList< KoChannelInfo * > &channels)
QList< KoChannelInfo * > channels
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
virtual const KoColorProfile * profile() const =0
void fromKoColor(const KoColor &src)
Definition KoColor.cpp:294
QString id() const
Definition KoID.cpp:63
#define dbgPlugins
Definition kis_debug.h:51
QIcon loadIcon(const QString &name)
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()