ratatui_toolkit/primitives/pane/methods/
mod.rs

1mod with_theme;
2
3use ratatui::layout::{Constraint, Direction, Layout, Rect};
4use ratatui::text::Line;
5use ratatui::widgets::{Block, Borders, Paragraph, Widget};
6use ratatui::Frame;
7
8use crate::primitives::pane::Pane;
9
10impl<'a> Pane<'a> {
11    pub fn render<W>(&self, frame: &mut Frame, area: Rect, content: W)
12    where
13        W: Widget,
14    {
15        let padded_area = self.get_padded_area(area);
16        let block = self.build_block();
17        let inner = block.inner(padded_area);
18
19        frame.render_widget(block, padded_area);
20        frame.render_widget(content, inner);
21    }
22
23    pub fn render_with_footer<C, F>(&self, frame: &mut Frame, area: Rect, content: C, footer: F)
24    where
25        C: Widget,
26        F: Widget,
27    {
28        let padded_area = self.get_padded_area(area);
29        let block = self.build_block();
30        let inner = block.inner(padded_area);
31
32        frame.render_widget(block, padded_area);
33
34        if self.footer_height == 0 {
35            frame.render_widget(content, inner);
36            return;
37        }
38
39        let chunks = Layout::default()
40            .direction(Direction::Vertical)
41            .constraints([Constraint::Min(0), Constraint::Length(self.footer_height)])
42            .split(inner);
43
44        frame.render_widget(content, chunks[0]);
45        frame.render_widget(footer, chunks[1]);
46    }
47
48    pub fn render_paragraph(&self, frame: &mut Frame, area: Rect, content: Vec<Line<'a>>) {
49        let paragraph = Paragraph::new(content);
50        self.render(frame, area, paragraph);
51    }
52
53    pub fn render_paragraph_with_footer<F>(
54        &self,
55        frame: &mut Frame,
56        area: Rect,
57        content: Vec<Line<'a>>,
58        footer: F,
59    ) where
60        F: Widget,
61    {
62        let paragraph = Paragraph::new(content);
63        self.render_with_footer(frame, area, paragraph, footer);
64    }
65
66    pub fn render_block(&self, frame: &mut Frame, area: Rect) -> (Rect, Option<Rect>) {
67        let padded_area = self.get_padded_area(area);
68        let block = self.build_block();
69        let inner = block.inner(padded_area);
70
71        frame.render_widget(block, padded_area);
72
73        if self.footer_height == 0 {
74            return (inner, None);
75        }
76
77        let chunks = Layout::default()
78            .direction(Direction::Vertical)
79            .constraints([Constraint::Min(0), Constraint::Length(self.footer_height)])
80            .split(inner);
81
82        (chunks[0], Some(chunks[1]))
83    }
84
85    fn get_padded_area(&self, area: Rect) -> Rect {
86        Rect {
87            x: area.x + self.padding.3,
88            y: area.y + self.padding.0,
89            width: area.width.saturating_sub(self.padding.1 + self.padding.3),
90            height: area.height.saturating_sub(self.padding.0 + self.padding.2),
91        }
92    }
93
94    fn build_title_line(&self) -> Line<'a> {
95        use ratatui::text::Span;
96
97        let mut spans = vec![Span::raw(" ")];
98
99        if let Some(ref icon) = self.icon {
100            spans.push(Span::styled(icon.clone(), self.title_style));
101            spans.push(Span::raw(" "));
102        }
103
104        spans.push(Span::styled(self.title.clone(), self.title_style));
105        spans.push(Span::raw(" "));
106
107        Line::from(spans)
108    }
109
110    fn build_block(&self) -> Block<'a> {
111        let mut block = Block::default()
112            .borders(Borders::ALL)
113            .border_type(self.border_type)
114            .border_style(self.border_style)
115            .title(self.build_title_line());
116
117        if let Some(ref footer) = self.text_footer {
118            block = block.title_bottom(footer.clone().style(self.footer_style));
119        }
120
121        block
122    }
123}