20 #include <QMouseEvent>
22 #include "layermanager.h"
23 #include "layervector.h"
24 #include "layerbitmap.h"
25 #include "colormanager.h"
26 #include "strokemanager.h"
27 #include "layermanager.h"
29 #include "scribblearea.h"
30 #include "pencilsettings.h"
33 #include "penciltool.h"
35 PencilTool::PencilTool( QObject* parent ) :
StrokeTool( parent )
40 void PencilTool::loadSettings()
42 m_enabledProperties[WIDTH] =
true;
43 m_enabledProperties[PRESSURE] =
true;
44 m_enabledProperties[VECTORMERGE] =
false;
45 m_enabledProperties[INTERPOLATION] =
true;
46 m_enabledProperties[FILLCONTOUR] =
true;
48 QSettings settings( PENCIL2D, PENCIL2D );
49 properties.width = settings.value(
"pencilWidth" ).toDouble();
50 properties.feather = 1;
51 properties.pressure = settings.value(
"pencilPressure" ).toBool();
52 properties.inpolLevel = 0;
53 properties.useAA = -1;
54 properties.useFillContour =
false;
59 if ( properties.width <= 0 )
69 void PencilTool::setWidth(
const qreal width)
72 properties.width = width;
75 QSettings settings( PENCIL2D, PENCIL2D );
76 settings.setValue(
"pencilWidth", width);
80 void PencilTool::setFeather(
const qreal feather )
82 properties.feather = feather;
85 void PencilTool::setInvisibility(
const bool )
88 properties.invisibility = 1;
91 void PencilTool::setPressure(
const bool pressure )
94 properties.pressure = pressure;
97 QSettings settings( PENCIL2D, PENCIL2D );
98 settings.setValue(
"pencilPressure", pressure);
102 void PencilTool::setPreserveAlpha(
const bool preserveAlpha )
105 Q_UNUSED( preserveAlpha );
106 properties.preserveAlpha = 0;
109 void PencilTool::setInpolLevel(
const int level)
111 properties.inpolLevel = level;
113 QSettings settings( PENCIL2D, PENCIL2D);
114 settings.setValue(
"lineInpol", level);
118 void PencilTool::setUseFillContour(
const bool useFillContour)
120 properties.useFillContour = useFillContour;
122 QSettings settings( PENCIL2D, PENCIL2D);
123 settings.setValue(
"FillContour", useFillContour);
127 QCursor PencilTool::cursor()
129 if ( mEditor->preference()->isOn( SETTING::TOOL_CURSOR ) )
131 return QCursor( QPixmap(
":icons/pencil2.png" ), 0, 16 );
133 return Qt::CrossCursor;
136 void PencilTool::mousePressEvent( QMouseEvent *event )
138 mLastBrushPoint = getCurrentPoint();
140 if ( event->button() == Qt::LeftButton )
142 mEditor->backup( typeName() );
144 mScribbleArea->setAllDirty();
149 if ( mEditor->layers()->currentLayer()->type() == Layer::BITMAP )
153 else if ( mEditor->layers()->currentLayer()->type() == Layer::VECTOR )
155 if ( !mEditor->preference()->isOn(SETTING::INVISIBLE_LINES) )
157 mScribbleArea->toggleThinLines();
162 mMouseDownPoint = getCurrentPoint();
163 mLastBrushPoint = getCurrentPoint();
166 void PencilTool::mouseMoveEvent( QMouseEvent *event )
168 Layer* layer = mEditor->layers()->currentLayer();
169 if ( layer->type() == Layer::BITMAP || layer->type() == Layer::VECTOR )
171 if ( event->buttons() & Qt::LeftButton )
174 if (properties.inpolLevel != m_pStrokeManager->getInpolLevel()) {
175 m_pStrokeManager->setInpolLevel(properties.inpolLevel);
181 void PencilTool::mouseReleaseEvent( QMouseEvent *event )
183 if ( event->button() == Qt::LeftButton )
185 Layer* layer = mEditor->layers()->currentLayer();
186 if ( mScribbleArea->isLayerPaintable() )
188 qreal distance = QLineF( getCurrentPoint(), mMouseDownPoint ).length();
191 paintAt(mMouseDownPoint);
199 if ( layer->type() == Layer::BITMAP ) {
202 else if (layer->type() == Layer::VECTOR )
204 paintVectorStroke( layer );
210 void PencilTool::adjustPressureSensitiveProperties( qreal pressure,
bool mouseDevice )
212 mCurrentWidth = properties.width;
214 if ( properties.pressure && !mouseDevice )
216 mCurrentPressure = pressure;
220 mCurrentPressure = 1.0;
225 void PencilTool::paintAt( QPointF point )
227 qDebug() <<
"Made a single dab at " << point;
228 Layer* layer = mEditor->layers()->currentLayer();
229 if ( layer->type() == Layer::BITMAP )
232 mCurrentWidth = properties.width;
233 qreal brushWidth = mCurrentWidth;
237 rect.extend( point.toPoint() );
238 mScribbleArea->drawPencil( QPoint( qRound(point.x() ), qRound(point.y() )),
240 mEditor->color()->frontColor(),
243 int rad = qRound( brushWidth ) / 2 + 2;
244 mScribbleArea->refreshBitmap( rect, rad );
249 void PencilTool::drawStroke()
251 StrokeTool::drawStroke();
254 Layer* layer = mEditor->layers()->currentLayer();
256 if ( layer->type() == Layer::BITMAP )
259 mCurrentWidth = properties.width;
260 if (properties.pressure ==
true) {
261 opacity = mCurrentPressure / 2;
262 mCurrentWidth = properties.width * mCurrentPressure;
264 qreal brushWidth = mCurrentWidth;
266 qreal brushStep = (0.5 * brushWidth);
267 brushStep = qMax( 1.0, brushStep );
271 QPointF a = mLastBrushPoint;
272 QPointF b = getCurrentPoint();
274 qreal distance = 4 * QLineF( b, a ).length();
275 int steps = qRound( distance / brushStep );
277 for (
int i = 0; i < steps; i++ )
279 QPointF point = mLastBrushPoint + ( i + 1 ) * brushStep * ( getCurrentPoint() - mLastBrushPoint ) / distance;
280 rect.extend( point.toPoint() );
281 mScribbleArea->drawPencil( QPoint( qRound(point.x() ), qRound(point.y() )),
283 mEditor->color()->frontColor(),
286 if ( i == ( steps - 1 ) )
288 mLastBrushPoint = getCurrentPoint();
292 int rad = qRound( brushWidth ) / 2 + 2;
294 mScribbleArea->paintBitmapBufferRect( rect );
295 mScribbleArea->refreshBitmap( rect, rad );
298 else if ( layer->type() == Layer::VECTOR )
300 QPen pen( mEditor->color()->frontColor(),
306 int rad = qRound( ( properties.width / 2 + 2 ) * mEditor->view()->scaling() );
308 if ( p.size() == 4 ) {
310 QPainterPath path( p[ 0 ] );
311 path.cubicTo( p[ 1 ],
314 mScribbleArea->drawPath( path, pen, Qt::NoBrush, QPainter::CompositionMode_Source );
315 mScribbleArea->refreshVector( path.boundingRect().toRect(), rad );
321 void PencilTool::paintBitmapStroke()
323 mScribbleArea->paintBitmapBuffer();
324 mScribbleArea->setAllDirty();
325 mScribbleArea->clearBitmapBuffer();
328 void PencilTool::paintVectorStroke(
Layer* layer)
331 mScribbleArea->clearBitmapBuffer();
332 qreal tol = mScribbleArea->getCurveSmoothing() / mEditor->view()->scaling();
334 BezierCurve curve( mStrokePoints, mStrokePressures, tol );
336 curve.setFeather( 0 );
337 curve.setInvisibility(
true );
338 curve.setVariableWidth(
false );
339 curve.setColourNumber( mEditor->color()->frontColorNumber() );
340 VectorImage* vectorImage = ( (
LayerVector * )layer )->getLastVectorImageAtFrame( mEditor->currentFrame(), 0 );
342 vectorImage->addCurve( curve, qAbs( mEditor->view()->scaling() ), properties.vectorMergeEnabled );
344 if (properties.useFillContour ==
true)
346 vectorImage->fillPath( mStrokePoints,
347 mEditor->color()->frontColorNumber(),
348 10.0 / mEditor->view()->scaling() );
350 mScribbleArea->setModified( mEditor->layers()->currentLayerIndex(), mEditor->currentFrame() );
351 mScribbleArea->setAllDirty();