tek/src/view.rs
2024-07-09 19:58:13 +03:00

85 lines
2.2 KiB
Rust

pub mod chain;
pub mod arranger;
pub mod layout;
pub mod sampler;
pub mod sequencer;
pub mod transport;
pub mod plugin;
pub mod border;
pub use self::border::*;
pub use self::layout::*;
pub use self::transport::TransportView;
pub use self::arranger::*;
pub use self::chain::ChainView;
pub use self::sequencer::SequencerView;
use crate::{render, App, core::*};
render!(App |self, buf, area| {
Split::down([
&TransportView::new(self),
&Split::down([
&ArrangerView::new(&self, !self.arranger_mode),
&If(self.track_cursor > 0, &Split::right([
&ChainView::vertical(&self),
&SequencerView::new(&self),
]))
])
]).render(buf, area)?;
if let Some(ref modal) = self.modal {
modal.render(buf, area)?;
}
Ok(area)
});
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> {
if self.0 {
self.1.render(buf, area)
} else {
().render(buf, area)
}
}
}
pub enum Direction {
Down,
Right,
}
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)
}
}