2
* kis_tool_brush.cc - part of Krita
4
* Copyright (c) 2003-2004 Boudewijn Rempt <boud@valdyas.org>
5
* Copyright (c) 2004 Bart Coppens <kde@bartcoppens.be>
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32
#include "kis_painter.h"
33
#include "kis_fill_painter.h"
34
#include "kis_tool_freehand.h"
35
#include "kis_cursor.h"
38
#include "kis_button_press_event.h"
39
#include "kis_button_release_event.h"
40
#include "kis_move_event.h"
42
KisToolFreehand::KisToolFreehand(QString transactionText)
43
: super(transactionText),
45
m_transactionText(transactionText),
51
m_useTempLayer = false;
54
KisToolFreehand::~KisToolFreehand()
58
void KisToolFreehand::update(KisCanvasSubject *subject)
60
super::update(subject);
61
m_currentImage = m_subject -> currentImg();
64
void KisToolFreehand::buttonPress(KisButtonPressEvent *e)
66
if (!m_subject) return;
68
if (!m_subject -> currentBrush()) return;
70
if (!m_currentImage || !m_currentImage -> activeDevice()) return;
72
if (e -> button() == QMouseEvent::LeftButton) {
76
paintAt(e -> pos(), e -> pressure(), e -> xTilt(), e -> yTilt());
78
m_prevPos = e -> pos();
79
m_prevPressure = e -> pressure();
80
m_prevXTilt = e -> xTilt();
81
m_prevYTilt = e -> yTilt();
83
QRect r = m_painter -> dirtyRect();
86
m_currentImage -> notify(r);
91
void KisToolFreehand::buttonRelease(KisButtonReleaseEvent* e)
93
if (e -> button() == QMouseEvent::LeftButton && m_mode == PAINT) {
98
void KisToolFreehand::move(KisMoveEvent *e)
100
if (m_mode == PAINT) {
101
paintLine(m_prevPos, m_prevPressure, m_prevXTilt, m_prevYTilt, e -> pos(), e -> pressure(), e -> xTilt(), e -> yTilt());
103
m_prevPos = e -> pos();
104
m_prevPressure = e -> pressure();
105
m_prevXTilt = e -> xTilt();
106
m_prevYTilt = e -> yTilt();
108
QRect r = m_painter -> dirtyRect();
110
m_currentImage -> notify(r);
114
void KisToolFreehand::initPaint(KisEvent *)
116
if (!m_currentImage || !m_currentImage -> activeDevice()) return;
122
KisPaintDeviceSP device;
123
if (m_currentImage && (device = m_currentImage -> activeDevice())) {
126
if (m_useTempLayer) {
127
if (m_currentImage -> undoAdapter())
128
m_currentImage -> undoAdapter() -> beginMacro(m_transactionText);
131
m_target = dynamic_cast<KisDoc*>(m_subject->document())->layerAdd(currentImage(), "temp", OPACITY_OPAQUE);
133
m_target -> setCompositeOp(m_compositeOp);
135
if (device -> hasSelection()) {
136
m_target -> addSelection(device -> selection());
137
m_target -> selection() -> setMaskColor( device -> selection() -> maskColor() );
140
dynamic_cast<KisLayer*>(m_target.data()) -> setVisible(true);
142
// XXX doesn't look very good I'm afraid
143
currentImage() -> add(dynamic_cast<KisLayer*>(m_target.data()),
144
currentImage() -> index(dynamic_cast<KisLayer*>(device.data())) + 1);
145
m_target = currentImage() -> activate(dynamic_cast<KisLayer*>(m_target.data()));
146
currentImage() -> notify();
150
m_painter = new KisPainter( m_target );
151
Q_CHECK_PTR(m_painter);
153
m_painter -> beginTransaction(m_transactionText);
156
m_painter -> setPaintColor(m_subject -> fgColor());
157
m_painter -> setBackgroundColor(m_subject -> bgColor());
158
m_painter -> setBrush(m_subject -> currentBrush());
160
m_painter -> setOpacity(m_opacity);
162
// if you're drawing on a temporary layer, the layer already sets this
163
if (m_useTempLayer) {
164
m_painter -> setCompositeOp(COMPOSITE_OVER);
166
m_painter -> setCompositeOp(m_compositeOp);
169
// Set the cursor -- ideally. this should be a mask created from the brush,
170
// now that X11 can handle colored cursors.
172
// Setting cursors has no effect until the tool is selected again; this
174
setCursor(KisCursor::brushCursor());
178
void KisToolFreehand::endPaint()
181
if (m_currentImage) {
182
KisUndoAdapter *adapter = m_currentImage -> undoAdapter();
183
if (adapter && m_painter) {
184
// If painting in mouse release, make sure painter
185
// is destructed or end()ed
186
if (m_useTempLayer) {
187
m_painter -> endTransaction();
188
KisPainter painter( m_source );
189
painter.setCompositeOp(m_compositeOp);
190
painter.beginTransaction(m_transactionText);
191
painter.bitBlt(m_dirtyRect.x(), m_dirtyRect.y(), m_compositeOp, m_target, OPACITY_OPAQUE,
192
m_dirtyRect.x(), m_dirtyRect.y(), m_dirtyRect.width(), m_dirtyRect.height());
194
adapter -> addCommand(painter.endTransaction());
195
dynamic_cast<KisDoc*>(m_subject->document())->layerRemove(
196
currentImage(), dynamic_cast<KisLayer*>(m_target.data()));
197
currentImage() -> activate(dynamic_cast<KisLayer*>(m_source.data()));
198
adapter -> endMacro();
200
adapter -> addCommand(m_painter->endTransaction());
209
void KisToolFreehand::paintAt(const KisPoint &pos,
210
const double pressure,
214
painter() -> paintAt(pos, pressure, xTilt, yTilt);
217
void KisToolFreehand::paintLine(const KisPoint & pos1,
218
const double pressure1,
221
const KisPoint & pos2,
222
const double pressure2,
226
m_dragDist = painter() -> paintLine(pos1, pressure1, xtilt1, ytilt1, pos2, pressure2, xtilt2, ytilt2, m_dragDist);
230
KisImageSP KisToolFreehand::currentImage()
232
return m_currentImage;
235
void KisToolFreehand::setUseTempLayer(bool u) {
239
#include "kis_tool_freehand.moc"