From d79baa67c6d394f1cb01db57710c388f412d5baa Mon Sep 17 00:00:00 2001 From: Thomas Eppers Date: Wed, 8 Sep 2021 18:58:21 +0200 Subject: [PATCH] added new widget to show errors and keybindings --- src/ui.rs | 52 ++++++++++++++++++++++++++-------------------- src/widget/info.rs | 33 +++++++++++++++++++++++++++++ src/widget/mod.rs | 1 + 3 files changed, 63 insertions(+), 23 deletions(-) create mode 100644 src/widget/info.rs diff --git a/src/ui.rs b/src/ui.rs index 6e9bee3..d6d70f9 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -8,6 +8,7 @@ use tui::backend::TermionBackend; use tui::layout::{Constraint, Direction, Layout}; use tui::Terminal; +use crate::widget::info; use crate::widget::repo_entry; use crate::widget::service_switcher; use crate::widget::tag_list; @@ -17,6 +18,7 @@ pub struct Ui { repo: crate::widget::repo_entry::RepoEntry, tags: crate::widget::tag_list::TagList, services: crate::widget::service_switcher::ServiceSwitcher, + info: crate::widget::info::Info, } #[derive(PartialEq, Clone)] @@ -26,13 +28,16 @@ pub enum State { SelectService, } -impl State { - fn next(&self) -> State { +impl std::iter::Iterator for State { + type Item = Self; + + fn next(&mut self) -> Option { match self { - State::EditRepo => State::SelectTag, - State::SelectTag => State::SelectService, - State::SelectService => State::EditRepo, + State::EditRepo => *self = State::SelectTag, + State::SelectTag => *self = State::SelectService, + State::SelectService => *self = State::EditRepo, } + Some(self.clone()) } } @@ -41,8 +46,9 @@ impl Ui { let mut ui = Ui { state: State::SelectService, repo: repo_entry::RepoEntry::new(repo_id), - tags: tag_list::TagList::with_status("Select image or edit Repository"), + tags: tag_list::TagList::with_status("Tags are empty"), services: service_switcher::ServiceSwitcher::new(), + info: info::Info::new("Select image of edit Repository"), }; //setup tui @@ -62,9 +68,10 @@ impl Ui { .direction(Direction::Vertical) .constraints( [ - Constraint::Min(3), + Constraint::Min(9), Constraint::Length(3), - Constraint::Max(7), + Constraint::Min(7), + Constraint::Length(2), ] .as_ref(), ) @@ -75,19 +82,23 @@ impl Ui { rect.render_widget(ui.repo.render(&ui.state), chunks[1]); let (list, state) = ui.tags.render(&ui.state); rect.render_stateful_widget(list, chunks[2], state); + rect.render_widget(ui.info.render(), chunks[3]); }) .unwrap(); //handle input match receiver.try_recv() { Ok(Key::Ctrl('q')) => break 'core, //quit program without saving - Ok(Key::Char('\t')) => ui.state = ui.state.next(), + Ok(Key::Char('\t')) => { + ui.state.next(); + () + } Ok(Key::Ctrl('s')) => match ui.services.save() { Err(e) => { - ui.show_info(&format!("{}", e)); + ui.info.set_info(&format!("{}", e)); continue; } - Ok(_) => (), + Ok(_) => ui.info.set_info("Saved compose file"), }, Ok(Key::Ctrl('r')) => { ui.repo.confirm(); @@ -104,7 +115,7 @@ impl Ui { let mut repo = ui.repo.get(); let tag = match ui.tags.get_selected() { Err(e) => { - ui.show_info(&format!("{}", e)); + ui.info.set_info(&format!("{}", e)); continue; } Ok(tag) => tag, @@ -117,14 +128,14 @@ impl Ui { }, Ok(Key::Char(key)) => { if ui.state == State::EditRepo { - ui.show_info("Editing Repository"); + ui.info.set_info("Editing Repository"); } ui.repo.handle_input(&ui.state, Key::Char(key)); ui.tags.handle_input(&ui.state, Key::Char(key)); } Ok(Key::Backspace) => { if ui.state == State::EditRepo { - ui.show_info("Editing Repository"); + ui.info.set_info("Editing Repository"); } ui.repo.handle_input(&ui.state, Key::Backspace); ui.tags.handle_input(&ui.state, Key::Backspace); @@ -132,11 +143,11 @@ impl Ui { Ok(Key::Up) => { if ui.state == State::SelectService && ui.services.find_previous_match() { match ui.services.extract_repo() { - Err(e) => ui.show_info(&format!("{}", e)), + Err(e) => ui.info.set_info(&format!("{}", e)), Ok(s) => { let repo = match crate::tags::Tags::check_repo(s) { Err(e) => { - ui.show_info(&format!("{}", e)); + ui.info.set_info(&format!("{}", e)); continue; } Ok(s) => s, @@ -152,11 +163,11 @@ impl Ui { Ok(Key::Down) => match ui.state { State::SelectService if ui.services.find_next_match() => { match ui.services.extract_repo() { - Err(e) => ui.show_info(&format!("{}", e)), + Err(e) => ui.info.set_info(&format!("{}", e)), Ok(s) => { let repo = match crate::tags::Tags::check_repo(s) { Err(e) => { - ui.show_info(&format!("{}", e)); + ui.info.set_info(&format!("{}", e)); continue; } Ok(s) => s, @@ -185,11 +196,6 @@ impl Ui { terminal.clear().unwrap(); } - /// helper function to show information in TagList - fn show_info(&mut self, error: &str) { - self.tags = tag_list::TagList::with_status(error); - } - /// create a thread for catching input and send them to core loop pub fn spawn_stdin_channel(&self) -> mpsc::Receiver { let (tx, rx) = mpsc::channel::(); diff --git a/src/widget/info.rs b/src/widget/info.rs new file mode 100644 index 0000000..a2b5772 --- /dev/null +++ b/src/widget/info.rs @@ -0,0 +1,33 @@ +use tui::style::{Color, Style}; +use tui::widgets::{Block, List, ListItem}; + +pub struct Info { + info: String, + keys: String, +} + +impl Info { + pub fn new(info: &str) -> Self { + Self { + info: String::from(info), + keys: String::from( + "Tab Cycle widgets C-s Save C-r Reload C-q Quit C-n Next page C-p Previous page ↑ ↓ Select tags or image line", + ), + } + } + + pub fn render(&self) -> List { + let items = vec![ + ListItem::new(self.info.clone()), + ListItem::new(self.keys.clone()), + ]; + List::new(items) + .block(Block::default()) + .style(Style::default().fg(Color::White).bg(Color::Black)) + .highlight_style(Style::default().bg(Color::Black)) + } + + pub fn set_info(&mut self, info: &str) { + self.info = String::from(info); + } +} diff --git a/src/widget/mod.rs b/src/widget/mod.rs index 6d86048..b722798 100644 --- a/src/widget/mod.rs +++ b/src/widget/mod.rs @@ -1,3 +1,4 @@ +pub mod info; pub mod repo_entry; pub mod service_switcher; pub mod tag_list;