1use le::{Alignment, Layout, MinimumNatural};
4
5use crate::{
6 le::layout::{Rect, Vec2},
7 terminal::Buffer,
8 Widget,
9};
10
11pub struct Align<T: Widget> {
17 pub widget: T,
19 pub align_x: Alignment,
21 pub align_y: Alignment,
23}
24
25impl<T: Widget> Align<T> {
26 pub fn new(widget: T) -> Self {
28 Self {
29 widget,
30 align_x: Alignment::Center,
31 align_y: Alignment::Center,
32 }
33 }
34
35 pub fn align_x(mut self, alignment: Alignment) -> Self {
37 self.align_x = alignment;
38 self
39 }
40
41 pub fn align_y(mut self, alignment: Alignment) -> Self {
43 self.align_y = alignment;
44 self
45 }
46}
47
48impl<W: Widget> Layout for Align<W> {
49 fn width_for_height(&self, height: usize) -> MinimumNatural<usize> {
50 self.widget.width_for_height(height)
51 }
52 fn height_for_width(&self, width: usize) -> MinimumNatural<usize> {
53 self.widget.height_for_width(width)
54 }
55
56 fn prefered_size(&self) -> MinimumNatural<Vec2> {
57 self.widget.prefered_size()
58 }
59
60 fn prefered_size_of_container(
61 &self,
62 container: Vec2,
63 ) -> MinimumNatural<Vec2> {
64 self.widget.prefered_size_of_container(container)
65 }
66}
67
68impl<W: Widget> Widget for Align<W> {
69 fn render(&self, rect: Rect, buffer: &mut Buffer) {
70 let mut widget_size =
72 self.widget.prefered_size_of_container(rect.size).natural;
73 if self.align_x == Alignment::Expand {
74 widget_size.x = rect.size.x;
75 }
76 if self.align_y == Alignment::Expand {
77 widget_size.y = rect.size.y;
78 }
79
80 if widget_size.y > rect.size.y {
81 widget_size.x = self.widget.width_for_height(rect.size.y).natural;
82 widget_size.y = rect.size.y;
83 }
84
85 if widget_size.x > rect.size.x {
86 widget_size.y = self.widget.height_for_width(rect.size.x).natural;
87 widget_size.x = rect.size.x;
88 }
89
90 let li_x = rect.layout_info_x();
92 let li_y = rect.layout_info_y();
93
94 let al_x = self.align_x.align(li_x, widget_size.x);
96 let al_y = self.align_y.align(li_y, widget_size.y);
97
98 let aligned_rect = Rect::new(
100 al_x.start,
101 al_y.start,
102 al_x.end - al_x.start,
103 al_y.end - al_y.start,
104 );
105
106 self.widget.render(aligned_rect, buffer);
107 }
108}