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 -> 8 case get_control popups x y |> or_else { get_control controls x y } of 9 None -> None 10 Some u -> find_control u x y f } 11 12 let mouse = Mouse =position_to_control 13 let mouse_button = Atom MouseAction/Release 14 15 os_window.mouse_positions.subscribe { x, y -> 16 mouse.position = (x, y) 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 || (try_link control x y).is_some } 52 53 case maybe_control 54 of None -> 55 if action == MouseAction/Press then 56 focus.set None 57 58 else Some control -> 59 let v = control.global_position 60 if action == MouseAction/Press then 61 let maybe_focusable = find_focusable control 62 if maybe_focusable.is_some then 63 focus.set maybe_focusable 64 65 let capture = Capture 66 =x =y 67 relative_x = x as f32 - v.x |> as<u32> 68 relative_y = y as f32 - v.y |> as<u32> 69 =control 70 71 mouse.capture = capture 72 73 if control.command.is_some then 74 mouse.presses.push (action, control) 75 76 else if not control.is_clickable then 77 let maybe_link = try_link control x y 78 if maybe_link ? Some link then 79 mouse.link_presses.push (action, control, link) 80 else 81 val event = MouseEvent/Button 82 =action 83 x = x as f32 - v.x |> as<u32> 84 y = y as f32 - v.y |> as<u32> 85 86 control.push event 87 88 if action == MouseAction/Press then 89 let event = MouseEvent/BeginMove =x =y 90 control.push event 91 92 if action == MouseAction/Release then 93 mouse.capture = None 94 95 else -> () } |> mouse.tokens.add 96 97 mouse 98 99 end@ mouse 100