diff --git a/examples/05_edit_field.rs b/examples/05_edit_field.rs new file mode 100644 index 0000000..c16b570 --- /dev/null +++ b/examples/05_edit_field.rs @@ -0,0 +1,15 @@ +use rcui::*; + +fn main() { + Rcui::exec(Proxy::wrap( + |field, rcui, event| { + if let Event::KeyStroke(key) = event { + if *key as u8 as char == '\n' { + rcui.quit() + } + } + field.handle_event(rcui, event) + }, + EditField::new(), + )) +} diff --git a/src/edit_field.rs b/src/edit_field.rs index 52fea3e..94b378d 100644 --- a/src/edit_field.rs +++ b/src/edit_field.rs @@ -1 +1,49 @@ -// TODO(#10): EditField is not implemented +use super::*; + +#[derive(Default)] +pub struct EditField { + text: String, + buffer: Vec, + // TODO(#34): EditField does not have any cursor functionality +} + +impl EditField { + pub fn new() -> Self { + Self { + text: String::new(), + buffer: Vec::new(), + } + } + + pub fn wrap() -> Box { + Box::new(Self::new()) + } +} + +impl Widget for EditField { + fn render(&mut self, _context: &mut Rcui, rect: &Rect, _active: bool) { + let x = rect.x.floor() as i32; + let y = rect.y.floor() as i32; + mv(y, x); + // TODO(#35): EditField does not wrap during the rendering + addstr(&self.text); + } + + fn handle_event(&mut self, _context: &mut Rcui, event: &Event) { + // TODO(#37): move the utf8 buffer mechanism to the main event loop + if let Event::KeyStroke(key) = event { + self.buffer.push(*key as u8); + match std::str::from_utf8(&self.buffer) { + Ok(s) => { + self.text.push_str(&s); + self.buffer.clear() + } + Err(_) => { + if self.buffer.len() >= 4 { + self.buffer.clear() + } + } + } + } + } +} diff --git a/src/item_list.rs b/src/item_list.rs index fa0e61a..26216e6 100644 --- a/src/item_list.rs +++ b/src/item_list.rs @@ -82,7 +82,6 @@ impl Widget for ItemList { }; attron(COLOR_PAIR(color_pair)); - // TODO(#17): ItemList should extend cursor to the whole available width let x = rect.x.floor() as i32; let y = (rect.y + i as f32).floor() as i32; let w = rect.w.floor() as usize; diff --git a/src/lib.rs b/src/lib.rs index 5d6184d..d72fc7e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,11 +74,17 @@ impl Rcui { self.event_queue.push_back(event); } + // TODO(#36): no support for nested event loops via Rcui::exec() + pub fn exec(mut ui: Box) { let mut context = Self::new(); + let locale_conf = LcCategory::all; + setlocale(locale_conf, "en_US.UTF-8"); + initscr(); keypad(stdscr(), true); + timeout(10); start_color(); init_pair(style::REGULAR_PAIR, COLOR_WHITE, COLOR_BLACK); @@ -103,8 +109,20 @@ impl Rcui { } erase(); ui.render(&mut context, &screen_rect(), true); - let key = getch(); - context.push_event(Event::KeyStroke(key)); + + // Busy waiting on the key event + let mut key = getch(); + while key == ERR { + key = getch(); + } + + // Flushing everything we've got + while key != ERR { + context.push_event(Event::KeyStroke(key)); + key = getch(); + } + + // Handling all of the events from the queue while !context.event_queue.is_empty() { if let Some(event) = context.event_queue.pop_front() { if let Event::Quit = event {