1 let contains_mouse (control : Control 2 x : u32 3 y : u32) = 4 let position = control.global_position 5 let width = control.width 6 let height = control.height 7 8 x as f32 >= position.x 9 && y as f32 >= position.y 10 && x as f32 < position.x + width as f32 11 && y as f32 < position.y + height as f32 12 13 local find_control (control : Control 14 x : u32 15 y : u32 16 f : Control -> bool) : Option<Control> = 17 let slice = case control of 18 is Container -> control.get_slice 19 else -> SafeSlice<Control>.empty 20 21 let controls = if slice.size == 0 then 22 List<Control>.empty 23 else 24 slice 25 |> filter { item -> item.is_visible && contains_mouse item x y } 26 |> map { find_control _ x y f } 27 |> filter { _.is_some } 28 |> map { _.unwrap } 29 30 when 31 controls.size > 1 -> controls.min_by { _.global_position.z } |> Some 32 controls.size == 1 -> Some controls[0] 33 else -> if f control 34 then Some control 35 else None 36 37 local find_focusable (control : Control) : Option<Control> = 38 if control.is_focusable then 39 Some control 40 else 41 case control.parent of 42 Some parent -> find_focusable parent 43 None -> None 44 45 local get_control (controls : List<Control> 46 x : u32 47 y : u32) = 48 let maybe_index = controls.try_find_index 49 { control -> control.is_visible && contains_mouse control x y } 50 51 case maybe_index of 52 None -> None 53 Some index -> Some controls[index] 54 55 local try_link (control : Control 56 x : u32 57 y : u32) = 58 if control is not TextBlock then 59 return None 60 61 let text_block = control as TextBlock 62 if text_block.links.is_none || text_block.linked.is_none then 63 return None 64 65 if text_block.links ? Some links then 66 let global_position = text_block.global_position 67 let relative_x = x as i32 - global_position.x as i32 |> as<u32> 68 let relative_y = y as i32 - global_position.y as i32 |> as<u32> 69 let mut index = 0 70 for bounds in links do 71 if relative_x >= bounds.left 72 && relative_x <= bounds.right 73 && relative_y >= bounds.up 74 && relative_y <= bounds.down 75 then 76 return Some index 77 78 index += 1 79 80 None 81 82 local try_window (control : Control) : Option<Window> = 83 let maybe_parent = control.parent 84 case maybe_parent of 85 None -> None 86 Some parent -> 87 if parent is Window 88 then Some parent 89 else try_window parent 90 91 def bring_to_front (window : Window) = 92 let canvas = window.parent.unwrap as Canvas 93 let items = canvas.items 94 if window as Control <> items[0] then 95 items.remove window 96 items.add 0 window 97 let mut z = Control.window_z 98 for i = items.size - 1 downto 0 do 99 let item = items[i] 100 item.set_z z 101 z += Control.window_z 102