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 if mouse_button.value == MouseAction/Release && mouse.capture.is_some then 17 let control = mouse.capture.unwrap.control 18 val event = MouseEvent/EndMove =x =y 19 control.push event 20 mouse.capture = None 21 22 if mouse.capture ? Some c then 23 let event = MouseEvent/Move x y c.x c.y c.relative_x c.relative_y 24 c.control.push event } 25 |> mouse.tokens.add 26 27 os_window.mouse_scrolls.subscribe { offset_x, offset_y -> 28 let (x, y) = os_window.get_mouse_position 29 let maybe_control = position_to_control x y { _.is_scrollable } 30 if maybe_control ? Some control then 31 val event = MouseEvent/Scroll offset_x offset_y 32 control.push event } 33 |> mouse.tokens.add 34 35 os_window.mouse_buttons.subscribe { button, action, _ -> case button of 36 MouseButton/Left -> 37 mouse_button.set action 38 let (x, y) = os_window.window.mouse_position 39 if action == MouseAction/Press then 40 let maybe_control = position_to_control x y { true } 41 let maybe_window = maybe_control.flat_map { try_window _ } 42 if maybe_window ? Some window then 43 bring_to_front window 44 45 let maybe_control = position_to_control 46 x y { control -> control.is_focusable 47 || control.is_clickable 48 || control.is_receive_mouse_move 49 || control.command.is_some 50 || (try_link control x y).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 not control.is_clickable then 76 let maybe_link = try_link control x y 77 if maybe_link ? Some link then 78 mouse.link_presses.push (action, control, link) 79 else 80 val event = MouseEvent/Button 81 =action 82 x = x as f32 - v.x |> as<u32> 83 y = y as f32 - v.y |> as<u32> 84 85 control.push event 86 87 if action == MouseAction/Press then 88 let event = MouseEvent/BeginMove =x =y 89 control.push event 90 91 if action == MouseAction/Release then 92 mouse.capture = None 93 94 else -> () } |> mouse.tokens.add 95 96 mouse 97 98 end@ mouse 99