1    object Mouse =
2        def create (os_window : OsWindow
3                    popups : List<Control>
4                    controls : List<Control>
5                    focus : mut Atom<Option<Control>>) =
6            let position_to_control : u32 * u32 * (Control -> bool) -> Option<Control> =
7                { x y f -> get_control popups x y
8                           |> or_else { get_control controls x y }
9                           |> flat_map { find_control _ x y f } }
10   
11           let mouse = Mouse =position_to_control
12           let mouse_button = Atom MouseAction/Release
13   
14           os_window.mouse_positions.subscribe { x, y ->
15               mouse.position = (x, y)
16                     update_hovered
17               if mouse_button.value == MouseAction/Release && mouse.capture.is_some then
18                   let control = mouse.capture.unwrap.control
19                   val event = MouseEvent/EndMove =x =y
20                   control.push event
21                   mouse.capture = None
22   
23               if mouse.capture ? Some c then
24                   let event = MouseEvent/Move x y c.x c.y c.relative_x c.relative_y
25                   c.control.push event }
26           |> mouse.tokens.add
27   
28           os_window.mouse_scrolls.subscribe { offset_x, offset_y ->
29               let (x, y) = os_window.get_mouse_position
30               let maybe_control = position_to_control x y { _.is_scrollable }
31               if maybe_control ? Some control then
32                   val event = MouseEvent/Scroll offset_x offset_y
33                   control.push event }
34           |> mouse.tokens.add
35   
36           os_window.mouse_buttons.subscribe { button, action, _ -> case button of
37               MouseButton/Left ->
38                   mouse_button.set action
39                   let (x, y) = os_window.window.mouse_position
40                   if action == MouseAction/Press then
41                       let maybe_control = position_to_control x y { true }
42                       let maybe_window = maybe_control.flat_map { try_window _ }
43                       if maybe_window ? Some window then
44                           bring_to_front window
45   
46                   let maybe_control = position_to_control
47                       x y { control -> control.is_focusable
48                                        || control.is_clickable
49                                        || control.is_receive_mouse_move
50                                        || control.command.is_some }
51   
52                   case maybe_control
53                   of   None ->
54                       if action == MouseAction/Press then
55                           focus.set None
56   
57                   else Some control ->
58                       let v = control.global_position
59                       if action == MouseAction/Press then
60                           let maybe_focusable = find_focusable control
61                           if maybe_focusable.is_some then
62                               focus.set maybe_focusable
63   
64                           let capture = Capture
65                               =x =y
66                               relative_x = x as f32 - v.x |> as<u32>
67                               relative_y = y as f32 - v.y |> as<u32>
68                               =control
69   
70                           mouse.capture = capture
71   
72                       if control.command.is_some then
73                           mouse.presses.push (action, control)
74   
75                       else if control.is_clickable then
76                           val event = MouseEvent/Button
77                               =action
78                               x = x as f32 - v.x |> as<u32>
79                               y = y as f32 - v.y |> as<u32>
80   
81                           control.push event
82   
83                       if action == MouseAction/Press then
84                           let event = MouseEvent/BeginMove =x =y
85                           control.push event
86   
87                   if action == MouseAction/Release then
88                       mouse.capture = None
89   
90               else -> () } |> mouse.tokens.add
91   
92           mouse
93   
94   endmodule mouse
95   
96   import mouse/Mouse
97                bring_to_front
98