Skip to main content

carch_core/ui/widgets/
header.rs

1use ratatui::Frame;
2use ratatui::layout::{Alignment, Constraint, Rect};
3use ratatui::style::{Modifier, Style};
4use ratatui::text::{Line, Span, Text};
5use ratatui::widgets::{Block, BorderType, Borders, Paragraph};
6
7use crate::ui::state::App;
8
9pub fn render_header(f: &mut Frame, app: &App, area: Rect) {
10    let header_block = Block::default()
11        .borders(Borders::ALL)
12        .border_style(Style::default().fg(app.theme.primary))
13        .border_type(BorderType::Rounded);
14
15    let inner_area = header_block.inner(area);
16    f.render_widget(header_block, area);
17
18    let chunks = ratatui::layout::Layout::default()
19        .direction(ratatui::layout::Direction::Horizontal)
20        .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
21        .split(inner_area);
22
23    let left_text = Text::from(Line::from(vec![
24        Span::styled(
25            " Carch  󰏗 ",
26            Style::default().fg(app.theme.accent).add_modifier(Modifier::BOLD),
27        ),
28        Span::raw(format!(" │ {}", app.distro)),
29    ]));
30    f.render_widget(Paragraph::new(left_text).alignment(Alignment::Left), chunks[0]);
31
32    let breadcrumb = if let Some(script_idx) = app.scripts.state.selected() {
33        let script = &app.scripts.items[script_idx];
34        let category_scripts = app.scripts.items.len();
35        let script_pos = script_idx + 1;
36        Text::from(Line::from(vec![
37            Span::styled(&script.category, Style::default().fg(app.theme.accent)),
38            Span::raw(" > "),
39            Span::styled(
40                &script.name,
41                Style::default().fg(app.theme.accent).add_modifier(Modifier::BOLD),
42            ),
43            Span::raw(format!(" ({script_pos}/{category_scripts})")),
44        ]))
45    } else if let Some(category_idx) = app.categories.state.selected() {
46        let category = &app.categories.items[category_idx];
47        let category_scripts = app.all_scripts.get(category).map_or(0, Vec::len);
48        Text::from(Line::from(vec![
49            Span::styled(
50                category,
51                Style::default().fg(app.theme.accent).add_modifier(Modifier::BOLD),
52            ),
53            Span::raw(format!(" ({category_scripts} scripts)")),
54        ]))
55    } else {
56        Text::from(Span::styled("Select a category", Style::default().fg(app.theme.secondary)))
57    };
58    f.render_widget(Paragraph::new(breadcrumb).alignment(Alignment::Right), chunks[1]);
59}