mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-02-21 10:39:03 +01:00
107 lines
3.7 KiB
Rust
107 lines
3.7 KiB
Rust
use crate::*;
|
|
|
|
pub trait TuiDraw = Draw<TuiOut>;
|
|
|
|
pub trait TuiLayout = Layout<TuiOut>;
|
|
|
|
pub trait TuiContent = Content<TuiOut>;
|
|
|
|
pub trait TuiHandle = Handle<TuiIn>;
|
|
|
|
pub trait TuiWidget = TuiDraw + TuiHandle;
|
|
|
|
pub trait HasColor { fn color (&self) -> ItemColor; }
|
|
|
|
pub trait BorderStyle: Content<TuiOut> + Copy {
|
|
fn enabled (&self) -> bool;
|
|
fn enclose (self, w: impl Content<TuiOut>) -> impl Content<TuiOut> {
|
|
Bsp::b(Fill::XY(Border(self.enabled(), self)), w)
|
|
}
|
|
fn enclose2 (self, w: impl Content<TuiOut>) -> impl Content<TuiOut> {
|
|
Bsp::b(Pad::XY(1, 1, Fill::XY(Border(self.enabled(), self))), w)
|
|
}
|
|
fn enclose_bg (self, w: impl Content<TuiOut>) -> impl Content<TuiOut> {
|
|
Tui::bg(self.style().unwrap().bg.unwrap_or(Color::Reset),
|
|
Bsp::b(Fill::XY(Border(self.enabled(), self)), w))
|
|
}
|
|
const NW: &'static str = "";
|
|
const N: &'static str = "";
|
|
const NE: &'static str = "";
|
|
const E: &'static str = "";
|
|
const SE: &'static str = "";
|
|
const S: &'static str = "";
|
|
const SW: &'static str = "";
|
|
const W: &'static str = "";
|
|
|
|
const N0: &'static str = "";
|
|
const S0: &'static str = "";
|
|
const W0: &'static str = "";
|
|
const E0: &'static str = "";
|
|
|
|
fn border_n (&self) -> &str { Self::N }
|
|
fn border_s (&self) -> &str { Self::S }
|
|
fn border_e (&self) -> &str { Self::E }
|
|
fn border_w (&self) -> &str { Self::W }
|
|
fn border_nw (&self) -> &str { Self::NW }
|
|
fn border_ne (&self) -> &str { Self::NE }
|
|
fn border_sw (&self) -> &str { Self::SW }
|
|
fn border_se (&self) -> &str { Self::SE }
|
|
#[inline] fn draw <'a> (
|
|
&self, to: &mut TuiOut
|
|
) -> Usually<()> {
|
|
if self.enabled() {
|
|
self.draw_horizontal(to, None)?;
|
|
self.draw_vertical(to, None)?;
|
|
self.draw_corners(to, None)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
#[inline] fn draw_horizontal (
|
|
&self, to: &mut TuiOut, style: Option<Style>
|
|
) -> Usually<XYWH<u16>> {
|
|
let area = to.area();
|
|
let style = style.or_else(||self.style_horizontal());
|
|
let [x, x2, y, y2] = area.lrtb();
|
|
for x in x..x2.saturating_sub(1) {
|
|
to.blit(&Self::N, x, y, style);
|
|
to.blit(&Self::S, x, y2.saturating_sub(1), style)
|
|
}
|
|
Ok(area)
|
|
}
|
|
#[inline] fn draw_vertical (
|
|
&self, to: &mut TuiOut, style: Option<Style>
|
|
) -> Usually<XYWH<u16>> {
|
|
let area = to.area();
|
|
let style = style.or_else(||self.style_vertical());
|
|
let [x, x2, y, y2] = area.lrtb();
|
|
let h = y2 - y;
|
|
if h > 1 {
|
|
for y in y..y2.saturating_sub(1) {
|
|
to.blit(&Self::W, x, y, style);
|
|
to.blit(&Self::E, x2.saturating_sub(1), y, style);
|
|
}
|
|
} else if h > 0 {
|
|
to.blit(&Self::W0, x, y, style);
|
|
to.blit(&Self::E0, x2.saturating_sub(1), y, style);
|
|
}
|
|
Ok(area)
|
|
}
|
|
#[inline] fn draw_corners (
|
|
&self, to: &mut TuiOut, style: Option<Style>
|
|
) -> Usually<XYWH<u16>> {
|
|
let area = to.area();
|
|
let style = style.or_else(||self.style_corners());
|
|
let XYWH(x, y, width, height) = area;
|
|
if width > 1 && height > 1 {
|
|
to.blit(&Self::NW, x, y, style);
|
|
to.blit(&Self::NE, x + width - 1, y, style);
|
|
to.blit(&Self::SW, x, y + height - 1, style);
|
|
to.blit(&Self::SE, x + width - 1, y + height - 1, style);
|
|
}
|
|
Ok(area)
|
|
}
|
|
#[inline] fn style (&self) -> Option<Style> { None }
|
|
#[inline] fn style_horizontal (&self) -> Option<Style> { self.style() }
|
|
#[inline] fn style_vertical (&self) -> Option<Style> { self.style() }
|
|
#[inline] fn style_corners (&self) -> Option<Style> { self.style() }
|
|
}
|