mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-08-28 05:06:56 +02:00
fix x/y/xy ops; remove button_2/3
This commit is contained in:
parent
799e497622
commit
de591addb3
7 changed files with 138 additions and 144 deletions
|
|
@ -96,6 +96,76 @@ impl Sizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Some layout operations exist in multiple variants that take a single argument.
|
||||||
|
/// Their handling in [eval_view] is uniform and goes like this:
|
||||||
|
macro_rules! eval_enum ((
|
||||||
|
$name:literal, $output:ident, $state:ident, $value:expr, $Enum:ident {
|
||||||
|
$($v:literal => $V:ident),* $(,)?
|
||||||
|
}
|
||||||
|
) => {{
|
||||||
|
match $value {
|
||||||
|
$(Some($v) => $Enum::$V,)*
|
||||||
|
frag => return Err(format!("invalid variant: {}/{frag:?}", $name).into())
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
|
||||||
|
/// Some layout operations exist in XY, X, and Y variants that take 3 or 2 arguments.
|
||||||
|
/// Their handling in [eval_view] is uniform and goes like this:
|
||||||
|
macro_rules! eval_xy (
|
||||||
|
// Valueless variant:
|
||||||
|
// (fill/x ...)
|
||||||
|
// (fill/y ...)
|
||||||
|
// (fill/xy ...)
|
||||||
|
(
|
||||||
|
$name:expr => $expr:expr, $head:expr, $output:ident, $state:ident,
|
||||||
|
$variant:expr, $xy:ident, $x:ident, $y:ident, $arg:expr,
|
||||||
|
) => {{
|
||||||
|
// frags.next(): 2nd slash-delimited fragment: /x, /y, /xy
|
||||||
|
let variant = $variant;
|
||||||
|
let thunk = draw(move|screen|$state.interpret(screen, &$arg));
|
||||||
|
match variant {
|
||||||
|
// X variant
|
||||||
|
Some("x") => thunk.$x().draw($output),
|
||||||
|
// Y variant
|
||||||
|
Some("y") => thunk.$y().draw($output),
|
||||||
|
// XY variant (can be omitted)
|
||||||
|
Some("xy") | None => thunk.$xy().draw($output),
|
||||||
|
// Other namespace members are invalid
|
||||||
|
frag => invalid_variant($name, frag, $expr, $head)
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
// Variadic variant:
|
||||||
|
// (push/x n ...)
|
||||||
|
// (push/y n ...)
|
||||||
|
// (push/xy n m ...)
|
||||||
|
(
|
||||||
|
$name:expr => $expr:expr, $head:expr, $output:ident, $state:ident,
|
||||||
|
$variant:expr, $xy:ident, $x:ident, $y:ident, $arg0:expr, $arg1:expr, $arg2:expr,
|
||||||
|
) => {{
|
||||||
|
// frags.next(): 2nd slash-delimited fragment: /x, /y, /xy
|
||||||
|
let variant = $variant;
|
||||||
|
let thunk = draw(move|screen|$state.interpret(screen, &match variant {
|
||||||
|
Some("x") | Some("y") => $arg1,
|
||||||
|
Some("xy") | None => $arg2,
|
||||||
|
_ => panic!("{}: unsupported axis {variant:?}; try /x, /y, /xy", $name)
|
||||||
|
}));
|
||||||
|
match variant {
|
||||||
|
// X variant
|
||||||
|
Some("x") => thunk.$x($state.namespace($arg0?)?)
|
||||||
|
.draw($output),
|
||||||
|
// Y variant
|
||||||
|
Some("y") => thunk.$y($state.namespace($arg0?)?)
|
||||||
|
.draw($output),
|
||||||
|
// XY variant (can be omitted)
|
||||||
|
Some("xy") | None => thunk.$xy($state.namespace($arg0?)?, $state.namespace($arg1?)?)
|
||||||
|
.draw($output),
|
||||||
|
// Other namespace members are invalid
|
||||||
|
frag => invalid_variant($name, frag, $expr, $head)
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
);
|
||||||
|
|
||||||
macro_rules! def_layout_modifier {
|
macro_rules! def_layout_modifier {
|
||||||
(
|
(
|
||||||
$Trait:ident ($fn_x:ident $fn_y:ident $fn_xy:ident),
|
$Trait:ident ($fn_x:ident $fn_y:ident $fn_xy:ident),
|
||||||
|
|
@ -126,7 +196,7 @@ macro_rules! def_layout_modifier {
|
||||||
fn_kw_layout!($kw_name |state, output, expr| {
|
fn_kw_layout!($kw_name |state, output, expr| {
|
||||||
let head = expr.head()?;
|
let head = expr.head()?;
|
||||||
let mut frags = head.src()?.unwrap_or_default().split("/");
|
let mut frags = head.src()?.unwrap_or_default().split("/");
|
||||||
Ok(matches!(expr.head()?, Some("exact")).then(||{
|
Ok(matches!(frags.next(), Some($name)).then(||{
|
||||||
let args = expr.tail();
|
let args = expr.tail();
|
||||||
let arg0 = args.head();
|
let arg0 = args.head();
|
||||||
let tail0 = args.tail();
|
let tail0 = args.tail();
|
||||||
|
|
|
||||||
|
|
@ -35,14 +35,23 @@ impl_draw!(<T: Screen, I: Draw<T>,>|self: Full<T, I>, to: T|{
|
||||||
def_layout_modifier!(
|
def_layout_modifier!(
|
||||||
LayoutExact (exact_w exact_h exact_wh),
|
LayoutExact (exact_w exact_h exact_wh),
|
||||||
Exact { W H WH } kw_exact "exact" |self, to| {
|
Exact { W H WH } kw_exact "exact" |self, to| {
|
||||||
let XYWH(x, y, w0, h0) = to.area();
|
let XYWH(x0, y0, w0, h0) = to.area();
|
||||||
let (item, w, h) = match self {
|
let (item, w1, h1) = match self {
|
||||||
Self::W(item, w) => (item, (*w).into(), None),
|
Self::W(item, w1) => (item, (*w1).into(), None),
|
||||||
Self::H(item, h) => (item, None, (*h).into()),
|
Self::H(item, h1) => (item, None, (*h1).into()),
|
||||||
Self::WH(item, w, h) => (item, (*w).into(), (*h).into()),
|
Self::WH(item, w1, h1) => (item, (*w1).into(), (*h1).into()),
|
||||||
_ => return Ok(None)
|
_ => unreachable!()
|
||||||
};
|
};
|
||||||
to.draw(XYWH(x, y, w.unwrap_or(w0), h.unwrap_or(h0)), item)
|
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!()
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -192,15 +192,13 @@ fn draw_stacks <S: Screen> (
|
||||||
area_b: impl Into<Option<XYWH<S::Unit>>>,
|
area_b: impl Into<Option<XYWH<S::Unit>>>,
|
||||||
origin_b: impl Into<Option<Azimuth>>,
|
origin_b: impl Into<Option<Azimuth>>,
|
||||||
) -> Usually<(Option<XYWH<S::Unit>>, Option<XYWH<S::Unit>>)> {
|
) -> Usually<(Option<XYWH<S::Unit>>, Option<XYWH<S::Unit>>)> {
|
||||||
let draw_a = |to: &mut S|Ok::<_, Box<dyn Error>>(if let Some(origin_a) = origin_a.into() {
|
let draw_a = |to: &mut S|Ok::<_, Box<dyn Error>>(match origin_a.into() {
|
||||||
to.draw(area_a.into(), a.align(origin_a))?
|
Some(origin_a) => to.draw(area_a.into(), a.align(origin_a))?,
|
||||||
} else {
|
None => to.draw(area_a.into(), a)?
|
||||||
to.draw(area_a.into(), a)?
|
|
||||||
});
|
});
|
||||||
let draw_b = |to: &mut S|Ok::<_, Box<dyn Error>>(if let Some(origin_b) = origin_b.into() {
|
let draw_b = |to: &mut S|Ok::<_, Box<dyn Error>>(match origin_b.into() {
|
||||||
to.draw(area_b.into(), b.align(origin_b))?
|
Some(origin_b) => to.draw(area_b.into(), b.align(origin_b))?,
|
||||||
} else {
|
None => to.draw(area_b.into(), b)?
|
||||||
to.draw(area_b.into(), b)?
|
|
||||||
});
|
});
|
||||||
Ok(if matches!(split, Split::Below) {
|
Ok(if matches!(split, Split::Below) {
|
||||||
let drawn_b = draw_b(to)?;
|
let drawn_b = draw_b(to)?;
|
||||||
|
|
@ -217,7 +215,7 @@ pub fn stack_areas <S: Screen> (
|
||||||
a: impl Draw<S>,
|
a: impl Draw<S>,
|
||||||
b: impl Draw<S>,
|
b: impl Draw<S>,
|
||||||
) -> Usually<(Option<XYWH<S::Unit>>, Option<XYWH<S::Unit>>)> {
|
) -> Usually<(Option<XYWH<S::Unit>>, Option<XYWH<S::Unit>>)> {
|
||||||
let area_a = to.draw(None, a)?;
|
let area_a = to.size(None, a)?;
|
||||||
Ok(match split {
|
Ok(match split {
|
||||||
Split::South => (
|
Split::South => (
|
||||||
area_a,
|
area_a,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,49 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
pub fn iter_south <'a, S: Screen, D: Draw<S>, I: Iterator<Item = D>> (
|
||||||
|
iter: impl Fn()->I
|
||||||
|
) -> impl Draw<S> {
|
||||||
|
draw(move|to: &mut S|{
|
||||||
|
let XYWH(x, y, w, h) = to.area();
|
||||||
|
let mut y_next = y;
|
||||||
|
let mut h_used = S::Unit::zero();
|
||||||
|
for item in iter() {
|
||||||
|
let area = XYWH(x, y_next, w, h.minus(h_used));
|
||||||
|
if let Some(used) = to.draw(area, item)? {
|
||||||
|
let used_h = used.h();
|
||||||
|
y_next = y_next.plus(used_h);
|
||||||
|
h_used = h_used.plus(used_h);
|
||||||
|
if h_used >= h {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Some(XYWH(x, y, w, h_used)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter_east <'a, S: Screen, D: Draw<S>, I: Iterator<Item = D>> (
|
||||||
|
iter: impl Fn()->I
|
||||||
|
) -> impl Draw<S> {
|
||||||
|
draw(move|to: &mut S|{
|
||||||
|
let XYWH(x, y, w, h) = to.area();
|
||||||
|
let mut x_next = x;
|
||||||
|
let mut w_used = S::Unit::zero();
|
||||||
|
for item in iter() {
|
||||||
|
let area = XYWH(x_next, y, w.minus(w_used), h);
|
||||||
|
if let Some(used) = to.draw(area, item)? {
|
||||||
|
let used_w = used.w();
|
||||||
|
x_next = x_next.plus(used_w);
|
||||||
|
w_used = w_used.plus(used_w);
|
||||||
|
if w_used >= w {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Some(XYWH(x, y, w_used, h)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Iterate over a collection of the same kind of [Draw]able:
|
/// Iterate over a collection of the same kind of [Draw]able:
|
||||||
pub fn iter <'a, S: Screen, D: 'a, I: Iterator<Item = D>, U: Draw<S>> (
|
pub fn iter <'a, S: Screen, D: 'a, I: Iterator<Item = D>, U: Draw<S>> (
|
||||||
_iter: impl Fn()->I, _draw: impl Fn(D, usize)->U,
|
_iter: impl Fn()->I, _draw: impl Fn(D, usize)->U,
|
||||||
|
|
@ -31,40 +75,12 @@ pub fn iter_north <'a, S: Screen, D: 'a, I: Iterator<Item = D>, U: Draw<S>> (
|
||||||
draw(move|_to: &mut S|{ todo!() })
|
draw(move|_to: &mut S|{ todo!() })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_east <'a, S: Screen, D: 'a, I: Iterator<Item = D>, U: Draw<S>> (
|
|
||||||
_iter: impl Fn()->I, _draw: impl Fn(D, usize)->U,
|
|
||||||
) -> impl Draw<S> {
|
|
||||||
draw(move|_to: &mut S|{ todo!() })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter_east_fixed <'a, S: Screen, D: 'a, I: Iterator<Item = D>, U: Draw<S>> (
|
pub fn iter_east_fixed <'a, S: Screen, D: 'a, I: Iterator<Item = D>, U: Draw<S>> (
|
||||||
_height: S::Unit, _iter: impl Fn()->I, _draw: impl Fn(D, usize)->U,
|
_height: S::Unit, _iter: impl Fn()->I, _draw: impl Fn(D, usize)->U,
|
||||||
) -> impl Draw<S> {
|
) -> impl Draw<S> {
|
||||||
draw(move|_to: &mut S|{ todo!() })
|
draw(move|_to: &mut S|{ todo!() })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_south <'a, S: Screen, D: Draw<S>, I: Iterator<Item = D>> (
|
|
||||||
iter: impl Fn()->I
|
|
||||||
) -> impl Draw<S> {
|
|
||||||
draw(move|to: &mut S|{
|
|
||||||
let XYWH(x, y, w, h) = to.area();
|
|
||||||
let mut y_next = y;
|
|
||||||
let mut h_used = S::Unit::zero();
|
|
||||||
for item in iter() {
|
|
||||||
let area = XYWH(x, y_next, w, h.minus(h_used));
|
|
||||||
if let Some(used) = to.draw(area, item)? {
|
|
||||||
let used_h = used.h();
|
|
||||||
y_next = y_next.plus(used_h);
|
|
||||||
h_used = h_used.plus(used_h);
|
|
||||||
if h_used >= h {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(Some(XYWH(x, y, w, h_used)))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter_south_fixed <'a, S: Screen, D: 'a, I: Iterator<Item = D>, U: Draw<S>> (
|
pub fn iter_south_fixed <'a, S: Screen, D: 'a, I: Iterator<Item = D>, U: Draw<S>> (
|
||||||
_height: S::Unit, _iter: impl Fn()->I, _draw: impl Fn(D, usize)->U,
|
_height: S::Unit, _iter: impl Fn()->I, _draw: impl Fn(D, usize)->U,
|
||||||
) -> impl Draw<S> {
|
) -> impl Draw<S> {
|
||||||
|
|
|
||||||
70
src/lib.rs
70
src/lib.rs
|
|
@ -179,76 +179,6 @@ pub trait AsMutOpt<T> { fn as_mut_opt (&mut self) -> Option<&mut T>; }
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Some layout operations exist in multiple variants that take a single argument.
|
|
||||||
/// Their handling in [eval_view] is uniform and goes like this:
|
|
||||||
macro_rules! eval_enum ((
|
|
||||||
$name:literal, $output:ident, $state:ident, $value:expr, $Enum:ident {
|
|
||||||
$($v:literal => $V:ident),* $(,)?
|
|
||||||
}
|
|
||||||
) => {{
|
|
||||||
match $value {
|
|
||||||
$(Some($v) => $Enum::$V,)*
|
|
||||||
frag => unimplemented!("{}/{frag:?}", $name)
|
|
||||||
}
|
|
||||||
}});
|
|
||||||
|
|
||||||
/// Some layout operations exist in XY, X, and Y variants that take 3 or 2 arguments.
|
|
||||||
/// Their handling in [eval_view] is uniform and goes like this:
|
|
||||||
macro_rules! eval_xy (
|
|
||||||
// Valueless variant:
|
|
||||||
// (fill/x ...)
|
|
||||||
// (fill/y ...)
|
|
||||||
// (fill/xy ...)
|
|
||||||
(
|
|
||||||
$name:expr => $expr:expr, $head:expr, $output:ident, $state:ident,
|
|
||||||
$variant:expr, $xy:ident, $x:ident, $y:ident, $arg:expr,
|
|
||||||
) => {{
|
|
||||||
// frags.next(): 2nd slash-delimited fragment: /x, /y, /xy
|
|
||||||
let variant = $variant;
|
|
||||||
let thunk = draw(move|screen|$state.interpret(screen, &$arg));
|
|
||||||
match variant {
|
|
||||||
// X variant
|
|
||||||
Some("x") => thunk.$x().draw($output),
|
|
||||||
// Y variant
|
|
||||||
Some("y") => thunk.$y().draw($output),
|
|
||||||
// XY variant (can be omitted)
|
|
||||||
Some("xy") | None => thunk.$xy().draw($output),
|
|
||||||
// Other namespace members are invalid
|
|
||||||
frag => invalid_variant($name, frag, $expr, $head)
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
|
|
||||||
// Variadic variant:
|
|
||||||
// (push/x n ...)
|
|
||||||
// (push/y n ...)
|
|
||||||
// (push/xy n m ...)
|
|
||||||
(
|
|
||||||
$name:expr => $expr:expr, $head:expr, $output:ident, $state:ident,
|
|
||||||
$variant:expr, $xy:ident, $x:ident, $y:ident, $arg0:expr, $arg1:expr, $arg2:expr,
|
|
||||||
) => {{
|
|
||||||
// frags.next(): 2nd slash-delimited fragment: /x, /y, /xy
|
|
||||||
let variant = $variant;
|
|
||||||
let thunk = draw(move|screen|$state.interpret(screen, &match variant {
|
|
||||||
Some("x") | Some("y") => $arg1,
|
|
||||||
Some("xy") | None => $arg2,
|
|
||||||
_ => panic!("{}: unsupported axis {variant:?}; try /x, /y, /xy", $name)
|
|
||||||
}));
|
|
||||||
match variant {
|
|
||||||
// X variant
|
|
||||||
Some("x") => thunk.$x($state.namespace($arg0?)?)
|
|
||||||
.draw($output),
|
|
||||||
// Y variant
|
|
||||||
Some("y") => thunk.$y($state.namespace($arg0?)?)
|
|
||||||
.draw($output),
|
|
||||||
// XY variant (can be omitted)
|
|
||||||
Some("xy") | None => thunk.$xy($state.namespace($arg0?)?, $state.namespace($arg1?)?)
|
|
||||||
.draw($output),
|
|
||||||
// Other namespace members are invalid
|
|
||||||
frag => invalid_variant($name, frag, $expr, $head)
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(feature = "exit")] pub use self::exit::*;
|
#[cfg(feature = "exit")] pub use self::exit::*;
|
||||||
#[cfg(feature = "exit")] mod exit {
|
#[cfg(feature = "exit")] mod exit {
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ pub(crate) use ::{
|
||||||
|
|
||||||
mod border; pub use self::border::*;
|
mod border; pub use self::border::*;
|
||||||
mod buffer; pub use self::buffer::*;
|
mod buffer; pub use self::buffer::*;
|
||||||
mod button; pub use self::button::*;
|
|
||||||
mod event; pub use self::event::*;
|
mod event; pub use self::event::*;
|
||||||
mod keys; pub use self::keys::*;
|
mod keys; pub use self::keys::*;
|
||||||
mod modify; pub use self::modify::*;
|
mod modify; pub use self::modify::*;
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
use crate::{*, Color::*};
|
|
||||||
|
|
||||||
/// ```
|
|
||||||
/// let _ = tengri::button_2("", "", true);
|
|
||||||
/// let _ = tengri::button_2("", "", false);
|
|
||||||
/// ```
|
|
||||||
pub const fn button_2 <'a> (key: impl Draw<Tui>, label: impl Draw<Tui>, hide: bool) -> impl Draw<Tui> {
|
|
||||||
let c1 = tui_orange();
|
|
||||||
let c2 = tui_g(0);
|
|
||||||
let c3 = tui_g(96);
|
|
||||||
let c4 = tui_g(255);
|
|
||||||
bold(true, fg_bg(c1, c2, east(fg(c2, east(key, fg(c3, "▐"))), when(!hide, fg_bg(c4, c3, label)))))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ```
|
|
||||||
/// let _ = tengri::button_3("", "", "", true);
|
|
||||||
/// let _ = tengri::button_3("", "", "", false);
|
|
||||||
/// ```
|
|
||||||
pub const fn button_3 <'a> (
|
|
||||||
key: impl Draw<Tui>, label: impl Draw<Tui>, value: impl Draw<Tui>, editing: bool,
|
|
||||||
) -> impl Draw<Tui> {
|
|
||||||
bold(true, east(
|
|
||||||
fg_bg(tui_orange(), tui_g(0),
|
|
||||||
east(fg(tui_g(0), "▐"), east(key, fg(if editing { tui_g(128) } else { tui_g(96) }, "▐")))),
|
|
||||||
east(
|
|
||||||
when(!editing, east(fg_bg(tui_g(255), tui_g(96), label), fg_bg(tui_g(128), tui_g(96), "▐"),)),
|
|
||||||
east(fg_bg(tui_g(224), tui_g(128), value), fg_bg(tui_g(128), Reset, "▌"), ))))
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue