aboutsummaryrefslogtreecommitdiff
path: root/src/ui.rs
blob: a1c3440b8fe07b1fd115908715e5e34bb8e21cea (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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);
}