32#include "kis_canvas_subject.h"
33#include "kis_undo_adapter.h"
34#include "kis_selection.h"
35#include "kis_painter.h"
36#include "kis_fill_painter.h"
37#include "kis_tool_freehand.h"
38#include "kis_cursor.h"
39#include "kis_button_press_event.h"
40#include "kis_button_release_event.h"
41#include "kis_move_event.h"
43#include "kis_group_layer.h"
44#include "kis_paint_layer.h"
45#include "kis_canvas.h"
46#include "kis_canvas_painter.h"
47#include "kis_boundary_painter.h"
50KisToolFreehand::KisToolFreehand(TQString transactionText)
51 : super(transactionText),
53 m_transactionText(transactionText),
59 m_paintIncremental =
true;
60 m_paintOnSelection =
false;
61 m_paintedOutline =
false;
64KisToolFreehand::~KisToolFreehand()
70 super::update(subject);
71 m_currentImage = m_subject->currentImg();
74void KisToolFreehand::buttonPress(KisButtonPressEvent *e)
76 if (!m_subject)
return;
78 if (!m_subject->currentBrush())
return;
80 if (!m_currentImage || !m_currentImage->activeDevice())
return;
82 if (e->button() == TQt::LeftButton) {
84 m_currentImage->activeDevice()->lock(
true );
85 kdDebug() <<
">>>>>>>>>>>>>>>>>>>Locking paint device\n";
93 paintAt(e->pos(), e->pressure(), e->xTilt(), e->yTilt());
96 m_prevPressure = e->pressure();
97 m_prevXTilt = e->xTilt();
98 m_prevYTilt = e->yTilt();
100 TQRect r = m_painter->dirtyRect();
104 r = TQRect(r.left()-1, r.top()-1, r.width()+2, r.height()+2);
105 if (!m_paintOnSelection) {
106 m_currentImage->activeLayer()->setDirty(r);
109 m_target->setDirty(r);
111 m_subject->canvasController()->updateCanvas( r );
117void KisToolFreehand::buttonRelease(KisButtonReleaseEvent* e)
119 if (e->button() == TQt::LeftButton && m_mode == PAINT) {
121 m_currentImage->activeDevice()->lock(
false );
122 kdDebug() <<
">>>>>>>>>>>>>>>>>>>UNLocking paint device\n";
125 KisToolPaint::buttonRelease(e);
128void KisToolFreehand::move(KisMoveEvent *e)
130 if (m_mode == PAINT) {
132 paintLine(m_prevPos, m_prevPressure, m_prevXTilt, m_prevYTilt, e->pos(), e->pressure(), e->xTilt(), e->yTilt());
134 m_prevPos = e->pos();
135 m_prevPressure = e->pressure();
136 m_prevXTilt = e->xTilt();
137 m_prevYTilt = e->yTilt();
139 TQRect r = m_painter->dirtyRect();
144 if (!m_paintOnSelection) {
145 m_currentImage->activeLayer()->setDirty(r);
149 r = TQRect(r.left()-1, r.top()-1, r.width()+2, r.height()+2);
150 m_target->setDirty(r);
151 m_subject->canvasController()->updateCanvas( r );
157void KisToolFreehand::initPaint(KisEvent *)
159 if (!m_currentImage || !m_currentImage->activeDevice())
return;
165 KisPaintDeviceSP device;
166 if (m_currentImage && (device = m_currentImage->activeDevice())) {
171 if (!m_paintIncremental) {
172 if (m_currentImage->undo())
173 m_currentImage->undoAdapter()->beginMacro(m_transactionText);
175 KisLayerSupportsIndirectPainting* layer;
176 if ((layer =
dynamic_cast<KisLayerSupportsIndirectPainting*
>(
177 m_currentImage->activeLayer().data()))) {
186 && (l->
parent()->childCount() == 1)
187 && l->
parent()->paintLayerInducesProjectionOptimization(pl)) {
190 l->
parent()->resetProjection(pl->paintDevice());
194 device->colorSpace());
195 layer->setTemporaryTarget(m_target);
196 layer->setTemporaryCompositeOp(m_compositeOp);
197 layer->setTemporaryOpacity(m_opacity);
199 if (device->hasSelection())
200 m_target->setSelection(device->selection());
205 if(m_target->hasSelection()) m_target->selection()->startCachingExactRect();
207 TQ_CHECK_PTR(m_painter);
209 if (currentImage()->undo()) m_painter->beginTransaction(m_transactionText);
212 m_painter->setPaintColor(m_subject->fgColor());
213 m_painter->setBackgroundColor(m_subject->bgColor());
214 m_painter->setBrush(m_subject->currentBrush());
218 if (m_paintIncremental) {
219 m_painter->setCompositeOp(m_compositeOp);
220 m_painter->setOpacity(m_opacity);
222 m_painter->setCompositeOp(COMPOSITE_ALPHA_DARKEN);
223 m_painter->setOpacity( OPACITY_OPAQUE );
237void KisToolFreehand::endPaint()
240 if (m_currentImage) {
245 if (!m_paintIncremental) {
246 if (m_currentImage->undo())
247 m_painter->endTransaction();
249 painter.setCompositeOp(m_compositeOp);
250 if (m_currentImage->undo())
251 painter.beginTransaction(m_transactionText);
252 painter.bitBlt(m_dirtyRect.x(), m_dirtyRect.y(), m_compositeOp, m_target,
254 m_dirtyRect.x(), m_dirtyRect.y(),
255 m_dirtyRect.width(), m_dirtyRect.height());
257 KisLayerSupportsIndirectPainting* layer =
258 dynamic_cast<KisLayerSupportsIndirectPainting*
>(m_source->parentLayer());
259 layer->setTemporaryTarget(0);
260 m_source->parentLayer()->setDirty(m_dirtyRect);
262 if (m_currentImage->undo()) {
263 m_currentImage->undoAdapter()->addCommand(painter.endTransaction());
264 m_currentImage->undoAdapter()->endMacro();
267 if (m_currentImage->undo())
268 m_currentImage->undoAdapter()->addCommand(m_painter->endTransaction());
274 if(m_target->hasSelection()) m_target->selection()->stopCachingExactRect();
278void KisToolFreehand::paintAt(
const KisPoint &pos,
279 const double pressure,
283 painter()->paintAt(pos, pressure, xTilt, yTilt);
286void KisToolFreehand::paintLine(
const KisPoint & pos1,
287 const double pressure1,
291 const double pressure2,
295 m_dragDist = painter()->paintLine(pos1, pressure1, xtilt1, ytilt1, pos2, pressure2, xtilt2, ytilt2, m_dragDist);
299KisImageSP KisToolFreehand::currentImage()
301 return m_currentImage;
305void KisToolFreehand::paintOutline(
const KisPoint& point) {
312 if (currentImage() && !currentImage()->bounds().contains(point.floorTQPoint())) {
313 if (m_paintedOutline) {
315 m_paintedOutline =
false;
320 KisCanvas *canvas = controller->
kiscanvas();
323 KisBrush *brush = m_subject->currentBrush();
326 KisCanvasPainter gc(canvas);
327 TQPen pen(TQt::SolidLine);
329 KisPoint hotSpot = brush->hotSpot();
331 gc.setRasterOp(TQt::NotROP);
333 gc.setViewport(0, 0,
static_cast<TQ_INT32
>(canvas->width() * m_subject->zoomFactor()),
334 static_cast<TQ_INT32
>(canvas->height() * m_subject->zoomFactor()));
335 gc.translate((- controller->
horzValue()) / m_subject->zoomFactor(),
336 (- controller->
vertValue()) / m_subject->zoomFactor());
340 if (m_subject->currentPaintop().id() ==
"pen") {
342 topLeft = topLeft.roundTQPoint();
345 gc.translate(topLeft.x(), topLeft.y());
347 KisBoundaryPainter::paint(brush->boundary(), gc);
348 m_paintedOutline =
true;
353#include "kis_tool_freehand.moc"
Interface for classes that implement a canvas; i.e., a widget where KisImages are painted onto.
virtual TQ_INT32 vertValue() const =0
virtual TQ_INT32 horzValue() const =0
virtual KisCanvas * kiscanvas() const =0
KisCanvasSubject is part of the Observer pattern.
Abstract class that represents the concept of a Layer in Chalk.
virtual KisGroupLayerSP parent() const
Returns the parent layer of a layer.
A paint device contains the actual pixel data and offers methods to read and write pixels.
This layer is of a type that can be painted on.
KisPainter contains the graphics primitives necessary to draw on a KisPaintDevice.
A double-based point class that can return it's coordinates approximated to integers.