mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
wip: return () from render method
This commit is contained in:
parent
5d00e9f284
commit
e3fa292a3c
3 changed files with 167 additions and 140 deletions
|
|
@ -310,7 +310,7 @@ impl<E: Engine> Widget for JackDevice<E> {
|
|||
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
self.state.read().unwrap().layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
self.state.read().unwrap().render(to)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,26 +35,26 @@ pub trait Output<E: Engine> {
|
|||
fn area_mut (&mut self)
|
||||
-> &mut E::Area;
|
||||
fn render_in (&mut self, area: E::Area, widget: &dyn Widget<Engine = E>)
|
||||
-> Perhaps<E::Area>;
|
||||
-> Usually<()>;
|
||||
}
|
||||
|
||||
pub trait Widget: Send + Sync {
|
||||
type Engine: Engine;
|
||||
fn layout (
|
||||
&self, to: <Self::Engine as Engine>::Size
|
||||
fn layout (&self,
|
||||
to: <Self::Engine as Engine>::Size
|
||||
) -> Perhaps<<Self::Engine as Engine>::Size> {
|
||||
Ok(Some(to))
|
||||
}
|
||||
fn render (
|
||||
&self, to: &mut <Self::Engine as Engine>::Output
|
||||
) -> Perhaps<<<Self as Widget>::Engine as Engine>::Area>;
|
||||
fn render (&self,
|
||||
to: &mut <Self::Engine as Engine>::Output
|
||||
) -> Usually<()>;
|
||||
}
|
||||
impl<'a, E: Engine> Widget for Box<dyn Widget<Engine = E> + 'a> {
|
||||
type Engine = E;
|
||||
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
(**self).layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
(**self).render(to)
|
||||
}
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ impl<E: Engine> Widget for &dyn Widget<Engine = E> {
|
|||
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
(*self).layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
(*self).render(to)
|
||||
}
|
||||
}
|
||||
|
|
@ -72,7 +72,7 @@ impl<E: Engine> Widget for &mut dyn Widget<Engine = E> {
|
|||
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
(**self).layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
(**self).render(to)
|
||||
}
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ impl<E: Engine, W: Widget<Engine = E>> Widget for Arc<W> {
|
|||
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
self.as_ref().layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
self.as_ref().render(to)
|
||||
}
|
||||
}
|
||||
|
|
@ -90,7 +90,7 @@ impl<E: Engine, W: Widget<Engine = E>> Widget for Mutex<W> {
|
|||
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
self.lock().unwrap().layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
self.lock().unwrap().render(to)
|
||||
}
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ impl<E: Engine, W: Widget<Engine = E>> Widget for RwLock<W> {
|
|||
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
self.read().unwrap().layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
self.read().unwrap().render(to)
|
||||
}
|
||||
}
|
||||
|
|
@ -108,8 +108,8 @@ impl<E: Engine, W: Widget<Engine = E>> Widget for Option<W> {
|
|||
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
Ok(self.as_ref().map(|widget|widget.layout(to)).transpose()?.flatten())
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
Ok(self.as_ref().map(|widget|widget.render(to)).transpose()?.flatten())
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
self.as_ref().map(|widget|widget.render(to)).unwrap_or(Ok(()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -127,10 +127,10 @@ impl<E: Engine, W: Content<Engine = E>> Widget for W {
|
|||
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
self.content().layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
match self.layout(to.area().wh().into())? {
|
||||
Some(wh) => to.render_in(to.area().clip(wh).into(), &self.content()),
|
||||
None => Ok(None)
|
||||
None => Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -428,17 +428,17 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Align<T> {
|
|||
fn layout (&self, outer_area: E::Size) -> Perhaps<E::Size> {
|
||||
self.inner().layout(outer_area)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
let outer_area = to.area();
|
||||
Ok(if let Some(inner_size) = self.layout(outer_area.wh().into())? {
|
||||
let inner_area = outer_area.clip(inner_size);
|
||||
if let Some(aligned) = align(&self, outer_area.into(), inner_area.into()) {
|
||||
to.render_in(aligned, self.inner())?
|
||||
} else {
|
||||
None
|
||||
()
|
||||
}
|
||||
} else {
|
||||
None
|
||||
()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -483,10 +483,10 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Min<E::Unit, T> {
|
|||
}.into()))
|
||||
}
|
||||
// TODO: 🡘 🡙 ←🡙→
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
Ok(self.layout(to.area().wh().into())?
|
||||
.map(|size|to.render_in(to.area().clip(size).into(), self.inner()))
|
||||
.transpose()?.flatten())
|
||||
.transpose()?.unwrap_or(()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -515,10 +515,10 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Max<E:: Unit, T> {
|
|||
Self::XY(w, h, _) => [to.w().min(w), to.h().min(h)],
|
||||
}.into()))
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
Ok(self.layout(to.area().wh().into())?
|
||||
.map(|size|to.render_in(to.area().clip(size).into(), self.inner()))
|
||||
.transpose()?.flatten())
|
||||
.transpose()?.unwrap_or(()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -547,10 +547,10 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Grow<E::Unit, T> {
|
|||
Self::XY(w, h, _) => [to.w() + w, to.h() + h],
|
||||
}.into()))
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
Ok(self.layout(to.area().wh().into())?
|
||||
.map(|size|to.render_in(to.area().clip(size).into(), self.inner()))
|
||||
.transpose()?.flatten())
|
||||
.transpose()?.unwrap_or(()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -579,10 +579,10 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Shrink<E::Unit, T> {
|
|||
Self::XY(w, h, _) => [to.w() - w, to.h() - h]
|
||||
}.into()))
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
Ok(self.layout(to.area().wh().into())?
|
||||
.map(|size|to.render_in(to.area().clip(size).into(), self.inner()))
|
||||
.transpose()?.flatten())
|
||||
.transpose()?.unwrap_or(()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -627,7 +627,7 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Inset<E::Unit, T> {
|
|||
Self::XY(x, y, ref inner) => Shrink::XY(x + x, y + y, inner as &dyn Widget<Engine = E>),
|
||||
}.layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
match *self {
|
||||
Self::X(x, ref inner) => Plus::X(x, inner as &dyn Widget<Engine = E>),
|
||||
Self::Y(y, ref inner) => Plus::Y(y, inner as &dyn Widget<Engine = E>),
|
||||
|
|
@ -645,7 +645,7 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Outset<E::Unit, T> {
|
|||
Self::XY(x, y, ref inner) => Grow::XY(x + x, y + y, inner as &dyn Widget<Engine = E>),
|
||||
}.layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
match *self {
|
||||
Self::X(x, ref inner) => Plus::X(x, inner as &dyn Widget<Engine = E>),
|
||||
Self::Y(y, ref inner) => Plus::Y(y, inner as &dyn Widget<Engine = E>),
|
||||
|
|
@ -681,14 +681,14 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Plus<E::Unit, T> {
|
|||
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
self.inner().layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
let area = to.area();
|
||||
Ok(self.layout(area.wh().into())?
|
||||
.map(|size|to.render_in(match *self {
|
||||
Self::X(x, _) => [area.x() + x, area.y(), size.w(), size.h()],
|
||||
Self::Y(y, _) => [area.x(), area.y() + y, size.w(), size.h()],
|
||||
Self::XY(x, y, _) => [area.x() + x, area.y() + y, size.w(), size.h()],
|
||||
}.into(), self.inner())).transpose()?.flatten())
|
||||
}.into(), self.inner())).transpose()?.unwrap_or(()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -719,14 +719,14 @@ impl<E: Engine, T: Widget<Engine = E>> Widget for Minus<E::Unit, T> {
|
|||
fn layout (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
self.inner().layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut E::Output) -> Perhaps<E::Area> {
|
||||
fn render (&self, to: &mut E::Output) -> Usually<()> {
|
||||
let area = to.area();
|
||||
Ok(self.layout(area.wh().into())?
|
||||
.map(|size|to.render_in(match *self {
|
||||
Self::X(x, _) => [area.x().minus(x), area.y(), size.w(), size.h()],
|
||||
Self::Y(y, _) => [area.x(), area.y().minus(y), size.w(), size.h()],
|
||||
Self::XY(x, y, _) => [area.x().minus(x), area.y().minus(y), size.w(), size.h()],
|
||||
}.into(), self.inner())).transpose()?.flatten())
|
||||
}.into(), self.inner())).transpose()?.unwrap_or(()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,12 +13,19 @@ use crossterm::terminal::{
|
|||
|
||||
pub struct Tui {
|
||||
exited: Arc<AtomicBool>,
|
||||
buffer: usize,
|
||||
buffers: [Buffer;2],
|
||||
buffer: Buffer,
|
||||
backend: CrosstermBackend<Stdout>,
|
||||
event: RwLock<Option<TuiEvent>>,
|
||||
area: [u16;4],
|
||||
}
|
||||
pub struct TuiInput {
|
||||
event: TuiEvent,
|
||||
exited: Arc<AtomicBool>,
|
||||
}
|
||||
pub struct TuiOutput {
|
||||
buffer: Buffer,
|
||||
area: [u16;4],
|
||||
}
|
||||
|
||||
impl Engine for Tui {
|
||||
type Unit = u16;
|
||||
|
|
@ -26,7 +33,7 @@ impl Engine for Tui {
|
|||
type Area = [Self::Unit;4];
|
||||
type Input = TuiInput;
|
||||
type Handled = bool;
|
||||
type Output = Self;
|
||||
type Output = TuiOutput;
|
||||
fn exited (&self) -> bool {
|
||||
self.exited.fetch_and(true, Ordering::Relaxed)
|
||||
}
|
||||
|
|
@ -48,28 +55,6 @@ impl Engine for Tui {
|
|||
disable_raw_mode().map_err(Into::into)
|
||||
}
|
||||
}
|
||||
impl Output<Tui> for Tui {
|
||||
#[inline] fn area (&self) -> <Self as Engine>::Area {
|
||||
self.area
|
||||
}
|
||||
#[inline] fn area_mut (&mut self) -> &mut <Self as Engine>::Area {
|
||||
&mut self.area
|
||||
}
|
||||
#[inline] fn render_in (&mut self,
|
||||
area: <Self as Engine>::Area,
|
||||
widget: &dyn Widget<Engine = Self>
|
||||
) -> Perhaps<<Self as Engine>::Area> {
|
||||
let last = self.area();
|
||||
*self.area_mut() = area;
|
||||
let next = widget.render(self)?;
|
||||
*self.area_mut() = last;
|
||||
Ok(next)
|
||||
}
|
||||
}
|
||||
pub struct TuiInput {
|
||||
event: TuiEvent,
|
||||
exited: Arc<AtomicBool>,
|
||||
}
|
||||
impl Input<Tui> for TuiInput {
|
||||
type Event = TuiEvent;
|
||||
fn event (&self) -> &TuiEvent {
|
||||
|
|
@ -82,6 +67,86 @@ impl Input<Tui> for TuiInput {
|
|||
self.exited.store(true, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
//impl Output<Tui> for Tui {
|
||||
//#[inline] fn area (&self) -> <Self as Engine>::Area {
|
||||
//self.area
|
||||
//}
|
||||
//#[inline] fn area_mut (&mut self) -> &mut <Self as Engine>::Area {
|
||||
//&mut self.area
|
||||
//}
|
||||
//#[inline] fn render_in (&mut self,
|
||||
//area: <Self as Engine>::Area,
|
||||
//widget: &dyn Widget<Engine = Self>
|
||||
//) -> Perhaps<<Self as Engine>::Area> {
|
||||
//let last = self.area();
|
||||
//*self.area_mut() = area;
|
||||
//let next = widget.render(self)?;
|
||||
//*self.area_mut() = last;
|
||||
//Ok(next)
|
||||
//}
|
||||
//}
|
||||
impl Output<Tui> for TuiOutput {
|
||||
#[inline] fn area (&self) -> [u16;4] {
|
||||
self.area
|
||||
}
|
||||
#[inline] fn area_mut (&mut self) -> &mut [u16;4] {
|
||||
&mut self.area
|
||||
}
|
||||
#[inline] fn render_in (&mut self,
|
||||
area: [u16;4],
|
||||
widget: &dyn Widget<Engine = Tui>
|
||||
) -> Usually<()> {
|
||||
let last = self.area();
|
||||
*self.area_mut() = area;
|
||||
widget.render(self)?;
|
||||
*self.area_mut() = last;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl TuiOutput {
|
||||
pub fn buffer_update (&mut self,
|
||||
area: [u16;4],
|
||||
callback: &impl Fn(&mut Cell, u16, u16)
|
||||
) {
|
||||
buffer_update(&mut self.buffer, area, callback);
|
||||
}
|
||||
pub fn fill_bg (&mut self, area: [u16;4], color: Color) {
|
||||
self.buffer_update(area, &|cell,_,_|{cell.set_bg(color);})
|
||||
}
|
||||
pub fn fill_fg (&mut self, area: [u16;4], color: Color) {
|
||||
self.buffer_update(area, &|cell,_,_|{cell.set_fg(color);})
|
||||
}
|
||||
pub fn fill_ul (&mut self, area: [u16;4], color: Color) {
|
||||
self.buffer_update(area, &|cell,_,_|{
|
||||
cell.modifier = ratatui::prelude::Modifier::UNDERLINED;
|
||||
cell.underline_color = color;
|
||||
})
|
||||
}
|
||||
pub fn fill_char (&mut self, area: [u16;4], c: char) {
|
||||
self.buffer_update(area, &|cell,_,_|{cell.set_char(c);})
|
||||
}
|
||||
pub fn make_dim (&mut self) {
|
||||
for cell in self.buffer.content.iter_mut() {
|
||||
cell.bg = ratatui::style::Color::Rgb(30,30,30);
|
||||
cell.fg = ratatui::style::Color::Rgb(100,100,100);
|
||||
cell.modifier = ratatui::style::Modifier::DIM;
|
||||
}
|
||||
}
|
||||
pub fn blit (
|
||||
&mut self, text: &impl AsRef<str>, x: u16, y: u16, style: Option<Style>
|
||||
) {
|
||||
let text = text.as_ref();
|
||||
let buf = &mut self.buffer;
|
||||
if x < buf.area.width && y < buf.area.height {
|
||||
buf.set_string(x, y, text, style.unwrap_or(Style::default()));
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn with_rect (&mut self, area: [u16;4]) -> &mut Self {
|
||||
self.area = area;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Tui {
|
||||
/// Run the main loop.
|
||||
|
|
@ -93,8 +158,7 @@ impl Tui {
|
|||
let engine = Self {
|
||||
exited: Arc::new(AtomicBool::new(false)),
|
||||
event: RwLock::new(None),
|
||||
buffer: 0,
|
||||
buffers: [Buffer::empty(area), Buffer::empty(area)],
|
||||
buffer: Buffer::empty(area),
|
||||
area: area.xywh(),
|
||||
backend,
|
||||
};
|
||||
|
|
@ -140,69 +204,30 @@ impl Tui {
|
|||
let exited = engine.read().unwrap().exited.clone();
|
||||
let engine = engine.clone();
|
||||
let state = state.clone();
|
||||
let mut buffer = Buffer::empty(
|
||||
engine.read().unwrap().backend.size().expect("get size failed")
|
||||
);
|
||||
spawn(move || loop {
|
||||
if exited.fetch_and(true, Ordering::Relaxed) {
|
||||
break
|
||||
}
|
||||
if let Ok(state) = state.try_read() {
|
||||
let mut engine = engine.write().unwrap();
|
||||
engine.area = engine.backend.size().expect("get size failed").xywh();
|
||||
state.render(&mut engine).expect("render failed");
|
||||
engine.flip();
|
||||
let area = engine.read().unwrap().backend.size().expect("get size failed").xywh();
|
||||
let mut output = TuiOutput { buffer, area };
|
||||
state.render(&mut output).expect("render failed");
|
||||
buffer = engine.write().unwrap().flip(output.buffer);
|
||||
}
|
||||
std::thread::sleep(sleep);
|
||||
})
|
||||
}
|
||||
pub fn buffer (&mut self) -> &mut Buffer {
|
||||
&mut self.buffers[self.buffer]
|
||||
}
|
||||
fn flip (&mut self) {
|
||||
let previous_buffer = &self.buffers[1 - self.buffer];
|
||||
let current_buffer = &self.buffers[self.buffer];
|
||||
let updates = previous_buffer.diff(current_buffer);
|
||||
//pub fn buffer (&mut self) -> &mut Buffer {
|
||||
//&mut self.buffers[self.buffer]
|
||||
//}
|
||||
fn flip (&mut self, mut buffer: Buffer) -> Buffer {
|
||||
let updates = self.buffer.diff(&buffer);
|
||||
self.backend.draw(updates.into_iter()).expect("failed to render");
|
||||
self.buffers[1 - self.buffer].reset();
|
||||
self.buffer = 1 - self.buffer;
|
||||
}
|
||||
pub fn buffer_update (&mut self, area: [u16;4], callback: &impl Fn(&mut Cell, u16, u16)) {
|
||||
buffer_update(self.buffer(), area, callback)
|
||||
}
|
||||
pub fn fill_bg (&mut self, area: [u16;4], color: Color) {
|
||||
self.buffer_update(area, &|cell,_,_|{cell.set_bg(color);})
|
||||
}
|
||||
pub fn fill_fg (&mut self, area: [u16;4], color: Color) {
|
||||
self.buffer_update(area, &|cell,_,_|{cell.set_fg(color);})
|
||||
}
|
||||
pub fn fill_ul (&mut self, area: [u16;4], color: Color) {
|
||||
self.buffer_update(area, &|cell,_,_|{
|
||||
cell.modifier = ratatui::prelude::Modifier::UNDERLINED;
|
||||
cell.underline_color = color;
|
||||
})
|
||||
}
|
||||
pub fn fill_char (&mut self, area: [u16;4], c: char) {
|
||||
self.buffer_update(area, &|cell,_,_|{cell.set_char(c);})
|
||||
}
|
||||
pub fn make_dim (&mut self) {
|
||||
for cell in self.buffer().content.iter_mut() {
|
||||
cell.bg = ratatui::style::Color::Rgb(30,30,30);
|
||||
cell.fg = ratatui::style::Color::Rgb(100,100,100);
|
||||
cell.modifier = ratatui::style::Modifier::DIM;
|
||||
}
|
||||
}
|
||||
pub fn blit (
|
||||
&mut self, text: &impl AsRef<str>, x: u16, y: u16, style: Option<Style>
|
||||
) -> Perhaps<[u16;4]> {
|
||||
let text = text.as_ref();
|
||||
let buf = self.buffer();
|
||||
if x < buf.area.width && y < buf.area.height {
|
||||
buf.set_string(x, y, text, style.unwrap_or(Style::default()));
|
||||
}
|
||||
Ok(Some([x, y, text.len() as u16, 1]))
|
||||
}
|
||||
#[inline]
|
||||
pub fn with_rect (&mut self, area: [u16;4]) -> &mut Self {
|
||||
self.area = area;
|
||||
self
|
||||
std::mem::swap(&mut self.buffer, &mut buffer);
|
||||
buffer
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -279,11 +304,10 @@ impl Widget for &str {
|
|||
// TODO: line breaks
|
||||
Ok(Some([self.len() as u16, 1]))
|
||||
}
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
let [x, y, ..] = to.area();
|
||||
let [w, h] = self.layout(to.area().wh())?.unwrap();
|
||||
to.blit(&self, x, y, None)?;
|
||||
Ok(Some([x, y, w, h]))
|
||||
Ok(to.blit(&self, x, y, None))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -294,9 +318,10 @@ impl Widget for Styled<&str> {
|
|||
fn layout (&self, area: [u16;2]) -> Perhaps<[u16;2]> {
|
||||
Ok(Some([self.1.len() as u16, 1]))
|
||||
}
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
|
||||
let _ = self.layout(to.area().wh())?.unwrap();
|
||||
Ok(Some([to.area.x(), to.area.y(), self.1.len() as u16, 1]))
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
todo!()
|
||||
//let _ = self.layout(to.area().wh())?.unwrap();
|
||||
//Ok(Some([to.area.x(), to.area.y(), self.1.len() as u16, 1]))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -307,9 +332,8 @@ impl Widget for Background {
|
|||
fn layout (&self, _: [u16;2]) -> Perhaps<[u16;2]> {
|
||||
Ok(Some([0,0]))
|
||||
}
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
|
||||
to.fill_bg(to.area(), self.0);
|
||||
Ok(Some(to.area))
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
Ok(to.fill_bg(to.area(), self.0))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -322,12 +346,12 @@ impl<T: Widget<Engine = Tui>> Widget for Fixed<u16, T> {
|
|||
Self::XY(w, h, _) => (to.w() < *w && to.h() < *h).then(||[to.w() - *w, to.h() - *h])
|
||||
}.map(|offset_area|self.inner().layout(offset_area.into())).transpose()?.flatten())
|
||||
}
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
// 🡘 🡙 ←🡙→
|
||||
if let Some(size) = self.layout(to.area().wh())? {
|
||||
to.render_in(to.area().clip(size), self.inner())
|
||||
} else {
|
||||
Ok(None)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -371,7 +395,7 @@ where
|
|||
};
|
||||
Ok(Some([w, h]))
|
||||
}
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
let area = to.area();
|
||||
let mut w = 0;
|
||||
let mut h = 0;
|
||||
|
|
@ -381,8 +405,10 @@ where
|
|||
if h >= area.h() {
|
||||
return Ok(())
|
||||
}
|
||||
let area = Plus::Y(h, component as &dyn Widget<Engine = Tui>).render(to)?;
|
||||
if let Some([_, _, width, height]) = area {
|
||||
// FIXME
|
||||
let area = Plus::Y(h, component as &dyn Widget<Engine = Tui>).layout(area.wh())?;
|
||||
if let Some([width, height]) = area {
|
||||
Plus::Y(h, component as &dyn Widget<Engine = Tui>).render(to)?;
|
||||
h += height;
|
||||
w = w.max(width)
|
||||
};
|
||||
|
|
@ -394,8 +420,9 @@ where
|
|||
if w >= area.w() {
|
||||
return Ok(())
|
||||
}
|
||||
let area = Plus::X(w, component as &dyn Widget<Engine = Tui>).render(to)?;
|
||||
if let Some([_, _, width, height]) = area {
|
||||
let area = Plus::X(w, component as &dyn Widget<Engine = Tui>).layout(area.wh())?;
|
||||
if let Some([width, height]) = area {
|
||||
Plus::X(w, component as &dyn Widget<Engine = Tui>).render(to)?;
|
||||
w += width;
|
||||
h = h.max(height)
|
||||
};
|
||||
|
|
@ -404,7 +431,7 @@ where
|
|||
},
|
||||
_ => todo!()
|
||||
};
|
||||
Ok(Some([area.x(), area.y(), w, h]))
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -425,7 +452,7 @@ where
|
|||
})?;
|
||||
Ok(Some([w, h]))
|
||||
}
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
self.layout(to.area().wh())?
|
||||
.map(|size|(self.0)(&mut |layer|{
|
||||
to.render_in(to.area().clip(size), &layer).map(|_|())
|
||||
|
|
@ -442,7 +469,7 @@ impl<S: BorderStyle> Widget for Border<S> {
|
|||
fn layout (&self, to: [u16;2]) -> Perhaps<[u16;2]> {
|
||||
Outset::XY(1, 1, "").layout(to)
|
||||
}
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
let area = to.area();
|
||||
if area.w() > 2 && area.y() > 2 {
|
||||
to.blit(&self.0.nw(), area.x(), area.y(), self.0.style())?;
|
||||
|
|
@ -498,7 +525,7 @@ pub trait BorderStyle: Send + Sync {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn draw <'a> (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
|
||||
fn draw <'a> (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
self.draw_horizontal(to, None)?;
|
||||
self.draw_vertical(to, None)?;
|
||||
self.draw_corners(to, None)?;
|
||||
|
|
@ -506,7 +533,7 @@ pub trait BorderStyle: Send + Sync {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn draw_horizontal (&self, to: &mut Tui, style: Option<Style>) -> Usually<[u16;4]> {
|
||||
fn draw_horizontal (&self, to: &mut TuiOutput, style: Option<Style>) -> Usually<[u16;4]> {
|
||||
let area = to.area();
|
||||
let style = style.or_else(||self.style_horizontal());
|
||||
let [x, x2, y, y2] = area.lrtb();
|
||||
|
|
@ -517,16 +544,16 @@ pub trait BorderStyle: Send + Sync {
|
|||
Ok(area)
|
||||
}
|
||||
#[inline]
|
||||
fn draw_north (&self, to: &mut Tui, x: u16, y: u16, style: Option<Style>) -> Perhaps<[u16;4]> {
|
||||
fn draw_north (&self, to: &mut TuiOutput, x: u16, y: u16, style: Option<Style>) -> Usually<()> {
|
||||
to.blit(&Self::N, x, y, style)
|
||||
}
|
||||
#[inline]
|
||||
fn draw_south (&self, to: &mut Tui, x: u16, y: u16, style: Option<Style>) -> Perhaps<[u16;4]> {
|
||||
fn draw_south (&self, to: &mut TuiOutput, x: u16, y: u16, style: Option<Style>) -> Usually<()> {
|
||||
to.blit(&Self::S, x, y, style)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn draw_vertical (&self, to: &mut Tui, style: Option<Style>) -> Usually<[u16;4]> {
|
||||
fn draw_vertical (&self, to: &mut TuiOutput, style: Option<Style>) -> Usually<[u16;4]> {
|
||||
let area = to.area();
|
||||
let style = style.or_else(||self.style_vertical());
|
||||
let [x, x2, y, y2] = area.lrtb();
|
||||
|
|
@ -538,7 +565,7 @@ pub trait BorderStyle: Send + Sync {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn draw_corners (&self, to: &mut Tui, style: Option<Style>) -> Usually<[u16;4]> {
|
||||
fn draw_corners (&self, to: &mut TuiOutput, style: Option<Style>) -> Usually<[u16;4]> {
|
||||
let area = to.area();
|
||||
let style = style.or_else(||self.style_corners());
|
||||
let [x, y, width, height] = area.xywh();
|
||||
|
|
@ -590,7 +617,7 @@ macro_rules! border {
|
|||
fn layout (&self, area: [u16;2]) -> Perhaps<[u16;2]> {
|
||||
Ok(Some(area))
|
||||
}
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
|
||||
fn render (&self, to: &mut TuiOutput) -> Usually<()> {
|
||||
self.draw(to)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue