Make text input cursor moveable

This commit is contained in:
Joscha 2022-02-21 02:10:51 +01:00
parent 28c3241fd9
commit ef019dc887

View file

@ -24,23 +24,64 @@ impl StatefulWidget for TextLine {
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct TextLineState { pub struct TextLineState {
content: String, content: String,
cursor: usize,
} }
impl TextLineState { impl TextLineState {
pub fn set_cursor<B: Backend>(&self, f: &mut Frame<B>, area: Rect) { pub fn set_cursor<B: Backend>(&self, f: &mut Frame<B>, area: Rect) {
let x = area.x + (self.content.width() as u16); let prefix = self.content.chars().take(self.cursor).collect::<String>();
let x = cmp::min(x, area.x + area.width); let position = prefix.width() as u16;
let x = area.x + cmp::min(position, area.width);
f.set_cursor(x, area.y); f.set_cursor(x, area.y);
} }
fn chars(&self) -> usize {
self.content.chars().count()
}
fn move_cursor_start(&mut self) {
self.cursor = 0;
}
fn move_cursor_left(&mut self) {
if self.cursor > 0 {
self.cursor -= 1;
}
}
fn move_cursor_right(&mut self) {
self.cursor = cmp::min(self.cursor + 1, self.chars());
}
fn move_cursor_end(&mut self) {
self.cursor = self.chars();
}
fn cursor_byte_offset(&self) -> usize {
self.content
.char_indices()
.nth(self.cursor)
.map(|(i, _)| i)
.unwrap_or_else(|| self.content.len())
}
pub fn process_input(&mut self, event: Event) { pub fn process_input(&mut self, event: Event) {
if let Event::Key(k) = event { if let Event::Key(k) = event {
match k.code { match k.code {
KeyCode::Backspace => { KeyCode::Backspace if self.cursor > 0 => {
self.content.pop(); self.move_cursor_left();
self.content.remove(self.cursor_byte_offset());
}
KeyCode::Left => self.move_cursor_left(),
KeyCode::Right => self.move_cursor_right(),
KeyCode::Home => self.move_cursor_start(),
KeyCode::End => self.move_cursor_end(),
KeyCode::Delete if self.cursor < self.chars() => {
self.content.remove(self.cursor_byte_offset());
} }
KeyCode::Char(c) => { KeyCode::Char(c) => {
self.content.push(c); self.content.insert(self.cursor_byte_offset(), c);
self.move_cursor_right();
} }
_ => {} _ => {}
} }