tek/crates/tek_layout/src/shrink.rs

62 lines
1.8 KiB
Rust

use crate::*;
impl<E: Engine, W: Render<E>> LayoutShrink<E> for W {}
pub trait LayoutShrink<E: Engine>: Render<E> + Sized {
fn shrink_x (self, x: E::Unit) -> Shrink<E, Self> {
Shrink::X(x, self)
}
fn shrink_y (self, y: E::Unit) -> Shrink<E, Self> {
Shrink::Y(y, self)
}
fn shrink_xy (self, x: E::Unit, y: E::Unit) -> Shrink<E, Self> {
Shrink::XY(x, y, self)
}
}
/// Shrink drawing area
pub enum Shrink<E: Engine, T> {
_Unused(PhantomData<E>),
/// Decrease width
X(E::Unit, T),
/// Decrease height
Y(E::Unit, T),
/// Decrease width and height
XY(E::Unit, E::Unit, T),
}
impl<E: Engine, T: Render<E>> Shrink<E, T> {
fn inner (&self) -> &T {
match self {
Self::X(_, i) => i,
Self::Y(_, i) => i,
Self::XY(_, _, i) => i,
_ => unreachable!(),
}
}
}
impl<E: Engine, T: Render<E>> Render<E> for Shrink<E, T> {
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
Ok(self.inner().min_size(to)?.map(|to|match *self {
Self::X(w, _) => [
if to.w() > w { to.w() - w } else { 0.into() },
to.h()
],
Self::Y(h, _) => [
to.w(),
if to.h() > h { to.h() - h } else { 0.into() }
],
Self::XY(w, h, _) => [
if to.w() > w { to.w() - w } else { 0.into() },
if to.h() > h { to.h() - h } else { 0.into() }
],
_ => unreachable!(),
}.into()))
}
fn render (&self, to: &mut E::Output) -> Usually<()> {
Ok(self.min_size(to.area().wh().into())?
.map(|size|to.render_in(to.area().clip(size).into(), self.inner()))
.transpose()?.unwrap_or(()))
}
}