rustty 0.1.12

A terminal UI library
Documentation
use core::position::{Pos, Size, HasSize, HasPosition};

pub enum VerticalAlign {
    Top,
    Middle,
    Bottom,
}

pub enum HorizontalAlign {
    Left,
    Middle,
    Right,
}

pub trait Alignable: HasSize + HasPosition {
    fn halign(&mut self, parent: &HasSize, halign: HorizontalAlign, margin: usize) {
        let (cols, _) = self.size();
        let (_, y) = self.origin();
        let (parent_cols, _) = parent.size();
        let newx = match halign {
            HorizontalAlign::Left => margin,
            HorizontalAlign::Right => parent_cols - cols - margin,
            HorizontalAlign::Middle => (parent_cols - cols) / 2,
        };
        self.set_origin((newx, y));
    }

    fn valign(&mut self, parent: &HasSize, valign: VerticalAlign, margin: usize) {
        let (_, rows) = self.size();
        let (x, _) = self.origin();
        let (_, parent_rows) = parent.size();
        let newy = match valign {
            VerticalAlign::Top => margin,
            VerticalAlign::Bottom => parent_rows - rows - margin,
            VerticalAlign::Middle => (parent_rows - rows) / 2,
        };
        self.set_origin((x, newy));
    }

    fn align(&mut self,
             parent: &HasSize,
             halign: HorizontalAlign,
             valign: VerticalAlign,
             margin: usize) {
        self.halign(parent, halign, margin);
        self.valign(parent, valign, margin);
    }
}

pub struct HorizontalLayout<'a> {
    origin: Pos,
    size: Size,
    inner_margin: usize,
    elems: Vec<&'a mut Alignable>,
}

impl<'a> HorizontalLayout<'a> {
    pub fn new(elems: Vec<&mut Alignable>, inner_margin: usize) -> HorizontalLayout {
        let first_origin = elems.first().unwrap().origin();
        let total_width = elems.iter().fold(0, |acc, item| acc + item.size().0);
        let width = total_width + inner_margin * (elems.len() - 1);
        HorizontalLayout {
            origin: first_origin,
            size: (width, 1),
            inner_margin: inner_margin,
            elems: elems,
        }
    }

    pub fn align_elems(&mut self) {
        let (x, y) = self.origin();
        let mut current_x = x;
        for elem in self.elems.iter_mut() {
            elem.set_origin((current_x, y));
            current_x += elem.size().0 + self.inner_margin;
        }
    }
}

impl<'a> HasSize for HorizontalLayout<'a> {
    fn size(&self) -> Size {
        self.size
    }
}

impl<'a> HasPosition for HorizontalLayout<'a> {
    fn origin(&self) -> Pos {
        self.origin
    }

    fn set_origin(&mut self, new_origin: Pos) {
        self.origin = new_origin;
    }
}

impl<'a> Alignable for HorizontalLayout<'a> {}