1    local set_cursor_index (text_box : TextBox
2                            prev_i : u32
3                            i : u32
4                            is_mouse_move : bool
5                            is_move : bool) =
6        if text_box.os_window.is_shift_pressed && is_move || is_mouse_move then
7            if prev_i <> i then
8                let length = text_box.display_text.length
9                let prev_selection = text_box.selection
10               let left = i.min length |> min prev_i
11               let right = i.min length |> max prev_i
12               let (min, max) = case prev_selection of
13                   None -> (left, right)
14                   Some (prev_min, prev_max) ->
15                       if i > prev_i then
16                           if prev_i == prev_max
17                           then (prev_min, right)
18                           else (prev_max.min right, prev_max.max right)
19                       else
20                           if prev_i == prev_min
21                           then (left, prev_max)
22                           else (left.min prev_min, left.max prev_min)
23   
24               let selection = if min == max then None else Some (min, max)
25               text_box.selection = selection
26       else
27           text_box.selection = None
28   
29       text_box.cursor_index = i
30       text_box.update_offset
31   
32   let char_offset (text_block : TextBlock) (index : u32) =
33       let value = text_block.offsets[index]
34       (left = value.left, up = value.up)
35   
36   let create_cursor (text_box : TextBox) =
37       let text_block = text_box.text_block
38       let canvas = text_box.canvas
39   
40       let cursor = QuadControl
41           is_visible = text_box.is_focused
42           size@obs =
43               let width = text_block.font_size@obs / 2 + 1
44               let height = width / 4 |> max 2
45               Size width height
46   
47       let height = Atom<u32> text_box.height
48       text_box.subscribe { _, event -> if event ? SizeEvent/Height h then
49           height.set h }
50   
51       (text_box.cursor_index@atom, height)
52       |> to_atom
53       |> bind { i, h ->
54           let offset = char_offset text_block i
55           let v = Vector3
56               x = offset.left as f32 + text_box.offset as f32
57               y = h as f32 - (h as f32 * 0.2).round
58               z = Control.offset_z * 2
59   
60           cursor.position = v } |> text_box.push_token
61   
62       text_box.offset_controls.add cursor
63       canvas.items.add cursor
64       cursor
65   
66   type TextBox
67       local move_cursor (x : u32) (is_mouse_move : bool) =
68           let maybe_index = text_block.offsets.try_find_index
69               { _.left as i32 >= x as i32 - offset }
70   
71           let index = case maybe_index of
72               None -> display_text.length
73               Some index -> if index == 0 then 0 else index - 1
74   
75           set_cursor_index self cursor_index
76                            index.as<u32> is_mouse_move true
77   
78       val cursor = create_cursor self
79