diff --git a/src/app/tools/controller.h b/src/app/tools/controller.h index 0ec00bfed..dcd0f0ab1 100644 --- a/src/app/tools/controller.h +++ b/src/app/tools/controller.h @@ -8,6 +8,7 @@ #define APP_TOOLS_CONTROLLER_H_INCLUDED #pragma once +#include "app/tools/trace_policy.h" #include "gfx/point.h" #include @@ -28,6 +29,8 @@ namespace app { virtual bool isFreehand() { return false; } virtual bool isOnePoint() { return false; } + virtual void prepareController(ToolLoop* loop) { } + // Called when the user starts drawing and each time a new button is // pressed. The controller could be sure that this method is called // at least one time. The point is a position relative to sprite @@ -47,6 +50,13 @@ namespace app { // 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); } + + // Special trace policy that can change in the middle of the + // ToolLoop. This is for LineFreehandController which uses a + // TracePolicy::Last for TwoPoints controller (Line-like tool) + // and then a TracePolicy::Accumulate for freehand (Pencil tool). + virtual bool handleTracePolicy() const { return false; } + virtual TracePolicy getTracePolicy() const { return TracePolicy::Accumulate; } }; } // namespace tools diff --git a/src/app/tools/controllers.h b/src/app/tools/controllers.h index b2b2a28db..5518da79f 100644 --- a/src/app/tools/controllers.h +++ b/src/app/tools/controllers.h @@ -99,6 +99,10 @@ private: // Controls clicks for tools like line class TwoPointsController : public MoveOriginCapability { public: + TwoPointsController(const bool enableModifiers) + : m_enableModifiers(enableModifiers) { + } + void pressButton(Stroke& stroke, const Point& point) override { MoveOriginCapability::pressButton(stroke, point); @@ -122,7 +126,8 @@ public: stroke[1] = point; - if (int(loop->getModifiers()) & int(ToolLoopModifiers::kSquareAspect)) { + if (m_enableModifiers && + (int(loop->getModifiers()) & int(ToolLoopModifiers::kSquareAspect))) { int dx = stroke[1].x - m_first.x; int dy = stroke[1].y - m_first.y; int minsize = MIN(ABS(dx), ABS(dy)); @@ -167,7 +172,8 @@ public: stroke[0] = m_first; - if (int(loop->getModifiers()) & int(ToolLoopModifiers::kFromCenter)) { + if (m_enableModifiers && + (int(loop->getModifiers()) & int(ToolLoopModifiers::kFromCenter))) { int rx = stroke[1].x - m_first.x; int ry = stroke[1].y - m_first.y; stroke[0].x = m_first.x - rx; @@ -226,6 +232,7 @@ private: } Point m_first; + bool m_enableModifiers; }; // Controls clicks for tools like polygon @@ -379,5 +386,64 @@ private: int m_clickCounter; }; +// Controls the shift+click to draw a two-points line and then +// freehand until the mouse is released. +class LineFreehandController : public Controller { +public: + LineFreehandController() : m_twoPoints(false) { } + + bool isFreehand() override { return true; } + + gfx::Point getLastPoint() const override { return m_last; } + + void prepareController(ToolLoop* loop) override { + m_controller = nullptr; + } + + void pressButton(Stroke& stroke, const Point& point) override { + m_last = point; + + if (m_controller == nullptr) + m_controller = &m_twoPoints; + else if (m_controller == &m_twoPoints) { + m_controller = &m_freehand; + return; // Don't send first pressButton() click to the freehand controller + } + + m_controller->pressButton(stroke, point); + } + + bool releaseButton(Stroke& stroke, const Point& point) override { + return false; + } + + void movement(ToolLoop* loop, Stroke& stroke, const Point& point) override { + m_last = point; + m_controller->movement(loop, stroke, point); + } + + void getStrokeToInterwine(const Stroke& input, Stroke& output) override { + m_controller->getStrokeToInterwine(input, output); + } + + void getStatusBarText(const Stroke& stroke, std::string& text) override { + m_controller->getStatusBarText(stroke, text); + } + + bool handleTracePolicy() const override { + return (m_controller == &m_twoPoints); + } + + TracePolicy getTracePolicy() const override { + return TracePolicy::Last; + } + +private: + Point m_last; + TwoPointsController m_twoPoints; + FreehandController m_freehand; + Controller* m_controller; +}; + } // namespace tools } // namespace app diff --git a/src/app/tools/tool_box.cpp b/src/app/tools/tool_box.cpp index b45a6c92e..c4b32e47a 100644 --- a/src/app/tools/tool_box.cpp +++ b/src/app/tools/tool_box.cpp @@ -69,6 +69,13 @@ const char* WellKnownInks::MoveSlice = "move_slice"; const char* WellKnownInks::Blur = "blur"; const char* WellKnownInks::Jumble = "jumble"; +const char* WellKnownControllers::Freehand = "freehand"; +const char* WellKnownControllers::PointByPoint = "point_by_point"; +const char* WellKnownControllers::OnePoints = "one_point"; +const char* WellKnownControllers::TwoPoints = "two_points"; +const char* WellKnownControllers::FourPoints = "four_points"; +const char* WellKnownControllers::LineFreehand = "line_freehand"; + const char* WellKnownIntertwiners::None = "none"; const char* WellKnownIntertwiners::FirstPoint = "first_point"; const char* WellKnownIntertwiners::AsLines = "as_lines"; @@ -105,11 +112,12 @@ ToolBox::ToolBox() m_inks[WellKnownInks::Blur] = new BlurInk(); m_inks[WellKnownInks::Jumble] = new JumbleInk(); - m_controllers["freehand"] = new FreehandController(); - m_controllers["point_by_point"] = new PointByPointController(); - m_controllers["one_point"] = new OnePointController(); - m_controllers["two_points"] = new TwoPointsController(); - m_controllers["four_points"] = new FourPointsController(); + m_controllers[WellKnownControllers::Freehand] = new FreehandController(); + m_controllers[WellKnownControllers::PointByPoint] = new PointByPointController(); + m_controllers[WellKnownControllers::OnePoints] = new OnePointController(); + m_controllers[WellKnownControllers::TwoPoints] = new TwoPointsController(true); + m_controllers[WellKnownControllers::FourPoints] = new FourPointsController(); + m_controllers[WellKnownControllers::LineFreehand] = new LineFreehandController(); m_pointshapers[WellKnownPointShapes::None] = new NonePointShape(); m_pointshapers[WellKnownPointShapes::Pixel] = new PixelPointShape(); @@ -161,6 +169,11 @@ Ink* ToolBox::getInkById(const std::string& id) return m_inks[id]; } +Controller* ToolBox::getControllerById(const std::string& id) +{ + return m_controllers[id]; +} + Intertwine* ToolBox::getIntertwinerById(const std::string& id) { return m_intertwiners[id]; diff --git a/src/app/tools/tool_box.h b/src/app/tools/tool_box.h index 22d983bef..f40f687d2 100644 --- a/src/app/tools/tool_box.h +++ b/src/app/tools/tool_box.h @@ -52,6 +52,15 @@ namespace app { extern const char* Jumble; }; + namespace WellKnownControllers { + extern const char* Freehand; + extern const char* PointByPoint; + extern const char* OnePoints; + extern const char* TwoPoints; + extern const char* FourPoints; + extern const char* LineFreehand; + }; + namespace WellKnownIntertwiners { extern const char* None; extern const char* FirstPoint; @@ -92,6 +101,7 @@ namespace app { Tool* getToolById(const std::string& id); Ink* getInkById(const std::string& id); + Controller* getControllerById(const std::string& id); Intertwine* getIntertwinerById(const std::string& id); PointShape* getPointShapeById(const std::string& id); int getGroupsCount() const { return m_groups.size(); } diff --git a/src/app/tools/tool_loop_manager.cpp b/src/app/tools/tool_loop_manager.cpp index 42739d5a0..f7d69ee0d 100644 --- a/src/app/tools/tool_loop_manager.cpp +++ b/src/app/tools/tool_loop_manager.cpp @@ -54,6 +54,7 @@ void ToolLoopManager::prepareLoop(const Pointer& pointer) // Prepare the ink m_toolLoop->getInk()->prepareInk(m_toolLoop); + m_toolLoop->getController()->prepareController(m_toolLoop); m_toolLoop->getIntertwine()->prepareIntertwine(); m_toolLoop->getPointShape()->preparePointShape(m_toolLoop); } diff --git a/src/app/ui/editor/drawing_state.cpp b/src/app/ui/editor/drawing_state.cpp index 2ac65f43b..e23db05bf 100644 --- a/src/app/ui/editor/drawing_state.cpp +++ b/src/app/ui/editor/drawing_state.cpp @@ -39,10 +39,13 @@ namespace app { using namespace ui; -DrawingState::DrawingState(tools::ToolLoop* toolLoop) - : m_toolLoop(toolLoop) +DrawingState::DrawingState(tools::ToolLoop* toolLoop, + const DrawingType type) + : m_type(type) + , m_toolLoop(toolLoop) , m_toolLoopManager(new tools::ToolLoopManager(toolLoop)) , m_mouseMoveReceived(false) + , m_mousePressedReceived(false) { } @@ -51,7 +54,8 @@ DrawingState::~DrawingState() destroyLoop(nullptr); } -void DrawingState::initToolLoop(Editor* editor, MouseMessage* msg) +void DrawingState::initToolLoop(Editor* editor, + const tools::Pointer& pointer) { // Prepare preview image (the destination image will be our preview // in the tool-loop time, so we can see what we are drawing) @@ -65,35 +69,18 @@ void DrawingState::initToolLoop(Editor* editor, MouseMessage* msg) static_cast(m_toolLoop->getLayer())->blendMode(): BlendMode::NEG_BW)); - tools::Pointer pointer; - bool movement = false; - - if (m_toolLoop->getController()->isFreehand() && - m_toolLoop->getInk()->isPaint() && - (editor->getCustomizationDelegate() - ->getPressedKeyAction(KeyContext::FreehandTool) & KeyAction::StraightLineFromLastPoint) == KeyAction::StraightLineFromLastPoint && - editor->document()->lastDrawingPoint() != app::Document::NoLastDrawingPoint()) { - pointer = tools::Pointer(editor->document()->lastDrawingPoint(), - button_from_msg(msg)); - movement = true; - } - else { - pointer = pointer_from_msg(editor, msg); - } - m_toolLoopManager->prepareLoop(pointer); m_toolLoopManager->pressButton(pointer); - // This first movement is done when the user pressed Shift+click in - // a freehand tool to draw a straight line. - if (movement) { - pointer = pointer_from_msg(editor, msg); - m_toolLoopManager->movement(pointer); - } - editor->captureMouse(); } +void DrawingState::sendMovementToToolLoop(const tools::Pointer& pointer) +{ + ASSERT(m_toolLoopManager); + m_toolLoopManager->movement(pointer); +} + void DrawingState::notifyToolLoopModifiersChange(Editor* editor) { if (!m_toolLoopManager->isCanceled()) @@ -105,6 +92,8 @@ bool DrawingState::onMouseDown(Editor* editor, MouseMessage* msg) // Drawing loop ASSERT(m_toolLoopManager != NULL); + m_mousePressedReceived = true; + // Notify the mouse button down to the tool loop manager. m_toolLoopManager->pressButton(pointer_from_msg(editor, msg)); @@ -195,8 +184,15 @@ bool DrawingState::onKeyDown(Editor* editor, KeyMessage* msg) bool DrawingState::onKeyUp(Editor* editor, KeyMessage* msg) { - if (msg->scancode() == ui::kKeyEsc) + // Cancel loop pressing Esc key... + if (msg->scancode() == ui::kKeyEsc || + // Cancel "Shift on freehand" line preview when the Shift key is + // released and the user didn't press the mouse button.. + (m_type == DrawingType::LineFreehand && + !m_mousePressedReceived && + !editor->startStraightLineWithFreehandTool())) { m_toolLoop->cancel(); + } // The user might have canceled the tool loop pressing the 'Esc' key. destroyLoopIfCanceled(editor); diff --git a/src/app/ui/editor/drawing_state.h b/src/app/ui/editor/drawing_state.h index 20759e9f1..37bb55363 100644 --- a/src/app/ui/editor/drawing_state.h +++ b/src/app/ui/editor/drawing_state.h @@ -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. @@ -12,13 +12,15 @@ namespace app { namespace tools { + class Pointer; class ToolLoop; class ToolLoopManager; } class DrawingState : public StandbyState { public: - DrawingState(tools::ToolLoop* loop); + DrawingState(tools::ToolLoop* loop, + const DrawingType type); virtual ~DrawingState(); virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override; virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override; @@ -33,13 +35,21 @@ namespace app { // already drawing (viewing the real trace). virtual bool requireBrushPreview() override { return false; } - void initToolLoop(Editor* editor, ui::MouseMessage* msg); + void initToolLoop(Editor* editor, + const tools::Pointer& pointer); + + // Used to send a movement() to the ToolLoopManager when + // Shift+brush tool is used to paint a line. + void sendMovementToToolLoop(const tools::Pointer& pointer); + void notifyToolLoopModifiersChange(Editor* editor); private: void destroyLoopIfCanceled(Editor* editor); void destroyLoop(Editor* editor); + DrawingType m_type; + // The tool-loop. tools::ToolLoop* m_toolLoop; @@ -55,6 +65,12 @@ namespace app { // DrawingState. It's used to restore the last drawing position in // case this stroke is canceled. gfx::Point m_lastPoint; + + // Used to know if the button was pressed after the DrawingState + // was initialized. In this way we can cancel the ToolLoop if the + // Shift press is used to draw a line, but then released without a + // mouse click. + bool m_mousePressedReceived; }; } // namespace app diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp index c0ca4908e..fe01cc439 100644 --- a/src/app/ui/editor/editor.cpp +++ b/src/app/ui/editor/editor.cpp @@ -24,6 +24,7 @@ #include "app/modules/palettes.h" #include "app/pref/preferences.h" #include "app/tools/active_tool.h" +#include "app/tools/controller.h" #include "app/tools/ink.h" #include "app/tools/tool.h" #include "app/tools/tool_box.h" @@ -59,6 +60,7 @@ #include #include +#include namespace app { @@ -1512,6 +1514,18 @@ app::Color Editor::getColorByPosition(const gfx::Point& mousePos) return app::Color::fromMask(); } +bool Editor::startStraightLineWithFreehandTool() +{ + tools::Tool* tool = App::instance()->activeToolManager()->selectedTool(); + return + (tool && + tool->getController(0)->isFreehand() && + tool->getInk(0)->isPaint() && + (getCustomizationDelegate() + ->getPressedKeyAction(KeyContext::FreehandTool) & KeyAction::StraightLineFromLastPoint) == KeyAction::StraightLineFromLastPoint && + document()->lastDrawingPoint() != app::Document::NoLastDrawingPoint()); +} + ////////////////////////////////////////////////////////////////////// // Message handler for the editor diff --git a/src/app/ui/editor/editor.h b/src/app/ui/editor/editor.h index a8480937d..392b7555b 100644 --- a/src/app/ui/editor/editor.h +++ b/src/app/ui/editor/editor.h @@ -254,6 +254,10 @@ namespace app { void setTagFocusBand(int value) { m_tagFocusBand = value; } int tagFocusBand() const { return m_tagFocusBand; } + // Returns true if the Shift key to draw straight lines with a + // freehand tool is pressed. + bool startStraightLineWithFreehandTool(); + protected: bool onProcessMessage(ui::Message* msg) override; void onSizeHint(ui::SizeHintEvent& ev) override; diff --git a/src/app/ui/editor/standby_state.cpp b/src/app/ui/editor/standby_state.cpp index 97a2dcf77..3618e230a 100644 --- a/src/app/ui/editor/standby_state.cpp +++ b/src/app/ui/editor/standby_state.cpp @@ -28,6 +28,7 @@ #include "app/ui/editor/drawing_state.h" #include "app/ui/editor/editor.h" #include "app/ui/editor/editor_customization_delegate.h" +#include "app/ui/editor/glue.h" #include "app/ui/editor/handle_type.h" #include "app/ui/editor/moving_cel_state.h" #include "app/ui/editor/moving_pixels_state.h" @@ -320,20 +321,9 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg) if (layerEdges) layerEdgesOption(false); - // We need to clear and redraw the brush boundaries after the - // first mouse pressed/point shape if drawn. This is to avoid - // graphical glitches (invalid areas in the ToolLoop's src/dst - // images). - HideBrushPreview hide(editor->brushPreview()); - - tools::ToolLoop* toolLoop = create_tool_loop(editor, context); - if (toolLoop) { - EditorStatePtr newState(new DrawingState(toolLoop)); - editor->setState(newState); - - static_cast(newState.get()) - ->initToolLoop(editor, msg); - } + startDrawingState(editor, + DrawingType::Regular, + pointer_from_msg(editor, msg)); // Restore layer edges if (layerEdges) @@ -497,6 +487,22 @@ bool StandbyState::onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos) bool StandbyState::onKeyDown(Editor* editor, KeyMessage* msg) { + // Start line preview with shift key + if (editor->startStraightLineWithFreehandTool()) { + DrawingState* drawingState = + startDrawingState(editor, + DrawingType::LineFreehand, + tools::Pointer( + editor->document()->lastDrawingPoint(), + tools::Pointer::Left)); + if (drawingState) { + drawingState->sendMovementToToolLoop( + tools::Pointer( + editor->screenToEditor(ui::get_mouse_position()), + tools::Pointer::Left)); + return true; + } + } return false; } @@ -586,6 +592,35 @@ bool StandbyState::onUpdateStatusBar(Editor* editor) return true; } +DrawingState* StandbyState::startDrawingState(Editor* editor, + const DrawingType drawingType, + const tools::Pointer& pointer) +{ + // We need to clear and redraw the brush boundaries after the + // first mouse pressed/point shape if drawn. This is to avoid + // graphical glitches (invalid areas in the ToolLoop's src/dst + // images). + HideBrushPreview hide(editor->brushPreview()); + + tools::ToolLoop* toolLoop = create_tool_loop( + editor, + UIContext::instance(), + (drawingType == DrawingType::LineFreehand)); + if (!toolLoop) + return nullptr; + + EditorStatePtr newState( + new DrawingState(toolLoop, + drawingType)); + editor->setState(newState); + + static_cast(newState.get()) + ->initToolLoop(editor, + pointer); + + return static_cast(newState.get()); +} + Transformation StandbyState::getTransformation(Editor* editor) { Transformation t = editor->document()->getTransformation(); diff --git a/src/app/ui/editor/standby_state.h b/src/app/ui/editor/standby_state.h index 2b4d131d2..27309e3df 100644 --- a/src/app/ui/editor/standby_state.h +++ b/src/app/ui/editor/standby_state.h @@ -17,12 +17,16 @@ namespace app { namespace tools { class Ink; + class Pointer; } + class DrawingState; class TransformHandles; class StandbyState : public StateWithWheelBehavior { public: + enum class DrawingType { Regular, LineFreehand }; + StandbyState(); virtual ~StandbyState(); virtual void onEnterState(Editor* editor) override; @@ -76,6 +80,9 @@ namespace app { }; private: + DrawingState* startDrawingState(Editor* editor, + const DrawingType drawingType, + const tools::Pointer& pointer); void transformSelection(Editor* editor, ui::MouseMessage* msg, HandleType handle); void onPivotChange(Editor* editor); gfx::Rect resizeCelBounds(Editor* editor) const; diff --git a/src/app/ui/editor/tool_loop_impl.cpp b/src/app/ui/editor/tool_loop_impl.cpp index d66f40486..e203c828c 100644 --- a/src/app/ui/editor/tool_loop_impl.cpp +++ b/src/app/ui/editor/tool_loop_impl.cpp @@ -97,6 +97,7 @@ public: Layer* layer, tools::Tool* tool, tools::Ink* ink, + tools::Controller* controller, Document* document, tools::ToolLoop::Button button, const app::Color& fgColor, @@ -116,7 +117,7 @@ public: , m_contiguous(m_toolPref.contiguous()) , m_button(button) , m_ink(ink->clone()) - , m_controller(m_tool->getController(m_button)) + , m_controller(controller) , m_pointShape(m_tool->getPointShape(m_button)) , m_intertwine(m_tool->getIntertwine(m_button)) , m_tracePolicy(m_tool->getTracePolicy(m_button)) @@ -243,7 +244,12 @@ public: tools::Controller* getController() override { return m_controller; } tools::PointShape* getPointShape() override { return m_pointShape; } tools::Intertwine* getIntertwine() override { return m_intertwine; } - tools::TracePolicy getTracePolicy() override { return m_tracePolicy; } + tools::TracePolicy getTracePolicy() override { + if (m_controller->handleTracePolicy()) + return m_controller->getTracePolicy(); + else + return m_tracePolicy; + } tools::Symmetry* getSymmetry() override { return m_symmetry.get(); } doc::Remap* getShadingRemap() override { return m_shadingRemap; } @@ -293,6 +299,7 @@ class ToolLoopImpl : public ToolLoopBase { Transaction m_transaction; ExpandCelCanvas* m_expandCelCanvas; Image* m_floodfillSrcImage; + bool m_saveLastPoint; public: ToolLoopImpl(Editor* editor, @@ -300,12 +307,21 @@ public: Context* context, tools::Tool* tool, tools::Ink* ink, + tools::Controller* controller, Document* document, tools::ToolLoop::Button button, const app::Color& fgColor, - const app::Color& bgColor) - : ToolLoopBase(editor, layer, tool, ink, document, - button, fgColor, bgColor) + const app::Color& bgColor, + const bool saveLastPoint) + : ToolLoopBase(editor, + layer, + tool, + ink, + controller, + document, + button, + fgColor, + bgColor) , m_context(context) , m_canceled(false) , m_transaction(m_context, @@ -318,6 +334,7 @@ public: ModifyDocument)) , m_expandCelCanvas(nullptr) , m_floodfillSrcImage(nullptr) + , m_saveLastPoint(saveLastPoint) { ASSERT(m_context->activeDocument() == m_editor->document()); @@ -414,15 +431,16 @@ public: bool redraw = false; if (!m_canceled) { + // Freehand changes the last point + if (m_saveLastPoint) { + m_transaction.execute( + new cmd::SetLastPoint( + m_document, + getController()->getLastPoint())); + } + // 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); @@ -512,12 +530,15 @@ public: }; -tools::ToolLoop* create_tool_loop(Editor* editor, Context* context) +tools::ToolLoop* create_tool_loop( + Editor* editor, + Context* context, + const bool convertLineToFreehand) { - tools::Tool* current_tool = editor->getCurrentEditorTool(); - tools::Ink* current_ink = editor->getCurrentEditorInk(); - if (!current_tool || !current_ink) - return NULL; + tools::Tool* tool = editor->getCurrentEditorTool(); + tools::Ink* ink = editor->getCurrentEditorInk(); + if (!tool || !ink) + return nullptr; Layer* layer; @@ -530,8 +551,8 @@ tools::ToolLoop* create_tool_loop(Editor* editor, Context* context) // Anyway this cannot be used in 'magic wand' tool (isSelection + // isFloodFill) because we need the original layer source // image/pixels to stop the flood-fill algorithm. - if (current_ink->isSelection() && - !current_tool->getPointShape(editor->isSecondaryButton() ? 1: 0)->isFloodFill()) { + if (ink->isSelection() && + !tool->getPointShape(editor->isSecondaryButton() ? 1: 0)->isFloodFill()) { layer = nullptr; } else { @@ -578,13 +599,30 @@ tools::ToolLoop* create_tool_loop(Editor* editor, Context* context) // Create the new tool loop try { + tools::ToolLoop::Button button = + (!editor->isSecondaryButton() ? tools::ToolLoop::Left: + tools::ToolLoop::Right); + + tools::Controller* controller = + (convertLineToFreehand ? + App::instance()->toolBox()->getControllerById( + tools::WellKnownControllers::LineFreehand): + tool->getController(button)); + + const bool saveLastPoint = + (ink->isPaint() && + (controller->isFreehand() || + convertLineToFreehand)); + return new ToolLoopImpl( editor, layer, context, - current_tool, - current_ink, + tool, + ink, + controller, editor->document(), - !editor->isSecondaryButton() ? tools::ToolLoop::Left: tools::ToolLoop::Right, - fg, bg); + button, + fg, bg, + saveLastPoint); } catch (const std::exception& ex) { Alert::show(PACKAGE @@ -612,8 +650,15 @@ public: const app::Color& bgColor, Image* image, const gfx::Point& celOrigin) - : ToolLoopBase(editor, editor->layer(), tool, ink, document, - tools::ToolLoop::Left, fgColor, bgColor) + : ToolLoopBase(editor, + editor->layer(), + tool, + ink, + tool->getController(tools::ToolLoop::Left), + document, + tools::ToolLoop::Left, + fgColor, + bgColor) , m_image(image) { m_celOrigin = celOrigin; @@ -661,9 +706,9 @@ tools::ToolLoop* create_tool_loop_preview( Editor* editor, Image* image, const gfx::Point& celOrigin) { - tools::Tool* current_tool = editor->getCurrentEditorTool(); - tools::Ink* current_ink = editor->getCurrentEditorInk(); - if (!current_tool || !current_ink) + tools::Tool* tool = editor->getCurrentEditorTool(); + tools::Ink* ink = editor->getCurrentEditorInk(); + if (!tool || !ink) return NULL; Layer* layer = editor->layer(); @@ -685,8 +730,8 @@ tools::ToolLoop* create_tool_loop_preview( try { return new PreviewToolLoopImpl( editor, - current_tool, - current_ink, + tool, + ink, editor->document(), fg, bg, image, celOrigin); } diff --git a/src/app/ui/editor/tool_loop_impl.h b/src/app/ui/editor/tool_loop_impl.h index e195afca5..b25b621e0 100644 --- a/src/app/ui/editor/tool_loop_impl.h +++ b/src/app/ui/editor/tool_loop_impl.h @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2001-2015 David Capello +// Copyright (C) 2001-2017 David Capello // // This program is distributed under the terms of // the End-User License Agreement for Aseprite. @@ -24,10 +24,13 @@ namespace app { } tools::ToolLoop* create_tool_loop( - Editor* editor, Context* context); + Editor* editor, + Context* context, + const bool convertLineToFreehand); tools::ToolLoop* create_tool_loop_preview( - Editor* editor, doc::Image* image, + Editor* editor, + doc::Image* image, const gfx::Point& celOrigin); } // namespace app