17#include "smudgetool.h"
21#include "pointerevent.h"
22#include "vectorimage.h"
24#include "scribblearea.h"
26#include "layermanager.h"
27#include "viewmanager.h"
28#include "selectionmanager.h"
29#include "undoredomanager.h"
31#include "layerbitmap.h"
32#include "layervector.h"
40ToolType SmudgeTool::type()
const
45void SmudgeTool::loadSettings()
50 QSettings pencilSettings(PENCIL2D, PENCIL2D);
51 mPropertyUsed[StrokeToolProperties::WIDTH_VALUE] = { Layer::BITMAP };
52 mPropertyUsed[StrokeToolProperties::FEATHER_VALUE] = { Layer::BITMAP };
54 info[StrokeToolProperties::WIDTH_VALUE] = { WIDTH_MIN, WIDTH_MAX, 24.0 };
55 info[StrokeToolProperties::FEATHER_VALUE] = { FEATHER_MIN, FEATHER_MAX, 48.0 };
57 toolProperties().insertProperties(info);
58 toolProperties().loadFrom(typeName(), pencilSettings);
60 if (toolProperties().requireMigration(pencilSettings, ToolProperties::VERSION_1)) {
61 toolProperties().setBaseValue(StrokeToolProperties::WIDTH_VALUE, pencilSettings.
value(
"smudgeWidth", 24.0).
toReal());
62 toolProperties().setBaseValue(StrokeToolProperties::FEATHER_VALUE, pencilSettings.
value(
"smudgeFeather", 48.0).
toReal());
64 pencilSettings.
remove(
"smudgeWidth");
65 pencilSettings.
remove(
"smudgeFeather");
81 return QCursor(
QPixmap(
":icons/general/cursor-smudge.svg"), 4, 18);
85 return QCursor(
QPixmap(
":icons/general/cursor-smudge-liquify.svg"), 4, 18);
89bool SmudgeTool::keyPressEvent(
QKeyEvent *event)
97 return StrokeTool::keyPressEvent(
event);
100bool SmudgeTool::keyReleaseEvent(
QKeyEvent *event)
108 return StrokeTool::keyReleaseEvent(
event);
113 mInterpolator.pointerPressEvent(
event);
114 if (handleQuickSizing(
event)) {
118 Layer* layer = mEditor->layers()->currentLayer();
119 auto selectMan = mEditor->select();
120 if (layer ==
nullptr) {
return; }
124 startStroke(
event->inputType());
125 if (layer->type() == Layer::BITMAP)
127 mLastBrushPoint = getCurrentPoint();
129 else if (layer->type() == Layer::VECTOR)
131 const int currentFrame = mEditor->currentFrame();
132 const float distanceFrom = selectMan->selectionTolerance();
134 if (vectorImage ==
nullptr) {
return; }
135 selectMan->setCurves(vectorImage->
getCurvesCloseTo(getCurrentPoint(), distanceFrom));
136 selectMan->setVertices(vectorImage->
getVerticesCloseTo(getCurrentPoint(), distanceFrom));
138 if (selectMan->closestCurves().size() > 0 || selectMan->closestCurves().size() > 0)
150 mEditor->deselectAll();
153 vectorImage->
setSelected(selectMan->closestVertices(),
true);
154 selectMan->vectorSelection.add(selectMan->closestCurves());
155 selectMan->vectorSelection.add(selectMan->closestVertices());
161 mEditor->deselectAll();
166 StrokeTool::pointerPressEvent(
event);
171 mInterpolator.pointerMoveEvent(
event);
172 if (handleQuickSizing(
event)) {
177 Layer* layer = mEditor->layers()->currentLayer();
178 if (layer ==
nullptr) {
return; }
180 if (layer->type() != Layer::BITMAP && layer->type() != Layer::VECTOR)
185 auto selectMan = mEditor->select();
186 if (
event->inputType() == mCurrentInputType) {
189 if (layer->type() == Layer::BITMAP)
197 VectorImage* vectorImage =
static_cast<LayerVector*
>(layer)->getLastVectorImageAtFrame(mEditor->currentFrame(), 0);
198 if (vectorImage ==
nullptr) {
return; }
205 blit.extend(vectorImage->getBoundsOfTransformedCurves().
toRect());
206 selectMan->setSelectionTransform(
QTransform().
translate(offsetFromPressPos().x(), offsetFromPressPos().y()));
208 blit.extend(vectorImage->getBoundsOfTransformedCurves().
toRect());
211 mScribbleArea->
update(mEditor->view()->mapCanvasToScreen(blit).toRect().adjusted(-1, -1, 1, 1));
217 if (layer->type() == Layer::VECTOR)
219 VectorImage* vectorImage =
static_cast<LayerVector*
>(layer)->getLastVectorImageAtFrame(mEditor->currentFrame(), 0);
220 if (vectorImage ==
nullptr) {
return; }
222 selectMan->setVertices(vectorImage->
getVerticesCloseTo(getCurrentPoint(), selectMan->selectionTolerance()));
228 StrokeTool::pointerMoveEvent(
event);
231void SmudgeTool::pointerReleaseEvent(
PointerEvent* event)
233 mInterpolator.pointerReleaseEvent(
event);
234 if (handleQuickSizing(
event)) {
238 if (
event->inputType() != mCurrentInputType)
return;
240 Layer* layer = mEditor->layers()->currentLayer();
241 if (layer ==
nullptr) {
return; }
245 mEditor->backup(typeName());
247 if (layer->type() == Layer::BITMAP)
250 mScribbleArea->paintBitmapBuffer();
251 mScribbleArea->clearDrawingBuffer();
254 else if (layer->type() == Layer::VECTOR)
257 if (vectorImage ==
nullptr) {
return; }
260 auto selectMan = mEditor->select();
261 selectMan->resetSelectionTransform();
262 for (
int k = 0; k < selectMan->vectorSelection.curve.size(); k++)
264 int curveNumber = selectMan->vectorSelection.curve.at(k);
265 vectorImage->curve(curveNumber).smoothCurve();
267 mEditor->setModified(mEditor->layers()->currentLayerIndex(), mEditor->currentFrame());
271 StrokeTool::pointerReleaseEvent(
event);
274void SmudgeTool::drawStroke()
276 Layer* layer = mEditor->layers()->currentLayer();
277 if (layer ==
nullptr || !layer->isPaintable()) {
return; }
279 BitmapImage *sourceImage =
static_cast<LayerBitmap*
>(layer)->getLastBitmapImageAtFrame(mEditor->currentFrame(), 0);
280 if (sourceImage ==
nullptr) {
return; }
282 StrokeTool::drawStroke();
285 for (
int i = 0; i < p.
size(); i++)
287 p[i] = mEditor->view()->mapScreenToCanvas(p[i]);
291 mCurrentWidth = mSettings.width();
292 qreal brushWidth = mCurrentWidth + 0.0 * mSettings.feather();
293 qreal offset = qMax(0.0, mCurrentWidth - 0.5 * mSettings.feather()) / brushWidth;
305 int steps = qRound(distance / brushStep);
307 QPointF sourcePoint = mLastBrushPoint;
308 for (
int i = 0; i < steps; i++)
310 targetImage.paste(&mScribbleArea->mTiledBuffer);
311 QPointF targetPoint = mLastBrushPoint + (i + 1) * (brushStep) * (b - mLastBrushPoint) / distance;
312 mScribbleArea->liquifyBrush(&targetImage,
319 if (i == (steps - 1))
321 mLastBrushPoint = targetPoint;
323 sourcePoint = targetPoint;
328 qreal brushStep = 2.0;
330 int steps = qRound(distance / brushStep);
332 QPointF sourcePoint = mLastBrushPoint;
333 for (
int i = 0; i < steps; i++)
335 targetImage.paste(&mScribbleArea->mTiledBuffer);
336 QPointF targetPoint = mLastBrushPoint + (i + 1) * (brushStep) * (b - mLastBrushPoint) / distance;
337 mScribbleArea->blurBrush(&targetImage,
344 if (i == (steps - 1))
346 mLastBrushPoint = targetPoint;
348 sourcePoint = targetPoint;
353QPointF SmudgeTool::offsetFromPressPos()
355 return getCurrentPoint() - getCurrentPressPoint();
void frameModified(int frameNumber)
This should be emitted after modifying the frame content.
void setSelected(int curveNumber, bool YesOrNo)
VectorImage::setSelected.
void applySelectionTransformation()
VectorImage::applySelectionTransformation.
void setSelectionTransformation(QTransform transform)
VectorImage::setSelectionTransformation.
QList< VertexRef > getVerticesCloseTo(QPointF thisPoint, qreal maxDistance)
VectorImage::getVerticesCloseTo.
bool isSelected(int curveNumber)
VectorImage::isSelected.
QList< int > getCurvesCloseTo(QPointF thisPoint, qreal maxDistance)
VectorImage::getCurvesCloseTo.
QHash::iterator insert(const Key &key, const T &value)
qreal length() const const
virtual bool event(QEvent *e)
QRect toRect() const const
void remove(const QString &key)
QVariant value(const QString &key, const QVariant &defaultValue) const const
qreal toReal(bool *ok) const const