1 | // Aseprite |
2 | // Copyright (C) 2019-2021 Igara Studio S.A. |
3 | // Copyright (C) 2001-2017 David Capello |
4 | // |
5 | // This program is distributed under the terms of |
6 | // the End-User License Agreement for Aseprite. |
7 | |
8 | #ifndef APP_TOOLS_TOOL_LOOP_MANAGER_H_INCLUDED |
9 | #define APP_TOOLS_TOOL_LOOP_MANAGER_H_INCLUDED |
10 | #pragma once |
11 | |
12 | #include "app/tools/dynamics.h" |
13 | #include "app/tools/pointer.h" |
14 | #include "app/tools/stroke.h" |
15 | #include "doc/brush.h" |
16 | #include "gfx/point.h" |
17 | #include "gfx/region.h" |
18 | |
19 | #include <vector> |
20 | |
21 | namespace gfx { class Region; } |
22 | |
23 | namespace app { |
24 | namespace tools { |
25 | |
26 | class ToolLoop; |
27 | |
28 | // Class to manage the drawing tool (editor <-> tool interface). |
29 | // |
30 | // The flow is this: |
31 | // 1. The user press a mouse button in a Editor widget |
32 | // 2. The Editor creates an implementation of ToolLoop and use it |
33 | // with the ToolLoopManager constructor |
34 | // 3. The ToolLoopManager is used to call |
35 | // the following methods: |
36 | // - ToolLoopManager::prepareLoop |
37 | // - ToolLoopManager::pressButton |
38 | // 4. If the user moves the mouse, the method |
39 | // - ToolLoopManager::movement |
40 | // is called. |
41 | // 5. When the user release the mouse: |
42 | // - ToolLoopManager::releaseButton |
43 | // |
44 | class ToolLoopManager { |
45 | public: |
46 | // Contructs a manager for the ToolLoop delegate. |
47 | ToolLoopManager(ToolLoop* toolLoop); |
48 | virtual ~ToolLoopManager(); |
49 | |
50 | // Returns true if the loop was canceled by the user |
51 | bool isCanceled() const; |
52 | |
53 | // Called when the tool loop must be canceled because another |
54 | // command was executed or the Esc key pressed. |
55 | void cancel(); |
56 | |
57 | // Called when the tool loop ends (this will commit or rollback the |
58 | // tool loop). |
59 | void end(); |
60 | |
61 | // Should be called when the user start a tool-trace (pressing the |
62 | // left or right button for first time in the editor). |
63 | void prepareLoop(const Pointer& pointer); |
64 | |
65 | // Should be called when the ToolLoop::getModifiers() |
66 | // value was modified (e.g. when the user press/release a key). |
67 | void notifyToolLoopModifiersChange(); |
68 | |
69 | // Should be called each time the user presses a mouse button. |
70 | void pressButton(const Pointer& pointer); |
71 | |
72 | // Should be called each time the user releases a mouse button. |
73 | // |
74 | // Returns true if the tool-loop should continue, or false |
75 | // if the editor should release the mouse capture. |
76 | bool releaseButton(const Pointer& pointer); |
77 | |
78 | // Should be called each time the user moves the mouse inside the editor. |
79 | void movement(Pointer pointer); |
80 | |
81 | const Pointer& lastPointer() const { return m_lastPointer; } |
82 | |
83 | private: |
84 | void doLoopStep(bool lastStep); |
85 | void snapToGrid(Stroke::Pt& pt); |
86 | Stroke::Pt getSpriteStrokePt(const Pointer& pointer); |
87 | bool useDynamics() const; |
88 | void adjustPointWithDynamics(const Pointer& pointer, Stroke::Pt& pt); |
89 | |
90 | void calculateDirtyArea(const Strokes& strokes); |
91 | |
92 | ToolLoop* m_toolLoop; |
93 | bool m_canceled; |
94 | Stroke m_stroke; |
95 | Pointer m_lastPointer; |
96 | gfx::Region m_dirtyArea; |
97 | gfx::Region m_nextDirtyArea; |
98 | doc::Brush m_brush0; |
99 | DynamicsOptions m_dynamics; |
100 | gfx::PointF m_stabilizerCenter; |
101 | }; |
102 | |
103 | } // namespace tools |
104 | } // namespace app |
105 | |
106 | #endif |
107 | |