interface_builder/builder/components/
page.rs1use std::{io::{stdout, Stdout}, fmt::Display};
2
3use crossterm::{execute, cursor, style::Print};
4
5use crate::builder::tools::{clear_terminal, move_cursor_to};
6
7use super::tools;
8
9pub enum Line<'a> {
10 String(String),
11 Str(&'a str),
12}
13impl<'a> Display for Line<'a> {
14 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
15 match self {
16 Line::String(value) => write!(f, "{}", value),
17 Line::Str(value) => write!(f, "{}", value),
18 }
19 }
20}
21
22pub struct Page<'a> {
23 stdout: Stdout,
24 width: u16,
25 height: Option<u16>,
26 title: Option<&'a str>,
27 content: Vec<Line<'a>>,
28 footer: Vec<Line<'a>>
29}
30impl<'a> Page<'a> {
31 pub fn new(width: u16, height: Option<u16>) -> Page<'a> {
32 Page {
33 stdout: stdout(),
34 width, height,
35 title: None,
36 content: Vec::new(),
37 footer: Vec::new()
38 }
39 }
40 pub fn title(&mut self, title: &'a str) {
41 self.title = Some(title);
42 }
43 pub fn content(&mut self, content: Vec<Line<'a>>){
44 self.content = content
45 }
46 pub fn footer(&mut self, footer: Vec<Line<'a>>) {
47 self.footer = footer
48 }
49
50 fn print_box(&self) {
51 match self.height {
52 Some(height) => tools::bordered_box::print(self.width, height),
53 None => tools::bordered_box::print(self.width, self.content.len() as u16 + 4)
54 }
55 }
56 fn print_title(&mut self) {
57 match &self.title {
58 Some(title) => {
59 execute!(
60 self.stdout,
61 cursor::MoveTo(5, 1),
62 Print(format!(" {} ", &title))
63 ).expect("Print title failed");
64 },
65 None => ()
66 }
67 }
68 fn print_content(&mut self) {
69 for (i, line) in self.content.iter().enumerate() {
70 execute!(
71 self.stdout,
72 cursor::MoveTo(5, i as u16 + 3),
73 Print(line)
74 ).expect("Failed on print content");
75 }
76 }
77 fn print_footer(&mut self) {
78 for (i, line) in self.footer.iter().enumerate() {
79 let y = match self.height {
80 Some(height) => height + i as u16 + 1,
81 None => i as u16 + self.content.len() as u16 + 5
82 };
83 execute!(
84 self.stdout,
85 cursor::MoveTo(5, y),
86 Print(line)
87 ).expect("Failed on print content");
88 }
89 }
90 pub fn print(&mut self) {
91 clear_terminal();
92 self.print_box();
93 self.print_title();
94 self.print_content();
95 self.print_footer();
96 let y = match self.height {
97 Some(height) => height + self.footer.len() as u16 + 2,
98 None => self.content.len() as u16 + self.footer.len() as u16 + 6
99 };
100 move_cursor_to(0, y)
101 }
102}