made TAB a switcher for widgets
This commit is contained in:
parent
0031c46d4b
commit
7748212878
46
src/ui.rs
46
src/ui.rs
@ -11,7 +11,7 @@ use tui::Terminal;
|
|||||||
use crate::tags;
|
use crate::tags;
|
||||||
use crate::widget::repo_entry;
|
use crate::widget::repo_entry;
|
||||||
use crate::widget::tag_list;
|
use crate::widget::tag_list;
|
||||||
use crate::widget::Widget;
|
// use crate::widget::Widget;
|
||||||
|
|
||||||
pub struct Ui {
|
pub struct Ui {
|
||||||
state: State,
|
state: State,
|
||||||
@ -51,14 +51,20 @@ impl Ui {
|
|||||||
.constraints([Constraint::Length(3), Constraint::Min(1)].as_ref())
|
.constraints([Constraint::Length(3), Constraint::Min(1)].as_ref())
|
||||||
.split(rect.size());
|
.split(rect.size());
|
||||||
|
|
||||||
rect.render_widget(ui.repo.render(), chunks[0]);
|
rect.render_widget(ui.repo.render(&ui.state), chunks[0]);
|
||||||
let (list, state) = ui.tags.render();
|
let (list, state) = ui.tags.render(&ui.state);
|
||||||
rect.render_stateful_widget(list, chunks[1], state);
|
rect.render_stateful_widget(list, chunks[1], state);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
//handle input
|
//handle input
|
||||||
match receiver.try_recv() {
|
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('q')) => break 'core, //quit program without saving
|
||||||
Ok(Key::Ctrl('s')) => {
|
Ok(Key::Ctrl('s')) => {
|
||||||
if ui.state == State::SelectTag {
|
if ui.state == State::SelectTag {
|
||||||
@ -67,34 +73,34 @@ impl Ui {
|
|||||||
}
|
}
|
||||||
Ok(Key::Char('\n')) => {
|
Ok(Key::Char('\n')) => {
|
||||||
if ui.state == State::EditRepo {
|
if ui.state == State::EditRepo {
|
||||||
ui.state = State::SelectTag;
|
|
||||||
ui.repo.confirm();
|
ui.repo.confirm();
|
||||||
//TODO query tags and show them switch
|
|
||||||
match tags::Tags::get_tags(ui.repo.get()) {
|
match tags::Tags::get_tags(ui.repo.get()) {
|
||||||
Ok(lines) => ui.tags = tag_list::TagList::new(lines),
|
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) => {
|
Ok(Key::Char(key)) => {
|
||||||
if ui.state == State::SelectTag {
|
if ui.state == State::EditRepo {
|
||||||
ui.tags.next();
|
ui.tags = tag_list::TagList::new_line("Editing Repository");
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(Key::Up) => {
|
|
||||||
if ui.state == State::SelectTag {
|
|
||||||
ui.tags.previous();
|
|
||||||
}
|
}
|
||||||
|
ui.repo.handle_input(&ui.state, Key::Char(key));
|
||||||
|
ui.tags.handle_input(&ui.state, Key::Char(key));
|
||||||
}
|
}
|
||||||
Ok(Key::Backspace) => {
|
Ok(Key::Backspace) => {
|
||||||
ui.state = State::EditRepo;
|
if ui.state == State::EditRepo {
|
||||||
ui.repo.input(Key::Backspace);
|
ui.tags = tag_list::TagList::new_line("Editing Repository");
|
||||||
ui.tags = tag_list::TagList::new(vec![String::from("editing Repository")]);
|
}
|
||||||
|
ui.repo.handle_input(&ui.state, Key::Backspace);
|
||||||
|
ui.tags.handle_input(&ui.state, Key::Backspace);
|
||||||
}
|
}
|
||||||
Ok(key) => {
|
Ok(key) => {
|
||||||
ui.state = State::EditRepo;
|
ui.repo.handle_input(&ui.state, key);
|
||||||
ui.repo.input(key);
|
ui.tags.handle_input(&ui.state, key);
|
||||||
ui.tags = tag_list::TagList::new(vec![String::from("editing Repository")]);
|
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,2 @@
|
|||||||
use tui::widgets::ListState;
|
|
||||||
|
|
||||||
pub mod repo_entry;
|
pub mod repo_entry;
|
||||||
pub mod tag_list;
|
pub mod tag_list;
|
||||||
|
|
||||||
pub trait Widget {
|
|
||||||
fn input(&mut self, event: termion::event::Key);
|
|
||||||
}
|
|
||||||
|
@ -3,6 +3,8 @@ use tui::layout::Alignment;
|
|||||||
use tui::style::{Color, Style};
|
use tui::style::{Color, Style};
|
||||||
use tui::widgets::{Block, Borders, Paragraph};
|
use tui::widgets::{Block, Borders, Paragraph};
|
||||||
|
|
||||||
|
use crate::ui::State;
|
||||||
|
|
||||||
pub struct RepoEntry {
|
pub struct RepoEntry {
|
||||||
text: String,
|
text: String,
|
||||||
old_text: String,
|
old_text: String,
|
||||||
@ -22,39 +24,54 @@ impl RepoEntry {
|
|||||||
self.text.clone()
|
self.text.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&self) -> Paragraph {
|
pub fn render(&self, state: &crate::ui::State) -> Paragraph {
|
||||||
let title = match self.changed {
|
let title = match self.changed {
|
||||||
true => "Repository*",
|
true => "Repository*",
|
||||||
false => "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())
|
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))
|
.style(Style::default().fg(Color::White).bg(Color::Black))
|
||||||
.alignment(Alignment::Left)
|
.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) {
|
pub fn confirm(&mut self) {
|
||||||
self.old_text = self.text.clone();
|
self.old_text = self.text.clone();
|
||||||
self.changed = false;
|
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;
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
use termion::event::Key;
|
||||||
use tui::style::{Color, Style};
|
use tui::style::{Color, Style};
|
||||||
use tui::widgets::{Block, Borders, List, ListState};
|
use tui::widgets::{Block, Borders, List, ListState};
|
||||||
|
|
||||||
|
use crate::ui::State;
|
||||||
|
|
||||||
pub struct TagList {
|
pub struct TagList {
|
||||||
list: Vec<String>,
|
list: Vec<String>,
|
||||||
state: ListState,
|
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
|
let items: Vec<tui::widgets::ListItem> = self
|
||||||
.list
|
.list
|
||||||
.iter()
|
.iter()
|
||||||
@ -26,7 +42,12 @@ impl TagList {
|
|||||||
|
|
||||||
// Create a List from all list items and highlight the currently selected one
|
// Create a List from all list items and highlight the currently selected one
|
||||||
let items = List::new(items)
|
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))
|
.style(Style::default().fg(Color::White).bg(Color::Black))
|
||||||
.highlight_style(Style::default().bg(Color::Black))
|
.highlight_style(Style::default().bg(Color::Black))
|
||||||
.highlight_symbol(">>");
|
.highlight_symbol(">>");
|
||||||
@ -34,6 +55,18 @@ impl TagList {
|
|||||||
(items, &mut self.state)
|
(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) {
|
pub fn next(&mut self) {
|
||||||
match self.state.selected() {
|
match self.state.selected() {
|
||||||
None if self.list.len() > 0 => self.state.select(Some(0)),
|
None if self.list.len() > 0 => self.state.select(Some(0)),
|
||||||
|
Loading…
Reference in New Issue
Block a user