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