First steps towards adding multiple panels

This commit is contained in:
kageru 2020-01-25 18:05:35 +01:00
parent 1428ced923
commit e0d3bad477
Signed by untrusted user: kageru
GPG Key ID: 8282A2BEA4ADA3D2
2 changed files with 60 additions and 17 deletions

View File

@ -1,6 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::from_reader; use serde_json::from_reader;
use std::fs::File; use std::fs::File;
use std::fmt;
use std::io::BufReader; use std::io::BufReader;
pub struct TodoList { pub struct TodoList {
@ -25,6 +26,12 @@ impl Todo {
} }
} }
impl fmt::Display for Todo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}] {}", if self.done { 'x' } else { ' ' }, self.text)
}
}
fn read_todos(path: &str) -> Option<Vec<Todo>> { fn read_todos(path: &str) -> Option<Vec<Todo>> {
File::open(path) File::open(path)
.ok() .ok()
@ -41,13 +48,6 @@ impl TodoList {
} }
} }
pub fn printable_todos(&self) -> Vec<String> {
self.todos
.iter()
.map(|todo| format!("[{}] {}", if todo.done { 'x' } else { ' ' }, todo.text))
.collect()
}
pub fn selection_down(&mut self) { pub fn selection_down(&mut self) {
self.selected = (self.selected + 1).min(self.todos.len().saturating_sub(1)); self.selected = (self.selected + 1).min(self.todos.len().saturating_sub(1));
} }
@ -97,4 +97,8 @@ impl TodoList {
pub fn current_pop(&mut self) { pub fn current_pop(&mut self) {
self.todos[self.selected].text.pop(); self.todos[self.selected].text.pop();
} }
pub fn printable(&self) -> Vec<String> {
self.todos.iter().map(Todo::to_string).collect()
}
} }

View File

@ -1,9 +1,10 @@
use super::todolist::TodoList; use super::todolist::TodoList;
use std::default::Default; use std::default::Default;
use std::io::{self,Write}; use std::io::{self, Write};
use termion::event::Key; use termion::event::Key;
use termion::input::TermRead; use termion::input::TermRead;
use tui::backend::TermionBackend; use tui::backend::TermionBackend;
use tui::layout::*;
use tui::style::{Color, Style}; use tui::style::{Color, Style};
use tui::widgets::*; use tui::widgets::*;
@ -19,6 +20,7 @@ pub struct Tracc {
todos: TodoList, todos: TodoList,
terminal: Terminal, terminal: Terminal,
input_mode: Mode, input_mode: Mode,
top_panel_selected: bool,
} }
impl Tracc { impl Tracc {
@ -27,13 +29,14 @@ impl Tracc {
todos: TodoList::open_or_create(JSON_PATH), todos: TodoList::open_or_create(JSON_PATH),
terminal, terminal,
input_mode: Mode::Normal, input_mode: Mode::Normal,
top_panel_selected: true,
} }
} }
pub fn run(&mut self) -> Result<(), io::Error> { pub fn run(&mut self) -> Result<(), io::Error> {
let mut inputs = io::stdin().keys(); let mut inputs = io::stdin().keys();
loop { loop {
refresh(&mut self.terminal, &self.todos)?; refresh(&mut self.terminal, &self.todos, self.top_panel_selected)?;
// I need to find a better way to handle inputs. This is awful. // I need to find a better way to handle inputs. This is awful.
let input = inputs.next().unwrap()?; let input = inputs.next().unwrap()?;
match self.input_mode { match self.input_mode {
@ -58,6 +61,7 @@ impl Tracc {
self.todos.insert(self.todos.register.clone().unwrap()); self.todos.insert(self.todos.register.clone().unwrap());
} }
} }
Key::Char('\t') => self.top_panel_selected = !self.top_panel_selected,
_ => (), _ => (),
}, },
Mode::Insert => match input { Mode::Insert => match input {
@ -86,17 +90,52 @@ impl Tracc {
} }
} }
fn refresh(terminal: &mut Terminal, todos: &TodoList) -> Result<(), io::Error> { fn refresh(terminal: &mut Terminal, todos: &TodoList, top_selected: bool) -> Result<(), io::Error> {
terminal.draw(|mut frame| { fn selectable_list<'a, C: AsRef<str>>(
let size = frame.size(); title: &'a str,
let block = Block::default().title(" t r a c c ").borders(Borders::ALL); content: &'a [C],
selected: Option<usize>,
) -> SelectableList<'a> {
SelectableList::default() SelectableList::default()
.block(block) .block(
.items(&todos.printable_todos()) Block::default()
.select(Some(todos.selected)) .title(title)
.borders(Borders::TOP | Borders::RIGHT | Borders::LEFT),
)
.items(content)
.select(selected.into())
.highlight_style(Style::default().fg(Color::LightGreen)) .highlight_style(Style::default().fg(Color::LightGreen))
.highlight_symbol(">") .highlight_symbol(">")
.render(&mut frame, size); }
terminal.draw(|mut frame| {
let size = frame.size();
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints(
[
Constraint::Percentage(42),
Constraint::Percentage(42),
Constraint::Percentage(16),
]
.as_ref(),
)
.split(size);
selectable_list(
" t r a c c ",
&todos.printable(),
Some(todos.selected).filter(|_| top_selected),
)
.render(&mut frame, chunks[0]);
selectable_list(
" 🕑 ",
&["[08:23] start", "[09:35] end"],
Some(0).filter(|_| !top_selected),
)
.render(&mut frame, chunks[1]);
Paragraph::new([Text::raw("Sum for today: 1:12")].iter())
.block(Block::default().borders(Borders::ALL))
.render(&mut frame, chunks[2]);
})?; })?;
Ok(()) Ok(())
} }