mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
wip: tui cleanup
This commit is contained in:
parent
df3dac183e
commit
14d619a10a
17 changed files with 345 additions and 306 deletions
|
|
@ -5,3 +5,10 @@ pub trait Component<E: Engine>: Render<E> + Handle<E> {}
|
|||
|
||||
/// Everything that implements [Render] and [Handle] is a [Component].
|
||||
impl<E: Engine, C: Render<E> + Handle<E>> Component<E> for C {}
|
||||
|
||||
submod! {
|
||||
collect
|
||||
layered
|
||||
offset
|
||||
split
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ pub enum Collected<'a, E: Engine> {
|
|||
Box(Box<dyn Render<E> + 'a>),
|
||||
Ref(&'a (dyn Render<E> + 'a)),
|
||||
}
|
||||
|
||||
impl<'a, E: Engine> Render<E> for Collected<'a, E> {
|
||||
fn render (&self, to: &mut E) -> Perhaps<E::Rendered> {
|
||||
match self {
|
||||
|
|
@ -12,14 +13,17 @@ impl<'a, E: Engine> Render<E> for Collected<'a, E> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Collection<'a, E: Engine>(
|
||||
pub Vec<Collected<'a, E>>
|
||||
);
|
||||
|
||||
impl<'a, E: Engine> Collection<'a, E> {
|
||||
pub fn new () -> Self {
|
||||
Self(vec![])
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Collect<'a, E: Engine> {
|
||||
fn add_box (self, item: Box<dyn Render<E> + 'a>) -> Self;
|
||||
fn add_ref (self, item: &'a dyn Render<E>) -> Self;
|
||||
|
|
@ -29,6 +33,7 @@ pub trait Collect<'a, E: Engine> {
|
|||
self.add_box(Box::new(item))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: Engine> Collect<'a, E> for Collection<'a, E> {
|
||||
fn add_box (mut self, item: Box<dyn Render<E> + 'a>) -> Self {
|
||||
self.0.push(Collected::Box(item));
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::*;
|
||||
|
||||
pub struct Layered<'a, E: Engine>(Collection<'a, E>);
|
||||
pub struct Layered<'a, E: Engine>(pub Collection<'a, E>);
|
||||
|
||||
impl<'a, E: Engine> Layered<'a, E> {
|
||||
pub fn new () -> Self {
|
||||
|
|
@ -18,13 +18,3 @@ impl<'a, E: Engine> Collect<'a, E> for Layered<'a, E> {
|
|||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Render<Tui> for Layered<'a, Tui> {
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
|
||||
let area = to.area();
|
||||
for layer in self.0.0.iter() {
|
||||
layer.render(to)?;
|
||||
}
|
||||
Ok(Some(area))
|
||||
}
|
||||
}
|
||||
38
crates/tek_core/src/component/offset.rs
Normal file
38
crates/tek_core/src/component/offset.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
use crate::*;
|
||||
use std::ops::Add;
|
||||
|
||||
pub struct Offset<N>(pub N, pub N);
|
||||
|
||||
impl<N: Copy> From<N> for Offset<N> {
|
||||
fn from (n: N) -> Self {
|
||||
Self(n, n)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Inset<N>(pub N, pub N, pub N, pub N);
|
||||
|
||||
impl<N: Copy> From<N> for Inset<N> {
|
||||
fn from (n: N) -> Self {
|
||||
Self(n, n, n, n)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy> From<(N, N)> for Inset<N> {
|
||||
fn from ((n1, n2): (N, N)) -> Self {
|
||||
Self(n1, n2, n1, n2)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Outset<N>(pub N, pub N, pub N, pub N);
|
||||
|
||||
impl<N: Copy> From<N> for Outset<N> {
|
||||
fn from (n: N) -> Self {
|
||||
Self(n, n, n, n)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy> From<(N, N)> for Outset<N> {
|
||||
fn from ((n1, n2): (N, N)) -> Self {
|
||||
Self(n1, n2, n1, n2)
|
||||
}
|
||||
}
|
||||
50
crates/tek_core/src/component/split.rs
Normal file
50
crates/tek_core/src/component/split.rs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
use crate::*;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Direction { Up, Down, Left, Right }
|
||||
|
||||
impl Direction {
|
||||
pub fn is_down (&self) -> bool {
|
||||
match self { Self::Down => true, _ => false }
|
||||
}
|
||||
pub fn is_right (&self) -> bool {
|
||||
match self { Self::Right => true, _ => false }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Split<'a, E: Engine> {
|
||||
items: Collection<'a, E>,
|
||||
direction: Direction,
|
||||
focus: Option<usize>
|
||||
}
|
||||
|
||||
impl<'a, E: Engine> Split<'a, E> {
|
||||
pub fn new (direction: Direction) -> Self {
|
||||
Self {
|
||||
items: Collection::new(),
|
||||
direction,
|
||||
focus: None
|
||||
}
|
||||
}
|
||||
pub fn down () -> Self {
|
||||
Self::new(Direction::Down)
|
||||
}
|
||||
pub fn right () -> Self {
|
||||
Self::new(Direction::Right)
|
||||
}
|
||||
pub fn focus (mut self, focus: Option<usize>) -> Self {
|
||||
self.focus = focus;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: Engine> Collect<'a, E> for Split<'a, E> {
|
||||
fn add_box (mut self, item: Box<dyn Render<E> + 'a>) -> Self {
|
||||
self.items = self.items.add_box(item);
|
||||
self
|
||||
}
|
||||
fn add_ref (mut self, item: &'a dyn Render<E>) -> Self {
|
||||
self.items = self.items.add_ref(item);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,6 @@ use better_panic::{Settings, Verbosity};
|
|||
}
|
||||
|
||||
submod! {
|
||||
collect
|
||||
component
|
||||
edn
|
||||
engine
|
||||
|
|
@ -40,11 +39,8 @@ submod! {
|
|||
jack_event
|
||||
jack_ports
|
||||
keymap
|
||||
space
|
||||
render
|
||||
render_axis
|
||||
render_buffer
|
||||
render_layered
|
||||
render_split
|
||||
time
|
||||
tui
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct BigBuffer {
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
pub content: Vec<Cell>
|
||||
}
|
||||
|
||||
impl BigBuffer {
|
||||
pub fn new (width: usize, height: usize) -> Self {
|
||||
Self { width, height, content: vec![Cell::default(); width*height] }
|
||||
}
|
||||
pub fn get (&self, x: usize, y: usize) -> Option<&Cell> {
|
||||
let i = self.index_of(x, y);
|
||||
self.content.get(i)
|
||||
}
|
||||
pub fn get_mut (&mut self, x: usize, y: usize) -> Option<&mut Cell> {
|
||||
let i = self.index_of(x, y);
|
||||
self.content.get_mut(i)
|
||||
}
|
||||
pub fn index_of (&self, x: usize, y: usize) -> usize {
|
||||
y * self.width + x
|
||||
}
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
use crate::*;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Direction {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
pub fn is_down (&self) -> bool {
|
||||
match self { Self::Down => true, _ => false }
|
||||
}
|
||||
pub fn is_right (&self) -> bool {
|
||||
match self { Self::Right => true, _ => false }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Split<'a, E: Engine> {
|
||||
items: Collection<'a, E>,
|
||||
direction: Direction,
|
||||
focus: Option<usize>
|
||||
}
|
||||
|
||||
impl<'a, E: Engine> Split<'a, E> {
|
||||
pub fn new (direction: Direction) -> Self {
|
||||
Self {
|
||||
items: Collection::new(),
|
||||
direction,
|
||||
focus: None
|
||||
}
|
||||
}
|
||||
pub fn down () -> Self {
|
||||
Self::new(Direction::Down)
|
||||
}
|
||||
pub fn right () -> Self {
|
||||
Self::new(Direction::Right)
|
||||
}
|
||||
pub fn focus (mut self, focus: Option<usize>) -> Self {
|
||||
self.focus = focus;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: Engine> Collect<'a, E> for Split<'a, E> {
|
||||
fn add_box (mut self, item: Box<dyn Render<E> + 'a>) -> Self {
|
||||
self.items = self.items.add_box(item);
|
||||
self
|
||||
}
|
||||
fn add_ref (mut self, item: &'a dyn Render<E>) -> Self {
|
||||
self.items = self.items.add_ref(item);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Render<Tui> for Split<'a, Tui> {
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
|
||||
Ok(None)//Rect::default())//Some(self.render_areas(to)?.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Split<'a, Tui> {
|
||||
pub fn render_areas (&self, to: &mut Tui) -> Usually<(Rect, Vec<Rect>)> {
|
||||
Ok((Rect::default(), vec![]))
|
||||
//let Rect { mut x, mut y, mut width, mut height } = to.area;
|
||||
//let TuiOutput { buffer, area } = to;
|
||||
//let mut areas = vec![];
|
||||
//for (index, item) in self.items.0.iter().enumerate() {
|
||||
//if width == 0 || height == 0 {
|
||||
//break
|
||||
//}
|
||||
//if let Some(result) = item.render(&mut TuiOutput {
|
||||
//buffer: to.buffer,
|
||||
//area: Rect { x, y, width, height }
|
||||
//})? {
|
||||
//match self.direction {
|
||||
//Direction::Down => {
|
||||
//y += result.height;
|
||||
//height = height.saturating_sub(result.height);
|
||||
//},
|
||||
//Direction::Right => {
|
||||
//x += result.width;
|
||||
//width = width.saturating_sub(result.width);
|
||||
//},
|
||||
//_ => unimplemented!()
|
||||
//};
|
||||
//areas.push(result);
|
||||
//if self.focus == Some(index) {
|
||||
//Corners(Style::default().green().not_dim()).draw(to.buffer, result)?;
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
//Ok((to.area, areas))
|
||||
}
|
||||
}
|
||||
|
|
@ -31,3 +31,4 @@ impl<T: Copy> ScaledAxis<T> {
|
|||
self.scale = cb(self.scale)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
use crate::*;
|
||||
|
||||
pub(crate) use ratatui::buffer::Cell;
|
||||
pub(crate) use crossterm::{ExecutableCommand};
|
||||
pub use crossterm::event::{Event, KeyEvent, KeyCode, KeyModifiers};
|
||||
|
|
@ -11,7 +10,6 @@ use crossterm::terminal::{
|
|||
EnterAlternateScreen, LeaveAlternateScreen,
|
||||
enable_raw_mode, disable_raw_mode
|
||||
};
|
||||
|
||||
pub struct Tui {
|
||||
exited: Arc<AtomicBool>,
|
||||
buffer: usize,
|
||||
|
|
@ -28,11 +26,18 @@ impl Engine for Tui {
|
|||
self.exited.fetch_and(true, Ordering::Relaxed)
|
||||
}
|
||||
fn setup (&mut self) -> Usually<()> {
|
||||
panic_hook_setup();
|
||||
terminal_setup()
|
||||
let better_panic_handler = Settings::auto().verbosity(Verbosity::Full).create_panic_handler();
|
||||
std::panic::set_hook(Box::new(move |info: &std::panic::PanicInfo|{
|
||||
stdout().execute(LeaveAlternateScreen).unwrap();
|
||||
disable_raw_mode().unwrap();
|
||||
better_panic_handler(info);
|
||||
}));
|
||||
stdout().execute(EnterAlternateScreen)?;
|
||||
enable_raw_mode().map_err(Into::into)
|
||||
}
|
||||
fn teardown (&mut self) -> Usually<()> {
|
||||
terminal_teardown()
|
||||
stdout().execute(LeaveAlternateScreen)?;
|
||||
disable_raw_mode().map_err(Into::into)
|
||||
}
|
||||
fn handle (&self, state: &mut impl Handle<Self>) -> Usually<()> {
|
||||
if ::crossterm::event::poll(self.poll).is_ok() {
|
||||
|
|
@ -49,6 +54,7 @@ impl Engine for Tui {
|
|||
}
|
||||
fn render (&mut self, state: &impl Render<Self>) -> Usually<()> {
|
||||
state.render(self).expect("render failed");
|
||||
self.flip();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -96,10 +102,6 @@ impl Tui {
|
|||
main_thread.join().expect("main thread failed");
|
||||
Ok(state)
|
||||
}
|
||||
pub fn target <'a> (&'a mut self) -> impl TuiTarget + 'a {
|
||||
let area = self.area();
|
||||
(self.buffer(), area)
|
||||
}
|
||||
fn flip (&mut self) {
|
||||
let previous_buffer = &self.buffers[1 - self.buffer];
|
||||
let current_buffer = &self.buffers[self.buffer];
|
||||
|
|
@ -108,6 +110,24 @@ impl Tui {
|
|||
self.buffers[1 - self.buffer].reset();
|
||||
self.buffer = 1 - self.buffer;
|
||||
}
|
||||
pub fn area (&self) -> Rect {
|
||||
self.area
|
||||
}
|
||||
pub fn buffer (&mut self) -> &mut Buffer {
|
||||
&mut self.buffers[self.buffer]
|
||||
}
|
||||
pub fn buffer_update (&mut self, area: Rect, callback: &impl Fn(&mut Cell, u16, u16)) {
|
||||
let buf = self.buffer();
|
||||
for row in 0..area.height {
|
||||
let y = area.y + row;
|
||||
for col in 0..area.width {
|
||||
let x = area.x + col;
|
||||
if x < buf.area.width && y < buf.area.height {
|
||||
callback(buf.get_mut(x, y), col, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn fill_bg (&mut self, area: Rect, color: Color) {
|
||||
self.buffer_update(area, &|cell,_,_|{cell.set_bg(color);})
|
||||
}
|
||||
|
|
@ -130,80 +150,24 @@ impl Tui {
|
|||
cell.modifier = ratatui::style::Modifier::DIM;
|
||||
}
|
||||
}
|
||||
pub fn buffer_update (&mut self, area: Rect, callback: &impl Fn(&mut Cell, u16, u16)) {
|
||||
pub fn blit (
|
||||
&mut self, text: &impl AsRef<str>, x: u16, y: u16, style: Option<Style>
|
||||
) -> Perhaps<Rect> {
|
||||
let text = text.as_ref();
|
||||
let buf = self.buffer();
|
||||
for row in 0..area.height {
|
||||
let y = area.y + row;
|
||||
for col in 0..area.width {
|
||||
let x = area.x + col;
|
||||
if x < buf.area.width && y < buf.area.height {
|
||||
callback(buf.get_mut(x, y), col, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TuiTarget {
|
||||
fn area (&self) -> Rect;
|
||||
fn buffer (&mut self) -> &mut Buffer;
|
||||
}
|
||||
|
||||
impl TuiTarget for Tui {
|
||||
fn area (&self) -> Rect {
|
||||
self.area
|
||||
}
|
||||
fn buffer (&mut self) -> &mut Buffer {
|
||||
&mut self.buffers[self.buffer]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TuiTarget for (&'a mut Buffer, Rect) {
|
||||
fn area (&self) -> Rect {
|
||||
self.1
|
||||
}
|
||||
fn buffer (&mut self) -> &mut Buffer {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Set up panic hook
|
||||
pub fn panic_hook_setup () {
|
||||
let better_panic_handler = Settings::auto().verbosity(Verbosity::Full).create_panic_handler();
|
||||
std::panic::set_hook(Box::new(move |info: &std::panic::PanicInfo|{
|
||||
stdout().execute(LeaveAlternateScreen).unwrap();
|
||||
disable_raw_mode().unwrap();
|
||||
better_panic_handler(info);
|
||||
}));
|
||||
}
|
||||
|
||||
/// Set up terminal
|
||||
pub fn terminal_setup () -> Usually<()> {
|
||||
stdout().execute(EnterAlternateScreen)?;
|
||||
enable_raw_mode()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Cleanup
|
||||
pub fn terminal_teardown () -> Usually<()> {
|
||||
stdout().execute(LeaveAlternateScreen)?;
|
||||
disable_raw_mode()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// A simpler analog to [Render].
|
||||
pub trait Blit {
|
||||
// Render something to X, Y coordinates in a buffer, ignoring width/height.
|
||||
fn blit (&self, buf: &mut Buffer, x: u16, y: u16, style: Option<Style>) -> Perhaps<Rect>;
|
||||
}
|
||||
|
||||
/// Text can be rendered.
|
||||
impl<T: AsRef<str>> Blit for T {
|
||||
fn blit (&self, buf: &mut Buffer, x: u16, y: u16, style: Option<Style>) -> Perhaps<Rect> {
|
||||
if x < buf.area.width && y < buf.area.height {
|
||||
buf.set_string(x, y, self.as_ref(), style.unwrap_or(Style::default()));
|
||||
buf.set_string(x, y, text, style.unwrap_or(Style::default()));
|
||||
}
|
||||
Ok(Some(Rect { x, y, width: self.as_ref().len() as u16, height: 1 }))
|
||||
Ok(Some(Rect { x, y, width: text.len() as u16, height: 1 }))
|
||||
}
|
||||
pub fn alter_area (
|
||||
&mut self, alter: impl Fn(u16, u16, u16, u16)->(u16, u16, u16, u16)
|
||||
) -> &mut Self {
|
||||
let (x, y, width, height) = alter(
|
||||
self.area.x, self.area.y, self.area.width, self.area.height
|
||||
);
|
||||
self.area = Rect { x, y, width, height };
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -264,28 +228,28 @@ pub trait BorderStyle {
|
|||
let buf = to.buffer();
|
||||
let style = style.or_else(||self.style_horizontal());
|
||||
for x in area.x..(area.x+area.width).saturating_sub(1) {
|
||||
self.draw_north(buf, x, area.y, style)?;
|
||||
self.draw_south(buf, x, (area.y + area.height).saturating_sub(1), style)?;
|
||||
self.draw_north(to, x, area.y, style)?;
|
||||
self.draw_south(to, x, (area.y + area.height).saturating_sub(1), style)?;
|
||||
}
|
||||
Ok(area)
|
||||
}
|
||||
#[inline]
|
||||
fn draw_north (&self, buf: &mut Buffer, x: u16, y: u16, style: Option<Style>) -> Perhaps<Rect> {
|
||||
Self::N.blit(buf, x, y, style)
|
||||
fn draw_north (&self, to: &mut Tui, x: u16, y: u16, style: Option<Style>) -> Perhaps<Rect> {
|
||||
to.blit(&Self::N, x, y, style)
|
||||
}
|
||||
#[inline]
|
||||
fn draw_south (&self, buf: &mut Buffer, x: u16, y: u16, style: Option<Style>) -> Perhaps<Rect> {
|
||||
Self::S.blit(buf, x, y, style)
|
||||
fn draw_south (&self, to: &mut Tui, x: u16, y: u16, style: Option<Style>) -> Perhaps<Rect> {
|
||||
to.blit(&Self::S, x, y, style)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn draw_vertical (&self, to: &mut Tui, style: Option<Style>) -> Usually<Rect> {
|
||||
let area = to.area();
|
||||
let buf = to.buffer();
|
||||
let style = style.or_else(||self.style_vertical());
|
||||
for y in area.y..(area.y+area.height).saturating_sub(1) {
|
||||
Self::W.blit(buf, area.x, y, style)?;
|
||||
Self::E.blit(buf, area.x + area.width - 1, y, style)?;
|
||||
let Rect { x, y, width, height } = area;
|
||||
for y in y..(y+height).saturating_sub(1) {
|
||||
to.blit(&Self::W, x, y, style)?;
|
||||
to.blit(&Self::E, x + width - 1, y, style)?;
|
||||
}
|
||||
Ok(area)
|
||||
}
|
||||
|
|
@ -293,13 +257,13 @@ pub trait BorderStyle {
|
|||
#[inline]
|
||||
fn draw_corners (&self, to: &mut Tui, style: Option<Style>) -> Usually<Rect> {
|
||||
let area = to.area();
|
||||
let buf = to.buffer();
|
||||
let style = style.or_else(||self.style_corners());
|
||||
if area.width > 0 && area.height > 0 {
|
||||
Self::NW.blit(buf, area.x, area.y, style)?;
|
||||
Self::NE.blit(buf, area.x + area.width - 1, area.y, style)?;
|
||||
Self::SW.blit(buf, area.x, area.y + area.height - 1, style)?;
|
||||
Self::SE.blit(buf, area.x + area.width - 1, area.y + area.height - 1, style)?;
|
||||
let Rect { x, y, width, height } = area;
|
||||
if width > 0 && height > 0 {
|
||||
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)
|
||||
}
|
||||
|
|
@ -556,3 +520,111 @@ pub const NOT_DIM_BOLD: Style = Style {
|
|||
add_modifier: Modifier::BOLD,
|
||||
sub_modifier: Modifier::DIM,
|
||||
};
|
||||
|
||||
impl<'a> Render<Tui> for Layered<'a, Tui> {
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
|
||||
let area = to.area();
|
||||
for layer in self.0.0.iter() {
|
||||
layer.render(to)?;
|
||||
}
|
||||
Ok(Some(area))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Render<Tui> for Split<'a, Tui> {
|
||||
fn render (&self, to: &mut Tui) -> Perhaps<Rect> {
|
||||
Ok(Some(self.render_areas(to)?.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Split<'a, Tui> {
|
||||
pub fn render_areas (&self, to: &mut Tui) -> Usually<(Rect, Vec<Rect>)> {
|
||||
Ok((Rect::default(), vec![]))
|
||||
//let Rect { mut x, mut y, mut width, mut height } = to.area;
|
||||
//let TuiOutput { buffer, area } = to;
|
||||
//let mut areas = vec![];
|
||||
//for (index, item) in self.items.0.iter().enumerate() {
|
||||
//if width == 0 || height == 0 {
|
||||
//break
|
||||
//}
|
||||
//if let Some(result) = item.render(&mut TuiOutput {
|
||||
//buffer: to.buffer,
|
||||
//area: Rect { x, y, width, height }
|
||||
//})? {
|
||||
//match self.direction {
|
||||
//Direction::Down => {
|
||||
//y += result.height;
|
||||
//height = height.saturating_sub(result.height);
|
||||
//},
|
||||
//Direction::Right => {
|
||||
//x += result.width;
|
||||
//width = width.saturating_sub(result.width);
|
||||
//},
|
||||
//_ => unimplemented!()
|
||||
//};
|
||||
//areas.push(result);
|
||||
//if self.focus == Some(index) {
|
||||
//Corners(Style::default().green().not_dim()).draw(to.buffer, result)?;
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
//Ok((to.area, areas))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct BigBuffer {
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
pub content: Vec<Cell>
|
||||
}
|
||||
|
||||
impl BigBuffer {
|
||||
pub fn new (width: usize, height: usize) -> Self {
|
||||
Self { width, height, content: vec![Cell::default(); width*height] }
|
||||
}
|
||||
pub fn get (&self, x: usize, y: usize) -> Option<&Cell> {
|
||||
let i = self.index_of(x, y);
|
||||
self.content.get(i)
|
||||
}
|
||||
pub fn get_mut (&mut self, x: usize, y: usize) -> Option<&mut Cell> {
|
||||
let i = self.index_of(x, y);
|
||||
self.content.get_mut(i)
|
||||
}
|
||||
pub fn index_of (&self, x: usize, y: usize) -> usize {
|
||||
y * self.width + x
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Render<Tui>> Render<Tui> for (Offset<u16>, R) {
|
||||
fn render (&self, engine: &mut Tui) -> Perhaps<Rect> {
|
||||
self.1.render(engine.alter_area(|x, y, width, height|(
|
||||
x + self.0.0,
|
||||
y + self.0.1,
|
||||
width.saturating_sub(self.0.0),
|
||||
height.saturating_sub(self.0.1),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Render<Tui>> Render<Tui> for (Inset<u16>, R) {
|
||||
fn render (&self, engine: &mut Tui) -> Perhaps<Rect> {
|
||||
self.1.render(engine.alter_area(|x, y, width, height|(
|
||||
x + self.0.0,
|
||||
y + self.0.1,
|
||||
width.saturating_sub(self.0.0 + self.0.2),
|
||||
height.saturating_sub(self.0.1 + self.0.3),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Render<Tui>> Render<Tui> for (Outset<u16>, R) {
|
||||
fn render (&self, engine: &mut Tui) -> Perhaps<Rect> {
|
||||
self.1.render(engine.alter_area(|x, y, width, height|(
|
||||
x.saturating_sub(self.0.0),
|
||||
y.saturating_sub(self.0.1),
|
||||
width + self.0.0 + self.0.2,
|
||||
height + self.0.1 + self.0.3,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue