use crate::*; #[derive(Debug, Copy, Clone, Default)] pub enum Alignment { #[default] Center, X, Y, NW, N, NE, E, SE, S, SW, W } pub struct Align>(Alignment, T, PhantomData); impl> Align { pub fn c (a: T) -> Self { Self(Alignment::Center, a, Default::default()) } pub fn x (a: T) -> Self { Self(Alignment::X, a, Default::default()) } pub fn y (a: T) -> Self { Self(Alignment::Y, a, Default::default()) } pub fn n (a: T) -> Self { Self(Alignment::N, a, Default::default()) } pub fn s (a: T) -> Self { Self(Alignment::S, a, Default::default()) } pub fn e (a: T) -> Self { Self(Alignment::E, a, Default::default()) } pub fn w (a: T) -> Self { Self(Alignment::W, a, Default::default()) } pub fn nw (a: T) -> Self { Self(Alignment::NW, a, Default::default()) } pub fn sw (a: T) -> Self { Self(Alignment::SW, a, Default::default()) } pub fn ne (a: T) -> Self { Self(Alignment::NE, a, Default::default()) } pub fn se (a: T) -> Self { Self(Alignment::SE, a, Default::default()) } } impl> Content for Align { fn content (&self) -> impl Content { &self.1 } fn layout (&self, on: E::Area) -> E::Area { use Alignment::*; let it = self.content().layout(on).xywh(); let centered = on.center_xy(it.wh()); let far_x = (on.x() + on.w()).minus(it.w()); let far_y = (on.y() + on.h()).minus(it.h()); let [x, y] = match self.0 { NW => [on.x(), on.y()], N => [centered.x(), on.y()], NE => [far_x, on.y()], E => [far_x, centered.y()], SE => [far_x, far_y ], S => [centered.x(), far_y ], SW => [on.x(), far_y ], W => [on.x(), centered.y()], Center => centered.xy(), X => [centered.x(), it.y()], Y => [it.x(), centered.y()], }; [x, y, centered.w(), centered.h()].into() //let [cfx, cfy, ..] = on.center(); //let [cmx, cmy, ..] = it.center(); ////let center = |cf, cm, m|if cf >= cm { m + (cf - cm) } else { m.minus(cm - cf) }; //let center_x = center(cfx, cmx, it.x()); //let center_y = center(cfy, cmy, it.y()); //let east_x = on.x() + on.w().minus(it.w()); //let south_y = on.y() + on.h().minus(it.h()); //let [x, y] = match self.0 { //Alignment::X => [center_x, it.y(), ], //Alignment::Y => [it.x(), center_y,], //Alignment::NW => [on.x(), on.y(), ], //Alignment::N => [center_x, on.y(), ], //Alignment::NE => [east_x, on.y(), ], //Alignment::E => [east_x, center_y,], //Alignment::SE => [east_x, south_y, ], //Alignment::S => [center_x, south_y, ], //Alignment::SW => [on.x(), south_y, ], //Alignment::W => [on.x(), center_y,], //}; //[x, y, it.w(), it.h()].into() } fn render (&self, render: &mut E::Output) { render.place(self.layout(render.area()), &self.content()) } } //fn align, N: Coordinate, R: Area + From<[N;4]>> (align: &Align, outer: R, content: R) -> Option { //if outer.w() < content.w() || outer.h() < content.h() { //None //} else { //let [ox, oy, ow, oh] = outer.xywh(); //let [ix, iy, iw, ih] = content.xywh(); //Some(match align { //Align::Center(_) => [ox + (ow - iw) / 2.into(), oy + (oh - ih) / 2.into(), iw, ih,].into(), //Align::X(_) => [ox + (ow - iw) / 2.into(), iy, iw, ih,].into(), //Align::Y(_) => [ix, oy + (oh - ih) / 2.into(), iw, ih,].into(), //Align::NW(_) => [ox, oy, iw, ih,].into(), //Align::N(_) => [ox + (ow - iw) / 2.into(), oy, iw, ih,].into(), //Align::NE(_) => [ox + ow - iw, oy, iw, ih,].into(), //Align::W(_) => [ox, oy + (oh - ih) / 2.into(), iw, ih,].into(), //Align::E(_) => [ox + ow - iw, oy + (oh - ih) / 2.into(), iw, ih,].into(), //Align::SW(_) => [ox, oy + oh - ih, iw, ih,].into(), //Align::S(_) => [ox + (ow - iw) / 2.into(), oy + oh - ih, iw, ih,].into(), //Align::SE(_) => [ox + ow - iw, oy + oh - ih, iw, ih,].into(), //_ => unreachable!() //}) //} //}