Make text input cursor moveable
This commit is contained in:
parent
28c3241fd9
commit
ef019dc887
1 changed files with 46 additions and 5 deletions
|
|
@ -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();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue