diff options
Diffstat (limited to 'src/ui.rs')
| -rw-r--r-- | src/ui.rs | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/ui.rs b/src/ui.rs new file mode 100644 index 0000000..a1c3440 --- /dev/null +++ b/src/ui.rs @@ -0,0 +1,77 @@ +use ratatui::{ + Frame, + layout::{Constraint, Layout}, + prelude::Rect, + style::{Color, Modifier, Style, Stylize}, + text::{Line, Span}, + widgets::{Block, Borders, List, ListItem, ListState}, +}; + +use crate::app::App; + +pub fn ui(frame: &mut Frame, app: &mut App) { + let constraints = [Constraint::Length(1), Constraint::Fill(1)]; + + let layout = Layout::vertical(constraints).spacing(1); + let [top, first] = frame.area().layout(&layout); + + let split = Layout::horizontal([Constraint::Percentage(70), Constraint::Percentage(30)]) + .spacing(1) + .split(first); + + let title = Line::from_iter([ + Span::from("Installed Packages").bold(), + Span::from(" (Press 'q' to quit and arrow keys to navigate)"), + ]); + frame.render_widget(title.centered(), top); + + render_packages(frame, split[0], app); + render_use_flags(frame, split[1], app); +} + +fn render_packages(frame: &mut Frame, area: Rect, app: &mut App) { + let items = app.installed_packages().into_iter().map(|x| x.name.clone()); + let list = List::new(items) + .style(Color::White) + .highlight_style(Modifier::REVERSED) + .highlight_symbol("> ") + .block(Block::new().borders(Borders::ALL)); + + frame.render_stateful_widget(list, area, &mut app.list_state); +} + +fn render_use_flags(frame: &mut Frame, area: Rect, app: &mut App) { + let selected_package_index = match app.list_state.selected() { + Some(selected) => selected, + None => 0, + }; + let selected_package = app.installed_packages()[selected_package_index].clone(); + + let items = selected_package.use_flags.into_iter().map(|x| { + let color = if x.enabled { + Color::Green + } else if x.default { + Color::Blue + } else { + Color::Red + }; + + let text_style = if x.default { + Style::default().add_modifier(Modifier::ITALIC).fg(color) + } else { + Style::default().fg(color) + }; + + ListItem::new(x.name).style(text_style) + }); + let list = List::new(items) + .style(Color::White) + .scroll_padding(1) + .direction(ratatui::widgets::ListDirection::TopToBottom) + .block(Block::new().borders(Borders::ALL)); + + let mut list_state = ListState::default(); + list_state.select_first(); + + frame.render_stateful_widget(list, area, &mut list_state); +} |
