aboutsummaryrefslogtreecommitdiff
path: root/script.it/state/state.ml
blob: 6c48979dc9cae52f2ea09a3d364af4473a588b7c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
module Path = Script_path

type mode =
  | Edit
  | Selection of Selection.t
  | Out

type worker_event = Worker_messages.from_worker

(*
 The state cant hold functionnal values, and thus cannot be used to store
 elements like timer
 *)
type state =
  { mode : mode
  ; paths : Outline.t list
  ; current : Path.Path_Builder.t
  ; width : float
  ; angle : float
  ; rendering : Layer.Paths.printer
  ; mouse_down_position : Gg.v2
  }

include Application.Make (struct
  type t = state
end)

let post : Brr_webworkers.Worker.t -> Worker_messages.to_worker -> unit =
  Brr_webworkers.Worker.post


let insert_or_replace state ((x, y) as p) stamp path =
  let width = state.width
  and angle = state.angle in
  let point = Path.Point.create ~x ~y ~angle ~width ~stamp in
  match Path.Path_Builder.peek path with
  | None -> Path.Path_Builder.add_point point path
  | Some p1 ->
      let open Gg.V2 in
      let p1' = Path.Point.get_coord p1 in

      let dist = norm (p1' - of_tuple p) in
      if dist < 5. then path else Path.Path_Builder.add_point point path


(** Select the given segment, and modify angle and width accordingly *)
let select_segment _ (_, selected, p0, p1) state dist =
  let point' = Path.Point.mix dist (Path.Point.get_coord p0) p0 p1 in

  let angle = (Float.round @@ (10. *. Path.Point.get_angle point')) /. 10.
  and width = (Float.round @@ (10. *. Path.Point.get_width point')) /. 10. in

  let id = Selection.select_path selected in
  { state with mode = Selection id; angle; width }


let init =
  { paths = []
  ; current = Path.Path_Builder.empty
  ; mode = Out
  ; angle = 30.
  ; width = 10.
  ; rendering = `Fill
  ; mouse_down_position = Gg.V2.ox
  }