use crate::rendering::{Cell, Theme, VideoBuffer};
pub struct SimpleInput {
pub text: String,
pub cursor_position: usize,
pub max_length: usize,
}
impl SimpleInput {
pub fn new(initial_text: &str, max_length: usize) -> Self {
let text = initial_text.to_string();
let cursor_position = text.len();
Self {
text,
cursor_position,
max_length,
}
}
pub fn insert_char(&mut self, c: char) {
if self.text.len() < self.max_length && c.is_ascii_alphanumeric() || c == '_' || c == '-' {
self.text.insert(self.cursor_position, c);
self.cursor_position += 1;
}
}
pub fn delete_char(&mut self) {
if self.cursor_position > 0 {
self.text.remove(self.cursor_position - 1);
self.cursor_position -= 1;
}
}
pub fn delete_char_forward(&mut self) {
if self.cursor_position < self.text.len() {
self.text.remove(self.cursor_position);
}
}
pub fn move_cursor_left(&mut self) {
if self.cursor_position > 0 {
self.cursor_position -= 1;
}
}
pub fn move_cursor_right(&mut self) {
if self.cursor_position < self.text.len() {
self.cursor_position += 1;
}
}
pub fn move_cursor_home(&mut self) {
self.cursor_position = 0;
}
pub fn move_cursor_end(&mut self) {
self.cursor_position = self.text.len();
}
#[allow(dead_code)]
pub fn get_text(&self) -> &str {
&self.text
}
pub fn render(
&self,
buffer: &mut VideoBuffer,
x: u16,
y: u16,
field_width: u16,
theme: &Theme,
focused: bool,
) {
let bg = if focused {
theme.slight_input_bg
} else {
theme.config_content_bg
};
let fg = if focused {
theme.slight_input_fg
} else {
theme.config_content_fg
};
buffer.set(x, y, Cell::new('[', fg, theme.config_content_bg));
let inner_width = field_width.saturating_sub(2) as usize; for i in 0..inner_width {
let ch = self.text.chars().nth(i).unwrap_or(' ');
let cell_bg = if focused && i == self.cursor_position {
fg } else {
bg
};
let cell_fg = if focused && i == self.cursor_position {
bg } else {
fg
};
buffer.set(x + 1 + i as u16, y, Cell::new(ch, cell_fg, cell_bg));
}
buffer.set(
x + field_width - 1,
y,
Cell::new(']', fg, theme.config_content_bg),
);
}
}