ansiq_widgets/
session_header.rs1use 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}