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)) {
202 Layer* layer = mEditor->layers()->currentLayer();
203 if (layer ==
nullptr) {
return; }
205 if (layer->type() != Layer::BITMAP && layer->type() != Layer::VECTOR)
210 auto selectMan = mEditor->select();
211 if (
event->inputType() == mCurrentInputType) {
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()));
253 StrokeTool::pointerMoveEvent(
event);
256void SmudgeTool::pointerReleaseEvent(
PointerEvent* event)
258 mInterpolator.pointerReleaseEvent(
event);
259 if (handleQuickSizing(
event)) {
263 if (
event->inputType() != mCurrentInputType)
return;
265 Layer* layer = mEditor->layers()->currentLayer();
266 if (layer ==
nullptr) {
return; }
270 mEditor->backup(typeName());
272 if (layer->type() == Layer::BITMAP)
275 mScribbleArea->paintBitmapBuffer();
276 mScribbleArea->clearDrawingBuffer();
279 else if (layer->type() == Layer::VECTOR)
282 if (vectorImage ==
nullptr) {
return; }
285 auto selectMan = mEditor->select();
286 selectMan->resetSelectionTransform();
287 for (
int k = 0; k < selectMan->vectorSelection.curve.size(); k++)
289 int curveNumber = selectMan->vectorSelection.curve.at(k);
290 vectorImage->curve(curveNumber).smoothCurve();
292 mEditor->setModified(mEditor->layers()->currentLayerIndex(), mEditor->currentFrame());
296 StrokeTool::pointerReleaseEvent(
event);
299void SmudgeTool::drawStroke()
301 Layer* layer = mEditor->layers()->currentLayer();
302 if (layer ==
nullptr || !layer->isPaintable()) {
return; }
304 BitmapImage *sourceImage =
static_cast<LayerBitmap*
>(layer)->getLastBitmapImageAtFrame(mEditor->currentFrame(), 0);
305 if (sourceImage ==
nullptr) {
return; }
307 StrokeTool::drawStroke();
310 for (
int i = 0; i < p.
size(); i++)
312 p[i] = mEditor->view()->mapScreenToCanvas(p[i]);
316 mCurrentWidth = properties.width;
317 qreal brushWidth = mCurrentWidth + 0.0 * properties.feather;
318 qreal offset = qMax(0.0, mCurrentWidth - 0.5 * properties.feather) / brushWidth;
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->liquifyBrush(&targetImage,
344 if (i == (steps - 1))
346 mLastBrushPoint = targetPoint;
348 sourcePoint = targetPoint;
353 qreal brushStep = 2.0;
355 int steps = qRound(distance / brushStep);
357 QPointF sourcePoint = mLastBrushPoint;
358 for (
int i = 0; i < steps; i++)
360 targetImage.paste(&mScribbleArea->mTiledBuffer);
361 QPointF targetPoint = mLastBrushPoint + (i + 1) * (brushStep) * (b - mLastBrushPoint) / distance;
362 mScribbleArea->blurBrush(&targetImage,
369 if (i == (steps - 1))
371 mLastBrushPoint = targetPoint;
373 sourcePoint = targetPoint;
378QPointF SmudgeTool::offsetFromPressPos()
380 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