1use core::position::{Pos, Size, HasSize, HasPosition};
2
3pub enum VerticalAlign {
4 Top,
5 Middle,
6 Bottom,
7}
8
9pub enum HorizontalAlign {
10 Left,
11 Middle,
12 Right,
13}
14
15pub trait Alignable: HasSize + HasPosition {
16 fn halign(&mut self, parent: &HasSize, halign: HorizontalAlign, margin: usize) {
17 let (cols, _) = self.size();
18 let (_, y) = self.origin();
19 let (parent_cols, _) = parent.size();
20 let newx = match halign {
21 HorizontalAlign::Left => margin,
22 HorizontalAlign::Right => parent_cols - cols - margin,
23 HorizontalAlign::Middle => (parent_cols - cols) / 2,
24 };
25 self.set_origin((newx, y));
26 }
27
28 fn valign(&mut self, parent: &HasSize, valign: VerticalAlign, margin: usize) {
29 let (_, rows) = self.size();
30 let (x, _) = self.origin();
31 let (_, parent_rows) = parent.size();
32 let newy = match valign {
33 VerticalAlign::Top => margin,
34 VerticalAlign::Bottom => parent_rows - rows - margin,
35 VerticalAlign::Middle => (parent_rows - rows) / 2,
36 };
37 self.set_origin((x, newy));
38 }
39
40 fn align(&mut self,
41 parent: &HasSize,
42 halign: HorizontalAlign,
43 valign: VerticalAlign,
44 margin: usize) {
45 self.halign(parent, halign, margin);
46 self.valign(parent, valign, margin);
47 }
48}
49
50pub struct HorizontalLayout<'a> {
51 origin: Pos,
52 size: Size,
53 inner_margin: usize,
54 elems: Vec<&'a mut Alignable>,
55}
56
57impl<'a> HorizontalLayout<'a> {
58 pub fn new(elems: Vec<&mut Alignable>, inner_margin: usize) -> HorizontalLayout {
59 let first_origin = elems.first().unwrap().origin();
60 let total_width = elems.iter().fold(0, |acc, item| acc + item.size().0);
61 let width = total_width + inner_margin * (elems.len() - 1);
62 HorizontalLayout {
63 origin: first_origin,
64 size: (width, 1),
65 inner_margin: inner_margin,
66 elems: elems,
67 }
68 }
69
70 pub fn align_elems(&mut self) {
71 let (x, y) = self.origin();
72 let mut current_x = x;
73 for elem in self.elems.iter_mut() {
74 elem.set_origin((current_x, y));
75 current_x += elem.size().0 + self.inner_margin;
76 }
77 }
78}
79
80impl<'a> HasSize for HorizontalLayout<'a> {
81 fn size(&self) -> Size {
82 self.size
83 }
84}
85
86impl<'a> HasPosition for HorizontalLayout<'a> {
87 fn origin(&self) -> Pos {
88 self.origin
89 }
90
91 fn set_origin(&mut self, new_origin: Pos) {
92 self.origin = new_origin;
93 }
94}
95
96impl<'a> Alignable for HorizontalLayout<'a> {}