use euclid::{Rect, Size2D};
use crate::{event::Event, unit::Cell, Printer, View as ViewTrait};
pub enum Alignment {
Start,
Middle,
End,
}
pub struct View<V> {
inner: V,
v: Alignment,
h: Alignment,
}
impl<V> View<V> {
pub fn new(view: V) -> Self {
Self {
inner: view,
v: Alignment::Middle,
h: Alignment::Middle,
}
}
pub fn h_align(mut self, alignment: Alignment) -> Self {
self.h = alignment;
self
}
pub fn v_align(mut self, alignment: Alignment) -> Self {
self.v = alignment;
self
}
}
pub fn new<V>(view: V) -> View<V> {
View::new(view)
}
impl<T, M, V> ViewTrait<T, M> for View<V>
where
V: ViewTrait<T, M>,
{
fn draw(&self, printer: &Printer, focused: bool) {
let p_size = printer.size();
let inner_size =
self.inner.layout((p_size.width, p_size.height).into());
let origin = {
let x = match self.h {
Alignment::Start => 0,
Alignment::Middle => {
(p_size.width / 2).saturating_sub(inner_size.width / 2)
}
Alignment::End => p_size.width.saturating_sub(inner_size.width),
};
let y = match self.v {
Alignment::Start => 0,
Alignment::Middle => {
(p_size.height / 2).saturating_sub(inner_size.height / 2)
}
Alignment::End => {
p_size.height.saturating_sub(inner_size.height)
}
};
(x, y)
};
let sub =
printer.to_sub_area(Rect::new(origin.into(), inner_size)).unwrap();
self.inner.draw(&sub, focused);
}
fn width(&self) -> Size2D<u16, Cell> {
self.inner.width()
}
fn height(&self) -> Size2D<u16, Cell> {
self.inner.height()
}
fn layout(&self, constraint: Size2D<u16, Cell>) -> Size2D<u16, Cell> {
self.inner.layout(constraint)
}
fn event(
&mut self,
event: &Event<T>,
focused: bool,
) -> Box<dyn Iterator<Item = M>> {
self.inner.event(event, focused)
}
fn interactive(&self) -> bool {
self.inner.interactive()
}
}
pub trait ViewExt {
fn align(self) -> View<Self>
where
Self: Sized,
{
View::new(self)
}
}
impl<V> ViewExt for V {}