Prototype tab complete ui

This commit is contained in:
Dheepak Krishnamurthy 2021-04-02 17:32:00 -06:00
parent 5303b800b9
commit fad1f37a8c
3 changed files with 102 additions and 1 deletions

View file

@ -1,4 +1,5 @@
use crate::calendar::Calendar;
use crate::completion::CompletionList;
use crate::config;
use crate::config::Config;
use crate::context::Context;
@ -49,7 +50,7 @@ use tui::{
style::{Color, Modifier, Style},
terminal::Frame,
text::{Span, Spans, Text},
widgets::{Block, BorderType, Borders, Clear, Paragraph},
widgets::{Block, BorderType, Borders, Clear, List, ListItem, Paragraph},
};
use rustyline::history::Direction as HistoryDirection;
@ -192,6 +193,8 @@ pub struct TaskwarriorTuiApp {
pub terminal_height: u16,
pub filter_history_context: HistoryContext,
pub command_history_context: HistoryContext,
pub completion_list: CompletionList,
pub show_completion_pane: bool,
}
impl TaskwarriorTuiApp {
@ -252,6 +255,8 @@ impl TaskwarriorTuiApp {
terminal_height: h,
filter_history_context: HistoryContext::new("filter.history"),
command_history_context: HistoryContext::new("command.history"),
completion_list: CompletionList::with_items(vec!["hello".to_string(), "word".to_string()]),
show_completion_pane: true,
};
for c in app.config.filter.chars() {
@ -405,6 +410,9 @@ impl TaskwarriorTuiApp {
}
}
};
if self.show_completion_pane {
self.draw_completion_pop_up(f, rects[1], 0);
}
match self.mode {
AppMode::TaskReport => self.draw_command(
f,
@ -416,6 +424,7 @@ impl TaskwarriorTuiApp {
),
AppMode::TaskFilter => {
let position = self.get_position(&self.filter);
self.draw_command(
f,
rects[1],
@ -605,6 +614,36 @@ impl TaskwarriorTuiApp {
f.render_stateful_widget(t, area, &mut self.context_table_state);
}
fn draw_completion_pop_up(&mut self, f: &mut Frame<impl Backend>, rect: Rect, cursor_position: usize) {
// Iterate through all elements in the `items` app and append some debug text to it.
let items: Vec<ListItem> = self
.completion_list
.items
.iter()
.map(|i| {
let lines = vec![Spans::from(i.clone())];
ListItem::new(lines).style(Style::default().fg(Color::Black))
})
.collect();
// Create a List from all list items and highlight the currently selected one
let items = List::new(items)
.block(Block::default().borders(Borders::NONE).title(""))
.style(Style::default().bg(Color::Rgb(223, 223, 223)));
let area = f.size();
let mut rect = rect.clone();
rect.y = rect
.y
.saturating_sub(self.completion_list.items.len() as u16)
.saturating_sub(5);
rect.height = self.completion_list.items.len() as u16 + 5;
rect.width = std::cmp::min(area.width / 4, 20);
// We can now render the item list
f.render_widget(Clear, rect);
f.render_stateful_widget(items, rect, &mut self.completion_list.state);
}
fn draw_command<'a, T>(
&self,
f: &mut Frame<impl Backend>,

61
src/completion.rs Normal file
View file

@ -0,0 +1,61 @@
use std::{error::Error, io};
use tui::{
layout::{Constraint, Corner, Direction, Layout},
style::{Color, Modifier, Style},
text::{Span, Spans},
widgets::{Block, Borders, List, ListItem, ListState},
Terminal,
};
pub struct CompletionList {
pub state: ListState,
pub items: Vec<String>,
}
impl CompletionList {
pub fn new() -> CompletionList {
CompletionList {
state: ListState::default(),
items: Vec::new(),
}
}
pub fn with_items(items: Vec<String>) -> CompletionList {
CompletionList {
state: ListState::default(),
items,
}
}
pub fn next(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i >= self.items.len() - 1 {
0
} else {
i + 1
}
}
None => 0,
};
self.state.select(Some(i));
}
pub fn previous(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i == 0 {
self.items.len() - 1
} else {
i - 1
}
}
None => 0,
};
self.state.select(Some(i));
}
pub fn unselect(&mut self) {
self.state.select(None);
}
}

View file

@ -4,6 +4,7 @@
mod app;
mod calendar;
mod completion;
mod config;
mod context;
mod event;