module Path = Script_path type mode = | Edit | Selection of Selection.t | Out type worker_event = Worker_messages.from_worker (* The state cant hold functionnal values, and thus cannot be used to store elements like timer *) type state = { mode : mode ; paths : Outline.t list ; current : Path.Path_Builder.t ; width : float ; angle : float ; rendering : Layer.Paths.printer ; mouse_down_position : Gg.v2 } include Application.Make (struct type t = state end) let post : Brr_webworkers.Worker.t -> Worker_messages.to_worker -> unit = Brr_webworkers.Worker.post let insert_or_replace state ((x, y) as p) stamp path = let width = state.width and angle = state.angle in let point = Path.Point.create ~x ~y ~angle ~width ~stamp in match Path.Path_Builder.peek path with | None -> Path.Path_Builder.add_point point path | Some p1 -> let open Gg.V2 in let p1' = Path.Point.get_coord p1 in let dist = norm (p1' - of_tuple p) in if dist < 5. then path else Path.Path_Builder.add_point point path (** Select the given segment, and modify angle and width accordingly *) let select_segment _ (_, selected, p0, p1) state dist = let point' = Path.Point.mix dist (Path.Point.get_coord p0) p0 p1 in let angle = (Float.round @@ (10. *. Path.Point.get_angle point')) /. 10. and width = (Float.round @@ (10. *. Path.Point.get_width point')) /. 10. in let id = Selection.select_path selected in { state with mode = Selection id; angle; width } let init = { paths = [] ; current = Path.Path_Builder.empty ; mode = Out ; angle = 30. ; width = 10. ; rendering = `Fill ; mouse_down_position = Gg.V2.ox }