mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 20:26:42 +01:00
detach all layout constructors from engine
This commit is contained in:
parent
61b447403b
commit
e0e680eb7c
19 changed files with 487 additions and 520 deletions
|
|
@ -1,59 +1,18 @@
|
|||
use crate::*;
|
||||
|
||||
impl<E: Engine> LayoutPushPull<E> for E {}
|
||||
|
||||
pub trait LayoutPushPull<E: Engine> {
|
||||
fn push_x <W: Render<E>> (x: E::Unit, w: W) -> Push<E, W> {
|
||||
Push::X(x, w)
|
||||
}
|
||||
fn push_y <W: Render<E>> (y: E::Unit, w: W) -> Push<E, W> {
|
||||
Push::Y(y, w)
|
||||
}
|
||||
fn push_xy <W: Render<E>> (x: E::Unit, y: E::Unit, w: W) -> Push<E, W> {
|
||||
Push::XY(x, y, w)
|
||||
}
|
||||
fn pull_x <W: Render<E>> (x: E::Unit, w: W) -> Pull<E, W> {
|
||||
Pull::X(x, w)
|
||||
}
|
||||
fn pull_y <W: Render<E>> (y: E::Unit, w: W) -> Pull<E, W> {
|
||||
Pull::Y(y, w)
|
||||
}
|
||||
fn pull_xy <W: Render<E>> (x: E::Unit, y: E::Unit, w: W) -> Pull<E, W> {
|
||||
Pull::XY(x, y, w)
|
||||
}
|
||||
}
|
||||
|
||||
/// Increment origin point of drawing area
|
||||
pub enum Push<E: Engine, T: Render<E>> {
|
||||
/// Move origin to the right
|
||||
X(E::Unit, T),
|
||||
/// Move origin downwards
|
||||
Y(E::Unit, T),
|
||||
/// Move origin to the right and downwards
|
||||
XY(E::Unit, E::Unit, T),
|
||||
}
|
||||
use super::*;
|
||||
|
||||
impl<E: Engine, T: Render<E>> Push<E, T> {
|
||||
pub fn inner (&self) -> &T {
|
||||
match self {
|
||||
Self::X(_, i) => i,
|
||||
Self::Y(_, i) => i,
|
||||
Self::XY(_, _, i) => i,
|
||||
}
|
||||
use Push::*;
|
||||
match self { X(_, i) => i, Y(_, i) => i, XY(_, _, i) => i, }
|
||||
}
|
||||
pub fn x (&self) -> E::Unit {
|
||||
match self {
|
||||
Self::X(x, _) => *x,
|
||||
Self::Y(_, _) => E::Unit::default(),
|
||||
Self::XY(x, _, _) => *x,
|
||||
}
|
||||
pub fn dx (&self) -> E::Unit {
|
||||
use Push::*;
|
||||
match self { X(x, _) => *x, Y(_, _) => E::Unit::default(), XY(x, _, _) => *x, }
|
||||
}
|
||||
pub fn y (&self) -> E::Unit {
|
||||
match self {
|
||||
Self::X(_, _) => E::Unit::default(),
|
||||
Self::Y(y, _) => *y,
|
||||
Self::XY(_, y, _) => *y,
|
||||
}
|
||||
pub fn dy (&self) -> E::Unit {
|
||||
use Push::*;
|
||||
match self { X(_, _) => E::Unit::default(), Y(y, _) => *y, XY(_, y, _) => *y, }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -72,17 +31,6 @@ impl<E: Engine, T: Render<E>> Render<E> for Push<E, T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Decrement origin point of drawing area
|
||||
pub enum Pull<E: Engine, T: Render<E>> {
|
||||
_Unused(PhantomData<E>),
|
||||
/// Move origin to the right
|
||||
X(E::Unit, T),
|
||||
/// Move origin downwards
|
||||
Y(E::Unit, T),
|
||||
/// Move origin to the right and downwards
|
||||
XY(E::Unit, E::Unit, T),
|
||||
}
|
||||
|
||||
impl<E: Engine, T: Render<E>> Pull<E, T> {
|
||||
pub fn inner (&self) -> &T {
|
||||
match self {
|
||||
|
|
@ -92,7 +40,7 @@ impl<E: Engine, T: Render<E>> Pull<E, T> {
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
pub fn x (&self) -> E::Unit {
|
||||
pub fn dx (&self) -> E::Unit {
|
||||
match self {
|
||||
Self::X(x, _) => *x,
|
||||
Self::Y(_, _) => E::Unit::default(),
|
||||
|
|
@ -100,7 +48,7 @@ impl<E: Engine, T: Render<E>> Pull<E, T> {
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
pub fn y (&self) -> E::Unit {
|
||||
pub fn dy (&self) -> E::Unit {
|
||||
match self {
|
||||
Self::X(_, _) => E::Unit::default(),
|
||||
Self::Y(y, _) => *y,
|
||||
|
|
@ -126,40 +74,6 @@ impl<E: Engine, T: Render<E>> Render<E> for Pull<E, T> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
impl<E: Engine + LayoutPushPull<E> + LayoutShrinkGrow<E>> LayoutInsetOutset<E> for E {}
|
||||
|
||||
pub trait LayoutInsetOutset<E: Engine>: LayoutPushPull<E> + LayoutShrinkGrow<E> {
|
||||
fn inset_x <W: Render<E>> (x: E::Unit, w: W) -> Inset<E, W> {
|
||||
Inset::X(x, w)
|
||||
}
|
||||
fn inset_y <W: Render<E>> (y: E::Unit, w: W) -> Inset<E, W> {
|
||||
Inset::Y(y, w)
|
||||
}
|
||||
fn inset_xy <W: Render<E>> (x: E::Unit, y: E::Unit, w: W) -> Inset<E, W> {
|
||||
Inset::XY(x, y, w)
|
||||
}
|
||||
fn outset_x <W: Render<E>> (x: E::Unit, w: W) -> Outset<E, W> {
|
||||
Outset::X(x, w)
|
||||
}
|
||||
fn outset_y <W: Render<E>> (y: E::Unit, w: W) -> Outset<E, W> {
|
||||
Outset::Y(y, w)
|
||||
}
|
||||
fn outset_xy <W: Render<E>> (x: E::Unit, y: E::Unit, w: W) -> Outset<E, W> {
|
||||
Outset::XY(x, y, w)
|
||||
}
|
||||
}
|
||||
|
||||
/// Shrink from each side
|
||||
pub enum Inset<E: Engine, T> {
|
||||
/// 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>> Inset<E, T> {
|
||||
pub fn inner (&self) -> &T {
|
||||
match self {
|
||||
|
|
@ -173,23 +87,13 @@ impl<E: Engine, T: Render<E>> Inset<E, T> {
|
|||
impl<E: Engine, T: Render<E>> Render<E> for Inset<E, T> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
match self {
|
||||
Self::X(x, inner) => E::push_x(*x, E::shrink_x(*x, inner)),
|
||||
Self::Y(y, inner) => E::push_y(*y, E::shrink_y(*y, inner)),
|
||||
Self::XY(x, y, inner) => E::push_xy(*x, *y, E::shrink_xy(*x, *y, inner)),
|
||||
Self::X(x, inner) => Push::x(*x, Shrink::x(*x, inner)),
|
||||
Self::Y(y, inner) => Push::y(*y, Shrink::y(*y, inner)),
|
||||
Self::XY(x, y, inner) => Push::xy(*x, *y, Shrink::xy(*x, *y, inner)),
|
||||
}.render(to)
|
||||
}
|
||||
}
|
||||
|
||||
/// Grow on each side
|
||||
pub enum Outset<E: Engine, T: Render<E>> {
|
||||
/// Increase width
|
||||
X(E::Unit, T),
|
||||
/// Increase height
|
||||
Y(E::Unit, T),
|
||||
/// Increase width and height
|
||||
XY(E::Unit, E::Unit, T),
|
||||
}
|
||||
|
||||
|
||||
impl<E: Engine, T: Render<E>> Outset<E, T> {
|
||||
pub fn inner (&self) -> &T {
|
||||
|
|
@ -204,16 +108,84 @@ impl<E: Engine, T: Render<E>> Outset<E, T> {
|
|||
impl<E: Engine, T: Render<E>> Render<E> for Outset<E, T> {
|
||||
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
match *self {
|
||||
Self::X(x, ref inner) => E::grow_x(x + x, inner),
|
||||
Self::Y(y, ref inner) => E::grow_y(y + y, inner),
|
||||
Self::XY(x, y, ref inner) => E::grow_xy(x + x, y + y, inner),
|
||||
Self::X(x, ref inner) => Grow::x(x + x, inner),
|
||||
Self::Y(y, ref inner) => Grow::y(y + y, inner),
|
||||
Self::XY(x, y, ref inner) => Grow::xy(x + x, y + y, inner),
|
||||
}.min_size(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
match *self {
|
||||
Self::X(x, ref inner) => E::push_x(x, inner),
|
||||
Self::Y(y, ref inner) => E::push_y(y, inner),
|
||||
Self::XY(x, y, ref inner) => E::push_xy(x, y, inner),
|
||||
Self::X(x, ref inner) => Push::x(x, inner),
|
||||
Self::Y(y, ref inner) => Push::y(y, inner),
|
||||
Self::XY(x, y, ref inner) => Push::xy(x, y, inner),
|
||||
}.render(to)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine, T: Render<E>> Align<E, T> {
|
||||
pub fn c (w: T) -> Self { Self::Center(w) }
|
||||
pub fn x (w: T) -> Self { Self::X(w) }
|
||||
pub fn y (w: T) -> Self { Self::Y(w) }
|
||||
pub fn n (w: T) -> Self { Self::N(w) }
|
||||
pub fn s (w: T) -> Self { Self::S(w) }
|
||||
pub fn e (w: T) -> Self { Self::E(w) }
|
||||
pub fn w (w: T) -> Self { Self::W(w) }
|
||||
pub fn nw (w: T) -> Self { Self::NW(w) }
|
||||
pub fn sw (w: T) -> Self { Self::SW(w) }
|
||||
pub fn ne (w: T) -> Self { Self::NE(w) }
|
||||
pub fn se (w: T) -> Self { Self::SE(w) }
|
||||
pub fn inner (&self) -> &T {
|
||||
match self {
|
||||
Self::Center(inner) => inner,
|
||||
Self::X(inner) => inner,
|
||||
Self::Y(inner) => inner,
|
||||
Self::NW(inner) => inner,
|
||||
Self::N(inner) => inner,
|
||||
Self::NE(inner) => inner,
|
||||
Self::W(inner) => inner,
|
||||
Self::E(inner) => inner,
|
||||
Self::SW(inner) => inner,
|
||||
Self::S(inner) => inner,
|
||||
Self::SE(inner) => inner,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn align<E: Engine, T: Render<E>, N: Coordinate, R: Area<N> + From<[N;4]>> (align: &Align<E, T>, outer: R, inner: R) -> Option<R> {
|
||||
if outer.w() < inner.w() || outer.h() < inner.h() {
|
||||
None
|
||||
} else {
|
||||
let [ox, oy, ow, oh] = outer.xywh();
|
||||
let [ix, iy, iw, ih] = inner.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!()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine, T: Render<E>> Render<E> for Align<E, T> {
|
||||
fn min_size (&self, outer_area: E::Size) -> Perhaps<E::Size> {
|
||||
self.inner().min_size(outer_area)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
let outer_area = to.area();
|
||||
Ok(if let Some(inner_size) = self.min_size(outer_area.wh().into())? {
|
||||
let inner_area = outer_area.clip(inner_size);
|
||||
if let Some(aligned) = align(&self, outer_area.into(), inner_area.into()) {
|
||||
to.render_in(aligned, self.inner())?
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue