mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 04:06:45 +01:00
arranger, transport: despaghettify
This commit is contained in:
parent
33bdf65e8d
commit
1104093395
10 changed files with 430 additions and 253 deletions
|
|
@ -53,6 +53,7 @@ submod! {
|
|||
render_border
|
||||
render_collect
|
||||
render_fill
|
||||
render_layered
|
||||
render_split
|
||||
render_theme
|
||||
time_base
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
use crate::*;
|
||||
pub(crate) use ratatui::prelude::CrosstermBackend;
|
||||
pub(crate) use ratatui::style::{Stylize, Style, Color};
|
||||
pub(crate) use ratatui::style::Style;
|
||||
pub(crate) use ratatui::layout::Rect;
|
||||
pub(crate) use ratatui::buffer::{Buffer, Cell};
|
||||
use ratatui::widgets::WidgetRef;
|
||||
|
||||
/// Main thread render loop
|
||||
pub fn render_thread (
|
||||
|
|
@ -37,7 +36,7 @@ pub fn render_thread (
|
|||
}
|
||||
|
||||
/// Trait for things that render to the display.
|
||||
pub trait Render {
|
||||
pub trait Render: Send + Sync {
|
||||
// Render something to an area of the buffer.
|
||||
// Returns area used by component.
|
||||
// This is insufficient but for the most basic dynamic layout algorithms.
|
||||
|
|
@ -76,23 +75,23 @@ impl Render for () {
|
|||
}
|
||||
}
|
||||
|
||||
//impl<T: Render> Render for &T {
|
||||
//fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
//(*self).render(buf, area)
|
||||
//}
|
||||
//fn into_collected <'a> (self) -> Collected<'a> where Self: Sized + 'a {
|
||||
//Collected::Ref(self)
|
||||
//}
|
||||
//}
|
||||
impl<T: Render> Render for &T {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
(*self).render(buf, area)
|
||||
}
|
||||
fn into_collected <'a> (self) -> Collected<'a> where Self: Sized + 'a {
|
||||
Collected::Ref(self)
|
||||
}
|
||||
}
|
||||
|
||||
//impl<T: Render> Render for &mut T {
|
||||
//fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
//(**self).render(buf, area)
|
||||
//}
|
||||
//fn into_collected <'a> (self) -> Collected<'a> where Self: Sized + 'a {
|
||||
//Collected::Ref(self)
|
||||
//}
|
||||
//}
|
||||
impl<T: Render> Render for &mut T {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
(**self).render(buf, area)
|
||||
}
|
||||
fn into_collected <'a> (self) -> Collected<'a> where Self: Sized + 'a {
|
||||
Collected::Ref(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Render> Render for Option<T> {
|
||||
fn render (&self, b: &mut Buffer, a: Rect) -> Usually<Rect> {
|
||||
|
|
@ -112,18 +111,18 @@ impl<'a> Render for Box<dyn Render + 'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Fn(&mut Buffer, Rect) -> Usually<Rect> + Send + Sync + 'a> Render for T {
|
||||
fn render (&self, b: &mut Buffer, a: Rect) -> Usually<Rect> {
|
||||
(*self)(b, a)
|
||||
}
|
||||
}
|
||||
|
||||
//impl<'a> Render for Box<dyn Fn(&mut Buffer, Rect) -> Usually<Rect> + Send + Sync + 'a> {
|
||||
//impl<'a, T: Fn(&mut Buffer, Rect) -> Usually<Rect> + Send + Sync + 'a> Render for T {
|
||||
//fn render (&self, b: &mut Buffer, a: Rect) -> Usually<Rect> {
|
||||
//(*self)(b, a)
|
||||
//}
|
||||
//}
|
||||
|
||||
impl<'a> Render for Box<dyn Fn(&mut Buffer, Rect) -> Usually<Rect> + Send + Sync + 'a> {
|
||||
fn render (&self, b: &mut Buffer, a: Rect) -> Usually<Rect> {
|
||||
(*self)(b, a)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Render> Render for Arc<Mutex<T>> {
|
||||
fn render (&self, b: &mut Buffer, a: Rect) -> Usually<Rect> {
|
||||
self.lock().unwrap().render(b, a)
|
||||
|
|
@ -203,17 +202,6 @@ impl BigBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Layered<'a, const N: usize>(pub [&'a (dyn Render + Sync); N]);
|
||||
|
||||
impl<'a, const N: usize> Render for Layered<'a, N> {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
for layer in self.0.iter() {
|
||||
layer.render(buf, area)?;
|
||||
}
|
||||
Ok(area)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct If<'a>(pub bool, pub &'a (dyn Render + Sync));
|
||||
|
||||
impl<'a> Render for If<'a> {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ impl<'a> Render for Collected<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Collection<'a>(Vec<Collected<'a>>);
|
||||
pub struct Collection<'a>(pub Vec<Collected<'a>>);
|
||||
|
||||
impl<'a> Collection<'a> {
|
||||
pub fn new () -> Self {
|
||||
|
|
@ -27,6 +27,9 @@ impl<'a> Collection<'a> {
|
|||
pub trait Collect<'a> {
|
||||
fn add_box (self, item: Box<dyn Render + 'a>) -> Self;
|
||||
fn add_ref (self, item: &'a dyn Render) -> Self;
|
||||
fn add <T: Render + Sized + 'a> (self, item: T) -> Self where Self: Sized {
|
||||
self.add_box(Box::new(item))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Collect<'a> for Collection<'a> {
|
||||
|
|
|
|||
29
crates/tek_core/src/render_layered.rs
Normal file
29
crates/tek_core/src/render_layered.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
use crate::*;
|
||||
|
||||
pub struct Layered<'a>(Collection<'a>);
|
||||
|
||||
impl<'a> Layered<'a> {
|
||||
pub fn new () -> Self {
|
||||
Self(Collection::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Render for Layered<'a> {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
for layer in self.0.0.iter() {
|
||||
layer.render(buf, area)?;
|
||||
}
|
||||
Ok(area)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Collect<'a> for Layered<'a> {
|
||||
fn add_box (mut self, item: Box<dyn Render + 'a>) -> Self {
|
||||
self.0 = self.0.add_box(item);
|
||||
self
|
||||
}
|
||||
fn add_ref (mut self, item: &'a dyn Render) -> Self {
|
||||
self.0 = self.0.add_ref(item);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
@ -9,9 +9,9 @@ pub enum Direction {
|
|||
}
|
||||
|
||||
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 <'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)
|
||||
}
|
||||
|
|
@ -23,26 +23,27 @@ impl Direction {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Split<'a, const N: usize>(
|
||||
pub Direction, pub [&'a (dyn Render + Sync);N]
|
||||
);
|
||||
pub struct Split<'a>(Collection<'a>, Direction);
|
||||
|
||||
impl<'a, const N: usize> Split<'a, N> {
|
||||
pub fn down (items: [&'a (dyn Render + Sync);N]) -> Self {
|
||||
Self(Direction::Down, items)
|
||||
impl<'a> Split<'a> {
|
||||
pub fn new (direction: Direction) -> Self {
|
||||
Self(Collection::new(), direction)
|
||||
}
|
||||
pub fn right (items: [&'a (dyn Render + Sync);N]) -> Self {
|
||||
Self(Direction::Right, items)
|
||||
pub fn down () -> Self {
|
||||
Self(Collection::new(), Direction::Down)
|
||||
}
|
||||
pub fn right () -> Self {
|
||||
Self(Collection::new(), Direction::Right)
|
||||
}
|
||||
pub fn render_areas (&self, buf: &mut Buffer, area: Rect) -> Usually<(Rect, Vec<Rect>)> {
|
||||
let Rect { mut x, mut y, mut width, mut height } = area;
|
||||
let mut areas = vec![];
|
||||
for item in self.1 {
|
||||
for item in self.0.0.iter() {
|
||||
if width == 0 || height == 0 {
|
||||
break
|
||||
}
|
||||
let result = item.render(buf, Rect { x, y, width, height })?;
|
||||
match self.0 {
|
||||
match self.1 {
|
||||
Direction::Down => {
|
||||
y = y + result.height;
|
||||
height = height.saturating_sub(result.height);
|
||||
|
|
@ -59,12 +60,65 @@ impl<'a, const N: usize> Split<'a, N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, const N: usize> Render for Split<'a, N> {
|
||||
impl<'a> Render for Split<'a> {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
Ok(self.render_areas(buf, area)?.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Collect<'a> for Split<'a> {
|
||||
fn add_box (mut self, item: Box<dyn Render + 'a>) -> Self {
|
||||
self.0 = self.0.add_box(item);
|
||||
self
|
||||
}
|
||||
fn add_ref (mut self, item: &'a dyn Render) -> Self {
|
||||
self.0 = self.0.add_ref(item);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
//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)
|
||||
//}
|
||||
//pub fn render_areas (&self, buf: &mut Buffer, area: Rect) -> Usually<(Rect, Vec<Rect>)> {
|
||||
//let Rect { mut x, mut y, mut width, mut height } = area;
|
||||
//let mut areas = vec![];
|
||||
//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);
|
||||
//},
|
||||
//_ => unimplemented!()
|
||||
//};
|
||||
//areas.push(area);
|
||||
//}
|
||||
//Ok((area, areas))
|
||||
//}
|
||||
//}
|
||||
|
||||
//impl<'a, const N: usize> Render for Split<'a, N> {
|
||||
//fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
//Ok(self.render_areas(buf, area)?.0)
|
||||
//}
|
||||
//}
|
||||
|
||||
type Renderables<'a> = &'a [&'a (dyn Render + Send + Sync)];
|
||||
|
||||
pub struct SplitFocus<'a>(pub Direction, pub usize, pub Renderables<'a>, pub Style);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::*;
|
||||
use ratatui::style::Modifier;
|
||||
|
||||
pub trait Theme {
|
||||
const BG0: Color;
|
||||
|
|
@ -69,3 +70,75 @@ impl Theme for Nord {
|
|||
const PLAYING: Color = Color::Rgb(60, 100, 50);
|
||||
const SEPARATOR: Color = Color::Rgb(0, 0, 0);
|
||||
}
|
||||
|
||||
pub const GRAY: Style = Style {
|
||||
fg: Some(Color::Gray),
|
||||
bg: None,
|
||||
underline_color: None,
|
||||
add_modifier: Modifier::empty(),
|
||||
sub_modifier: Modifier::empty(),
|
||||
};
|
||||
|
||||
pub const GRAY_NOT_DIM: Style = Style {
|
||||
fg: Some(Color::Gray),
|
||||
bg: None,
|
||||
underline_color: None,
|
||||
add_modifier: Modifier::empty(),
|
||||
sub_modifier: Modifier::DIM,
|
||||
};
|
||||
|
||||
pub const DIM: Style = Style {
|
||||
fg: None,
|
||||
bg: None,
|
||||
underline_color: None,
|
||||
add_modifier: Modifier::DIM,
|
||||
sub_modifier: Modifier::empty(),
|
||||
};
|
||||
|
||||
pub const GRAY_DIM: Style = Style {
|
||||
fg: Some(Color::Gray),
|
||||
bg: None,
|
||||
underline_color: None,
|
||||
add_modifier: Modifier::DIM,
|
||||
sub_modifier: Modifier::empty(),
|
||||
};
|
||||
|
||||
pub const WHITE_NOT_DIM_BOLD: Style = Style {
|
||||
fg: Some(Color::White),
|
||||
bg: None,
|
||||
underline_color: None,
|
||||
add_modifier: Modifier::BOLD,
|
||||
sub_modifier: Modifier::DIM,
|
||||
};
|
||||
|
||||
pub const GRAY_NOT_DIM_BOLD: Style = Style {
|
||||
fg: Some(Color::Gray),
|
||||
bg: None,
|
||||
underline_color: None,
|
||||
add_modifier: Modifier::BOLD,
|
||||
sub_modifier: Modifier::DIM,
|
||||
};
|
||||
|
||||
pub const NOT_DIM: Style = Style {
|
||||
fg: None,
|
||||
bg: None,
|
||||
underline_color: None,
|
||||
add_modifier: Modifier::empty(),
|
||||
sub_modifier: Modifier::DIM,
|
||||
};
|
||||
|
||||
pub const NOT_DIM_GREEN: Style = Style {
|
||||
fg: Some(Color::Green),
|
||||
bg: None,
|
||||
underline_color: None,
|
||||
add_modifier: Modifier::BOLD,
|
||||
sub_modifier: Modifier::DIM,
|
||||
};
|
||||
|
||||
pub const NOT_DIM_BOLD: Style = Style {
|
||||
fg: None,
|
||||
bg: None,
|
||||
underline_color: None,
|
||||
add_modifier: Modifier::BOLD,
|
||||
sub_modifier: Modifier::DIM,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue