Fix reset last drawn point on undo/redo for draw line behavior (fix #1005)

This commit is contained in:
David Capello 2017-06-16 12:18:22 -03:00
parent 288b9aa8f9
commit 34e794519c
13 changed files with 141 additions and 39 deletions

View File

@ -201,6 +201,7 @@ add_library(app-lib
cmd/set_frame_tag_color.cpp
cmd/set_frame_tag_name.cpp
cmd/set_frame_tag_range.cpp
cmd/set_last_point.cpp
cmd/set_layer_blend_mode.cpp
cmd/set_layer_flags.cpp
cmd/set_layer_name.cpp

View File

@ -0,0 +1,42 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/cmd/set_last_point.h"
#include "app/document.h"
namespace app {
namespace cmd {
SetLastPoint::SetLastPoint(Document* doc, const gfx::Point& pos)
: WithDocument(doc)
, m_oldPoint(doc->lastDrawingPoint())
, m_newPoint(pos)
{
}
void SetLastPoint::onExecute()
{
setLastPoint(m_newPoint);
}
void SetLastPoint::onUndo()
{
setLastPoint(m_oldPoint);
}
void SetLastPoint::setLastPoint(const gfx::Point& pos)
{
Document* doc = document();
doc->setLastDrawingPoint(pos);
}
} // namespace cmd
} // namespace app

View File

@ -0,0 +1,41 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifndef APP_CMD_SET_LAST_POINT_H_INCLUDED
#define APP_CMD_SET_LAST_POINT_H_INCLUDED
#pragma once
#include "app/cmd.h"
#include "app/cmd/with_document.h"
#include "gfx/point.h"
namespace app {
namespace cmd {
using namespace doc;
class SetLastPoint : public Cmd
, public WithDocument {
public:
SetLastPoint(Document* doc, const gfx::Point& pos);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override {
return sizeof(*this);
}
private:
void setLastPoint(const gfx::Point& pos);
gfx::Point m_oldPoint;
gfx::Point m_newPoint;
};
} // namespace cmd
} // namespace app
#endif

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -33,6 +33,7 @@
#include "doc/palette.h"
#include "doc/sprite.h"
#include <limits>
#include <map>
namespace app {
@ -48,6 +49,7 @@ Document::Document(Sprite* sprite)
// Mask
, m_mask(new Mask())
, m_maskVisible(true)
, m_lastDrawingPoint(Document::NoLastDrawingPoint())
{
setFilename("Sprite");
@ -432,4 +434,11 @@ void Document::onContextChanged()
m_undo->setContext(context());
}
// static
gfx::Point Document::NoLastDrawingPoint()
{
return gfx::Point(std::numeric_limits<int>::min(),
std::numeric_limits<int>::min());
}
} // namespace app

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -148,6 +148,14 @@ namespace app {
void setTransformation(const Transformation& transform);
void resetTransformation();
//////////////////////////////////////////////////////////////////////
// Last point used to draw straight lines using freehand tools + Shift key
// (EditorCustomizationDelegate::isStraightLineFromLastPoint() modifier)
static gfx::Point NoLastDrawingPoint();
gfx::Point lastDrawingPoint() const { return m_lastDrawingPoint; }
void setLastDrawingPoint(const gfx::Point& pos) { m_lastDrawingPoint = pos; }
//////////////////////////////////////////////////////////////////////
// Copying
@ -180,6 +188,8 @@ namespace app {
// Current transformation.
Transformation m_transformation;
gfx::Point m_lastDrawingPoint;
DISABLE_COPYING(Document);
};

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -43,6 +43,10 @@ namespace app {
// The input and output strokes are relative to sprite coordinates.
virtual void getStrokeToInterwine(const Stroke& input, Stroke& output) = 0;
virtual void getStatusBarText(const Stroke& stroke, std::string& text) = 0;
// Last point used by this controller, useful to save the last
// point of a freehand tool.
virtual gfx::Point getLastPoint() const { return gfx::Point(0, 0); }
};
} // namespace tools

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -52,7 +52,10 @@ class FreehandController : public Controller {
public:
bool isFreehand() override { return true; }
gfx::Point getLastPoint() const override { return m_last; }
void pressButton(Stroke& stroke, const Point& point) override {
m_last = point;
stroke.addPoint(point);
}
@ -61,6 +64,7 @@ public:
}
void movement(ToolLoop* loop, Stroke& stroke, const Point& point) override {
m_last = point;
stroke.addPoint(point);
}
@ -88,6 +92,8 @@ public:
text = buf;
}
private:
Point m_last;
};
// Controls clicks for tools like line

View File

@ -61,7 +61,8 @@ namespace app {
enum Button { Left = 0, Right = 1 };
virtual ~ToolLoop() { }
virtual void dispose() = 0;
virtual void commitOrRollback() = 0;
// Returns the tool to use to draw or use
virtual Tool* getTool() = 0;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -66,6 +66,8 @@ public:
// Should be called each time the user moves the mouse inside the editor.
void movement(const Pointer& pointer);
const Pointer& lastPointer() const { return m_lastPointer; }
private:
void doLoopStep(bool last_step);
void snapToGrid(gfx::Point& point);

View File

@ -65,8 +65,6 @@ void DrawingState::initToolLoop(Editor* editor, MouseMessage* msg)
static_cast<LayerImage*>(m_toolLoop->getLayer())->blendMode():
BlendMode::NEG_BW));
m_lastPoint = editor->lastDrawingPosition();
tools::Pointer pointer;
bool movement = false;
@ -74,8 +72,9 @@ void DrawingState::initToolLoop(Editor* editor, MouseMessage* msg)
m_toolLoop->getInk()->isPaint() &&
(editor->getCustomizationDelegate()
->getPressedKeyAction(KeyContext::FreehandTool) & KeyAction::StraightLineFromLastPoint) == KeyAction::StraightLineFromLastPoint &&
m_lastPoint.x >= 0) {
pointer = tools::Pointer(m_lastPoint, button_from_msg(msg));
editor->document()->lastDrawingPoint() != app::Document::NoLastDrawingPoint()) {
pointer = tools::Pointer(editor->document()->lastDrawingPoint(),
button_from_msg(msg));
movement = true;
}
else {
@ -92,7 +91,6 @@ void DrawingState::initToolLoop(Editor* editor, MouseMessage* msg)
m_toolLoopManager->movement(pointer);
}
editor->setLastDrawingPosition(pointer.point());
editor->captureMouse();
}
@ -165,9 +163,6 @@ bool DrawingState::onMouseMove(Editor* editor, MouseMessage* msg)
ASSERT(m_toolLoopManager != NULL);
m_toolLoopManager->movement(pointer);
// Save the last point.
editor->setLastDrawingPosition(pointer.point());
return true;
}
@ -235,17 +230,11 @@ void DrawingState::destroyLoopIfCanceled(Editor* editor)
void DrawingState::destroyLoop(Editor* editor)
{
if (editor) {
if (m_toolLoopManager &&
m_toolLoopManager->isCanceled()) {
editor->setLastDrawingPosition(m_lastPoint);
}
if (editor)
editor->renderEngine().removePreviewImage();
}
if (m_toolLoop)
m_toolLoop->dispose();
m_toolLoop->commitOrRollback();
delete m_toolLoopManager;
delete m_toolLoop;

View File

@ -163,7 +163,6 @@ Editor::Editor(Document* document, EditorFlags flags)
, m_frame(frame_t(0))
, m_docPref(Preferences::instance().document(document))
, m_brushPreview(this)
, m_lastDrawingPosition(-1, -1)
, m_toolLoopModifiers(tools::ToolLoopModifiers::kNone)
, m_padding(0, 0)
, m_antsTimer(100, this)
@ -1830,11 +1829,6 @@ void Editor::setCursor(const gfx::Point& mouseScreenPos)
showMouseCursor(kArrowCursor);
}
void Editor::setLastDrawingPosition(const gfx::Point& pos)
{
m_lastDrawingPosition = pos;
}
bool Editor::canDraw()
{
return (m_layer != NULL &&

View File

@ -190,9 +190,6 @@ namespace app {
bool isAutoSelectLayer() const;
bool isSecondaryButton() const { return m_secondaryButton; }
gfx::Point lastDrawingPosition() const { return m_lastDrawingPosition; }
void setLastDrawingPosition(const gfx::Point& pos);
// Returns true if we are able to draw in the current doc/sprite/layer/cel.
bool canDraw();
@ -336,10 +333,6 @@ namespace app {
// Brush preview
BrushPreview m_brushPreview;
// Position used to draw straight lines using freehand tools + Shift key
// (EditorCustomizationDelegate::isStraightLineFromLastPoint() modifier)
gfx::Point m_lastDrawingPosition;
tools::ToolLoopModifiers m_toolLoopModifiers;
// Extra space around the sprite.

View File

@ -12,6 +12,7 @@
#include "app/app.h"
#include "app/cmd/add_slice.h"
#include "app/cmd/set_last_point.h"
#include "app/cmd/set_mask.h"
#include "app/color.h"
#include "app/color_utils.h"
@ -409,13 +410,19 @@ public:
}
// IToolLoop interface
void dispose() override
{
void commitOrRollback() override {
bool redraw = false;
if (!m_canceled) {
// Paint ink
if (getInk()->isPaint()) {
// Freehand changes the last point
if (getController()->isFreehand())
m_transaction.execute(
new cmd::SetLastPoint(
m_document,
getController()->getLastPoint()));
try {
ContextReader reader(m_context, 500);
ContextWriter writer(reader, 500);
@ -440,8 +447,9 @@ public:
m_transaction.commit();
}
else
else {
redraw = true;
}
// If the trace was canceled or it is not a 'paint' ink...
if (m_canceled || !getInk()->isPaint()) {
@ -622,7 +630,9 @@ public:
}
// IToolLoop interface
void dispose() override { }
void commitOrRollback() override {
// Do nothing
}
const Image* getSrcImage() override { return m_image; }
const Image* getFloodFillSrcImage() override { return m_image; }
Image* getDstImage() override { return m_image; }