1 | // Aseprite |
2 | // Copyright (C) 2019-2022 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_H_INCLUDED |
9 | #define APP_TOOLS_TOOL_LOOP_H_INCLUDED |
10 | #pragma once |
11 | |
12 | #include "app/shade.h" |
13 | #include "app/util/tiled_mode.h" |
14 | #include "app/tools/dynamics.h" |
15 | #include "app/tools/stroke.h" |
16 | #include "app/tools/tool_loop_modifiers.h" |
17 | #include "app/tools/trace_policy.h" |
18 | #include "doc/brush.h" |
19 | #include "doc/color.h" |
20 | #include "doc/frame.h" |
21 | #include "doc/grid.h" |
22 | #include "filters/tiled_mode.h" |
23 | #include "gfx/point.h" |
24 | #include "gfx/rect.h" |
25 | #include "render/gradient.h" |
26 | |
27 | namespace gfx { |
28 | class Region; |
29 | } |
30 | |
31 | namespace doc { |
32 | class Image; |
33 | class Layer; |
34 | class Mask; |
35 | class Palette; |
36 | class Remap; |
37 | class RgbMap; |
38 | class Slice; |
39 | class Sprite; |
40 | class Tileset; |
41 | } |
42 | |
43 | namespace render { |
44 | class DitheringAlgorithmBase; |
45 | class DitheringMatrix; |
46 | } |
47 | |
48 | namespace app { |
49 | class Context; |
50 | class Doc; |
51 | |
52 | namespace tools { |
53 | class Controller; |
54 | class Ink; |
55 | class Intertwine; |
56 | class PointShape; |
57 | class Symmetry; |
58 | class Tool; |
59 | |
60 | using namespace doc; |
61 | |
62 | // Interface to communicate the sprite editor with the tool when the user |
63 | // starts using a tool to paint, select, pick color, etc. |
64 | // |
65 | // All this information should be provided by the editor and consumed |
66 | // by the tool (+controller+intertwiner+pointshape+ink). |
67 | // |
68 | // TODO This interface is huge, it should be refactored. |
69 | class ToolLoop { |
70 | public: |
71 | enum Button { Left = 0, Right = 1 }; |
72 | |
73 | virtual ~ToolLoop() { } |
74 | |
75 | virtual void commit() = 0; |
76 | virtual void rollback() = 0; |
77 | |
78 | // Returns the tool to use to draw or use |
79 | virtual Tool* getTool() = 0; |
80 | |
81 | // Returns the brush which will be used with the tool |
82 | virtual Brush* getBrush() = 0; |
83 | virtual void setBrush(const BrushRef& newBrush) = 0; |
84 | |
85 | // Returns the document to which belongs the sprite. |
86 | virtual Doc* getDocument() = 0; |
87 | |
88 | // Returns the sprite where we will draw on |
89 | virtual Sprite* sprite() = 0; |
90 | |
91 | // Returns the layer that will be modified if the tool paints |
92 | virtual Layer* getLayer() = 0; |
93 | |
94 | virtual const Cel* getCel() = 0; |
95 | |
96 | // Returns true if the current mode is TileMap (false = Pixels) |
97 | virtual bool isTilemapMode() = 0; |
98 | |
99 | virtual bool isManualTilesetMode() const = 0; |
100 | |
101 | // Returns the frame where we're paiting |
102 | virtual frame_t getFrame() = 0; |
103 | |
104 | // Should return an image where we can read pixels (readonly image) |
105 | virtual const Image* getSrcImage() = 0; |
106 | |
107 | // The image used to get get pixels in floodfill algorithm. |
108 | virtual const Image* getFloodFillSrcImage() = 0; |
109 | |
110 | // Should return an image where we can write pixels |
111 | virtual Image* getDstImage() = 0; |
112 | |
113 | // Can return a tileset used for preview purposes in Manual |
114 | // tiles mode (to show a preview modifying all instances of the |
115 | // same tile at the same time). |
116 | virtual Tileset* getDstTileset() = 0; |
117 | |
118 | // Makes the specified region valid in the source |
119 | // image. Basically the implementation should copy from the |
120 | // original cel the given region to the source image. The source |
121 | // image is used by inks to create blur effects or similar. |
122 | virtual void validateSrcImage(const gfx::Region& rgn) = 0; |
123 | |
124 | // Makes the specified destination image region valid to be |
125 | // painted. The destination image is used by inks to compose the |
126 | // brush, so we've to make sure that the destination image |
127 | // matches the original cel when we make that composition. |
128 | virtual void validateDstImage(const gfx::Region& rgn) = 0; |
129 | virtual void validateDstTileset(const gfx::Region& rgn) = 0; |
130 | |
131 | // Invalidates the whole destination image. It's used for tools |
132 | // like line or rectangle which don't accumulate the effect so |
133 | // they need to start with a fresh destination image on each |
134 | // loop step/cycle. |
135 | virtual void invalidateDstImage() = 0; |
136 | virtual void invalidateDstImage(const gfx::Region& rgn) = 0; |
137 | |
138 | // Copies the given region from the destination to the source |
139 | // image, used by "overlap" tools like jumble or spray. |
140 | virtual void copyValidDstToSrcImage(const gfx::Region& rgn) = 0; |
141 | |
142 | // Returns the current Palette. |
143 | virtual Palette* getPalette() = 0; |
144 | |
145 | // Returns the RGB map used to convert RGB values to palette index. |
146 | virtual RgbMap* getRgbMap() = 0; |
147 | |
148 | // Returns true if we should use the mask to limit the paint area. |
149 | virtual bool useMask() = 0; |
150 | |
151 | // Current mask to limit paint area |
152 | virtual Mask* getMask() = 0; |
153 | virtual void setMask(Mask* newMask) = 0; |
154 | |
155 | // Gets mask X,Y origin coordinates |
156 | virtual gfx::Point getMaskOrigin() = 0; |
157 | |
158 | // Return the mouse button which start the tool-loop. It can be used |
159 | // by some tools that instead of using the primary/secondary color |
160 | // uses the pressed button for different behavior (like selection |
161 | // tools). |
162 | virtual Button getMouseButton() = 0; |
163 | |
164 | // Returns active foreground/background color (certain tools |
165 | // needs to know the exact foreground/background color, they |
166 | // cannot used the primary/secondary). |
167 | virtual doc::color_t getFgColor() = 0; |
168 | virtual doc::color_t getBgColor() = 0; |
169 | |
170 | // Primary color to draw (e.g. foreground if the user start drawing |
171 | // with the left button, or background color if he used the right |
172 | // button) |
173 | virtual doc::color_t getPrimaryColor() = 0; |
174 | virtual void setPrimaryColor(doc::color_t color) = 0; |
175 | |
176 | // Secondary color to draw (e.g. background if the user start drawing |
177 | // with the left button, or foreground color if he used the right |
178 | // button) |
179 | virtual doc::color_t getSecondaryColor() = 0; |
180 | virtual void setSecondaryColor(doc::color_t color) = 0; |
181 | |
182 | // Returns the opacity to be used by the ink (Ink). |
183 | virtual int getOpacity() = 0; |
184 | |
185 | // Returns the tolerance to be used by the ink (Ink). |
186 | virtual int getTolerance() = 0; |
187 | |
188 | // Returns true if the flood fill algorithm should take care |
189 | // contiguous pixels or not. |
190 | virtual bool getContiguous() = 0; |
191 | |
192 | // Returns flags/modifiers that change the way each part of the |
193 | // tool (ink/controllers/etc.) work. |
194 | virtual tools::ToolLoopModifiers getModifiers() = 0; |
195 | |
196 | // Returns the preferred "tiled" mode of the document. |
197 | // See the method PointShape::doInkHline to check how this member is |
198 | // used. When tiled mode is activated, each scanline can be divided |
199 | // in various sub-lines if they pass the image bounds. For each of |
200 | // these scanlines a Ink::inkHline is called |
201 | virtual filters::TiledMode getTiledMode() = 0; |
202 | |
203 | virtual bool getGridVisible() = 0; |
204 | virtual bool getSnapToGrid() = 0; |
205 | virtual bool isSelectingTiles() = 0; |
206 | virtual bool getStopAtGrid() = 0; // For floodfill-like tools |
207 | virtual const doc::Grid& getGrid() const = 0; |
208 | virtual gfx::Rect getGridBounds() = 0; |
209 | virtual bool isPixelConnectivityEightConnected() = 0; |
210 | |
211 | // Returns true if the figure must be filled when we release the |
212 | // mouse (e.g. a filled rectangle, etc.) |
213 | // |
214 | // To fill a shape, the Intertwine::fillPoints function is used. |
215 | virtual bool getFilled() = 0; |
216 | |
217 | // Returns true if the preview should be with filled shapes. |
218 | virtual bool getPreviewFilled() = 0; |
219 | |
220 | // Spray configuration |
221 | virtual int getSprayWidth() = 0; |
222 | virtual int getSpraySpeed() = 0; |
223 | |
224 | // X,Y origin of the cel where we are drawing |
225 | virtual gfx::Point getCelOrigin() = 0; |
226 | virtual bool needsCelCoordinates() = 0; |
227 | |
228 | // Velocity vector of the mouse |
229 | virtual void setSpeed(const gfx::Point& speed) = 0; |
230 | virtual gfx::Point getSpeed() = 0; |
231 | |
232 | // Returns the ink to use with the tool. Each tool has an associated |
233 | // ink, but it could be modified for this specific loop, so |
234 | // generally you should return the same ink as the tool, but it can |
235 | // be different. The same for the other properties. |
236 | virtual Ink* getInk() = 0; |
237 | virtual Controller* getController() = 0; |
238 | virtual PointShape* getPointShape() = 0; |
239 | virtual Intertwine* getIntertwine() = 0; |
240 | virtual TracePolicy getTracePolicy() = 0; |
241 | virtual Symmetry* getSymmetry() = 0; |
242 | |
243 | virtual const Shade& getShade() = 0; |
244 | virtual const doc::Remap* getShadingRemap() = 0; |
245 | |
246 | virtual void limitDirtyAreaToViewport(gfx::Region& rgn) = 0; |
247 | |
248 | // Redraws the dirty area. |
249 | virtual void updateDirtyArea(const gfx::Region& dirtyArea) = 0; |
250 | |
251 | virtual void updateStatusBar(const char* text) = 0; |
252 | virtual gfx::Point statusBarPositionOffset() = 0; |
253 | |
254 | // For gradients |
255 | virtual render::DitheringMatrix getDitheringMatrix() = 0; |
256 | virtual render::DitheringAlgorithmBase* getDitheringAlgorithm() = 0; |
257 | virtual render::GradientType getGradientType() = 0; |
258 | |
259 | // For freehand algorithms with dynamics |
260 | virtual tools::DynamicsOptions getDynamics() = 0; |
261 | |
262 | // Called when the user release the mouse on SliceInk |
263 | virtual void onSliceRect(const gfx::Rect& bounds) = 0; |
264 | |
265 | virtual const app::TiledModeHelper& getTiledModeHelper() = 0; |
266 | }; |
267 | |
268 | } // namespace tools |
269 | } // namespace app |
270 | |
271 | #endif // TOOLS_TOOL_LOOP_H_INCLUDED |
272 | |