node_launchpad/components/
header.rs1use crate::style::{GHOST_WHITE, LIGHT_PERIWINKLE, VIVID_SKY_BLUE};
10use ratatui::{prelude::*, widgets::*};
11
12pub enum SelectedMenuItem {
13 Status,
14 Options,
15 Help,
16}
17
18pub struct Header {
19 launchpad_version_str: String,
20}
21
22impl Default for Header {
23 fn default() -> Self {
24 let version_str = env!("CARGO_PKG_VERSION");
25 Self {
26 launchpad_version_str: version_str.to_string(),
27 }
28 }
29}
30
31impl Header {
32 pub fn new() -> Self {
33 Self::default()
34 }
35}
36
37impl StatefulWidget for Header {
38 type State = SelectedMenuItem;
39
40 fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
41 let layout = Layout::default()
42 .direction(Direction::Vertical)
43 .constraints(vec![Constraint::Length(1)])
44 .split(area);
45
46 let application_text = Span::styled(
48 format!(" Autonomi Node Launchpad (v{})", self.launchpad_version_str),
49 Style::default().fg(LIGHT_PERIWINKLE),
50 );
51
52 let status_color = if matches!(state, SelectedMenuItem::Status) {
54 VIVID_SKY_BLUE
55 } else {
56 GHOST_WHITE
57 };
58
59 let options_color = if matches!(state, SelectedMenuItem::Options) {
60 VIVID_SKY_BLUE
61 } else {
62 GHOST_WHITE
63 };
64
65 let help_color = if matches!(state, SelectedMenuItem::Help) {
66 VIVID_SKY_BLUE
67 } else {
68 GHOST_WHITE
69 };
70
71 let status = Span::styled("[S]tatus", Style::default().fg(status_color));
73 let options = Span::styled("[O]ptions", Style::default().fg(options_color));
74 let help = Span::styled("[H]elp", Style::default().fg(help_color));
75
76 let menu = vec![
78 status,
79 Span::raw(" | ").fg(VIVID_SKY_BLUE),
80 options,
81 Span::raw(" | ").fg(VIVID_SKY_BLUE),
82 help,
83 ];
84
85 let total_width = (layout[0].width - 1) as usize;
87 let spaces = " ".repeat(total_width.saturating_sub(
88 application_text.content.len() + menu.iter().map(|s| s.width()).sum::<usize>(),
89 ));
90
91 let line = Line::from(
93 vec![application_text, Span::raw(spaces)]
94 .into_iter()
95 .chain(menu)
96 .collect::<Vec<_>>(),
97 );
98
99 let paragraph = Paragraph::new(line).block(Block::default().borders(Borders::NONE));
101
102 paragraph.render(layout[0], buf);
103 }
104}