Krita Source Code Documentation
Loading...
Searching...
No Matches
dlg_colorrange.cc
Go to the documentation of this file.
1/*
2 * dlg_colorrange.cc - part of KimageShop^WKrayon^WKrita
3 *
4 * SPDX-FileCopyrightText: 2004 Boudewijn Rempt <boud@valdyas.org>
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9#include "dlg_colorrange.h"
10#include <QApplication>
11#include <QCheckBox>
12#include <QSlider>
13#include <QColor>
14#include <QRadioButton>
15
16#include <klocalizedstring.h>
17#include <kis_debug.h>
18
19#include <KoColorConversions.h>
20#include <KoColorProfile.h>
21#include <KoColorSpace.h>
22#include <KoColor.h>
25#include <KoColorSpaceTraits.h>
26
27#include <kis_layer.h>
28#include <kis_paint_device.h>
29#include <kis_selection.h>
31#include <kis_default_bounds.h>
33#include <kis_types.h>
34#include <kis_undo_adapter.h>
35#include <KisViewManager.h>
36#include <kis_transaction.h>
37#include <kis_cursor.h>
38#include "kis_iterator_ng.h"
40#include <kis_slider_spin_box.h>
42
43DlgColorRange::DlgColorRange(KisViewManager *viewManager, QWidget *parent)
44 : KoDialog(parent)
45 , m_selectionCommandsAdded(0)
46 , m_viewManager(viewManager)
47{
48 setCaption(i18n("Color Range"));
51
52 m_page = new WdgColorRange(this);
53 Q_CHECK_PTR(m_page);
54 m_page->setObjectName("color_range");
55
56 setCaption(i18n("Color Range"));
58 resize(m_page->sizeHint());
59
60 m_page->intFuzziness->setObjectName("fuzziness");
61 m_page->intFuzziness->setRange(0, 200);
62 m_page->intFuzziness->setSingleStep(10);
63 m_page->intFuzziness->setValue(100);
64
65 m_invert = false;
68
69 connect(this, SIGNAL(okClicked()),
70 this, SLOT(okClicked()));
71
72 connect(this, SIGNAL(cancelClicked()),
73 this, SLOT(cancelClicked()));
74
75 connect(m_page->chkInvert, SIGNAL(clicked()),
76 this, SLOT(slotInvertClicked()));
77
78 connect(m_page->cmbSelect, SIGNAL(activated(int)),
79 this, SLOT(slotSelectionTypeChanged(int)));
80
81 connect(m_page->radioAdd, SIGNAL(toggled(bool)),
82 this, SLOT(slotAdd(bool)));
83
84 connect(m_page->radioSubtract, SIGNAL(toggled(bool)),
85 this, SLOT(slotSubtract(bool)));
86
87 connect(m_page->bnSelect, SIGNAL(clicked()),
88 this, SLOT(slotSelectClicked()));
89
90 connect(m_page->bnDeselect, SIGNAL(clicked()),
91 this, SLOT(slotDeselectClicked()));
92
93 m_page->bnDeselect->setEnabled(false);
94
95}
96
101
103{
104 accept();
105}
106
108{
109 if (!m_viewManager) return;
110 if (!m_viewManager->image()) return;
111
112 for (int i = 0; i < m_selectionCommandsAdded; i++) {
114 }
115 m_viewManager->canvas()->update();
116 reject();
117}
118
120{
121 m_invert = m_page->chkInvert->isChecked();
122}
123
128
130{
131 if (on)
133}
134
136{
137 if (on)
139}
140
142{
145
146 QRect rc = m_viewManager->image()->bounds();
147
148 if (rc.isEmpty()) return;
149
150 KisCursorOverrideLock cursorLock(KisCursor::waitCursor());
151
152 qint32 x, y, w, h;
153 rc.getRect(&x, &y, &w, &h);
154
157
158 KoColor match;
159 switch (m_currentAction) {
160 case REDS:
161 match = KoColor(QColor(Qt::red), cs);
162 break;
163 case YELLOWS:
164 match = KoColor(QColor(Qt::yellow), cs);
165 break;
166 case GREENS:
167 match = KoColor(QColor(Qt::green), cs);
168 break;
169 case CYANS:
170 match = KoColor(QColor(Qt::cyan), cs);
171 break;
172 case BLUES:
173 match = KoColor(QColor(Qt::blue), cs);
174 break;
175 case MAGENTAS:
176 match = KoColor(QColor(Qt::magenta), cs);
177 break;
178 default:
179 ;
180 };
181
182 int fuzziness = m_page->intFuzziness->value();
183
186
188 KisHLineIteratorSP selIter = selection->pixelSelection()->createHLineIteratorNG(x, y, w);
189
190 for (int row = y; row < h - y; ++row) {
191 do {
192 // Don't try to select transparent pixels.
193 if (cs->opacityU8(hiter->oldRawData()) > OPACITY_TRANSPARENT_U8) {
194
195 bool selected = false;
196
197 KoColor c(hiter->oldRawData(), cs);
199 c.convertTo(lab);
200 quint8 L = lab->scaleToU8(c.data(), 0);
201
202 switch (m_currentAction) {
203 case HIGHLIGHTS:
204 selected = (L > MAX_SELECTED - fuzziness);
205 break;
206 case MIDTONES:
207 selected = (L > MAX_SELECTED / 2 - fuzziness && L < MAX_SELECTED / 2 + fuzziness);
208 break;
209 case SHADOWS:
210 selected = (L < MIN_SELECTED + fuzziness);
211 break;
212 default:
213 ;
214 }
215 }
216 else {
217 quint8 difference = cs->difference(match.data(), c.data());
218 selected = (difference <= fuzziness);
219 }
220
221 if (selected) {
222 if (!m_invert) {
223 if (m_mode == SELECTION_ADD) {
224 *(selIter->rawData()) = MAX_SELECTED;
225 } else if (m_mode == SELECTION_SUBTRACT) {
226 *(selIter->rawData()) = MIN_SELECTED;
227 }
228 } else {
229 if (m_mode == SELECTION_ADD) {
230 *(selIter->rawData()) = MIN_SELECTED;
231 } else if (m_mode == SELECTION_SUBTRACT) {
232 *(selIter->rawData()) = MAX_SELECTED;
233 }
234 }
235 }
236 }
237 } while (hiter->nextPixel() && selIter->nextPixel());
238 hiter->nextRow();
239 selIter->nextRow();
240 }
241
243 KisSelectionToolHelper helper(m_viewManager->canvasBase(), kundo2_i18n("Color Range Selection"));
244 helper.selectPixelSelection(selection->pixelSelection(), m_mode);
245
246 m_page->bnDeselect->setEnabled(true);
248}
249
251{
252 if (!m_viewManager) return;
253
254
258 m_page->bnDeselect->setEnabled(false);
259 }
260}
261
262
@ SELECTION_SUBTRACT
@ SELECTION_ADD
const quint8 OPACITY_TRANSPARENT_U8
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void slotAdd(bool on)
DlgColorRange(KisViewManager *viewManager, QWidget *parent=0)
int m_selectionCommandsAdded
void slotSelectionTypeChanged(int index)
void slotSubtract(bool on)
WdgColorRange * m_page
~DlgColorRange() override
KisViewManager * m_viewManager
void slotDeselectClicked()
enumAction m_currentAction
SelectionAction m_mode
virtual const quint8 * oldRawData() const =0
virtual bool nextPixel()=0
static QCursor waitCursor()
Definition kis_cursor.cc:54
virtual void nextRow()=0
QRect bounds() const override
KisHLineIteratorSP createHLineIteratorNG(qint32 x, qint32 y, qint32 w)
const KoColorSpace * colorSpace() const
KisHLineConstIteratorSP createHLineConstIteratorNG(qint32 x, qint32 y, qint32 w) const
void selectPixelSelection(KisProcessingApplicator &applicator, KisPixelSelectionSP selection, SelectionAction action)
virtual void undoLastCommand()=0
KisCanvas2 * canvasBase() const
Return the canvas base class.
KisUndoAdapter * undoAdapter()
The undo adapter is used to add commands to the undo stack.
QWidget * canvas() const
Return the actual widget that is displaying the current image.
KisPaintDeviceSP activeDevice()
Convenience method to get at the active paint device.
KisImageWSP image() const
Return the image this view is displaying.
virtual quint8 difference(const quint8 *src1, const quint8 *src2) const =0
virtual quint8 scaleToU8(const quint8 *srcPixel, qint32 channelPos) const =0
virtual quint8 opacityU8(const quint8 *pixel) const =0
void convertTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
Definition KoColor.cpp:136
quint8 * data()
Definition KoColor.h:144
A dialog base class with standard buttons and predefined layouts.
Definition KoDialog.h:116
void setMainWidget(QWidget *widget)
Definition KoDialog.cpp:354
virtual void setCaption(const QString &caption)
Definition KoDialog.cpp:498
void setButtons(ButtonCodes buttonMask)
Definition KoDialog.cpp:195
void setDefaultButton(ButtonCode id)
Definition KoDialog.cpp:302
@ Ok
Show Ok button. (this button accept()s the dialog; result set to QDialog::Accepted)
Definition KoDialog.h:127
@ Cancel
Show Cancel-button. (this button reject()s the dialog; result set to QDialog::Rejected)
Definition KoDialog.h:130
enumAction
@ CYANS
@ BLUES
@ SHADOWS
@ MAGENTAS
@ MIDTONES
@ REDS
@ YELLOWS
@ GREENS
@ HIGHLIGHTS
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75
const quint8 MAX_SELECTED
Definition kis_global.h:32
const quint8 MIN_SELECTED
Definition kis_global.h:33
QSharedPointer< T > toQShared(T *ptr)
KUndo2MagicString kundo2_i18n(const char *text)
KisPixelSelectionSP pixelSelection
const KoColorSpace * lab16(const QString &profileName=QString())
static KoColorSpaceRegistry * instance()