module State = Script_state.State module Selection = Script_state.Selection (** Handle a click outside of the selection *) type t = { point : float * float ; timer : Elements.Timer.t ; worker : Brr_webworkers.Worker.t } (** The drag function is incorrectly named, as we dont't care if we are selecting an element or not. But, in the case we are (point, path…), we effectively move the element with the mouse. *) let drag mouse_coord state worker = function | State.Selection t -> let mouse_v2 = Gg.V2.of_tuple mouse_coord in begin match Selection.find_selection t state.State.paths with | None -> state | Some (Point (path, point)) -> let point' = Path.Point.copy point mouse_v2 in State.post worker (`TranslatePoint (point', path)); (* Just replace the position of the selected point *) { state with mode = Selection (Point (path.id, point')) } | Some (Path path) -> let delta = Gg.V2.(mouse_v2 - state.State.mouse_down_position) in State.post worker (`TranslatePath (path, delta)); state end (* TODO Long click in out mode should translate the whole slate *) | _ -> state let process {point; timer ; worker} state = match state.State.mode with | Edit -> let stamp = Elements.Timer.delay timer in Elements.Timer.stop timer; begin match Path.Path_Builder.peek2 state.current with (* If there is at last two points selected, handle this as a curve creation. And we add the new point in the current path *) | Some _ -> let current = State.insert_or_replace state point stamp state.current in let path = Path.Fixed.to_fixed (module Path.Path_Builder) current in (* Create a copy from the path with all the interior points *) let back = Path.Fixed.map path (fun pt -> Path.Point.copy pt @@ Path.Point.get_coord' pt) in let last = Outline.{ path ; back ; id = Outline.get_id () } in (* Send to the worker for a full review *) let () = State.post worker (`Complete last) in let state = { state with mode = Out ; paths = last::state.paths ; current = Path.Path_Builder.empty } in state (* Else, check if there is a curve under the cursor, and remove it *) | None -> let current = Path.Path_Builder.empty in begin match Selection.get_from_paths point state.paths with | _, None -> { state with mode = Out ; current } | dist, Some selection -> State.select_segment point selection { state with current } dist end end | _ when Elements.Timer.delay timer < 0.3 -> state | _ -> drag point state worker state.mode