Add configurable grid + snap to the layout system
Two independent grids, each with a size and a snap toggle: - Garden grid (owner-set, in the garden settings form): drives the editor's visual grid and, when snapping is on, snaps objects on place/move and snaps their dimensions to whole grid steps on resize. - Bed grid (per plantable object, in the bed Inspector): when snapping is on, plants snap to the bed's grid on place/move, and the grid is drawn inside the focused bed. Plant radius stays free. Snapping defaults off on both, so existing gardens keep free placement. Grid spacing shares the [1cm, 100m] range and defaults to 1m (garden) / 30cm (bed); 0 is treated as unset and re-defaulted. Backend: migration 0005 adds grid_size_cm/snap_to_grid to gardens and garden_objects, threaded through domain/store/service/api with service + api round-trip tests. Frontend: new geometry snap helpers (unit-tested), schema/type plumbing, canvas + overlay snapping, and the two forms. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01JdQpdYYsTgtkJBxbcpAszi
This commit is contained in:
@@ -27,6 +27,8 @@ type objectCreateRequest struct {
|
||||
Plantable *bool `json:"plantable"`
|
||||
Color *string `json:"color"`
|
||||
Props json.RawMessage `json:"props"`
|
||||
GridSizeCM float64 `json:"gridSizeCm"`
|
||||
SnapToGrid bool `json:"snapToGrid"`
|
||||
Notes string `json:"notes"`
|
||||
}
|
||||
|
||||
@@ -35,7 +37,8 @@ func (r objectCreateRequest) toInput() service.ObjectInput {
|
||||
Kind: r.Kind, Name: r.Name, Shape: r.Shape,
|
||||
XCM: r.XCM, YCM: r.YCM, WidthCM: r.WidthCM, HeightCM: r.HeightCM,
|
||||
RotationDeg: r.RotationDeg, ZIndex: r.ZIndex, Plantable: r.Plantable,
|
||||
Color: r.Color, Props: propsFromRaw(r.Props), Notes: r.Notes,
|
||||
Color: r.Color, Props: propsFromRaw(r.Props),
|
||||
GridSizeCM: r.GridSizeCM, SnapToGrid: r.SnapToGrid, Notes: r.Notes,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +57,8 @@ type objectUpdateRequest struct {
|
||||
Plantable *bool `json:"plantable"`
|
||||
Color json.RawMessage `json:"color"`
|
||||
Props json.RawMessage `json:"props"`
|
||||
GridSizeCM *float64 `json:"gridSizeCm"`
|
||||
SnapToGrid *bool `json:"snapToGrid"`
|
||||
Notes *string `json:"notes"`
|
||||
Version int64 `json:"version" binding:"required,min=1"`
|
||||
}
|
||||
@@ -67,7 +72,8 @@ func (r objectUpdateRequest) toPatch() (service.ObjectPatch, error) {
|
||||
return service.ObjectPatch{
|
||||
Name: r.Name, XCM: r.XCM, YCM: r.YCM, WidthCM: r.WidthCM, HeightCM: r.HeightCM,
|
||||
RotationDeg: r.RotationDeg, ZIndex: r.ZIndex, Plantable: r.Plantable,
|
||||
SetColor: setColor, Color: color, SetProps: setProps, Props: props, Notes: r.Notes,
|
||||
SetColor: setColor, Color: color, SetProps: setProps, Props: props,
|
||||
GridSizeCM: r.GridSizeCM, SnapToGrid: r.SnapToGrid, Notes: r.Notes,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user