17#include "penciltool.h"
21#include "pointerevent.h"
23#include "layermanager.h"
24#include "colormanager.h"
25#include "viewmanager.h"
26#include "preferencemanager.h"
27#include "selectionmanager.h"
28#include "undoredomanager.h"
31#include "scribblearea.h"
32#include "layervector.h"
33#include "vectorimage.h"
40void PencilTool::loadSettings()
44 mPropertyUsed[StrokeToolProperties::WIDTH_VALUE] = { Layer::BITMAP };
45 mPropertyUsed[StrokeToolProperties::PRESSURE_ENABLED] = { Layer::BITMAP };
46 mPropertyUsed[StrokeToolProperties::FILLCONTOUR_ENABLED] = { Layer::VECTOR };
47 mPropertyUsed[StrokeToolProperties::STABILIZATION_VALUE] = { Layer::BITMAP, Layer::VECTOR };
49 QSettings pencilSettings(PENCIL2D, PENCIL2D);
53 info[StrokeToolProperties::WIDTH_VALUE] = { WIDTH_MIN, WIDTH_MAX, 4.0 };
54 info[StrokeToolProperties::FEATHER_VALUE] = { FEATHER_MIN, FEATHER_MAX, 50.0 };
55 info[StrokeToolProperties::PRESSURE_ENABLED] =
true;
56 info[StrokeToolProperties::FEATHER_ENABLED] =
false;
57 info[StrokeToolProperties::STABILIZATION_VALUE] = { StabilizationLevel::NONE, StabilizationLevel::STRONG, StabilizationLevel::STRONG };
58 info[StrokeToolProperties::FILLCONTOUR_ENABLED] =
false;
60 toolProperties().insertProperties(info);
61 toolProperties().loadFrom(typeName(), pencilSettings);
63 if (toolProperties().requireMigration(pencilSettings, ToolProperties::VERSION_1)) {
64 toolProperties().setBaseValue(StrokeToolProperties::WIDTH_VALUE, pencilSettings.
value(
"pencilWidth", 4.0).
toReal());
65 toolProperties().setBaseValue(StrokeToolProperties::PRESSURE_ENABLED, pencilSettings.
value(
"pencilPressure",
true).
toBool());
66 toolProperties().setBaseValue(StrokeToolProperties::STABILIZATION_VALUE, pencilSettings.
value(
"pencilLineStabilization", StabilizationLevel::STRONG).
toInt());
67 toolProperties().setBaseValue(StrokeToolProperties::FILLCONTOUR_ENABLED, pencilSettings.
value(
"FillContour",
false).
toBool());
69 pencilSettings.
remove(
"pencilWidth");
70 pencilSettings.
remove(
"pencilPressure");
71 pencilSettings.
remove(
"pencilLineStabilization");
72 pencilSettings.
remove(
"FillContour");
75 toolProperties().setBaseValue(StrokeToolProperties::FEATHER_VALUE, info[StrokeToolProperties::FEATHER_VALUE].defaultReal());
82 if (mEditor->preference()->isOn(SETTING::TOOL_CURSOR))
84 return QCursor(
QPixmap(
":icons/general/cursor-pencil.svg"), 4, 14);
91 mInterpolator.pointerPressEvent(
event);
92 if (handleQuickSizing(
event)) {
96 mMouseDownPoint = getCurrentPoint();
97 mLastBrushPoint = getCurrentPoint();
99 startStroke(
event->inputType());
102 if (mEditor->layers()->currentLayer()->type() == Layer::VECTOR && !mEditor->preference()->isOn(SETTING::INVISIBLE_LINES))
104 mScribbleArea->toggleThinLines();
107 StrokeTool::pointerPressEvent(
event);
112 mInterpolator.pointerMoveEvent(
event);
113 if (handleQuickSizing(
event)) {
119 mCurrentPressure = mInterpolator.getPressure();
121 if (mSettings.stabilizerLevel() != mInterpolator.getStabilizerLevel())
123 mInterpolator.setStabilizerLevel(mSettings.stabilizerLevel());
126 StrokeTool::pointerMoveEvent(
event);
129void PencilTool::pointerReleaseEvent(
PointerEvent *event)
131 mInterpolator.pointerReleaseEvent(
event);
132 if (handleQuickSizing(
event)) {
136 if (
event->inputType() != mCurrentInputType)
return;
138 mEditor->backup(typeName());
139 qreal distance =
QLineF(getCurrentPoint(), mMouseDownPoint).
length();
142 paintAt(mMouseDownPoint);
149 Layer* layer = mEditor->layers()->currentLayer();
150 if (layer->type() == Layer::VECTOR) {
151 paintVectorStroke(layer);
155 StrokeTool::pointerReleaseEvent(
event);
159void PencilTool::paintAt(
QPointF point)
162 Layer* layer = mEditor->layers()->currentLayer();
163 if (layer->type() == Layer::BITMAP)
165 qreal opacity = (mSettings.pressureEnabled()) ? (mCurrentPressure * 0.5) : 1.0;
166 qreal pressure = (mSettings.pressureEnabled()) ? mCurrentPressure : 1.0;
167 qreal brushWidth = mSettings.width() * pressure;
168 qreal fixedBrushFeather = mSettings.feather();
170 mCurrentWidth = brushWidth;
171 mScribbleArea->drawPencil(point,
180void PencilTool::drawStroke()
182 StrokeTool::drawStroke();
185 Layer* layer = mEditor->layers()->currentLayer();
187 if (layer->type() == Layer::BITMAP)
189 qreal pressure = (mSettings.pressureEnabled()) ? mCurrentPressure : 1.0;
190 qreal opacity = (mSettings.pressureEnabled()) ? (mCurrentPressure * 0.5) : 1.0;
191 qreal brushWidth = mSettings.width() * pressure;
192 mCurrentWidth = brushWidth;
194 qreal fixedBrushFeather = mSettings.feather();
195 qreal brushStep = qMax(1.0, (0.5 * brushWidth));
201 int steps = qRound(distance / brushStep);
203 for (
int i = 0; i < steps; i++)
205 QPointF point = mLastBrushPoint + (i + 1) * brushStep * (getCurrentPoint() - mLastBrushPoint) / distance;
206 mScribbleArea->drawPencil(point,
212 if (i == (steps - 1))
214 mLastBrushPoint = getCurrentPoint();
218 else if (layer->type() == Layer::VECTOR)
238void PencilTool::paintVectorStroke(
Layer* layer)
240 if (mStrokePoints.
empty())
244 mScribbleArea->clearDrawingBuffer();
245 qreal tol = mScribbleArea->getCurveSmoothing() / mEditor->view()->scaling();
247 BezierCurve curve(mStrokePoints, mStrokePressures, tol);
250 curve.setFilled(
false);
251 curve.setInvisibility(
true);
252 curve.setVariableWidth(
false);
253 curve.setColorNumber(mEditor->color()->frontColorNumber());
254 VectorImage* vectorImage =
static_cast<LayerVector*
>(layer)->getLastVectorImageAtFrame(mEditor->currentFrame(), 0);
255 if (vectorImage ==
nullptr) {
return; }
256 vectorImage->
addCurve(curve, qAbs(mEditor->view()->scaling()),
false);
258 if (mSettings.fillContourEnabled())
261 mEditor->color()->frontColorNumber());
266 mEditor->deselectAll();
274 mEditor->setModified(mEditor->layers()->currentLayerIndex(), mEditor->currentFrame());
QColor frontColor(bool useIndexedColor=true)
frontColor
void setSelected(int curveNumber, bool YesOrNo)
VectorImage::setSelected.
int getLastCurveNumber()
VectorImage::getLastCurveNumber.
void addCurve(BezierCurve &newCurve, qreal factor, bool interacts=true)
VectorImage::addCurve.
void fillContour(QList< QPointF > contourPath, int color)
VectorImage::fillContour.
bool isAnyCurveSelected()
VectorImage::isAnyCurveSelected.
QHash::iterator insert(const Key &key, const T &value)
qreal length() const const
virtual bool event(QEvent *e)
void remove(const QString &key)
QVariant value(const QString &key, const QVariant &defaultValue) const const
bool toBool() const const
int toInt(bool *ok) const const
qreal toReal(bool *ok) const const