rustic_rs/commands/tui/widgets/
with_block.rs

1use super::{Block, Draw, Event, Frame, ProcessEvent, Rect, SizedWidget, layout};
2use layout::Size;
3
4pub struct WithBlock<T> {
5    pub block: Block<'static>,
6    pub widget: T,
7}
8
9impl<T> WithBlock<T> {
10    pub fn new(widget: T, block: Block<'static>) -> Self {
11        Self { block, widget }
12    }
13
14    // Note: this could be a method of self.block, but is unfortunately not present
15    // So we compute ourselves using self.block.inner() on an artificial Rect.
16    fn size_diff(&self) -> Size {
17        let rect = Rect {
18            x: 0,
19            y: 0,
20            width: u16::MAX,
21            height: u16::MAX,
22        };
23        let inner = self.block.inner(rect);
24        Size {
25            width: rect.as_size().width - inner.as_size().width,
26            height: rect.as_size().height - inner.as_size().height,
27        }
28    }
29}
30
31impl<T: ProcessEvent> ProcessEvent for WithBlock<T> {
32    type Result = T::Result;
33    fn input(&mut self, event: Event) -> Self::Result {
34        self.widget.input(event)
35    }
36}
37
38impl<T: SizedWidget> SizedWidget for WithBlock<T> {
39    fn height(&self) -> Option<u16> {
40        self.widget
41            .height()
42            .map(|h| h.saturating_add(self.size_diff().height))
43    }
44
45    fn width(&self) -> Option<u16> {
46        self.widget
47            .width()
48            .map(|w| w.saturating_add(self.size_diff().width))
49    }
50}
51
52impl<T: Draw + SizedWidget> Draw for WithBlock<T> {
53    fn draw(&mut self, area: Rect, f: &mut Frame<'_>) {
54        f.render_widget(self.block.clone(), area);
55        self.widget.draw(self.block.inner(area), f);
56    }
57}