output: refactor Content and Render traits

This commit is contained in:
🪞👃🪞 2025-09-06 08:46:52 +03:00
parent 74b3af2212
commit 1c21a85f27
24 changed files with 346 additions and 613 deletions

View file

@ -1,40 +1,49 @@
use crate::*;
pub struct Bordered<S: BorderStyle, W: Content<TuiOut>>(pub bool, pub S, pub W);
content!(TuiOut: |self: Bordered<S: BorderStyle, W: Content<TuiOut>>|Fill::xy(
lay!(When::new(self.0, Border(self.0, self.1)), Padding::xy(1, 1, &self.2))
));
pub struct Bordered<S, W>(pub bool, pub S, pub W);
impl<S: BorderStyle, W: Render<TuiOut>> Content<TuiOut> for Bordered<S, W> {
fn content (&self) -> Option<impl Render<TuiOut> + '_> {
Some(Fill::xy(
lay!(When::new(self.0, Border(self.0, self.1)), Padding::xy(1, 1, &self.2))
))
}
}
pub struct Border<S: BorderStyle>(pub bool, pub S);
render!(TuiOut: |self: Border<S: BorderStyle>, to| {
if self.0 {
let area = to.area();
if area.w() > 0 && area.y() > 0 {
to.blit(&self.1.nw(), area.x(), area.y(), self.1.style());
to.blit(&self.1.ne(), area.x() + area.w() - 1, area.y(), self.1.style());
to.blit(&self.1.sw(), area.x(), area.y() + area.h() - 1, self.1.style());
to.blit(&self.1.se(), area.x() + area.w() - 1, area.y() + area.h() - 1, self.1.style());
for x in area.x()+1..area.x()+area.w()-1 {
to.blit(&self.1.n(), x, area.y(), self.1.style());
to.blit(&self.1.s(), x, area.y() + area.h() - 1, self.1.style());
}
for y in area.y()+1..area.y()+area.h()-1 {
to.blit(&self.1.w(), area.x(), y, self.1.style());
to.blit(&self.1.e(), area.x() + area.w() - 1, y, self.1.style());
impl<S: BorderStyle> Render<TuiOut> for Border<S> {
fn layout (&self, area: [u16;4]) -> [u16;4] {
self.1.layout(area)
}
fn render (&self, to: &mut TuiOut) {
if self.0 {
let area = to.area();
if area.w() > 0 && area.y() > 0 {
to.blit(&self.1.nw(), area.x(), area.y(), self.1.style());
to.blit(&self.1.ne(), area.x() + area.w() - 1, area.y(), self.1.style());
to.blit(&self.1.sw(), area.x(), area.y() + area.h() - 1, self.1.style());
to.blit(&self.1.se(), area.x() + area.w() - 1, area.y() + area.h() - 1, self.1.style());
for x in area.x()+1..area.x()+area.w()-1 {
to.blit(&self.1.n(), x, area.y(), self.1.style());
to.blit(&self.1.s(), x, area.y() + area.h() - 1, self.1.style());
}
for y in area.y()+1..area.y()+area.h()-1 {
to.blit(&self.1.w(), area.x(), y, self.1.style());
to.blit(&self.1.e(), area.x() + area.w() - 1, y, self.1.style());
}
}
}
}
});
}
pub trait BorderStyle: Send + Sync + Copy {
pub trait BorderStyle: Render<TuiOut> + Copy {
fn enabled (&self) -> bool;
fn enclose <W: Content<TuiOut>> (self, w: W) -> impl Content<TuiOut> {
fn enclose <W: Render<TuiOut>> (self, w: W) -> impl Render<TuiOut> {
Bsp::b(Fill::xy(Border(self.enabled(), self)), w)
}
fn enclose2 <W: Content<TuiOut>> (self, w: W) -> impl Content<TuiOut> {
fn enclose2 <W: Render<TuiOut>> (self, w: W) -> impl Render<TuiOut> {
Bsp::b(Margin::xy(1, 1, Fill::xy(Border(self.enabled(), self))), w)
}
fn enclose_bg <W: Content<TuiOut>> (self, w: W) -> impl Content<TuiOut> {
fn enclose_bg <W: Render<TuiOut>> (self, w: W) -> impl Render<TuiOut> {
Tui::bg(self.style().unwrap().bg.unwrap_or(Color::Reset),
Bsp::b(Fill::xy(Border(self.enabled(), self)), w))
}
@ -138,7 +147,7 @@ macro_rules! border {
fn enabled (&self) -> bool { self.0 }
}
#[derive(Copy, Clone)] pub struct $T(pub bool, pub Style);
impl Content<TuiOut> for $T {
impl Render<TuiOut> for $T {
fn render (&self, to: &mut TuiOut) {
if self.enabled() { let _ = self.draw(to); }
}