mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-10 21:56:42 +01:00
110 lines
3.4 KiB
Rust
110 lines
3.4 KiB
Rust
use crate::{core::*, view::*};
|
|
|
|
pub struct If<'a>(pub bool, pub &'a (dyn Render + Sync));
|
|
|
|
impl<'a> Render for If<'a> {
|
|
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
|
match self.0 {
|
|
true => self.1 as &dyn Render,
|
|
false => &() as &dyn Render
|
|
}.render(buf, area)
|
|
}
|
|
}
|
|
|
|
pub struct IfElse<'a>(pub bool, pub &'a (dyn Render + Sync), pub &'a (dyn Render + Sync));
|
|
|
|
impl<'a> Render for IfElse<'a> {
|
|
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
|
match self.0 {
|
|
true => self.1 as &dyn Render,
|
|
false => &() as &dyn Render
|
|
}.render(buf, area)
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone)]
|
|
pub enum Direction { Down, Right }
|
|
|
|
impl Direction {
|
|
pub fn split <'a, const N: usize> (&self, items: [&'a (dyn Render + Sync);N]) -> Split<'a, N> {
|
|
Split(*self, items)
|
|
}
|
|
pub fn split_focus <'a> (&self, index: usize, items: Renderables<'a>, style: Style) -> SplitFocus<'a> {
|
|
SplitFocus(*self, index, items, style)
|
|
}
|
|
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, const N: usize>(
|
|
pub Direction, pub [&'a (dyn Render + Sync);N]
|
|
);
|
|
|
|
impl<'a, const N: usize> Split<'a, N> {
|
|
pub fn down (items: [&'a (dyn Render + Sync);N]) -> Self {
|
|
Self(Direction::Down, items)
|
|
}
|
|
pub fn right (items: [&'a (dyn Render + Sync);N]) -> Self {
|
|
Self(Direction::Right, items)
|
|
}
|
|
}
|
|
|
|
impl<'a, const N: usize> Render for Split<'a, N> {
|
|
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
|
let Rect { mut x, mut y, mut width, mut height } = area;
|
|
for item in self.1 {
|
|
if width == 0 || height == 0 {
|
|
break
|
|
}
|
|
let result = item.render(buf, Rect { x, y, width, height })?;
|
|
match self.0 {
|
|
Direction::Down => {
|
|
y = y + result.height;
|
|
height = height.saturating_sub(result.height);
|
|
},
|
|
Direction::Right => {
|
|
x = x + result.width;
|
|
width = width.saturating_sub(result.width);
|
|
},
|
|
}
|
|
}
|
|
Ok(area)
|
|
}
|
|
}
|
|
|
|
type Renderables<'a> = &'a [JackDevice];
|
|
|
|
pub struct SplitFocus<'a>(pub Direction, pub usize, pub Renderables<'a>, pub Style);
|
|
|
|
impl<'a> Render for SplitFocus<'a> {
|
|
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
|
let Rect { mut x, mut y, mut width, mut height } = area;
|
|
let mut results = vec![];
|
|
for item in self.2.iter() {
|
|
if width == 0 || height == 0 {
|
|
break
|
|
}
|
|
let result = item.render(buf, Rect { x, y, width, height })?;
|
|
results.push(result);
|
|
match self.0 {
|
|
Direction::Down => {
|
|
y = y + result.height;
|
|
height = height.saturating_sub(result.height);
|
|
},
|
|
Direction::Right => {
|
|
x = x + result.width;
|
|
width = width.saturating_sub(result.width);
|
|
},
|
|
}
|
|
}
|
|
results
|
|
.get(self.1)
|
|
.map(|focused|Lozenge(self.3).draw(buf, Rect { width, ..*focused }))
|
|
.transpose()?;
|
|
Ok(area)
|
|
}
|
|
}
|