maptool
maptool copied to clipboard
Decompose drawing, expose, and topology tools
Identify the Bug or Feature request
Supports #3691 Partially addresses #5004 (just for drawings) Fixes #4218
Description of the Change
This PR replaces the deep AbstractDrawingTool
hierarchy strategy-based classes. The goal here is to consolidate each tool's logic so it takes fewer lines of code and isn't spread across several classes, while still reusing code. Future work for #3691 will build off this now that it is easier to change the rendering logic of each tool.
The drawing tools, FoW expose tools, and topology tools have all been refactored. There are now only three tool classes for all of them:
-
DrawingTool
, for any drawing tool -
ExposeTool
, for any FoW expose tool -
TopologyTool
for any topology tool
The different shape are obtained by strategies that can be plugged into the above tools:
-
RectangleStrategy
for drawing any type of rectangle -
OvalStrategy
for drawing any type of ellipse -
IsoRectangleStrategy
for drawing any type of isometric rectangle -
PolyLineStrategy
for drawing any type of polylines, polygons, and freehand lines. -
CrossStrategy
for drawing any type of X (only used for topology right now)
These strategies produce idealized shapes, which in practice are Rectangle
and Path2D
. They can be used for either hollow or filled shapes, which is why there is only one of each. It is up to the tool itself to decide whether to fill the shape, whether it needs a stroke, and what the final shape means. The strategies can also optionally provide measurements of their shape, which is how the drawing and expose tools now show those.
These new tools provide the user with more of a WYSIWYG experience: the temporary shape drawn by the tool will exactly match the final outcome. This effects a lot of the tools, but is especially noticable for the ellipse topology tool - it results in a decagon, and the tool now shows the user the exact decagon they will end up with, rather than showing them a larger idealized ellipse.
The implementation of the template tools have not been touched as they are quite different and would be a lot of extra effort. I plan to do something about them in a separate PR.
Supporting changes
Toolbox
The toolbox used to only work with tool classes, which forces the need for the deep tool hierarchies. In order to make it work for the new strategized tools, the toolbox was extended to allow adding Tool
instances. The behaviour is much the same, except that it is not possible to look up an instance-based tool by its Class<?>
.
Legacy drawings
These Drawable
implementations were only used by the tools and therefore are no longer used:- Cross
-
Oval
-
Rectangle
They have all been marked @Deprecated
to discourage any further use. Because they might have somehow been serialized in existing campaigns, they have been kept around, but reduced to just their fields and no behaviour. They all use readResolve()
to replace themselves with a ShapeDrawable
instead.
Protobuf
The set of shapes representable in protobuf was expanded slightly:
-
Path2D
can now be sent in addition toArea
. This was originally meant to be used in this change, though in the end it was not necessary. But I decided it was still worth keeping around sincePath2D
andArea
share the same logic. - Any
Ellipse2D
and be sent, not justEllipse2D.Float
. On the other end, it will be mapped back to aEllipse2D.Double
.
The Ellipse2D
had some knock-on effects. The trivial one is that we now use Ellipse2D.Double
everywhere and never use Ellipse2D..Float
anymore. Another issue is that we actually rely on our ellipses being backed by a class with the simple name "Float"
, as it is for in Ellipse2D.Float
. Some of these examples were doing type checks this way and have been updated to use instanceof Ellipse2D
instead. Other places genuinely needed a string from a ShapeDrawable
, so there is now a ShapeDrawable.getShapeTypeName()
that will return a name for any support type, with ellipses being given the name "Oval"
.
Possible Drawbacks
This is a big change, so there's a chance I missed something in testing that doesn't work quite how it used to.
Because of the slight differences in drawing, expose, and topolgy tool behaviour (see #5002), there is some logic duplication between these tools. It's more of a mess to try avoid this. If we ever implement #5002, the tools can be simplified quite a bit further.
Documentation Notes
N/A
Release Notes
- Updated drawing, FoW, and topology tools to show the actual shape that will be produced.
- Fixed a bug where the snap-to-grid and eraser toggle buttons for drawings were specific to each tool.