summaryrefslogtreecommitdiff
path: root/script.it/script_event/click.ml
diff options
context:
space:
mode:
authorSébastien Dailly <sebastien@chimrod.com>2021-05-25 11:08:00 +0200
committerSébastien Dailly <sebastien@dailly.me>2022-02-07 16:22:43 +0100
commit6a75fb043ed30389fff1ce97fe20ee56b1c95066 (patch)
tree20e0c2cb39dffcf85449e0b810d773909c405a0e /script.it/script_event/click.ml
parent90f1f73f08b2d9231b2ee029b9e39dd570e36f36 (diff)
Update script.it project
Diffstat (limited to 'script.it/script_event/click.ml')
-rwxr-xr-xscript.it/script_event/click.ml91
1 files changed, 91 insertions, 0 deletions
diff --git a/script.it/script_event/click.ml b/script.it/script_event/click.ml
new file mode 100755
index 0000000..591887b
--- /dev/null
+++ b/script.it/script_event/click.ml
@@ -0,0 +1,91 @@
+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 update {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
+