tui_framework_experiment/
stack_container.rs1use ratatui::layout::Flex;
2use ratatui::prelude::*;
3use ratatui::widgets::WidgetRef;
4use std::fmt;
5
6#[derive(Default)]
29pub struct StackContainer {
30 direction: Direction,
31 flex: Flex,
32 margin: u16,
33 spacing: u16,
34 widgets: Vec<(Box<dyn WidgetRef>, Constraint)>,
35}
36
37impl fmt::Debug for StackContainer {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 f.debug_struct("StackContainer")
40 .field("direction", &self.direction)
41 .finish_non_exhaustive()
42 }
43}
44
45impl StackContainer {
46 pub fn new(direction: Direction) -> Self {
47 Self {
48 direction,
49 ..Default::default()
50 }
51 }
52
53 pub fn horizontal() -> Self {
54 Self::new(Direction::Horizontal)
55 }
56
57 pub fn vertical() -> Self {
58 Self::new(Direction::Vertical)
59 }
60
61 pub fn with_margin(mut self, margin: u16) -> Self {
62 self.margin = margin;
63 self
64 }
65
66 pub fn with_spacing(mut self, spacing: u16) -> Self {
67 self.spacing = spacing;
68 self
69 }
70
71 pub fn with_flex(mut self, flex: Flex) -> Self {
72 self.flex = flex;
73 self
74 }
75
76 pub fn with_widget(mut self, widget: Box<dyn WidgetRef>, constraint: Constraint) -> Self {
77 self.widgets.push((widget, constraint));
78 self
79 }
80
81 pub fn with_widgets(mut self, widgets: Vec<(Box<dyn WidgetRef>, Constraint)>) -> Self {
82 self.widgets = widgets;
83 self
84 }
85
86 pub fn push(&mut self, widget: Box<dyn WidgetRef>, constraint: Constraint) {
87 self.widgets.push((widget, constraint));
88 }
89
90 pub fn remove(&mut self, index: usize) {
91 self.widgets.remove(index);
92 }
93}
94
95impl Widget for &StackContainer {
96 fn render(self, area: Rect, buf: &mut Buffer) {
97 let layout = Layout::default()
98 .direction(self.direction)
99 .flex(self.flex)
100 .margin(self.margin)
101 .spacing(self.spacing)
102 .constraints(self.widgets.iter().map(|(_, c)| *c));
103 let areas = layout.split(area);
104 let widgets = self.widgets.iter().map(|(w, _)| w);
105 for (widget, area) in widgets.zip(areas.iter()) {
106 widget.render_ref(*area, buf);
107 }
108 }
109}