mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-07-17 07:56:56 +02:00
wip: impl_draw, optional drawing
This commit is contained in:
parent
0b9e9c0696
commit
bf16288884
12 changed files with 213 additions and 229 deletions
43
src/draw.rs
43
src/draw.rs
|
|
@ -35,11 +35,18 @@ pub trait Screen: Xy<Self::Unit> + Wh<Self::Unit> + Send + Sync + Sized {
|
|||
/// todo!("your draw logic")
|
||||
/// });
|
||||
/// ```
|
||||
#[macro_export] macro_rules! impl_draw ((|
|
||||
#[macro_export] macro_rules! impl_draw (
|
||||
($(<$($T:ident: $Trait:path,)+>)?|
|
||||
$self:ident:$Self:path, $to:ident:$To:ty
|
||||
|$draw:block)=>{ impl$(<$($T:$Trait),+>)? Draw<$To> for $Self {
|
||||
fn draw ($self, $to: &mut $To) -> Perhaps<XYWH<<$To as Screen>::Unit>> $draw
|
||||
} };
|
||||
($(<$($T:ident: $Trait:path,)+>)?|
|
||||
$self:ident:$Self:ty, $to:ident:$To:ty
|
||||
|$draw:block)=>{ impl Draw<$To> for $Self {
|
||||
fn draw ($self, $to: &mut $To) -> Usually<XYWH<<$To as Screen>::Unit>> $draw
|
||||
} });
|
||||
|$draw:block)=>{ impl$(<$($T:$Trait),+>)? Draw<$To> for $Self {
|
||||
fn draw ($self, $to: &mut $To) -> Perhaps<XYWH<<$To as Screen>::Unit>> $draw
|
||||
} }
|
||||
);
|
||||
|
||||
/// Drawable that supports dynamic dispatch.
|
||||
///
|
||||
|
|
@ -57,38 +64,36 @@ pub trait Screen: Xy<Self::Unit> + Wh<Self::Unit> + Send + Sync + Sized {
|
|||
/// use tengri::{*, draw::*, term::*};
|
||||
/// struct MyWidget(bool);
|
||||
/// impl Draw<Tui> for MyWidget {
|
||||
/// fn draw (self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
/// fn draw (self, to: &mut Tui) -> Perhaps<XYWH<u16>> {
|
||||
/// todo!("your draw logic")
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub trait Draw<S: Screen> {
|
||||
fn draw (self, to: &mut S) -> Usually<XYWH<S::Unit>>;
|
||||
fn draw (self, to: &mut S) -> Perhaps<XYWH<S::Unit>>;
|
||||
fn layout (&self, area: XYWH<S::Unit>) -> Perhaps<XYWH<S::Unit>> {
|
||||
Ok(Some(area))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Screen> Draw<S> for () {
|
||||
fn draw (self, __: &mut S) -> Usually<XYWH<S::Unit>> {
|
||||
Ok(Default::default())
|
||||
fn draw (self, _: &mut S) -> Perhaps<XYWH<S::Unit>> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Screen, D: Draw<S>> Draw<S> for Option<D> {
|
||||
fn draw (self, to: &mut S) -> Usually<XYWH<S::Unit>> {
|
||||
impl_draw!(<S: Screen, D: Draw<S>,>|self: Option<D>, to: S|{
|
||||
self.map(|it|it.draw(to)).transpose().map(Option::unwrap_or_default)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//impl<S: Screen, D: Draw<S>> Draw<S> for RwLock<D> {
|
||||
//fn draw (self, __: &mut S) -> Usually<XYWH<S::Unit>> {
|
||||
//fn draw (self, __: &mut S) -> Perhaps<XYWH<S::Unit>> {
|
||||
//todo!()
|
||||
//}
|
||||
//}
|
||||
|
||||
//impl<T: Screen, D: Draw<T>> Draw<T> for Arc<D> {
|
||||
//fn draw (self, __: &mut T) -> Usually<XYWH<T::Unit>> {
|
||||
//fn draw (self, __: &mut T) -> Perhaps<XYWH<T::Unit>> {
|
||||
//todo!()
|
||||
//}
|
||||
//}
|
||||
|
|
@ -101,19 +106,19 @@ pub trait View<T: Screen> {
|
|||
}
|
||||
|
||||
impl<T: Screen, V: View<T>> Draw<T> for &V {
|
||||
fn draw (self, to: &mut T) -> Usually<XYWH<T::Unit>> {
|
||||
fn draw (self, to: &mut T) -> Perhaps<XYWH<T::Unit>> {
|
||||
self.view().draw(to)
|
||||
}
|
||||
}
|
||||
|
||||
/// Because we can't implement [Draw] for `F: FnOnce...` without conflicts.
|
||||
pub struct Thunk<T: Screen, F: FnOnce(&mut T)->Usually<XYWH<T::Unit>>>(
|
||||
pub struct Thunk<T: Screen, F: FnOnce(&mut T)->Perhaps<XYWH<T::Unit>>>(
|
||||
pub F,
|
||||
std::marker::PhantomData<T>
|
||||
);
|
||||
|
||||
impl<T: Screen, F: FnOnce(&mut T)->Usually<XYWH<T::Unit>>> Draw<T> for Thunk<T, F> {
|
||||
fn draw (self, to: &mut T) -> Usually<XYWH<T::Unit>> {
|
||||
impl<T: Screen, F: FnOnce(&mut T)->Perhaps<XYWH<T::Unit>>> Draw<T> for Thunk<T, F> {
|
||||
fn draw (self, to: &mut T) -> Perhaps<XYWH<T::Unit>> {
|
||||
(self.0)(to)
|
||||
}
|
||||
}
|
||||
|
|
@ -126,7 +131,7 @@ impl<T: Screen, F: FnOnce(&mut T)->Usually<XYWH<T::Unit>>> Draw<T> for Thunk<T,
|
|||
/// thunk(|to: &mut Tui|Ok(to.1))
|
||||
/// # }
|
||||
/// ```
|
||||
pub const fn thunk <T: Screen, F: FnOnce(&mut T)->Usually<XYWH<T::Unit>>> (
|
||||
pub const fn thunk <T: Screen, F: FnOnce(&mut T)->Perhaps<XYWH<T::Unit>>> (
|
||||
draw: F
|
||||
) -> Thunk<T, F> {
|
||||
Thunk(draw, std::marker::PhantomData)
|
||||
|
|
|
|||
33
src/eval.rs
33
src/eval.rs
|
|
@ -114,22 +114,23 @@ pub fn eval_view <'a, O: Screen + 'a, S> (
|
|||
).draw(output),
|
||||
|
||||
// Second `frags.next()` calls returns the namespace member.
|
||||
Some("bsp") => eval_enum!(
|
||||
"bsp", output, state, frags.next(), arg0, Split {
|
||||
Some("bsp") => {
|
||||
let direction = eval_enum!("bsp", output, state, frags.next(), arg0, Split {
|
||||
"n" => North, "s" => South, "e" => East, "w" => West, "a" => Above, "b" => Below
|
||||
}
|
||||
).half(
|
||||
});
|
||||
direction.half(
|
||||
thunk(move|output: &mut O|state.interpret(output, &arg0)),
|
||||
thunk(move|output: &mut O|state.interpret(output, &arg1)),
|
||||
).draw(output),
|
||||
).draw(output)
|
||||
},
|
||||
|
||||
Some("align") => eval_enum!(
|
||||
"align", output, state, frags.next(), arg0, Origin {
|
||||
Some("align") => {
|
||||
let alignment = eval_enum!("align", output, state, frags.next(), arg0, Origin {
|
||||
"c" => C, "n" => N, "s" => S, "e" => E, "w" => W, "x" => X, "y" => Y
|
||||
}
|
||||
).align(
|
||||
thunk(move|output: &mut O|state.interpret(output, &arg0))
|
||||
).draw(output),
|
||||
});
|
||||
let content = thunk(move|output: &mut O|state.interpret(output, &arg0));
|
||||
align(alignment, content).draw(output)
|
||||
},
|
||||
|
||||
Some("exact") => eval_xy!(
|
||||
"exact", expr, head, output, state, frags.next(),
|
||||
|
|
@ -191,11 +192,11 @@ pub fn eval_view_tui <'a, S> (
|
|||
let arg0 = args.head();
|
||||
let tail0 = args.tail();
|
||||
let arg1 = tail0.head();
|
||||
Ok(Some(match frags.next() {
|
||||
match frags.next() {
|
||||
|
||||
Some("text") => {
|
||||
if let Some(src) = args?.src()? {
|
||||
output.show(src)?
|
||||
output.show(src)
|
||||
} else {
|
||||
return Ok(None)
|
||||
}
|
||||
|
|
@ -208,7 +209,7 @@ pub fn eval_view_tui <'a, S> (
|
|||
state.interpret(output, &arg1)?;
|
||||
// FIXME?: don't max out the used area?
|
||||
Ok(output.area().into())
|
||||
})))?
|
||||
})))
|
||||
},
|
||||
|
||||
Some("bg") => {
|
||||
|
|
@ -218,10 +219,10 @@ pub fn eval_view_tui <'a, S> (
|
|||
state.interpret(output, &arg1)?;
|
||||
// FIXME?: don't max out the used area?
|
||||
Ok(output.area().into())
|
||||
})))?
|
||||
})))
|
||||
},
|
||||
|
||||
_ => return Ok(None)
|
||||
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ use crate::*;
|
|||
|
||||
mod align; pub use self::align::*;
|
||||
mod area; pub use self::area::*;
|
||||
mod origin; pub use self::origin::*;
|
||||
mod split; pub use self::split::*;
|
||||
|
||||
pub enum Layout<T: Screen, X: Into<Option<T::Unit>>, I: Draw<T>> {
|
||||
|
|
@ -21,12 +20,11 @@ pub enum Layout<T: Screen, X: Into<Option<T::Unit>>, I: Draw<T>> {
|
|||
ClipWH(X, X, I),
|
||||
}
|
||||
|
||||
impl<
|
||||
impl_draw!(<
|
||||
T: Screen,
|
||||
X: Into<Option<T::Unit>>,
|
||||
I: Draw<T>
|
||||
> Draw<T> for Layout<T, X, I> {
|
||||
fn draw (self, to: &mut T) -> Usually<XYWH<T::Unit>> {
|
||||
I: Draw<T>,
|
||||
>|self: Layout<T, X, I>, to: T|{
|
||||
use Layout::*;
|
||||
match self {
|
||||
__(_) => unreachable!(),
|
||||
|
|
@ -83,5 +81,4 @@ impl<
|
|||
it.draw(to)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
use crate::*;
|
||||
|
||||
pub struct Align<T>(Option<Origin>, T);
|
||||
|
||||
/// ```
|
||||
/// use tengri::*;
|
||||
/// let _ = align(None, "unaligned");
|
||||
|
|
@ -11,3 +9,7 @@ pub struct Align<T>(Option<Origin>, T);
|
|||
pub fn align <S: Screen, T: Draw<S>, U: Into<Option<Origin>>> (origin: U, it: T) -> Align<T> {
|
||||
Align(origin.into(), it)
|
||||
}
|
||||
|
||||
pub struct Align<T>(Option<Origin>, T);
|
||||
|
||||
impl_draw!(<S: Screen, T: Draw<S>,>|self: Align<T>, to: S|{ todo!() });
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
use crate::*;
|
||||
|
||||
pub struct Area<S: Screen, T: Draw<S>>(Option<XYWH<S::Unit>>, T);
|
||||
|
||||
/// ```
|
||||
/// use tengri::*;
|
||||
/// let _ = area(None, "unareaed");
|
||||
|
|
@ -13,3 +11,7 @@ pub fn area <S: Screen, T: Draw<S>, U: Into<Option<XYWH<S::Unit>>>> (
|
|||
) -> Area<S, T> {
|
||||
Area(origin.into(), it)
|
||||
}
|
||||
|
||||
pub struct Area<S: Screen, T: Draw<S>>(Option<XYWH<S::Unit>>, T);
|
||||
|
||||
impl_draw!(<S: Screen, T: Draw<S>,>|self: Area<S, T>, to: S|{ todo!() });
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
use super::*;
|
||||
|
||||
/// Where is [0, 0] located?
|
||||
///
|
||||
/// ```
|
||||
/// use tengri::draw::Origin;
|
||||
/// let _ = Origin::NW.align(());
|
||||
/// ```
|
||||
#[cfg_attr(test, derive(Arbitrary))]
|
||||
#[derive(Debug, Copy, Clone, Default)] pub enum Origin {
|
||||
#[default] C, X, Y, NW, N, NE, E, SE, S, SW, W
|
||||
}
|
||||
|
||||
/// Something that has `[0, 0]` at a particular point.
|
||||
pub trait HasOrigin {
|
||||
fn origin (&self) -> Origin;
|
||||
}
|
||||
|
||||
impl<T: AsRef<Origin>> HasOrigin for T {
|
||||
fn origin (&self) -> Origin {
|
||||
*self.as_ref()
|
||||
}
|
||||
}
|
||||
|
|
@ -5,3 +5,4 @@ mod coord; pub use self::coord::*;
|
|||
mod iter; pub use self::iter::*;
|
||||
mod sizer; pub use self::sizer::*;
|
||||
mod xywh; pub use self::xywh::*;
|
||||
mod lrtb; pub use self::lrtb::*;
|
||||
|
|
|
|||
47
src/space/lrtb.rs
Normal file
47
src/space/lrtb.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
use crate::*;
|
||||
use Origin::*;
|
||||
|
||||
impl<N: Coord, T: Xywh<N>> Lrtb<N> for T {}
|
||||
|
||||
pub trait Lrtb<N: Coord>: Xywh<N> {
|
||||
fn lrtb (&self) -> [N;4] {
|
||||
// FIXME: factor origin
|
||||
[self.x(), self.y(), self.x()+self.w(), self.y()+self.h()]
|
||||
}
|
||||
fn iter_x (&self) -> impl Iterator<Item = N> where Self: HasOrigin {
|
||||
self.x_west()..self.x_east()
|
||||
}
|
||||
fn x_west (&self) -> N where Self: HasOrigin {
|
||||
let w = self.w();
|
||||
let a = self.origin();
|
||||
let d = match a { NW|W|SW => 0.into(), N|X|C|Y|S => w/2.into(), NE|E|SE => w };
|
||||
self.x().minus(d)
|
||||
}
|
||||
fn x_east (&self) -> N where Self: HasOrigin {
|
||||
let w = self.w();
|
||||
let a = self.origin();
|
||||
let d = match a { NW|W|SW => w, N|X|C|Y|S => w/2.into(), NE|E|SE => 0.into() };
|
||||
self.x().plus(d)
|
||||
}
|
||||
fn x_center (&self) -> N where Self: HasOrigin {
|
||||
todo!()
|
||||
}
|
||||
fn iter_y (&self) -> impl Iterator<Item = N> where Self: HasOrigin {
|
||||
self.y_north()..self.y_south()
|
||||
}
|
||||
fn y_north (&self) -> N where Self: HasOrigin {
|
||||
let a = self.origin();
|
||||
let h = self.h();
|
||||
let d = match a { NW|N|NE => 0.into(), W|X|C|Y|E => h/2.into(), SW|S|SE => h };
|
||||
self.y().minus(d)
|
||||
}
|
||||
fn y_south (&self) -> N where Self: HasOrigin {
|
||||
let a = self.origin();
|
||||
let h = self.h();
|
||||
let d = match a { NW|N|NE => h, W|X|C|Y|E => h/2.into(), SW|S|SE => 0.into() };
|
||||
self.y().plus(d)
|
||||
}
|
||||
fn y_center (&self) -> N where Self: HasOrigin {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,28 @@ use super::*;
|
|||
use Origin::*;
|
||||
use Split::*;
|
||||
|
||||
/// Where is [0, 0] located?
|
||||
///
|
||||
/// ```
|
||||
/// use tengri::draw::Origin;
|
||||
/// let _ = Origin::NW.align(());
|
||||
/// ```
|
||||
#[cfg_attr(test, derive(Arbitrary))]
|
||||
#[derive(Debug, Copy, Clone, Default)] pub enum Origin {
|
||||
#[default] C, X, Y, NW, N, NE, E, SE, S, SW, W
|
||||
}
|
||||
|
||||
/// Something that has `[0, 0]` at a particular point.
|
||||
pub trait HasOrigin {
|
||||
fn origin (&self) -> Origin;
|
||||
}
|
||||
|
||||
impl<T: AsRef<Origin>> HasOrigin for T {
|
||||
fn origin (&self) -> Origin {
|
||||
*self.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Xy<N: Coord> {
|
||||
fn x (&self) -> N;
|
||||
fn y (&self) -> N;
|
||||
|
|
@ -17,59 +39,16 @@ pub trait Xywh<N: Coord>: Xy<N> + Wh<N> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait Lrtb<N: Coord> {
|
||||
// FIXME: factor origin
|
||||
fn lrtb (&self) -> [N;4] {
|
||||
[self.x(), self.y(), self.x()+self.w(), self.y()+self.h()]
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Wide<N: Coord> {
|
||||
pub trait Wide<N: Coord>: Xy<N> {
|
||||
fn w (&self) -> N { N::zero() }
|
||||
fn w_min (&self) -> N { self.w() }
|
||||
fn w_max (&self) -> N { self.w() }
|
||||
fn iter_x (&self) -> impl Iterator<Item = N> where Self: HasOrigin {
|
||||
self.x_west()..self.x_east()
|
||||
}
|
||||
fn x_west (&self) -> N where Self: HasOrigin {
|
||||
let w = self.w();
|
||||
let a = self.origin();
|
||||
let d = match a { NW|W|SW => 0.into(), N|X|C|Y|S => w/2.into(), NE|E|SE => w };
|
||||
self.x().minus(d)
|
||||
}
|
||||
fn x_east (&self) -> N where Self: HasOrigin {
|
||||
let w = self.w();
|
||||
let a = self.origin();
|
||||
let d = match a { NW|W|SW => w, N|X|C|Y|S => w/2.into(), NE|E|SE => 0.into() };
|
||||
self.x().plus(d)
|
||||
}
|
||||
fn x_center (&self) -> N where Self: HasOrigin {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Tall<N: Coord> {
|
||||
fn h (&self) -> N { N::zero() }
|
||||
fn h_min (&self) -> N { self.h() }
|
||||
fn h_max (&self) -> N { self.h() }
|
||||
fn iter_y (&self) -> impl Iterator<Item = N> where Self: HasOrigin {
|
||||
self.y_north()..self.y_south()
|
||||
}
|
||||
fn y_north (&self) -> N where Self: HasOrigin {
|
||||
let a = self.origin();
|
||||
let h = self.h();
|
||||
let d = match a { NW|N|NE => 0.into(), W|X|C|Y|E => h/2.into(), SW|S|SE => h };
|
||||
self.y().minus(d)
|
||||
}
|
||||
fn y_south (&self) -> N where Self: HasOrigin {
|
||||
let a = self.origin();
|
||||
let h = self.h();
|
||||
let d = match a { NW|N|NE => h, W|X|C|Y|E => h/2.into(), SW|S|SE => 0.into() };
|
||||
self.y().plus(d)
|
||||
}
|
||||
fn y_center (&self) -> N where Self: HasOrigin {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
/// Point with size.
|
||||
|
|
|
|||
|
|
@ -325,13 +325,8 @@ impl Coord for u16 {
|
|||
}
|
||||
}
|
||||
|
||||
impl Draw<Tui> for u64 {
|
||||
fn draw (self, _to: &mut Tui) -> Usually<XYWH<u16>> { todo!() }
|
||||
}
|
||||
|
||||
impl Draw<Tui> for f64 {
|
||||
fn draw (self, _to: &mut Tui) -> Usually<XYWH<u16>> { todo!() }
|
||||
}
|
||||
impl_draw!(|self: u64, _to: Tui|{ todo!() });
|
||||
impl_draw!(|self: f64, _to: Tui|{ todo!() });
|
||||
|
||||
mod phat {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ pub const fn border (on: bool, style: impl BorderStyle, draw: impl Draw<Tui>) ->
|
|||
to.blit(&style.border_e(), x + w - 1, y, style.style());
|
||||
}
|
||||
}
|
||||
Ok(XYWH(x, y, w, h))
|
||||
Ok(Some(XYWH(x, y, w, h)))
|
||||
}));
|
||||
above(outline, content)
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@ macro_rules! border {
|
|||
#[derive(Copy, Clone)] pub struct $T(pub bool, pub Style);
|
||||
//impl Layout<Tui> for $T {}
|
||||
impl Draw<Tui> for $T {
|
||||
fn draw (self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
fn draw (self, to: &mut Tui) -> Perhaps<XYWH<u16>> {
|
||||
when(self.enabled(), thunk(|to: &mut Tui|BorderStyle::draw(self, to))).draw(to)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
44
src/text.rs
44
src/text.rs
|
|
@ -3,40 +3,19 @@ pub(crate) use ::unicode_width::*;
|
|||
|
||||
#[cfg(feature = "term")] mod impl_term {
|
||||
use super::*;
|
||||
use crate::term::Tui;
|
||||
use crate::*;
|
||||
use ratatui::prelude::Position;
|
||||
|
||||
impl Draw<Tui> for &str {
|
||||
fn draw (self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
impl_draw!(|self: String, to: Tui|{self.as_str().draw(to)});
|
||||
impl_draw!(|self: std::sync::Arc<str>, to: Tui|{self.as_ref().draw(to)});
|
||||
impl_draw!(|self: &std::sync::Arc<str>, to: Tui|{self.as_ref().draw(to)});
|
||||
impl_draw!(|self: &str, to: Tui|{
|
||||
let XYWH(x, y, w, ..) = to.1.centered_xy([width_chars_max(to.w(), self), 1]);
|
||||
to.text(&self, x, y, w)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
impl Draw<Tui> for String {
|
||||
fn draw (self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
self.as_str().draw(to)
|
||||
}
|
||||
}
|
||||
|
||||
impl Draw<Tui> for std::sync::Arc<str> {
|
||||
fn draw (self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
self.as_ref().draw(to)
|
||||
}
|
||||
}
|
||||
|
||||
impl Draw<Tui> for &std::sync::Arc<str> {
|
||||
fn draw (self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
self.as_ref().draw(to)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>> Draw<Tui> for TrimString<T> {
|
||||
fn draw (self, to: &mut Tui) -> Usually<XYWH<u16>> { self.as_ref().draw(to) }
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>> Draw<Tui> for TrimStringRef<'_, T> {
|
||||
fn draw (self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||
impl_draw!(<T: AsRef<str>,>|self: TrimString<T>, to: Tui|{self.as_ref().draw(to)});
|
||||
impl_draw!(<T: AsRef<str>,>|self: TrimStringRef<'_, T>, to: Tui|{
|
||||
let XYWH(x, y, w, ..) = to.1;
|
||||
let mut width: u16 = 1;
|
||||
let mut chars = self.1.as_ref().chars();
|
||||
|
|
@ -52,14 +31,13 @@ pub(crate) use ::unicode_width::*;
|
|||
}
|
||||
let XYWH(x, y, w, ..) = XYWH(to.x(), to.y(), to.w().min(self.0).min(self.1.as_ref().width() as u16), to.h());
|
||||
to.text(&self.as_ref(), x, y, w)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
impl Tui {
|
||||
/// Write a line of text
|
||||
///
|
||||
/// TODO: do a paragraph (handle newlines)
|
||||
pub fn text (&mut self, text: &impl AsRef<str>, x0: u16, y: u16, max_width: u16) -> Usually<XYWH<u16>> {
|
||||
pub fn text (&mut self, text: &impl AsRef<str>, x0: u16, y: u16, max_width: u16) -> Perhaps<XYWH<u16>> {
|
||||
let text = text.as_ref();
|
||||
let mut string_width: u16 = 0;
|
||||
for character in text.chars() {
|
||||
|
|
@ -75,7 +53,7 @@ pub(crate) use ::unicode_width::*;
|
|||
break
|
||||
}
|
||||
}
|
||||
Ok(XYWH(x0, y, string_width, 1))
|
||||
Ok(Some(XYWH(x0, y, string_width, 1)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue