From a63662059215a26db627c4b76147a3c9338f5b74 Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Wed, 6 Jan 2021 22:09:53 +0100 Subject: Point suppression --- script.it/state.ml | 79 +++++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 36 deletions(-) (limited to 'script.it/state.ml') diff --git a/script.it/state.ml b/script.it/state.ml index 53cc861..f08c3a1 100755 --- a/script.it/state.ml +++ b/script.it/state.ml @@ -5,7 +5,7 @@ let backgroundColor = Blog.Nord.nord0 type mode = | Edit - | Selection of int + | Selection of Selection.t | Out (** Events *) @@ -76,21 +76,6 @@ let insert_or_replace state ((x, y) as p) stamp path = let threshold = 20. -let check_selection - : (float * float) -> Path.Fixed.t list -> (Gg.v2 * Path.Fixed.t * Path.Point.t * Path.Point.t) option - = fun position paths -> - let point = Gg.V2.of_tuple position in - (* If the user click on a curve, select it *) - let _, res = List.fold_left paths - ~init:(threshold, None) - ~f:(fun (dist, selection) path -> - match Path.Fixed.distance point path with - | Some (point', p, p0, p1) when p < dist -> - dist, Some (point', path, p0, p1) - | _ -> dist, selection - ) in - res - (** Update the path in the selection with the given function applied to every point *) let update_selection id state f = @@ -105,18 +90,17 @@ let update_selection id state f = { state with paths } -let select_segment point (p, selected, p0, p1) state = +(** Select the given segment, and modify angle and width accordingly *) +let select_segment _ (_, selected, p0, p1) state dist = let angle0 = Path.Point.get_angle p0 and angle1 = Path.Point.get_angle p1 in let width0 = Path.Point.get_width p0 and width1 = Path.Point.get_width p1 in - let dist = Gg.V2.(norm ( p - (Gg.V2.of_tuple point))) in - let angle = angle0 +. dist *. ( angle1 -. angle0 ) in let width = width0 +. dist *. ( width1 -. width0 ) in - let id = Path.Fixed.id selected in + let id = Selection.select_path selected in { state with mode = (Selection id) ; angle @@ -144,11 +128,11 @@ let do_action let stamp = 0. in let point = - match check_selection p state.paths with - | None -> + match Selection.get_from_paths p state.paths with + | _, None -> (* Start a new path with the point clicked *) Path.Point.create ~x ~y ~angle ~width ~stamp - | Some (p, _, _, _) -> + | _, 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 @@ -162,13 +146,20 @@ let do_action (* Click anywhere while in selection mode, we either select another path, or switch to Out mode*) - | `Click position, (Selection _) -> - begin match check_selection position state.paths with - | None -> + | `Click position, (Selection (Path id)) + | `Click position, (Selection (Point (id, _))) -> + begin match Selection.get_from_paths position state.paths with + | _, None -> { state with mode = Out } - | Some selection -> - select_segment position selection state + | dist, Some selection -> + let _, path, _, _ = selection in + if Path.Fixed.id path != id then + select_segment position selection state dist + else + (* On the same segment, check for a point *) + let selection = Selection.select_point path (Gg.V2.of_tuple position) in + {state with mode= Selection selection} end | `Out point, Edit -> @@ -200,21 +191,37 @@ let do_action (* Else, check if there is a curve under the cursor, and remove it *) | None -> let current = Path.Path_Builder.empty in - begin match check_selection point state.paths with - | None -> + begin match Selection.get_from_paths point state.paths with + | _, None -> { state with mode = Out ; current } - | Some selection -> - select_segment point selection { state with current } + | dist, Some selection -> + select_segment point selection { state with current } dist end end - | `Delete, Selection id -> - let paths = List.filter state.paths ~f:(fun p -> Path.Fixed.id p != id) in + | `Delete, Selection (Path id) -> + let paths = List.filter + state.paths + ~f:(fun p -> + Path.Fixed.id p != id + ) in { state with paths ; mode = Out} + | `Delete, Selection (Point (id, point)) -> + List.iter + state.paths + ~f:(fun p -> + let id' = Path.Fixed.id p in + match id' = id with + | false -> () + | true -> + (* Send the job to the worker *) + Brr_webworkers.Worker.post worker (`DeletePoint (id, point, p)) + ); + state | `Export, _ -> @@ -253,10 +260,10 @@ let do_action state (* Change the select curve with the appropriate setting *) - | `Angle angle, Selection s -> + | `Angle angle, Selection (Path s) -> let state = { state with angle } in update_selection s state (fun p -> Path.Point.set_angle p angle) - | `Width width, Selection s -> + | `Width width, Selection (Path s) -> let state = { state with width } in update_selection s state (fun p -> Path.Point.set_width p width) -- cgit v1.2.3