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