summaryrefslogtreecommitdiff
path: root/script.it/state.ml
diff options
context:
space:
mode:
Diffstat (limited to 'script.it/state.ml')
-rwxr-xr-xscript.it/state.ml79
1 files changed, 43 insertions, 36 deletions
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)