I need to create a simple 2D designer where user can draw shapes (triangles, rectangles, polygons etc) and also change already created shapes. I have three main classes:
- Entity class
Area. Contains name, list of points (offsets) - Listenable
AreaControllerwhich exposesAreaControllerState. AreaControllerStatecontainsareasproperty. When it changes the listenable notifies listener.AreaCustomPainterusesAreaControllerStateto draw on 2D canvas.
The simple use case: User presses left mouse button as many times as he need to draw a polygon. The double click closes Area. The CustomPaint is re-drawn with new state. Then user may select a drawn shape. When the shape is selected the user moves mouse pointer over some shape vertex (point) which should be highlighted and mouse cursor also must be changed and then user can move that vertex (point) to change the original shape.
The challenge is hardness of aiming of the current mouse pointer to the specific vertex. So to make aiming easy I am going to create a round Path around the vertex with small radius and do check if this "point path" will contain mouse pointer. But here another challenge raised. Since the path radius is a CustomPainter responsibility. I can create point of any radius I want and AreaPainterController should not care which radius is used. The only thing controller should care it is its state which contains list of Areas (and cirtainly points).
But as mentioned above I need to to change the mouse cursor and I can only that from outside of painter class. So I need a way to make posible to know which radius is used for shape vertices paths in parent widget but I coud not figured out the correct one.
I have an idea to to use onPaint callback which will returns the required data but than I need to create a property which is not belongs to state (but simple widget state variable) and I think it is wrong because it looks like two states.
So how can I implement relations between objects which are responsible for their own functionality but one of them can inform another one in corresponding of SOLID principle?
Again I need a way to know the rounded Path (or radius of that path) of the point which is drawn in painter above this painter to have an ability to change mouse cursor.
The simple code:
Listenable(
onPointerHover: (event) {
// In this method I need to change the mouse cursor
// if mouse pointer belongs to the path around some area vertex.
_controller.handleMouseMove(event);
},
child: AnimatedBuilder(
animation: _controller.state,
builder: (context, child) {
return MouseRegion(
cursor: _controller.state.mouseCursor,
child CustomPaint(
painter: AreaPainter(
options: AreaPainterOptions(), // similar to theme.
state: _controller.state,
),
),
);
},
),
)
CustomPaintat all? if you want different shapes useShapeBorderand normalGestureDetectorsat each selected shape vertexInteractiveViewerthen - it seems that you want to "reinvent the wheel" - something like stackoverflow.com/questions/75090991/…line by line. I.e. mouse click (point) then move mouse, then click (point) etc... double click (the shape/room is ready). You may see the editor herehttps://www.sweethome3d.com/SweetHome3DJSOnline.jsp