mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-08-28 05:06:56 +02:00
449 lines
17 KiB
Rust
449 lines
17 KiB
Rust
use crate::*;
|
|
|
|
pub enum Full<'a, S: Screen, I: Draw<S>> {
|
|
__(PhantomData<&'a S>), W(I), H(I), WH(I),
|
|
}
|
|
|
|
pub enum Exact<'a, S: Screen, I: Draw<S>, X: Into<Option<S::Unit>>> {
|
|
__(PhantomData<&'a S>), W(I, X), H(I, X), WH(I, X, X),
|
|
}
|
|
|
|
pub enum Push<'a, S: Screen, I: Draw<S>, X: Into<Option<S::Unit>>> {
|
|
__(PhantomData<&'a S>), X(I, X), Y(I, X), XY(I, X, X),
|
|
}
|
|
|
|
pub enum Pull<'a, S: Screen, I: Draw<S>, X: Into<Option<S::Unit>>> {
|
|
__(PhantomData<&'a S>), X(I, X), Y(I, X), XY(I, X, X),
|
|
}
|
|
|
|
pub enum Min<'a, S: Screen, I: Draw<S>, X: Into<Option<S::Unit>>> {
|
|
__(PhantomData<&'a S>), W(I, X), H(I, X), WH(I, X, X),
|
|
}
|
|
|
|
pub enum Max<'a, S: Screen, I: Draw<S>, X: Into<Option<S::Unit>>> {
|
|
__(PhantomData<&'a S>), W(I, X), H(I, X), WH(I, X, X),
|
|
}
|
|
|
|
pub enum Pad<'a, S: Screen, I: Draw<S>, X: Into<Option<S::Unit>>> {
|
|
__(PhantomData<&'a S>), X(I, X), Y(I, X), XY(I, X, X),
|
|
}
|
|
|
|
/// ```
|
|
/// # use ::tengri::*; fn test_layout_full () -> Usually<()> {
|
|
/// assert_eq!(check_layout("1")?, Some(XYWH(1u16, 1, 1, 1)));
|
|
/// assert_eq!(check_layout("1".full_w())?, Some(XYWH(1u16, 1, 80, 1)));
|
|
/// assert_eq!(check_layout("1".full_h())?, Some(XYWH(1u16, 1, 1, 25)));
|
|
/// assert_eq!(check_layout("1".full_wh())?, Some(XYWH(1u16, 1, 80, 25)));
|
|
/// # Ok(()) }
|
|
/// ```
|
|
pub trait LayoutFull<'a, S: Screen>: Draw<S> + Sized {
|
|
fn full_w (self) -> Full<'a, S, Self> { Full::W(self) }
|
|
fn full_h (self) -> Full<'a, S, Self> { Full::H(self) }
|
|
fn full_wh (self) -> Full<'a, S, Self> { Full::WH(self) }
|
|
}
|
|
|
|
/// ```
|
|
/// # use ::tengri::*; fn test_layout_exact () -> Usually<()> {
|
|
/// assert_eq!(check_layout("FOOBAR\nKILROY")?, Some(XYWH(1, 1, 6, 2)));
|
|
/// assert_eq!(check_layout("FOOBAR\nKILROY".exact_w(3))?, Some(XYWH(1, 1, 3, 2)));
|
|
/// assert_eq!(check_layout("FOOBAR\nKILROY".exact_h(1))?, Some(XYWH(1, 1, 6, 1)));
|
|
/// assert_eq!(check_layout("FOOBAR\nKILROY".exact_wh(2, 1))?, Some(XYWH(1, 1, 2, 1)));
|
|
/// # Ok(()) }
|
|
/// ```
|
|
pub trait LayoutExact<'a, S: Screen>: Draw<S> + Sized {
|
|
fn exact_w <X: Into<Option<S::Unit>> + Copy> (self, w: X)
|
|
-> Exact<'a, S, Self, X> { Exact::W(self, w) }
|
|
fn exact_h <X: Into<Option<S::Unit>> + Copy> (self, h: X)
|
|
-> Exact<'a, S, Self, X> { Exact::H(self, h) }
|
|
fn exact_wh <X: Into<Option<S::Unit>> + Copy> (self, w: X, h: X)
|
|
-> Exact<'a, S, Self, X> { Exact::WH(self, w, h) }
|
|
}
|
|
|
|
/// ```
|
|
/// # use ::tengri::*; fn test_layout_min () -> Usually<()> {
|
|
/// assert_eq!(check_layout("1".min_w(5))?, Some(XYWH(1u16, 1, 5, 1)));
|
|
/// assert_eq!(check_layout("1".min_h(5))?, Some(XYWH(1u16, 1, 1, 5)));
|
|
/// assert_eq!(check_layout("1".min_wh(5, 5))?, Some(XYWH(1u16, 1, 5, 5)));
|
|
/// assert_eq!(check_layout("123456".min_w(5))?, Some(XYWH(1u16, 1, 6, 1)));
|
|
/// # Ok(()) }
|
|
/// ```
|
|
pub trait LayoutMin<'a, S: Screen>: Draw<S> + Sized {
|
|
fn min_w <X: Into<Option<S::Unit>> + Copy> (self, w: X)
|
|
-> Min<'a, S, Self, X> { Min::W(self, w) }
|
|
fn min_h <X: Into<Option<S::Unit>> + Copy> (self, h: X)
|
|
-> Min<'a, S, Self, X> { Min::H(self, h) }
|
|
fn min_wh <X: Into<Option<S::Unit>> + Copy> (self, w: X, h: X)
|
|
-> Min<'a, S, Self, X> { Min::WH(self, w, h) }
|
|
}
|
|
|
|
pub trait LayoutMax<'a, S: Screen>: Draw<S> + Sized {
|
|
fn max_w <X: Into<Option<S::Unit>> + Copy> (self, w: X)
|
|
-> Max<'a, S, Self, X> { Max::W(self, w) }
|
|
fn max_h <X: Into<Option<S::Unit>> + Copy> (self, h: X)
|
|
-> Max<'a, S, Self, X> { Max::H(self, h) }
|
|
fn max_wh <X: Into<Option<S::Unit>> + Copy> (self, w: X, h: X)
|
|
-> Max<'a, S, Self, X> { Max::WH(self, w, h) }
|
|
}
|
|
|
|
pub trait LayoutPad<'a, S: Screen>: Draw<S> + Sized {
|
|
fn pad_w <X: Into<Option<S::Unit>> + Copy> (self, w: X)
|
|
-> Pad<'a, S, Self, X> { Pad::X(self, w) }
|
|
fn pad_h <X: Into<Option<S::Unit>> + Copy> (self, h: X)
|
|
-> Pad<'a, S, Self, X> { Pad::Y(self, h) }
|
|
fn pad_wh <X: Into<Option<S::Unit>> + Copy> (self, w: X, h: X)
|
|
-> Pad<'a, S, Self, X> { Pad::XY(self, w, h) }
|
|
}
|
|
|
|
/// ```
|
|
/// # use ::tengri::*; fn test_layout_pull () -> Usually<()> {
|
|
/// assert_eq!(check_layout("1")?, Some(XYWH(1u16, 1, 1, 1)));
|
|
/// assert_eq!(check_layout("1".push_x(1))?, Some(XYWH(2u16, 1, 1, 1)));
|
|
/// assert_eq!(check_layout("1".push_y(1))?, Some(XYWH(1u16, 2, 1, 1)));
|
|
/// assert_eq!(check_layout("1".push_xy(1, 1))?, Some(XYWH(2u16, 2, 1, 1)));
|
|
/// # Ok(()) }
|
|
/// ```
|
|
pub trait LayoutPush<'a, S: Screen>: Draw<S> + Sized {
|
|
fn push_x <X: Into<Option<S::Unit>> + Copy> (self, w: X)
|
|
-> Push<'a, S, Self, X> { Push::X(self, w) }
|
|
fn push_y <X: Into<Option<S::Unit>> + Copy> (self, h: X)
|
|
-> Push<'a, S, Self, X> { Push::Y(self, h) }
|
|
fn push_xy <X: Into<Option<S::Unit>> + Copy> (self, w: X, h: X)
|
|
-> Push<'a, S, Self, X> { Push::XY(self, w, h) }
|
|
}
|
|
|
|
/// ```
|
|
/// # use ::tengri::*; fn test_layout_push () -> Usually<()> {
|
|
/// assert_eq!(check_layout("1")?, Some(XYWH(1u16, 1, 1, 1)));
|
|
/// assert_eq!(check_layout("1".pull_x(1))?, Some(XYWH(0u16, 1, 1, 1)));
|
|
/// assert_eq!(check_layout("1".pull_y(1))?, Some(XYWH(1u16, 0, 1, 1)));
|
|
/// assert_eq!(check_layout("1".pull_xy(1, 1))?, Some(XYWH(0u16, 0, 1, 1)));
|
|
/// # Ok(()) }
|
|
/// ```
|
|
pub trait LayoutPull<'a, S: Screen>: Draw<S> + Sized {
|
|
fn pull_x <X: Into<Option<S::Unit>> + Copy> (self, w: X)
|
|
-> Pull<'a, S, Self, X> { Pull::X(self, w) }
|
|
fn pull_y <X: Into<Option<S::Unit>> + Copy> (self, h: X)
|
|
-> Pull<'a, S, Self, X> { Pull::Y(self, h) }
|
|
fn pull_xy <X: Into<Option<S::Unit>> + Copy> (self, w: X, h: X)
|
|
-> Pull<'a, S, Self, X> { Pull::XY(self, w, h) }
|
|
}
|
|
|
|
#[cfg(all(feature = "draw", feature = "eval"))]
|
|
pub fn kw_full <O, S> (state: &S, to: &mut O, expr: &str)
|
|
-> Perhaps<XYWH<O::Unit>>
|
|
where
|
|
O: Screen,
|
|
S: Interpret<O, Option<XYWH<O::Unit>>>
|
|
+ Namespace<bool>
|
|
+ Namespace<O::Unit>
|
|
+ Namespace<Option<O::Unit>>
|
|
{
|
|
let thunk = draw(move|screen|ok_flat(expr.nth(1)?.map(|x|state.interpret(screen, x))));
|
|
Ok(match expr.head()? {
|
|
Some("full/x") | Some("full/w") => Full::W(thunk).draw(to)?,
|
|
Some("full/y") | Some("full/h") => Full::H(thunk).draw(to)?,
|
|
Some("full/xy") | Some("full/wh") => Full::WH(thunk).draw(to)?,
|
|
frag => return Err(format!("full: invalid variant: {frag:?}").into())
|
|
})
|
|
}
|
|
|
|
#[cfg(all(feature = "draw", feature = "eval"))]
|
|
pub fn kw_exact <O, S> (state: &S, to: &mut O, expr: &str)
|
|
-> Perhaps<XYWH<O::Unit>>
|
|
where
|
|
O: Screen,
|
|
S: Interpret<O, Option<XYWH<O::Unit>>>
|
|
+ Namespace<bool>
|
|
+ Namespace<O::Unit>
|
|
+ Namespace<Option<O::Unit>>
|
|
{
|
|
let thunk = draw(move|screen|ok_flat(expr.last()?.map(|x|state.interpret(screen, x))));
|
|
Ok(match expr.head()? {
|
|
Some("exact/w") => thunk.exact_w(
|
|
state.namespace(&expr.nth(1)?)?
|
|
).draw(to)?,
|
|
Some("exact/h") => thunk.exact_h(
|
|
state.namespace(&expr.nth(1)?)?
|
|
).draw(to)?,
|
|
Some("exact/wh") => thunk.exact_wh(
|
|
state.namespace(&expr.nth(1)?)?,
|
|
state.namespace(&expr.nth(2)?)?,
|
|
).draw(to)?,
|
|
_ => return Err(format!("exact: invalid variant: {:?}", expr.head()?).into())
|
|
})
|
|
}
|
|
|
|
#[cfg(all(feature = "draw", feature = "eval"))]
|
|
pub fn kw_min <O, S> (state: &S, to: &mut O, expr: &str)
|
|
-> Perhaps<XYWH<O::Unit>>
|
|
where
|
|
O: Screen,
|
|
S: Interpret<O, Option<XYWH<O::Unit>>>
|
|
+ Namespace<bool>
|
|
+ Namespace<O::Unit>
|
|
+ Namespace<Option<O::Unit>>
|
|
{
|
|
let thunk = draw(move|screen|ok_flat(expr.last()?.map(|x|state.interpret(screen, x))));
|
|
Ok(match expr.head()? {
|
|
Some("min/w") => thunk.min_w(
|
|
state.namespace(&expr.nth(1)?)?
|
|
).draw(to)?,
|
|
Some("min/h") => thunk.min_h(
|
|
state.namespace(&expr.nth(1)?)?
|
|
).draw(to)?,
|
|
Some("min/wh") => thunk.min_wh(
|
|
state.namespace(&expr.nth(1)?)?,
|
|
state.namespace(&expr.nth(2)?)?,
|
|
).draw(to)?,
|
|
_ => return Err(format!("min: invalid variant: {:?}", expr.head()?).into())
|
|
})
|
|
}
|
|
|
|
#[cfg(all(feature = "draw", feature = "eval"))]
|
|
pub fn kw_max <O, S> (state: &S, to: &mut O, expr: &str)
|
|
-> Perhaps<XYWH<O::Unit>>
|
|
where
|
|
O: Screen,
|
|
S: Interpret<O, Option<XYWH<O::Unit>>>
|
|
+ Namespace<bool>
|
|
+ Namespace<O::Unit>
|
|
+ Namespace<Option<O::Unit>>
|
|
{
|
|
let thunk = draw(move|screen|ok_flat(expr.last()?.map(|x|state.interpret(screen, x))));
|
|
Ok(match expr.head()? {
|
|
Some("max/w") => thunk.max_w(
|
|
state.namespace(&expr.nth(1)?)?
|
|
).draw(to)?,
|
|
Some("max/h") => thunk.max_h(
|
|
state.namespace(&expr.nth(1)?)?
|
|
).draw(to)?,
|
|
Some("max/wh") => thunk.max_wh(
|
|
state.namespace(&expr.nth(1)?)?,
|
|
state.namespace(&expr.nth(2)?)?,
|
|
).draw(to)?,
|
|
_ => return Err(format!("max: invalid variant: {:?}", expr.head()?).into())
|
|
})
|
|
}
|
|
|
|
#[cfg(all(feature = "draw", feature = "eval"))]
|
|
pub fn kw_push <O, S> (state: &S, to: &mut O, expr: &str)
|
|
-> Perhaps<XYWH<O::Unit>>
|
|
where
|
|
O: Screen,
|
|
S: Interpret<O, Option<XYWH<O::Unit>>>
|
|
+ Namespace<bool>
|
|
+ Namespace<O::Unit>
|
|
+ Namespace<Option<O::Unit>>
|
|
{
|
|
let thunk = draw(move|screen|ok_flat(expr.last()?.map(|x|state.interpret(screen, x))));
|
|
Ok(match expr.head()? {
|
|
Some("push/w") => thunk.push_x(state.namespace(&expr.nth(1)?)?).draw(to)?,
|
|
Some("push/h") => thunk.push_y(state.namespace(&expr.nth(1)?)?).draw(to)?,
|
|
Some("push/wh") => thunk.push_xy(
|
|
state.namespace(&expr.nth(1)?)?,
|
|
state.namespace(&expr.nth(2)?)?,
|
|
).draw(to)?,
|
|
_ => return Err(format!("push: invalid variant: {:?}", expr.head()?).into())
|
|
})
|
|
}
|
|
|
|
#[cfg(all(feature = "draw", feature = "eval"))]
|
|
pub fn kw_pull <O, S> (state: &S, to: &mut O, expr: &str)
|
|
-> Perhaps<XYWH<O::Unit>>
|
|
where
|
|
O: Screen,
|
|
S: Interpret<O, Option<XYWH<O::Unit>>>
|
|
+ Namespace<bool>
|
|
+ Namespace<O::Unit>
|
|
+ Namespace<Option<O::Unit>>
|
|
{
|
|
let thunk = draw(move|screen|ok_flat(expr.last()?.map(|x|state.interpret(screen, x))));
|
|
Ok(match expr.head()? {
|
|
Some("pull/w") => thunk.pull_x(state.namespace(&expr.nth(1)?)?).draw(to)?,
|
|
Some("pull/h") => thunk.pull_y(state.namespace(&expr.nth(1)?)?).draw(to)?,
|
|
Some("pull/wh") => thunk.pull_xy(
|
|
state.namespace(&expr.nth(1)?)?,
|
|
state.namespace(&expr.nth(2)?)?,
|
|
).draw(to)?,
|
|
_ => return Err(format!("pull: invalid variant: {:?}", expr.head()?).into())
|
|
})
|
|
}
|
|
|
|
#[cfg(all(feature = "draw", feature = "eval"))]
|
|
pub fn kw_pad <O, S> (state: &S, to: &mut O, expr: &str)
|
|
-> Perhaps<XYWH<O::Unit>>
|
|
where
|
|
O: Screen,
|
|
S: Interpret<O, Option<XYWH<O::Unit>>>
|
|
+ Namespace<bool>
|
|
+ Namespace<O::Unit>
|
|
+ Namespace<Option<O::Unit>>
|
|
{
|
|
let thunk = draw(move|screen|ok_flat(expr.last()?.map(|x|state.interpret(screen, x))));
|
|
Ok(match expr.head()? {
|
|
Some("pad/w") => thunk.pad_w(
|
|
state.namespace(&expr.nth(1)?)?
|
|
).draw(to)?,
|
|
Some("pad/h") => thunk.pad_h(
|
|
state.namespace(&expr.nth(1)?)?
|
|
).draw(to)?,
|
|
Some("pad/wh") => thunk.pad_wh(
|
|
state.namespace(&expr.nth(1)?)?,
|
|
state.namespace(&expr.nth(2)?)?,
|
|
).draw(to)?,
|
|
_ => return Err(format!("pad: invalid variant: {:?}", expr.head()?).into())
|
|
})
|
|
}
|
|
|
|
impl <'a, S: Screen, I: Draw<S>> Draw<S> for Full<'a, S, I> {
|
|
fn draw (&self, to: &mut S) -> Drawn<S::Unit> {
|
|
let XYWH(x0, y0, w0, h0) = to.area();
|
|
let item = match self {
|
|
Self::W(i) => i, Self::H(i) => i, Self::WH(i) => i, _ => unreachable!()
|
|
};
|
|
let (x1, y1, w1, h1) = match self {
|
|
Self::W(..) => (Some(x0), None, Some(w0), None),
|
|
Self::H(..) => (None, Some(y0), None, Some(h0)),
|
|
Self::WH(..) => (Some(x0), Some(y0), Some(w0), Some(h0)),
|
|
_ => unreachable!()
|
|
};
|
|
Ok(to.draw(to.area(), item)?.map(|XYWH(x2, y2, w2, h2)|XYWH(
|
|
x1.unwrap_or(x2), y1.unwrap_or(y2), w1.unwrap_or(w2), h1.unwrap_or(h2),
|
|
)))
|
|
}
|
|
}
|
|
|
|
impl <'a, S: Screen, I: Draw<S>, X: Into<Option<S::Unit>> + Copy> Draw<S> for Exact<'a, S, I, X> {
|
|
fn draw (&self, to: &mut S) -> Drawn<S::Unit> {
|
|
let XYWH(x0, y0, w0, h0) = to.area();
|
|
let (item, w1, h1) = match self {
|
|
Self::W(item, w1) => (item, (*w1).into(), None),
|
|
Self::H(item, h1) => (item, None, (*h1).into()),
|
|
Self::WH(item, w1, h1) => (item, (*w1).into(), (*h1).into()),
|
|
_ => unreachable!()
|
|
};
|
|
let w1 = w1.unwrap_or(w0);
|
|
let h1 = h1.unwrap_or(h0);
|
|
let area = XYWH(x0, y0, w1, h1);
|
|
let area = to.draw(area, item)?;
|
|
Ok(area.map(|XYWH(x2, y2, w2, h2)|match self {
|
|
Self::W(..) => XYWH(x0, y2, w1, h2),
|
|
Self::H(..) => XYWH(x2, y0, w2, h1),
|
|
Self::WH(..) => XYWH(x0, y0, w1, h1),
|
|
_ => unreachable!()
|
|
}))
|
|
}
|
|
}
|
|
|
|
impl <'a, S: Screen, I: Draw<S>, X: Into<Option<S::Unit>> + Copy> Draw<S> for Min<'a, S, I, X> {
|
|
fn draw (&self, to: &mut S) -> Drawn<S::Unit> {
|
|
let XYWH(x0, y0, w0, h0) = to.area();
|
|
let (item, w1, h1) = match self {
|
|
Self::W(item, w1) => (item, (*w1).into(), None),
|
|
Self::H(item, h1) => (item, None, (*h1).into()),
|
|
Self::WH(item, w1, h1) => (item, (*w1).into(), (*h1).into()),
|
|
_ => return Ok(None)
|
|
};
|
|
Ok(to.draw(XYWH(
|
|
x0, y0,
|
|
w1.map(|w1|w1.max(w0)).unwrap_or(w0),
|
|
h1.map(|h1|h1.max(h0)).unwrap_or(h0)
|
|
), item)?.map(|XYWH(x2, y2, w2, h2)|XYWH(
|
|
x2, y2,
|
|
w1.map(|w1|w1.max(w2)).unwrap_or(w2),
|
|
h1.map(|h1|h1.max(h2)).unwrap_or(h2)
|
|
)))
|
|
}
|
|
}
|
|
|
|
impl <'a, S: Screen, I: Draw<S>, X: Into<Option<S::Unit>> + Copy> Draw<S> for Max<'a, S, I, X> {
|
|
fn draw (&self, to: &mut S) -> Drawn<S::Unit> {
|
|
let XYWH(x, y, w0, h0) = to.area();
|
|
let (item, w, h) = match self {
|
|
Self::W(item, w) => (item, (*w).into().unwrap_or(w0), h0),
|
|
Self::H(item, h) => (item, w0, (*h).into().unwrap_or(h0)),
|
|
Self::WH(item, w, h) => (item, (*w).into().unwrap_or(h0), (*h).into().unwrap_or(h0)),
|
|
_ => return Ok(None)
|
|
};
|
|
to.draw(XYWH(x, y, if w0 > w { w } else { w0 }, if h0 > h { h } else { h0 }), item)
|
|
}
|
|
}
|
|
|
|
impl <'a, S: Screen, I: Draw<S>, X: Into<Option<S::Unit>> + Copy> Draw<S> for Push<'a, S, I, X> {
|
|
fn draw (&self, to: &mut S) -> Drawn<S::Unit> {
|
|
match self {
|
|
Self::__(_) => unreachable!(),
|
|
Self::X(item, x1) if let Some(XYWH(x, y, w, h)) = to.size(None, item)? => {
|
|
to.draw(XYWH(x + (*x1).into().unwrap_or_default(), y, w, h), item)
|
|
},
|
|
Self::Y(item, y1) if let Some(XYWH(x, y, w, h)) = to.size(None, item)? => {
|
|
to.draw(XYWH(x, y + (*y1).into().unwrap_or_default(), w, h), item)
|
|
},
|
|
Self::XY(item, x1, y1) if let Some(XYWH(x, y, w, h)) = to.size(None, item)? => {
|
|
to.draw(XYWH(x + (*x1).into().unwrap_or_default(), y + (*y1).into().unwrap_or_default(), w, h), item)
|
|
},
|
|
_ => Ok(None)
|
|
}
|
|
}
|
|
}
|
|
|
|
impl <'a, S: Screen, I: Draw<S>, X: Into<Option<S::Unit>> + Copy> Draw<S> for Pull<'a, S, I, X> {
|
|
fn draw (&self, to: &mut S) -> Drawn<S::Unit> {
|
|
match self {
|
|
Self::__(_) => unreachable!(),
|
|
Self::X(item, x1) if let Some(XYWH(x, y, w, h)) = to.size(None, item)? => {
|
|
to.draw(XYWH(x.minus((*x1).into().unwrap_or_default()),
|
|
y,
|
|
w, h), item)
|
|
},
|
|
Self::Y(item, y1) if let Some(XYWH(x, y, w, h)) = to.size(None, item)? => {
|
|
to.draw(XYWH(x,
|
|
y.minus((*y1).into().unwrap_or_default()),
|
|
w, h), item)
|
|
},
|
|
Self::XY(item, x1, y1) if let Some(XYWH(x, y, w, h)) = to.size(None, item)? => {
|
|
to.draw(XYWH(x.minus((*x1).into().unwrap_or_default()),
|
|
y.minus((*y1).into().unwrap_or_default()),
|
|
w, h), item)
|
|
},
|
|
_ => Ok(None)
|
|
}
|
|
}
|
|
}
|
|
|
|
impl <'a, S: Screen, I: Draw<S>, X: Into<Option<S::Unit>> + Copy> Draw<S> for Pad<'a, S, I, X> {
|
|
fn draw (&self, to: &mut S) -> Drawn<S::Unit> {
|
|
let XYWH(x, y, w0, h0) = to.area();
|
|
let (item, w, h) = match self {
|
|
Self::X(item, w) => (item, (*w).into().unwrap_or_default(), Default::default()),
|
|
Self::Y(item, h) => (item, Default::default(), (*h).into().unwrap_or_default()),
|
|
Self::XY(item, w, h) => (item, (*w).into().unwrap_or_default(),
|
|
(*h).into().unwrap_or_default()),
|
|
_ => return Ok(None)
|
|
};
|
|
to.draw(XYWH(
|
|
x.plus(w),
|
|
y.plus(h),
|
|
w0.minus(w).minus(w),
|
|
h0.minus(h).minus(h),
|
|
), item)
|
|
}
|
|
}
|
|
|
|
impl<'a, S: Screen, T: Draw<S>> LayoutFull<'a, S> for T {}
|
|
|
|
impl<'a, S: Screen, T: Draw<S>> LayoutExact<'a, S> for T {}
|
|
|
|
impl<'a, S: Screen, T: Draw<S>> LayoutMin<'a, S> for T {}
|
|
|
|
impl<'a, S: Screen, T: Draw<S>> LayoutMax<'a, S> for T {}
|
|
|
|
impl<'a, S: Screen, T: Draw<S>> LayoutPush<'a, S> for T {}
|
|
|
|
impl<'a, S: Screen, T: Draw<S>> LayoutPull<'a, S> for T {}
|
|
|
|
impl<'a, S: Screen, T: Draw<S>> LayoutPad<'a, S> for T {}
|
|
|
|
pub fn check_layout <'a> (t: impl Draw<Tui>) -> Drawn<u16> {
|
|
Tui::Layout(XYWH(1u16, 1, 80, 25)).size(None, t)
|
|
}
|