1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#[derive(Default)]
pub struct TextInput {
pub text: String,
pub cursor_position: usize,
}
impl TextInput {
pub fn move_cursor_left(&mut self) {
let cursor_moved_left = self.cursor_position.saturating_sub(1);
self.cursor_position = self.clamp_cursor(cursor_moved_left);
}
pub fn move_cursor_right(&mut self) {
let cursor_moved_right = self.cursor_position.saturating_add(1);
self.cursor_position = self.clamp_cursor(cursor_moved_right);
}
pub fn enter_char(&mut self, new_char: char) {
if !new_char.is_ascii() {
return;
}
self.text.insert(self.cursor_position, new_char);
self.move_cursor_right();
}
pub fn enter_str(&mut self, string: &str) {
for char in string.chars() {
self.enter_char(char)
}
}
pub fn delete_char_backward(&mut self) {
let is_not_cursor_leftmost = self.cursor_position != 0;
if is_not_cursor_leftmost {
// Method "remove" is not used on the saved text for deleting the selected char.
// Reason: Using remove on String works on bytes instead of the chars.
// Using remove would require special care because of char boundaries.
let current_index = self.cursor_position;
let from_left_to_current_index = current_index - 1;
// Getting all characters before the selected character.
let before_char_to_delete = self.text.chars().take(from_left_to_current_index);
// Getting all characters after selected character.
let after_char_to_delete = self.text.chars().skip(current_index);
// Put all characters together except the selected one.
// By leaving the selected one out, it is forgotten and therefore deleted.
self.text = before_char_to_delete.chain(after_char_to_delete).collect();
self.move_cursor_left();
}
}
pub fn delete_char_forward(&mut self) {
let is_not_cursor_rightmost = self.cursor_position != self.text.len();
if is_not_cursor_rightmost {
// Method "remove" is not used on the saved text for deleting the selected char.
// Reason: Using remove on String works on bytes instead of the chars.
// Using remove would require special care because of char boundaries.
let current_index = self.cursor_position;
// Getting all characters before the selected character.
let before_char_to_delete = self.text.chars().take(current_index);
// Getting all characters after selected character.
let after_char_to_delete = self.text.chars().skip(current_index + 1);
// Put all characters together except the selected one.
// By leaving the selected one out, it is forgotten and therefore deleted.
self.text = before_char_to_delete.chain(after_char_to_delete).collect();
}
}
pub fn clamp_cursor(&self, new_cursor_pos: usize) -> usize {
new_cursor_pos.clamp(0, self.text.len())
}
pub fn reset_cursor(&mut self) {
self.cursor_position = 0;
}
pub fn reset_input(&mut self) {
self.text.clear();
self.reset_cursor();
}
}