1 type MultilineTextBox 2 def update_offset self = 3 let text_box_width = self.scissor_control.width as i32 4 let prev_offset = self.offset 5 6 let text_display = self.text_display 7 if text_display.has_text then 8 let cursor_width = text_display.advance as i32 9 let content_width = text_display.width as i32 10 let overflows = content_width > text_box_width 11 if overflows || prev_offset <> 0 then 12 self.offset = if overflows then 13 let cursor_pos = self.cursor_pos 14 let right_margin = text_display.margin.right as i32 15 let max_cursor_left = text_box_width - right_margin - cursor_width 16 let current_cursor_left = text_display.bounds cursor_pos |> left 17 18 let left_offset = text_display.margin.left 19 let cursor_left = text_display.bounds cursor_pos 20 |> left - left_offset 21 22 let cursor_right = text_display.bounds cursor_pos |> right 23 24 if cursor_left as i32 + prev_offset >= 0 25 && cursor_right as i32 + prev_offset < text_box_width 26 then 27 let line_length = self.display_text[cursor_pos.line].length 28 let text_pos = TextPos cursor_pos.line (line_length - 1) 29 let max_index_left = text_display.bounds text_pos 30 |> left 31 32 let min_offset = max_cursor_left - max_index_left as i32 33 |> min 0 34 35 let u = prev_offset.max min_offset 36 37 if current_cursor_left as i32 - max_cursor_left < -u 38 then u 39 else max_cursor_left - current_cursor_left as i32 40 else 41 let left_diff = if cursor_left as i32 > -prev_offset 42 then 0 43 else -cursor_left.as<i32> - prev_offset 44 45 let right_diff = 46 if cursor_right as i32 + prev_offset < text_box_width 47 then 0 48 else max_cursor_left - current_cursor_left as i32 49 - prev_offset 50 51 assert left_diff == 0 || right_diff == 0 52 prev_offset + left_diff + right_diff 53 else 54 0 55 56 let diff = self.offset - prev_offset 57 for control in self.offset_controls do 58 let v = control.position 59 control.position = v.with_x (v.x + diff as f32) 60 61 scissor_control.subscribe { _, event -> if event ? SizeEvent/Width _ then 62 update_offset } 63