1use chargrid_core::*;
2
3#[derive(Debug, Clone, Copy)]
4pub enum AlignmentX {
5 Left,
6 Centre,
7 Right,
8}
9
10#[derive(Debug, Clone, Copy)]
11pub enum AlignmentY {
12 Top,
13 Centre,
14 Bottom,
15}
16
17#[derive(Debug, Clone, Copy)]
18pub struct Alignment {
19 pub x: AlignmentX,
20 pub y: AlignmentY,
21}
22
23impl Alignment {
24 pub fn centre() -> Self {
25 Self {
26 x: AlignmentX::Centre,
27 y: AlignmentY::Centre,
28 }
29 }
30}
31
32pub struct Align<C: Component> {
33 pub component: C,
34 pub alignment: Alignment,
35}
36
37impl<C: Component> Align<C> {
38 pub fn centre(component: C) -> Self {
39 Self {
40 component,
41 alignment: Alignment::centre(),
42 }
43 }
44 fn child_ctx<'a>(&self, state: &C::State, ctx: Ctx<'a>) -> Ctx<'a> {
45 let size = self.component.size(state, ctx);
46 let ctx_size = ctx.bounding_box.size();
47 let x_offset = match self.alignment.x {
48 AlignmentX::Left => 0,
49 AlignmentX::Centre => (ctx_size.x() as i32 - size.x() as i32) / 2,
50 AlignmentX::Right => ctx_size.x() as i32 - size.x() as i32,
51 };
52 let y_offset = match self.alignment.y {
53 AlignmentY::Top => 0,
54 AlignmentY::Centre => (ctx_size.y() as i32 - size.y() as i32) / 2,
55 AlignmentY::Bottom => ctx_size.y() as i32 - size.y() as i32,
56 };
57 ctx.add_offset(Coord::new(x_offset, y_offset))
58 }
59}
60
61impl<C: Component> Component for Align<C> {
62 type Output = C::Output;
63 type State = C::State;
64 fn render(&self, state: &Self::State, ctx: Ctx, fb: &mut FrameBuffer) {
65 self.component.render(state, self.child_ctx(state, ctx), fb);
66 }
67 fn update(&mut self, state: &mut Self::State, ctx: Ctx, event: Event) -> Self::Output {
68 self.component
69 .update(state, self.child_ctx(state, ctx), event)
70 }
71 fn size(&self, state: &Self::State, ctx: Ctx) -> Size {
72 self.component.size(state, self.child_ctx(state, ctx))
73 }
74}