2
* Copyright (c) 1999 Matthias Elter <me@kde.org>
3
* Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
4
* Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
#include <qcheckbox.h>
25
#include <qcombobox.h>
29
#include <kapplication.h>
32
#include <knuminput.h>
34
#include <kis_cursor.h>
35
#include <kis_selection_manager.h>
36
#include <kis_canvas_subject.h>
37
#include <kis_image.h>
38
#include <kis_paint_device.h>
39
#include <kis_button_press_event.h>
40
#include <kis_canvas_subject.h>
41
#include <kis_selection_options.h>
42
#include <kis_selection.h>
43
#include <kis_paint_device.h>
44
#include <kis_iterators_pixel.h>
45
#include <kis_color_utilities.h>
46
#include <kis_selected_transaction.h>
47
#include <kis_undo_adapter.h>
49
#include "kis_tool_selectpicker.h"
51
void selectByColor(KisPaintDeviceSP dev, KisSelectionSP selection, const QColor & c, int fuzziness, enumSelectionMode mode)
53
// XXX: Multithread this!
57
dev -> exactBounds(x, y, w, h);
59
KisStrategyColorSpaceSP cs = dev -> colorStrategy();
60
KisProfileSP profile = dev -> profile();
62
for (int y2 = y; y2 < h - y; ++y2) {
63
KisHLineIterator hiter = dev -> createHLineIterator(x, y2, w, false);
64
KisHLineIterator selIter = selection -> createHLineIterator(x, y2, w, true);
65
while (!hiter.isDone()) {
67
cs -> toQColor(hiter.rawData(), &c2, &opacity, profile);
69
// Don't try to select transparent pixels. The Gimp has an option to match transparent pixels; we don't, for the moment.
70
if (opacity > OPACITY_TRANSPARENT) {
72
Q_UINT8 match = matchColors(c, c2, fuzziness);
73
//kdDebug() << " Match: " << QString::number(match) << ", mode: " << mode << "\n";
74
if (mode == SELECTION_ADD) {
75
Q_UINT8 d = *(selIter.rawData());
76
if (d + match > MAX_SELECTED) {
77
*(selIter.rawData()) = MAX_SELECTED;
80
*(selIter.rawData()) = match + d;
84
else if (mode == SELECTION_SUBTRACT) {
85
Q_UINT8 selectedness = *(selIter.rawData());
86
if (match < selectedness) {
87
*(selIter.rawData()) = selectedness - match;
90
*(selIter.rawData()) = 0;
103
KisToolSelectPicker::KisToolSelectPicker()
105
setName("tool_selectpicker");
106
setCursor(KisCursor::pickerCursor());
109
m_selectionOptionsWidget = 0;
111
m_currentSelectAction = m_defaultSelectAction = SELECTION_ADD;
112
m_timer = new QTimer(this);
113
connect(m_timer, SIGNAL(timeout()), SLOT(slotTimer()) );
116
KisToolSelectPicker::~KisToolSelectPicker()
120
void KisToolSelectPicker::activate()
122
KisToolNonPaint::activate();
124
setPickerCursor(m_currentSelectAction);
126
if (m_selectionOptionsWidget) {
127
m_selectionOptionsWidget -> slotActivated();
131
void KisToolSelectPicker::clear()
136
void KisToolSelectPicker::buttonPress(KisButtonPressEvent *e)
138
kdDebug() << "button press: " << m_subject << "\n";
142
KisPaintDeviceSP dev;
147
if (e -> button() != QMouseEvent::LeftButton && e -> button() != QMouseEvent::RightButton)
150
if (!(img = m_subject -> currentImg()))
153
dev = img -> activeDevice();
155
if (!dev || !dev -> visible())
159
pos = QPoint(e -> pos().floorX(), e -> pos().floorY());
161
KisSelectedTransaction *t = new KisSelectedTransaction(i18n("Selection Picker"),dev);
163
dev -> pixel(pos.x(), pos.y(), &c, &opacity);
164
kdDebug() << "Going to select colors similar to: " << c.red() << ", " << c.green() << ", "<< c.blue() << "\n";
165
if (opacity > OPACITY_TRANSPARENT)
166
selectByColor(dev, dev -> selection(), c, m_fuzziness, m_currentSelectAction);
168
m_subject -> selectionManager() -> selectAll();
170
if(img -> undoAdapter())
171
img -> undoAdapter() -> addCommand(t);
172
m_subject -> canvasController() -> updateCanvas();
173
m_selectionOptionsWidget -> ensureMaskColor();
177
void KisToolSelectPicker::slotTimer()
179
#if KDE_IS_VERSION(3,4,0)
180
int state = kapp->keyboardMouseState() & (Qt::ShiftButton|Qt::ControlButton|Qt::AltButton);
182
int state = kapp->keyboardModifiers() & (KApplication::ShiftModifier
183
|KApplication::ControlModifier|KApplication::Modifier1);
185
enumSelectionMode action;
187
if (state == Qt::ShiftButton)
188
action = SELECTION_ADD;
189
else if (state == Qt::ControlButton)
190
action = SELECTION_SUBTRACT;
192
action = m_defaultSelectAction;
194
if (action != m_currentSelectAction) {
195
m_currentSelectAction = action;
196
setPickerCursor(action);
200
void KisToolSelectPicker::setPickerCursor(enumSelectionMode action)
204
m_subject -> setCanvasCursor(KisCursor::pickerPlusCursor());
206
case SELECTION_SUBTRACT:
207
m_subject -> setCanvasCursor(KisCursor::pickerMinusCursor());
211
void KisToolSelectPicker::setup(KActionCollection *collection)
213
m_action = static_cast<KRadioAction *>(collection -> action(name()));
216
m_action = new KRadioAction(i18n("Tool &Selection Picker"), "tool_picker_selection", Qt::Key_E, this, SLOT(activate()), collection, name());
217
Q_CHECK_PTR(m_action);
218
m_action -> setExclusiveGroup("tools");
223
void KisToolSelectPicker::update(KisCanvasSubject *subject)
225
super::update(subject);
229
void KisToolSelectPicker::slotSetFuzziness(int fuzziness)
231
m_fuzziness = fuzziness;
234
void KisToolSelectPicker::slotSetAction(int action)
236
m_defaultSelectAction = (enumSelectionMode)action;
239
QWidget* KisToolSelectPicker::createOptionWidget(QWidget* parent)
241
m_optWidget = new QWidget(parent);
242
Q_CHECK_PTR(m_optWidget);
244
m_optWidget -> setCaption(i18n("Selection Picker"));
246
QVBoxLayout * l = new QVBoxLayout(m_optWidget);
249
m_selectionOptionsWidget = new KisSelectionOptions(m_optWidget, m_subject);
250
Q_CHECK_PTR(m_selectionOptionsWidget);
252
l -> addWidget(m_selectionOptionsWidget);
253
connect (m_selectionOptionsWidget, SIGNAL(actionChanged(int)), this, SLOT(slotSetAction(int)));
255
QHBoxLayout * hbox = new QHBoxLayout(l);
258
QLabel * lbl = new QLabel(i18n("Fuzziness: "), m_optWidget);
261
hbox -> addWidget(lbl);
263
KIntNumInput * input = new KIntNumInput(m_optWidget, "fuzziness");
266
input -> setRange(0, 200, 10, true);
267
input -> setValue(20);
268
hbox -> addWidget(input);
269
connect(input, SIGNAL(valueChanged(int)), this, SLOT(slotSetFuzziness(int)));
274
QWidget* KisToolSelectPicker::optionWidget()
279
#include "kis_tool_selectpicker.moc"