Krita Source Code Documentation
Loading...
Searching...
No Matches
KisDlgInternalColorSelector.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Wolthera van Hovell tot Westerflier <griffinvalley@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#include <QAbstractSpinBox>
8#include <QSpinBox>
9#include <QDoubleSpinBox>
10#include <QCompleter>
11
12#include <functional>
13
14#include <KConfigGroup>
15#include <kstandardguiitem.h>
16
18#include <KoColorSet.h>
19#include <KisPaletteModel.h>
20#include <KisPaletteChooser.h>
21#include <kis_palette_view.h>
23#include <KoResourceServer.h>
24
27
29
31#include "ui_WdgDlgInternalColorSelector.h"
32#include "kis_config_notifier.h"
33#include "kis_color_input.h"
34#include "kis_icon_utils.h"
35#include "KisSqueezedComboBox.h"
36
38
56
57KisDlgInternalColorSelector::KisDlgInternalColorSelector(QWidget *parent, KoColor color, Config config, const QString &caption, const KoColorDisplayRendererInterface *displayRenderer)
58 : QDialog(parent)
59 , m_d(new Private)
60{
61 setModal(config.modal);
62 setFocusPolicy(Qt::ClickFocus);
63 m_ui = new Ui_WdgDlgInternalColorSelector();
64 m_ui->setupUi(this);
65
66 setWindowTitle(caption);
67
68 m_d->selectorModel = m_ui->visualSelector->selectorModel();
69
70 m_d->currentColor = color;
71 m_d->currentColorSpace = m_d->currentColor.colorSpace();
72 m_d->displayRenderer = displayRenderer;
73
74 m_ui->spinboxselector->slotSetColor(color);
75 connect(m_ui->spinboxselector, SIGNAL(sigNewColor(KoColor)), this, SLOT(slotColorUpdated(KoColor)));
76
77 m_ui->spinboxHSXSelector->setModel(m_d->selectorModel);
78
79 m_ui->visualSelector->setDisplayRenderer(displayRenderer);
80 m_ui->visualSelector->setConfig(false, config.modal);
81 if (config.visualColorSelector) {
82 connect(m_d->selectorModel.data(), SIGNAL(sigNewColor(KoColor)), this, SLOT(slotColorUpdated(KoColor)));
83 connect(m_d->selectorModel.data(), SIGNAL(sigColorModelChanged()), this, SLOT(slotSelectorModelChanged()));
84 connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), m_ui->visualSelector, SLOT(slotConfigurationChanged()));
85 } else {
86 m_ui->visualSelector->hide();
87 }
88 m_ui->visualSelector->slotSetColor(color);
89
90 m_d->paletteChooser = new KisPaletteChooser(this);
91 m_d->paletteModel = new KisPaletteModel(this);
92 m_ui->bnPaletteChooser->setIcon(KisIconUtils::loadIcon("palette-library"));
93 m_ui->bnPaletteChooser->setToolTip(i18n("Load a palette"));
94 m_ui->paletteBox->setPaletteModel(m_d->paletteModel);
95 m_ui->paletteBox->setDisplayRenderer(displayRenderer);
96 m_ui->cmbNameList->setCompanionView(m_ui->paletteBox);
97 connect(m_d->paletteChooser, SIGNAL(sigPaletteSelected(KoColorSetSP)), this, SLOT(slotChangePalette(KoColorSetSP)));
98 connect(m_ui->cmbNameList, SIGNAL(sigColorSelected(KoColor)), SLOT(slotColorUpdated(KoColor)));
99
100 // For some bizarre reason, the modal dialog doesn't like having the colorset set, so let's not.
101 if (config.paletteBox) {
102 //TODO: Add disable signal as well. Might be not necessary...?
103 KConfigGroup cfg(KSharedConfig::openConfig()->group(""));
104 QString paletteMd5 = cfg.readEntry("internal_selector_active_color_set_md5", QString());
105 QString paletteName = cfg.readEntry("internal_selector_active_color_set", QString());
107 KoColorSetSP savedPal = rServer->resource(paletteMd5, "", paletteName);
108 if (savedPal) {
109 this->slotChangePalette(savedPal);
110 } else {
111 if (rServer->resourceCount()) {
112 savedPal = rServer->firstResource();
113 if (savedPal) {
114 this->slotChangePalette(savedPal);
115 }
116 }
117 }
118
119 connect(m_ui->paletteBox, SIGNAL(sigColorSelected(KoColor)), this,
121 m_ui->bnPaletteChooser->setPopupWidget(m_d->paletteChooser);
122 } else {
123 m_ui->paletteBox->setEnabled(false);
124 m_ui->cmbNameList->setEnabled(false);
125 m_ui->bnPaletteChooser->setEnabled(false);
126 }
127
128 if (config.prevNextButtons) {
129 m_ui->currentColor->setColor(m_d->currentColor);
130 m_ui->currentColor->setDisplayRenderer(displayRenderer);
131 m_ui->previousColor->setColor(m_d->previousColor);
132 m_ui->previousColor->setDisplayRenderer(displayRenderer);
133 connect(m_ui->previousColor, SIGNAL(triggered(KoColorPatch*)), SLOT(slotSetColorFromPatch(KoColorPatch*)));
134 } else {
135 m_ui->currentColor->hide();
136 m_ui->previousColor->hide();
137 }
138
139 if (config.hexInput) {
140 m_d->sRGB.fromKoColor(m_d->currentColor);
141 m_d->hexColorInput = new KisHexColorInput(this, &m_d->sRGB);
142 m_d->hexColorInput->update();
143 connect(m_d->hexColorInput, SIGNAL(updated()), SLOT(slotSetColorFromHex()));
144 m_ui->rightPane->addWidget(m_d->hexColorInput);
145 m_d->hexColorInput->setToolTip(i18n("This is a hexcode input, for webcolors. It can only get colors in the sRGB space."));
146 }
147
148 // KisScreenColorSampler is in the kritaui module, so dependency inversion is used to access it.
149 m_ui->screenColorSamplerWidget->setLayout(new QHBoxLayout());
151 m_d->screenColorSampler = s_screenColorSamplerFactory(m_ui->screenColorSamplerWidget);
152 m_ui->screenColorSamplerWidget->layout()->addWidget(m_d->screenColorSampler);
153 if (config.screenColorSampler) {
154 connect(m_d->screenColorSampler, SIGNAL(sigNewColorSampled(KoColor)),this, SLOT(slotColorUpdated(KoColor)));
155 } else {
156 m_d->screenColorSampler->hide();
157 }
158 }
159
160 m_d->compressColorChanges = new KisSignalCompressor(100 /* ms */, KisSignalCompressor::POSTPONE, this);
161 connect(m_d->compressColorChanges, SIGNAL(timeout()), this, SLOT(endUpdateWithNewColor()));
162
163 KGuiItem::assign(m_ui->buttonBox->button(QDialogButtonBox::Ok), KStandardGuiItem::ok());
164 KGuiItem::assign(m_ui->buttonBox->button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel());
165 connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()), Qt::UniqueConnection);
166 connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()), Qt::UniqueConnection);
167
168 connect(this, SIGNAL(finished(int)), SLOT(slotFinishUp()));
169}
170
175
177{
178 // not-so-nice solution: if someone calls this slot directly and that code was
179 // triggered by our compressor signal, our compressor is technically the sender()!
180 if (sender() == m_d->compressColorChanges) {
181 return;
182 }
183 // Do not accept external updates while a color update Q_EMIT is pending;
184 // Note: Assumes external updates only come from parent(), a separate slot might be better
185 if (m_d->allowUpdates || (QObject::sender() && QObject::sender() != this->parent())) {
186 // Enforce palette colors
187 KConfigGroup group(KSharedConfig::openConfig(), "");
188 if (group.readEntry("colorsettings/forcepalettecolors", false)) {
189 newColor = m_ui->paletteBox->closestColor(newColor);
190 }
191
192 if (m_d->lockUsedCS){
193 newColor.convertTo(m_d->currentColorSpace);
194 } else {
195 colorSpaceChanged(newColor.colorSpace());
196 }
197 m_d->currentColor = newColor;
198 updateAllElements(QObject::sender());
199 }
200}
201
206
208{
209 if (cs == m_d->currentColorSpace) {
210 return;
211 }
212
213 m_d->currentColorSpace = KoColorSpaceRegistry::instance()->colorSpace(cs->colorModelId().id(), cs->colorDepthId().id(), cs->profile());
214 m_ui->spinboxselector->slotSetColorSpace(m_d->currentColorSpace);
215 m_ui->visualSelector->slotSetColorSpace(m_d->currentColorSpace);
216
217}
218
220{
222 if (m_d->currentColor.colorSpace() != m_d->currentColorSpace) {
223 m_d->currentColor.convertTo(m_d->currentColorSpace);
224 m_ui->spinboxselector->slotSetColor(m_d->currentColor);
225 m_ui->visualSelector->slotSetColor(m_d->currentColor);
226 }
227 m_d->lockUsedCS = true;
228}
229
231{
232 if (displayRenderer) {
233 m_d->displayRenderer = displayRenderer;
234 m_ui->visualSelector->setDisplayRenderer(displayRenderer);
235 m_ui->currentColor->setDisplayRenderer(displayRenderer);
236 m_ui->previousColor->setDisplayRenderer(displayRenderer);
237 m_ui->paletteBox->setDisplayRenderer(displayRenderer);
238 } else {
239 m_d->displayRenderer = KoDumbColorDisplayRenderer::instance();
240 }
241}
242
243KoColor KisDlgInternalColorSelector::getModalColorDialog(const KoColor color, QWidget* parent, QString caption)
244{
245 Config config = Config();
246 KisDlgInternalColorSelector dialog(parent, color, config, caption);
247 dialog.setPreviousColor(color);
248 dialog.exec();
249 return dialog.getCurrentColor();
250}
251
253{
254 return m_d->currentColor;
255}
256
258{
259 m_d->chooseAlpha = chooseAlpha;
260}
261
263{
264 m_d->previousColor = c;
265}
266
268{
269 slotColorUpdated(m_d->previousColor);
270 QDialog::reject();
271}
272
274{
275 //update everything!!!
276 if (source != m_ui->spinboxselector) {
277 m_ui->spinboxselector->slotSetColor(m_d->currentColor);
278 }
279
280 if (source != m_ui->visualSelector) {
281 m_ui->visualSelector->slotSetColor(m_d->currentColor);
282 }
283
284 if (source != m_d->hexColorInput) {
285 m_d->sRGB.fromKoColor(m_d->currentColor);
286 m_d->hexColorInput->update();
287 }
288
289 if (source != m_ui->paletteBox) {
290 m_ui->paletteBox->selectClosestColor(m_d->currentColor);
291 }
292
293 m_ui->previousColor->setColor(m_d->previousColor);
294
295 m_ui->currentColor->setColor(m_d->currentColor);
296
297 if (source && source != this->parent()) {
298 m_d->allowUpdates = false;
299 m_d->compressColorChanges->start();
300 }
301
302 if (m_d->screenColorSampler) {
303 m_d->screenColorSampler->updateIcons();
304 }
305}
306
308{
309 if (m_d->selectorModel->isHSXModel()) {
310 QString label;
311 switch (m_d->selectorModel->colorModel()) {
313 label = i18n("HSV");
314 break;
316 label = i18n("HSL");
317 break;
319 label = i18n("HSI");
320 break;
322 label = i18n("HSY'");
323 break;
324 default:
325 label = i18n("Unknown");
326 }
327 if (m_ui->tabWidget->count() == 1) {
328 m_ui->tabWidget->addTab(m_ui->tab_hsx, label);
329 }
330 else {
331 m_ui->tabWidget->setTabText(1, label);
332 }
333 }
334 else {
335 if (m_ui->tabWidget->count() == 2) {
336 m_ui->tabWidget->removeTab(1);
337 }
338 }
339}
340
342{
343 Q_EMIT signalForegroundColorChosen(m_d->currentColor);
344 m_d->allowUpdates = true;
345}
346
348{
349 //setPreviousColor();
350}
351
353{
354 setPreviousColor(m_d->currentColor);
355 KConfigGroup cfg(KSharedConfig::openConfig()->group(""));
356 if (m_d->paletteModel) {
357 if (m_d->paletteModel->colorSet()) {
358 cfg.writeEntry("internal_selector_active_color_set_md5", m_d->paletteModel->colorSet()->md5Sum());
359 cfg.writeEntry("internal_selector_active_color_set", m_d->paletteModel->colorSet()->name());
360 }
361 }
362}
363
368
370{
371 if (!set) {
372 return;
373 }
374 m_d->paletteModel->setColorSet(set);
375}
376
378{
380 QDialog::showEvent(event);
381}
382
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
static KisConfigNotifier * instance()
The KisInternalColorSelector class.
static std::function< KisScreenColorSamplerBase *(QWidget *) s_screenColorSamplerFactory)
void setPreviousColor(KoColor c)
setPreviousColor set the previous color.
void colorSpaceChanged(const KoColorSpace *cs)
slotColorSpaceChanged Color space has changed, use this dialog to change the colorspace.
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 setDisplayRenderer(const KoColorDisplayRendererInterface *displayRenderer)
setDisplayRenderer Set the display renderer. This is necessary for HDR color manage support.
void signalForegroundColorChosen(KoColor color)
signalForegroundColorChosen The most important signal. This will sent out when a color has been chose...
void lockUsedColorSpace(const KoColorSpace *cs)
lockUsedColorSpace Lock the used colorspace of this selector.
void showEvent(QShowEvent *event) override
void slotColorUpdated(KoColor newColor)
slotColorUpdated Very important slot. Is connected to krita's resources to make sure it has the curre...
void slotFinishUp()
slotFinishUp This is called when the selector is closed, for saving the current palette.
void slotSetColorFromPatch(KoColorPatch *patch)
slotSetColorFromPatch update current color from kocolorpatch.
void focusInEvent(QFocusEvent *) override
void slotSetColorFromHex()
slotSetColorFromHex Update from the hex color input.
KisDlgInternalColorSelector(QWidget *parent, KoColor color, Config config, const QString &caption, const KoColorDisplayRendererInterface *displayRenderer=KoDumbColorDisplayRenderer::instance())
void updateAllElements(QObject *source)
updateAllElements Updates each widget with the new element, and if it's responsible for the update se...
const QScopedPointer< Private > m_d
Ui_WdgDlgInternalColorSelector * m_ui
The KisPaletteModel class This, together with KisPaletteView and KisPaletteDelegate forms a mvc way t...
KoColor color() const
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
virtual const KoColorProfile * profile() const =0
void convertTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
Definition KoColor.cpp:136
const KoColorSpace * colorSpace() const
return the current colorSpace
Definition KoColor.h:82
static KoColorDisplayRendererInterface * instance()
QString id() const
Definition KoID.cpp:63
int resourceCount() const
QSharedPointer< T > resource(const QString &md5, const QString &fileName, const QString &name)
resource retrieves a resource. If the md5sum is not empty, the resource will only be retrieved if a r...
QSharedPointer< T > firstResource() const
Return the first resource available.
QIcon loadIcon(const QString &name)
const KoColorDisplayRendererInterface * displayRenderer
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()
static KoResourceServerProvider * instance()
KoResourceServer< KoColorSet > * paletteServer