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