module State = Script_state.State module Selection = Script_state.Selection module Path = Script_path type t = { position : float * float ; timer : Elements.Timer.t } let process { position; timer } state = match state.State.mode with | Out -> let x, y = position in Elements.Timer.start timer 0.3; let width = state.width and angle = state.angle in let stamp = 0. in let point = match Selection.get_from_paths position state.paths with | _, None -> (* Start a new path with the point clicked *) Path.Point.create ~x ~y ~angle ~width ~stamp | _, Some (p, _, _, _) -> (* If the point is close to an existing path, we use the closest point in the path instead *) let x, y = Gg.V2.to_tuple p in Path.Point.create ~x ~y ~angle ~width ~stamp in let current = Path.Path_Builder.add_point point state.current in { state with current ; mode = Edit ; mouse_down_position = Gg.V2.of_tuple (x, y) } | Selection (Path id) | Selection (Point (id, _)) -> let get_any () = match Selection.get_from_paths position state.paths with | _, None -> { state with mode = Out ; mouse_down_position = Gg.V2.of_tuple position } | dist, Some selection -> let _, outline, _, _ = selection in if outline.Outline.id != id then let mouse_down_position = Gg.V2.of_tuple position in State.select_segment position selection { state with mouse_down_position } dist else (* On the same segment, check for a point *) let selection = Selection.select_point outline (Gg.V2.of_tuple position) in ( match selection with | Path _ -> { state with mode = Selection selection ; mouse_down_position = Gg.V2.of_tuple position } | Point (_, pt) -> (* In order to handle the point move, start the timer *) Elements.Timer.start timer 0.3; { state with mode = Selection selection ; angle = Path.Point.get_angle pt ; width = Path.Point.get_width pt ; mouse_down_position = Gg.V2.of_tuple position } ) in (* First, check for a point in the selected path. If any of them in found, check anything to select in all the elements *) ( match Outline.find state.paths id with | None -> get_any () | Some outline -> ( match Selection.select_point outline (Gg.V2.of_tuple position) with | Path _ -> get_any () | other -> Elements.Timer.start timer 0.3; { state with mode = Selection other ; mouse_down_position = Gg.V2.of_tuple position } ) ) | Edit -> state