Skip to main content

prototty_decorator/
align.rs

1use prototty_render::*;
2#[cfg(feature = "serialize")]
3use serde::{Deserialize, Serialize};
4
5#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
6#[derive(Debug, Clone, Copy)]
7pub enum AlignmentX {
8    Left,
9    Centre,
10    Right,
11}
12
13#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
14#[derive(Debug, Clone, Copy)]
15pub enum AlignmentY {
16    Top,
17    Centre,
18    Bottom,
19}
20
21#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
22#[derive(Debug, Clone, Copy)]
23pub struct Alignment {
24    pub x: AlignmentX,
25    pub y: AlignmentY,
26}
27
28impl Alignment {
29    pub fn new(x: AlignmentX, y: AlignmentY) -> Self {
30        Self { x, y }
31    }
32    pub fn centre() -> Self {
33        Self::new(AlignmentX::Centre, AlignmentY::Centre)
34    }
35}
36
37pub struct AlignView<V> {
38    pub view: V,
39    pub alignment: Alignment,
40}
41
42impl<V, T> View<T> for AlignView<V>
43where
44    V: View<T>,
45    T: Clone,
46{
47    fn view<F: Frame, C: ColModify>(&mut self, data: T, context: ViewContext<C>, frame: &mut F) {
48        let data_size = self.view.size(data.clone(), context);
49        let x_offset = match self.alignment.x {
50            AlignmentX::Left => 0,
51            AlignmentX::Centre => (context.size.x() as i32 - data_size.x() as i32) / 2,
52            AlignmentX::Right => context.size.x() as i32 - data_size.x() as i32,
53        };
54        let y_offset = match self.alignment.y {
55            AlignmentY::Top => 0,
56            AlignmentY::Centre => (context.size.y() as i32 - data_size.y() as i32) / 2,
57            AlignmentY::Bottom => context.size.y() as i32 - data_size.y() as i32,
58        };
59        self.view
60            .view(data, context.add_offset(Coord::new(x_offset, y_offset)), frame);
61    }
62}