made TAB a switcher for widgets

This commit is contained in:
Thomas Eppers 2021-08-28 17:37:55 +02:00
parent 0031c46d4b
commit 7748212878
4 changed files with 100 additions and 50 deletions

View File

@ -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);
}
_ => (),
}

View File

@ -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);
}

View File

@ -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;
}
_ => (),
}
}
}

View File

@ -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<String>,
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<tui::widgets::ListItem> = 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)),