From 77482128784535826e49b9a38c706897f02a8aae Mon Sep 17 00:00:00 2001 From: Thomas Eppers Date: Sat, 28 Aug 2021 17:37:55 +0200 Subject: [PATCH] made TAB a switcher for widgets --- src/ui.rs | 46 +++++++++++++++++------------- src/widget/mod.rs | 6 ---- src/widget/repo_entry.rs | 61 +++++++++++++++++++++++++--------------- src/widget/tag_list.rs | 37 ++++++++++++++++++++++-- 4 files changed, 100 insertions(+), 50 deletions(-) diff --git a/src/ui.rs b/src/ui.rs index 506d7ff..cab365a 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -11,7 +11,7 @@ use tui::Terminal; use crate::tags; use crate::widget::repo_entry; use crate::widget::tag_list; -use crate::widget::Widget; +// use crate::widget::Widget; pub struct Ui { state: State, @@ -51,14 +51,20 @@ impl Ui { .constraints([Constraint::Length(3), Constraint::Min(1)].as_ref()) .split(rect.size()); - rect.render_widget(ui.repo.render(), chunks[0]); - let (list, state) = ui.tags.render(); + rect.render_widget(ui.repo.render(&ui.state), chunks[0]); + let (list, state) = ui.tags.render(&ui.state); rect.render_stateful_widget(list, chunks[1], state); }) .unwrap(); //handle input match receiver.try_recv() { + Ok(Key::Char('\t')) => { + ui.state = match ui.state { + State::EditRepo => State::SelectTag, + State::SelectTag => State::EditRepo, + }; + } Ok(Key::Ctrl('q')) => break 'core, //quit program without saving Ok(Key::Ctrl('s')) => { if ui.state == State::SelectTag { @@ -67,34 +73,34 @@ impl Ui { } Ok(Key::Char('\n')) => { if ui.state == State::EditRepo { - ui.state = State::SelectTag; ui.repo.confirm(); - //TODO query tags and show them switch match tags::Tags::get_tags(ui.repo.get()) { Ok(lines) => ui.tags = tag_list::TagList::new(lines), - Err(_) => (), + Err(_) => { + ui.tags = tag_list::TagList::new_line( + "Error fetich tags. Is there a typo in the Repository?", + ); + } } } } - Ok(Key::Down) => { - if ui.state == State::SelectTag { - ui.tags.next(); - } - } - Ok(Key::Up) => { - if ui.state == State::SelectTag { - ui.tags.previous(); + Ok(Key::Char(key)) => { + if ui.state == State::EditRepo { + ui.tags = tag_list::TagList::new_line("Editing Repository"); } + ui.repo.handle_input(&ui.state, Key::Char(key)); + ui.tags.handle_input(&ui.state, Key::Char(key)); } Ok(Key::Backspace) => { - ui.state = State::EditRepo; - ui.repo.input(Key::Backspace); - ui.tags = tag_list::TagList::new(vec![String::from("editing Repository")]); + if ui.state == State::EditRepo { + ui.tags = tag_list::TagList::new_line("Editing Repository"); + } + ui.repo.handle_input(&ui.state, Key::Backspace); + ui.tags.handle_input(&ui.state, Key::Backspace); } Ok(key) => { - ui.state = State::EditRepo; - ui.repo.input(key); - ui.tags = tag_list::TagList::new(vec![String::from("editing Repository")]); + ui.repo.handle_input(&ui.state, key); + ui.tags.handle_input(&ui.state, key); } _ => (), } diff --git a/src/widget/mod.rs b/src/widget/mod.rs index 86ef6e1..7d2cab9 100644 --- a/src/widget/mod.rs +++ b/src/widget/mod.rs @@ -1,8 +1,2 @@ -use tui::widgets::ListState; - pub mod repo_entry; pub mod tag_list; - -pub trait Widget { - fn input(&mut self, event: termion::event::Key); -} diff --git a/src/widget/repo_entry.rs b/src/widget/repo_entry.rs index 86bcd40..e3bb313 100644 --- a/src/widget/repo_entry.rs +++ b/src/widget/repo_entry.rs @@ -3,6 +3,8 @@ use tui::layout::Alignment; use tui::style::{Color, Style}; use tui::widgets::{Block, Borders, Paragraph}; +use crate::ui::State; + pub struct RepoEntry { text: String, old_text: String, @@ -22,39 +24,54 @@ impl RepoEntry { self.text.clone() } - pub fn render(&self) -> Paragraph { + pub fn render(&self, state: &crate::ui::State) -> Paragraph { let title = match self.changed { true => "Repository*", false => "Repository", }; + + let border_style = if state == &crate::ui::State::EditRepo { + Style::default().fg(Color::Green) + } else { + Style::default().fg(Color::Gray) + }; + Paragraph::new(self.text.clone()) - .block(Block::default().title(title).borders(Borders::ALL)) + .block( + Block::default() + .title(title) + .borders(Borders::ALL) + .border_style(border_style), + ) .style(Style::default().fg(Color::White).bg(Color::Black)) .alignment(Alignment::Left) } + pub fn handle_input(&mut self, state: &State, key: termion::event::Key) { + if state != &State::EditRepo { + return; + } + + match key { + // Key::Char('\n') => self.confirm(), //handled in Ui + Key::Char(c) => { + self.text.push(c); + self.changed = true; + } + Key::Backspace => { + self.text.pop(); + self.changed = true; + } + Key::Esc => { + self.text = self.old_text.clone(); + self.changed = false; + } + _ => (), + } + } + pub fn confirm(&mut self) { self.old_text = self.text.clone(); self.changed = false; } } - -impl super::Widget for RepoEntry { - fn input(&mut self, key: termion::event::Key) { - match key { - Key::Esc => { - self.text = self.old_text.clone(); //TODO return to other structure - self.changed = false; - } - Key::Backspace => { - self.text.pop(); - self.changed = true; - } - Key::Char(c) => { - self.text.push(c); - self.changed = true; - } - _ => (), - } - } -} diff --git a/src/widget/tag_list.rs b/src/widget/tag_list.rs index 37bf506..a25f397 100644 --- a/src/widget/tag_list.rs +++ b/src/widget/tag_list.rs @@ -1,6 +1,9 @@ +use termion::event::Key; use tui::style::{Color, Style}; use tui::widgets::{Block, Borders, List, ListState}; +use crate::ui::State; + pub struct TagList { list: Vec, state: ListState, @@ -14,7 +17,20 @@ impl TagList { } } - pub fn render(&mut self) -> (List, &mut ListState) { + pub fn new_line(line: &str) -> Self { + Self { + list: vec![String::from(line)], + state: ListState::default(), + } + } + + pub fn render(&mut self, state: &State) -> (List, &mut ListState) { + let border_style = if state == &State::SelectTag { + Style::default().fg(Color::Green) + } else { + Style::default().fg(Color::Gray) + }; + let items: Vec = self .list .iter() @@ -26,7 +42,12 @@ impl TagList { // Create a List from all list items and highlight the currently selected one let items = List::new(items) - .block(Block::default().title("Tags").borders(Borders::ALL)) + .block( + Block::default() + .title("Tags") + .borders(Borders::ALL) + .border_style(border_style), + ) .style(Style::default().fg(Color::White).bg(Color::Black)) .highlight_style(Style::default().bg(Color::Black)) .highlight_symbol(">>"); @@ -34,6 +55,18 @@ impl TagList { (items, &mut self.state) } + pub fn handle_input(&mut self, state: &State, key: termion::event::Key) { + if state != &State::SelectTag { + return; + } + + match key { + Key::Down => self.next(), + Key::Up => self.previous(), + _ => (), + } + } + pub fn next(&mut self) { match self.state.selected() { None if self.list.len() > 0 => self.state.select(Some(0)),