Skip to main content

ansiq_widgets/
session_header.rs

1use ansiq_core::{Element, Layout, Length, Style};
2
3use crate::{Box, Pane, StatusBar, Text};
4
5pub struct SessionHeader<Message = ()> {
6    status: Option<String>,
7    title: Option<String>,
8    meta_lines: Vec<String>,
9    gap: u16,
10    pane_width: u16,
11    status_style: Style,
12    pane_style: Style,
13    title_style: Style,
14    meta_style: Style,
15    marker: std::marker::PhantomData<Message>,
16}
17
18impl<Message> SessionHeader<Message> {
19    pub fn new() -> Self {
20        Self {
21            status: None,
22            title: None,
23            meta_lines: Vec::new(),
24            gap: 1,
25            pane_width: 56,
26            status_style: Style::default(),
27            pane_style: Style::default(),
28            title_style: Style::default(),
29            meta_style: Style::default(),
30            marker: std::marker::PhantomData,
31        }
32    }
33    pub fn status(mut self, status: impl Into<String>) -> Self {
34        self.status = Some(status.into());
35        self
36    }
37
38    pub fn title(mut self, title: impl Into<String>) -> Self {
39        self.title = Some(title.into());
40        self
41    }
42
43    pub fn meta_line(mut self, line: impl Into<String>) -> Self {
44        self.meta_lines.push(line.into());
45        self
46    }
47
48    pub fn gap(mut self, gap: u16) -> Self {
49        self.gap = gap;
50        self
51    }
52
53    pub fn pane_width(mut self, pane_width: u16) -> Self {
54        self.pane_width = pane_width;
55        self
56    }
57
58    pub fn status_style(mut self, style: Style) -> Self {
59        self.status_style = style;
60        self
61    }
62
63    pub fn pane_style(mut self, style: Style) -> Self {
64        self.pane_style = style;
65        self
66    }
67
68    pub fn title_style(mut self, style: Style) -> Self {
69        self.title_style = style;
70        self
71    }
72
73    pub fn meta_style(mut self, style: Style) -> Self {
74        self.meta_style = style;
75        self
76    }
77
78    pub fn build(self) -> Element<Message> {
79        let mut header = Box::column().gap(self.gap).layout(Layout {
80            width: Length::Fill,
81            height: Length::Auto,
82        });
83
84        if let Some(status) = self.status {
85            header = header.child(StatusBar::new(status).build().with_style(self.status_style));
86        }
87
88        let mut banner = Box::column().gap(0).style(self.pane_style);
89        if let Some(title) = self.title {
90            banner = banner.child(Text::new(title).style(self.title_style).build());
91        }
92        for line in self.meta_lines {
93            banner = banner.child(Text::new(line).style(self.meta_style).build());
94        }
95
96        let pane = Pane::new()
97            .layout(Layout {
98                width: Length::Fixed(self.pane_width),
99                height: Length::Auto,
100            })
101            .child(banner.build())
102            .build()
103            .with_style(self.pane_style);
104
105        header.child(pane).build()
106    }
107}