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::saveSettings()
66 settings.setValue(
"smudgeWidth", properties.width);
67 settings.setValue(
"smudgeFeather", properties.feather);
68 settings.setValue(
"smudgePressure", properties.pressure);
73void SmudgeTool::resetToDefault()
79void SmudgeTool::setWidth(
const qreal width)
82 properties.width = width;
85void SmudgeTool::setFeather(
const qreal feather)
88 properties.feather = feather;
91void SmudgeTool::setPressure(
const bool pressure)
94 properties.pressure = pressure;
106 return QCursor(
QPixmap(
":icons/general/cursor-smudge.svg"), 4, 18);
110 return QCursor(
QPixmap(
":icons/general/cursor-smudge-liquify.svg"), 4, 18);
114bool SmudgeTool::keyPressEvent(
QKeyEvent *event)
122 return StrokeTool::keyPressEvent(
event);
125bool SmudgeTool::keyReleaseEvent(
QKeyEvent *event)
133 return StrokeTool::keyReleaseEvent(
event);
138 mInterpolator.pointerPressEvent(
event);
139 if (handleQuickSizing(
event)) {
143 Layer* layer = mEditor->layers()->currentLayer();
144 auto selectMan = mEditor->select();
145 if (layer ==
nullptr) {
return; }
149 startStroke(
event->inputType());
150 if (layer->type() == Layer::BITMAP)
152 mLastBrushPoint = getCurrentPoint();
154 else if (layer->type() == Layer::VECTOR)
156 const int currentFrame = mEditor->currentFrame();
157 const float distanceFrom = selectMan->selectionTolerance();
159 if (vectorImage ==
nullptr) {
return; }
160 selectMan->setCurves(vectorImage->
getCurvesCloseTo(getCurrentPoint(), distanceFrom));
161 selectMan->setVertices(vectorImage->
getVerticesCloseTo(getCurrentPoint(), distanceFrom));
163 if (selectMan->closestCurves().size() > 0 || selectMan->closestCurves().size() > 0)
175 mEditor->deselectAll();
178 vectorImage->
setSelected(selectMan->closestVertices(),
true);
179 selectMan->vectorSelection.add(selectMan->closestCurves());
180 selectMan->vectorSelection.add(selectMan->closestVertices());
186 mEditor->deselectAll();
191 StrokeTool::pointerPressEvent(
event);
196 mInterpolator.pointerMoveEvent(
event);
197 if (handleQuickSizing(
event)) {
201 if (
event->inputType() != mCurrentInputType)
return;
203 Layer* layer = mEditor->layers()->currentLayer();
204 if (layer ==
nullptr) {
return; }
206 if (layer->type() != Layer::BITMAP && layer->type() != Layer::VECTOR)
211 auto selectMan = mEditor->select();
214 if (layer->type() == Layer::BITMAP)
222 VectorImage* vectorImage =
static_cast<LayerVector*
>(layer)->getLastVectorImageAtFrame(mEditor->currentFrame(), 0);
223 if (vectorImage ==
nullptr) {
return; }
230 blit.extend(vectorImage->getBoundsOfTransformedCurves().
toRect());
231 selectMan->setSelectionTransform(
QTransform().
translate(offsetFromPressPos().x(), offsetFromPressPos().y()));
233 blit.extend(vectorImage->getBoundsOfTransformedCurves().
toRect());
236 mScribbleArea->
update(mEditor->view()->mapCanvasToScreen(blit).toRect().adjusted(-1, -1, 1, 1));
242 if (layer->type() == Layer::VECTOR)
244 VectorImage* vectorImage =
static_cast<LayerVector*
>(layer)->getLastVectorImageAtFrame(mEditor->currentFrame(), 0);
245 if (vectorImage ==
nullptr) {
return; }
247 selectMan->setVertices(vectorImage->
getVerticesCloseTo(getCurrentPoint(), selectMan->selectionTolerance()));
252 StrokeTool::pointerMoveEvent(
event);
255void SmudgeTool::pointerReleaseEvent(
PointerEvent* event)
257 mInterpolator.pointerReleaseEvent(
event);
258 if (handleQuickSizing(
event)) {
262 if (
event->inputType() != mCurrentInputType)
return;
264 Layer* layer = mEditor->layers()->currentLayer();
265 if (layer ==
nullptr) {
return; }
269 mEditor->backup(typeName());
271 if (layer->type() == Layer::BITMAP)
274 mScribbleArea->paintBitmapBuffer();
275 mScribbleArea->clearDrawingBuffer();
278 else if (layer->type() == Layer::VECTOR)
281 if (vectorImage ==
nullptr) {
return; }
284 auto selectMan = mEditor->select();
285 selectMan->resetSelectionTransform();
286 for (
int k = 0; k < selectMan->vectorSelection.curve.size(); k++)
288 int curveNumber = selectMan->vectorSelection.curve.at(k);
289 vectorImage->curve(curveNumber).smoothCurve();
291 mEditor->setModified(mEditor->layers()->currentLayerIndex(), mEditor->currentFrame());
295 StrokeTool::pointerReleaseEvent(
event);
298void SmudgeTool::drawStroke()
300 Layer* layer = mEditor->layers()->currentLayer();
301 if (layer ==
nullptr || !layer->isPaintable()) {
return; }
303 BitmapImage *sourceImage =
static_cast<LayerBitmap*
>(layer)->getLastBitmapImageAtFrame(mEditor->currentFrame(), 0);
304 if (sourceImage ==
nullptr) {
return; }
306 StrokeTool::drawStroke();
309 for (
int i = 0; i < p.
size(); i++)
311 p[i] = mEditor->view()->mapScreenToCanvas(p[i]);
315 mCurrentWidth = properties.width;
316 qreal brushWidth = mCurrentWidth + 0.0 * properties.feather;
317 qreal offset = qMax(0.0, mCurrentWidth - 0.5 * properties.feather) / brushWidth;
329 int steps = qRound(distance / brushStep);
331 QPointF sourcePoint = mLastBrushPoint;
332 for (
int i = 0; i < steps; i++)
334 targetImage.paste(&mScribbleArea->mTiledBuffer);
335 QPointF targetPoint = mLastBrushPoint + (i + 1) * (brushStep) * (b - mLastBrushPoint) / distance;
336 mScribbleArea->liquifyBrush(&targetImage,
343 if (i == (steps - 1))
345 mLastBrushPoint = targetPoint;
347 sourcePoint = targetPoint;
352 qreal brushStep = 2.0;
354 int steps = qRound(distance / brushStep);
356 QPointF sourcePoint = mLastBrushPoint;
357 for (
int i = 0; i < steps; i++)
359 targetImage.paste(&mScribbleArea->mTiledBuffer);
360 QPointF targetPoint = mLastBrushPoint + (i + 1) * (brushStep) * (b - mLastBrushPoint) / distance;
361 mScribbleArea->blurBrush(&targetImage,
368 if (i == (steps - 1))
370 mLastBrushPoint = targetPoint;
372 sourcePoint = targetPoint;
377QPointF SmudgeTool::offsetFromPressPos()
379 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