aboutsummaryrefslogtreecommitdiff
path: root/script.it/script_event/out.ml
blob: b8b8599c3df08a8185592c5bd18261126b64fb30 (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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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
         }

(** Long click, move the selected element if any *)
let longClick 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 slate *)
  | _ -> state

let apply {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

  | _ ->
    longClick point state worker state.mode