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()
45void SmudgeTool::loadSettings()
49 mPropertyEnabled[WIDTH] =
true;
50 mPropertyEnabled[FEATHER] =
true;
53 properties.width = settings.value(
"smudgeWidth", 24.0).toDouble();
54 properties.feather = settings.value(
"smudgeFeather", 48.0).toDouble();
55 properties.pressure =
false;
56 properties.stabilizerLevel = -1;
62void SmudgeTool::resetToDefault()
68void SmudgeTool::setWidth(
const qreal width)
71 properties.width = width;
75 settings.setValue(
"smudgeWidth", width);
79void SmudgeTool::setFeather(
const qreal feather)
82 properties.feather = feather;
86 settings.setValue(
"smudgeFeather", feather);
90void SmudgeTool::setPressure(
const bool pressure)
93 properties.pressure = pressure;
97 settings.setValue(
"smudgePressure", pressure);
110 return QCursor(
QPixmap(
":icons/general/cursor-smudge.svg"), 4, 18);
114 return QCursor(
QPixmap(
":icons/general/cursor-smudge-liquify.svg"), 4, 18);
118bool SmudgeTool::keyPressEvent(
QKeyEvent *event)
126 return StrokeTool::keyPressEvent(
event);
129bool SmudgeTool::keyReleaseEvent(
QKeyEvent *event)
137 return StrokeTool::keyReleaseEvent(
event);
142 mInterpolator.pointerPressEvent(
event);
143 if (handleQuickSizing(
event)) {
147 Layer* layer = mEditor->layers()->currentLayer();
148 auto selectMan = mEditor->select();
149 if (layer ==
nullptr) {
return; }
153 startStroke(
event->inputType());
154 if (layer->type() == Layer::BITMAP)
156 mLastBrushPoint = getCurrentPoint();
158 else if (layer->type() == Layer::VECTOR)
160 const int currentFrame = mEditor->currentFrame();
161 const float distanceFrom = selectMan->selectionTolerance();
163 if (vectorImage ==
nullptr) {
return; }
164 selectMan->setCurves(vectorImage->
getCurvesCloseTo(getCurrentPoint(), distanceFrom));
165 selectMan->setVertices(vectorImage->
getVerticesCloseTo(getCurrentPoint(), distanceFrom));
167 if (selectMan->closestCurves().size() > 0 || selectMan->closestCurves().size() > 0)
179 mEditor->deselectAll();
182 vectorImage->
setSelected(selectMan->closestVertices(),
true);
183 selectMan->vectorSelection.add(selectMan->closestCurves());
184 selectMan->vectorSelection.add(selectMan->closestVertices());
190 mEditor->deselectAll();
195 StrokeTool::pointerPressEvent(
event);
200 mInterpolator.pointerMoveEvent(
event);
201 if (handleQuickSizing(
event)) {
205 if (
event->inputType() != mCurrentInputType)
return;
207 Layer* layer = mEditor->layers()->currentLayer();
208 if (layer ==
nullptr) {
return; }
210 if (layer->type() != Layer::BITMAP && layer->type() != Layer::VECTOR)
215 auto selectMan = mEditor->select();
218 if (layer->type() == Layer::BITMAP)
226 VectorImage* vectorImage =
static_cast<LayerVector*
>(layer)->getLastVectorImageAtFrame(mEditor->currentFrame(), 0);
227 if (vectorImage ==
nullptr) {
return; }
234 blit.extend(vectorImage->getBoundsOfTransformedCurves().
toRect());
235 selectMan->setSelectionTransform(
QTransform().
translate(offsetFromPressPos().x(), offsetFromPressPos().y()));
237 blit.extend(vectorImage->getBoundsOfTransformedCurves().
toRect());
240 mScribbleArea->
update(mEditor->view()->mapCanvasToScreen(blit).toRect().adjusted(-1, -1, 1, 1));
246 if (layer->type() == Layer::VECTOR)
248 VectorImage* vectorImage =
static_cast<LayerVector*
>(layer)->getLastVectorImageAtFrame(mEditor->currentFrame(), 0);
249 if (vectorImage ==
nullptr) {
return; }
251 selectMan->setVertices(vectorImage->
getVerticesCloseTo(getCurrentPoint(), selectMan->selectionTolerance()));
256 StrokeTool::pointerMoveEvent(
event);
259void SmudgeTool::pointerReleaseEvent(
PointerEvent* event)
261 mInterpolator.pointerReleaseEvent(
event);
262 if (handleQuickSizing(
event)) {
266 if (
event->inputType() != mCurrentInputType)
return;
268 Layer* layer = mEditor->layers()->currentLayer();
269 if (layer ==
nullptr) {
return; }
273 mEditor->backup(typeName());
275 if (layer->type() == Layer::BITMAP)
278 mScribbleArea->paintBitmapBuffer();
279 mScribbleArea->clearDrawingBuffer();
282 else if (layer->type() == Layer::VECTOR)
285 if (vectorImage ==
nullptr) {
return; }
288 auto selectMan = mEditor->select();
289 selectMan->resetSelectionTransform();
290 for (
int k = 0; k < selectMan->vectorSelection.curve.size(); k++)
292 int curveNumber = selectMan->vectorSelection.curve.at(k);
293 vectorImage->curve(curveNumber).smoothCurve();
295 mEditor->setModified(mEditor->layers()->currentLayerIndex(), mEditor->currentFrame());
299 StrokeTool::pointerReleaseEvent(
event);
302void SmudgeTool::drawStroke()
304 Layer* layer = mEditor->layers()->currentLayer();
305 if (layer ==
nullptr || !layer->isPaintable()) {
return; }
307 BitmapImage *sourceImage =
static_cast<LayerBitmap*
>(layer)->getLastBitmapImageAtFrame(mEditor->currentFrame(), 0);
308 if (sourceImage ==
nullptr) {
return; }
310 StrokeTool::drawStroke();
313 for (
int i = 0; i < p.
size(); i++)
315 p[i] = mEditor->view()->mapScreenToCanvas(p[i]);
319 mCurrentWidth = properties.width;
320 qreal brushWidth = mCurrentWidth + 0.0 * properties.feather;
321 qreal offset = qMax(0.0, mCurrentWidth - 0.5 * properties.feather) / brushWidth;
333 int steps = qRound(distance / brushStep);
335 QPointF sourcePoint = mLastBrushPoint;
336 for (
int i = 0; i < steps; i++)
338 targetImage.paste(&mScribbleArea->mTiledBuffer);
339 QPointF targetPoint = mLastBrushPoint + (i + 1) * (brushStep) * (b - mLastBrushPoint) / distance;
340 mScribbleArea->liquifyBrush(&targetImage,
347 if (i == (steps - 1))
349 mLastBrushPoint = targetPoint;
351 sourcePoint = targetPoint;
356 qreal brushStep = 2.0;
358 int steps = qRound(distance / brushStep);
360 QPointF sourcePoint = mLastBrushPoint;
361 for (
int i = 0; i < steps; i++)
363 targetImage.paste(&mScribbleArea->mTiledBuffer);
364 QPointF targetPoint = mLastBrushPoint + (i + 1) * (brushStep) * (b - mLastBrushPoint) / distance;
365 mScribbleArea->blurBrush(&targetImage,
372 if (i == (steps - 1))
374 mLastBrushPoint = targetPoint;
376 sourcePoint = targetPoint;
381QPointF SmudgeTool::offsetFromPressPos()
383 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