implement Split::bar
Some checks failed
/ build (push) Has been cancelled

This commit is contained in:
facile pop culture reference 2026-08-31 19:04:16 +03:00
parent e55a7da3b4
commit b318d498e5
3 changed files with 77 additions and 18 deletions

View file

@ -308,7 +308,9 @@ impl <'a, S: Screen, I: Draw<S>> Draw<S> for Full<'a, S, I> {
Self::WH(..) => (Some(x0), Some(y0), Some(w0), Some(h0)), Self::WH(..) => (Some(x0), Some(y0), Some(w0), Some(h0)),
_ => unreachable!() _ => unreachable!()
}; };
Ok(to.draw(to.area(), item)?.map(|XYWH(x2, y2, w2, h2)|XYWH( 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), x1.unwrap_or(x2), y1.unwrap_or(y2), w1.unwrap_or(w2), h1.unwrap_or(h2),
))) )))
} }
@ -326,9 +328,9 @@ impl <'a, S: Screen, I: Draw<S>, X: Into<Option<S::Unit>> + Copy> Draw<S> for Ex
}; };
let w1 = w1.unwrap_or(w0); let w1 = w1.unwrap_or(w0);
let h1 = h1.unwrap_or(h0); let h1 = h1.unwrap_or(h0);
let area = XYWH(x0, y0, w1, h1); Ok(to
let area = to.draw(area, item)?; .draw(XYWH(x0, y0, w1, h1), item)?
Ok(area.map(|XYWH(x2, y2, w2, h2)|match self { .map(|XYWH(x2, y2, w2, h2)|match self {
Self::W(..) => XYWH(x0, y2, w1, h2), Self::W(..) => XYWH(x0, y2, w1, h2),
Self::H(..) => XYWH(x2, y0, w2, h1), Self::H(..) => XYWH(x2, y0, w2, h1),
Self::WH(..) => XYWH(x0, y0, w1, h1), Self::WH(..) => XYWH(x0, y0, w1, h1),

View file

@ -185,6 +185,52 @@ fn_kw_layout!(kw_split |state, output, expr| {
#[default] Below #[default] Below
} }
/// Two components, first one has fixed size along the transverse axis.
pub struct Bar<N, A, B>(Split, N, A, B);
/// Define a split with first component having fixed size along the transverse axis.
pub fn bar <S: Screen, A: Draw<S>, B: Draw<S>> (
split: Split, n: impl Into<S::Unit>, a: A, b: B
) -> Bar<S::Unit, A, B> {
Bar(split, n.into(), a, b)
}
impl<S: Screen, A: Draw<S>, B: Draw<S>> Draw<S> for Bar<S::Unit, A, B> {
fn draw (&self, to: &mut S) -> Drawn<S::Unit> {
#[cfg(feature = "prof")] profiling::scope!("bar_draw");
let Self(split, n, a, b, ..) = self;
let (area_a, area_b) = bar_areas(to, split, *n, a, b)?;
let (drawn_a, drawn_b) = draw_stacks(split, to, a, area_a, None, b, area_b, None)?;
Ok(stack_drawn(split, drawn_a, drawn_b))
}
}
pub fn bar_areas <'a, S: Screen> (
to: &mut S, split: &Split, n: S::Unit, a: impl Draw<S>, b: impl Draw<S>,
) -> UsuallyRef<'a, (Option<XYWH<S::Unit>>, Option<XYWH<S::Unit>>)> {
let XYWH(x0, y0, w0, h0) = to.area();
Ok(match split {
Split::South => (
to.size(XYWH(x0, y0, w0, n), a)?,
to.size(XYWH(x0, y0 + n, w0, h0 - n), b)?,
),
Split::East => (
to.size(XYWH(x0, y0, n, h0), a)?,
to.size(XYWH(x0 + n, y0, w0 - n, h0), b)?,
),
Split::North => (
to.size(XYWH(x0, y0 + h0 - n, w0, n), a)?,
to.size(XYWH(x0, y0, w0, h0 - n), b)?,
),
Split::West => (
to.size(XYWH(x0 + w0 - n, y0, n, h0), a)?,
to.size(XYWH(x0, y0, w0 - n, h0), b)?,
),
_ => todo!()
})
}
/// Dynamically laid out split
pub struct Pair<A, B>(Split, A, B); pub struct Pair<A, B>(Split, A, B);
/// ``` /// ```
@ -200,7 +246,7 @@ pub struct Pair<A, B>(Split, A, B);
/// assert_eq!(size_of(&split(East, split(South, "foo", "bar"), "baz"))?, Some(XYWH(0, 0, 6, 2))); /// assert_eq!(size_of(&split(East, split(South, "foo", "bar"), "baz"))?, Some(XYWH(0, 0, 6, 2)));
/// # return Ok(()); } /// # return Ok(()); }
/// ``` /// ```
pub fn split <'a, S: Screen, A: Draw<S>, B: Draw<S>> ( pub fn split <S: Screen, A: Draw<S>, B: Draw<S>> (
split: Split, a: A, b: B split: Split, a: A, b: B
) -> Pair<A, B> { ) -> Pair<A, B> {
Pair(split, a, b) Pair(split, a, b)
@ -258,10 +304,7 @@ fn draw_stacks <'a, S: Screen> (
/// # Ok(()) } /// # Ok(()) }
/// ``` /// ```
pub fn stack_areas <'a, S: Screen> ( pub fn stack_areas <'a, S: Screen> (
split: &Split, split: &Split, to: &mut S, a: impl Draw<S>, b: impl Draw<S>,
to: &mut S,
a: impl Draw<S>,
b: impl Draw<S>,
) -> UsuallyRef<'a, (Option<XYWH<S::Unit>>, Option<XYWH<S::Unit>>)> { ) -> UsuallyRef<'a, (Option<XYWH<S::Unit>>, Option<XYWH<S::Unit>>)> {
let area_a = to.size(None, a)?; let area_a = to.size(None, a)?;
Ok(match split { Ok(match split {
@ -329,6 +372,21 @@ fn stack_drawn <S: Coord> (
impl Split { impl Split {
/// ```
/// use tengri::*;
/// let _ = Split::Above.stack(&"", &"");
/// let _ = Split::Below.stack(&"", &"");
/// let _ = Split::North.stack(&"", &"");
/// let _ = Split::South.stack(&"", &"");
/// let _ = Split::East.stack(&"", &"");
/// let _ = Split::West.stack(&"", &"");
/// ```
pub const fn bar <'a, S: Screen, A: Draw<S>, B: Draw<S>> (&self, n: S::Unit, a: A, b: B)
-> impl Draw<S>
{
Bar(*self, n, a, b)
}
/// ``` /// ```
/// use tengri::*; /// use tengri::*;
/// let _ = Split::Above.stack(&"", &""); /// let _ = Split::Above.stack(&"", &"");

View file

@ -1,5 +1,4 @@
use crate::*; use crate::*;
use Color::*;
//use unicode_width::{UnicodeWidthStr, UnicodeWidthChar}; //use unicode_width::{UnicodeWidthStr, UnicodeWidthChar};
//use rand::distributions::uniform::UniformSampler; //use rand::distributions::uniform::UniformSampler;
pub(crate) use ::{ pub(crate) use ::{
@ -268,7 +267,7 @@ impl Tui {
let Size { width, height } = backend.size().expect("get size failed"); let Size { width, height } = backend.size().expect("get size failed");
let mut prev = Tui::new(width, height); let mut prev = Tui::new(width, height);
let mut next = Tui::new(width, height); let mut next = Tui::new(width, height);
Ok(Task::new_sleep(Some("tengri output"), exited.clone(), sleep, move |perf| { Ok(Task::new_sleep(Some("tengri output"), exited.clone(), sleep, move |_perf| {
let Size { width, height } = backend.size().expect("get size failed"); let Size { width, height } = backend.size().expect("get size failed");
if let Some(state) = state.try_read() { if let Some(state) = state.try_read() {
prev.resize(&mut backend, width, height); prev.resize(&mut backend, width, height);