add widget dynamic helper and Split::up

This commit is contained in:
🪞👃🪞 2024-10-18 23:51:58 +03:00
parent 038451e2f4
commit 97af45b576
4 changed files with 47 additions and 17 deletions

View file

@ -42,6 +42,10 @@ pub trait Output<E: Engine> {
/// Render widget in area /// Render widget in area
fn render_in (&mut self, area: E::Area, widget: &dyn Widget<Engine = E>) -> Usually<()>; fn render_in (&mut self, area: E::Area, widget: &dyn Widget<Engine = E>) -> Usually<()>;
} }
/// Cast to dynamic pointer
pub fn widget <E: Engine, T: Widget<Engine = E>> (w: &T) -> &dyn Widget<Engine = E> {
w as &dyn Widget<Engine = E>
}
/// A renderable component /// A renderable component
pub trait Widget: Send + Sync { pub trait Widget: Send + Sync {
/// Engine for which this component is implemented /// Engine for which this component is implemented

View file

@ -94,6 +94,10 @@ pub trait Area<N: Number>: Copy {
} }
#[inline] fn split_fixed (&self, direction: Direction, a: N) -> ([N;4],[N;4]) { #[inline] fn split_fixed (&self, direction: Direction, a: N) -> ([N;4],[N;4]) {
match direction { match direction {
Direction::Up => (
[self.x(), self.y() + self.h() - a, self.w(), a],
[self.x(), self.y(), self.w(), self.h() - a],
),
Direction::Down => ( Direction::Down => (
[self.x(), self.y(), self.w(), a], [self.x(), self.y(), self.w(), a],
[self.x(), self.y() + a, self.w(), self.h() - a], [self.x(), self.y() + a, self.w(), self.h() - a],
@ -817,6 +821,18 @@ impl<E: Engine, A: Widget<Engine = E>, B: Widget<Engine = E>> Split<E, A, B> {
pub fn new (direction: Direction, proportion: E::Unit, a: A, b: B) -> Self { pub fn new (direction: Direction, proportion: E::Unit, a: A, b: B) -> Self {
Self(direction, proportion, a, b, Default::default()) Self(direction, proportion, a, b, Default::default())
} }
pub fn up (proportion: E::Unit, a: A, b: B) -> Self {
Self(Direction::Up, proportion, a, b, Default::default())
}
pub fn down (proportion: E::Unit, a: A, b: B) -> Self {
Self(Direction::Down, proportion, a, b, Default::default())
}
pub fn left (proportion: E::Unit, a: A, b: B) -> Self {
Self(Direction::Left, proportion, a, b, Default::default())
}
pub fn right (proportion: E::Unit, a: A, b: B) -> Self {
Self(Direction::Right, proportion, a, b, Default::default())
}
} }
impl<E: Engine, A: Widget<Engine = E>, B: Widget<Engine = E>> Widget for Split<E, A, B> { impl<E: Engine, A: Widget<Engine = E>, B: Widget<Engine = E>> Widget for Split<E, A, B> {

View file

@ -12,8 +12,6 @@ pub struct Arranger<E: Engine> {
pub phrases: Arc<RwLock<PhrasePool<E>>>, pub phrases: Arc<RwLock<PhrasePool<E>>>,
/// Phrase editor view /// Phrase editor view
pub editor: PhraseEditor<E>, pub editor: PhraseEditor<E>,
/// This allows the sequencer view to be moved or hidden.
pub show_sequencer: Option<tek_core::Direction>,
/// Status bar /// Status bar
pub status: ArrangerStatusBar, pub status: ArrangerStatusBar,
/// Height of arrangement /// Height of arrangement
@ -36,7 +34,10 @@ pub enum ArrangerFocus {
/// Status bar for arranger ap /// Status bar for arranger ap
pub enum ArrangerStatusBar { pub enum ArrangerStatusBar {
Transport, Transport,
Arrangement, ArrangementMix,
ArrangementTrack,
ArrangementScene,
ArrangementClip,
PhrasePool, PhrasePool,
PhraseEditor, PhraseEditor,
} }
@ -116,7 +117,6 @@ impl<E: Engine> Arranger<E> {
) -> Self { ) -> Self {
let mut app = Self { let mut app = Self {
focus_cursor: (0, 1), focus_cursor: (0, 1),
show_sequencer: Some(tek_core::Direction::Down),
editor: PhraseEditor::new(), editor: PhraseEditor::new(),
status: ArrangerStatusBar::Transport, status: ArrangerStatusBar::Transport,
transport, transport,

View file

@ -3,19 +3,29 @@ use crate::*;
impl Content for Arranger<Tui> { impl Content for Arranger<Tui> {
type Engine = Tui; type Engine = Tui;
fn content (&self) -> impl Widget<Engine = Tui> { fn content (&self) -> impl Widget<Engine = Tui> {
Stack::down(move|add|{ Split::down(
add(&self.transport)?; 2,
let arrangement = &self.arrangement as &dyn Widget<Engine = Tui>; widget(&self.transport),
if let Some(direction) = self.show_sequencer { Split::up(
add(&arrangement.split(direction, self.arrangement_split, 1,
self.phrases.clone().split(direction.ccw(), self.phrases_split, widget(&self.status),
&self.editor as &dyn Widget<Engine = Tui> Split::down(
).min_y(self.arrangement_split) self.arrangement_split,
).fill_y()) widget(&self.arrangement),
} else { Split::right(
add(&self.arrangement) self.phrases_split,
} self.phrases.clone(),
}) widget(&self.editor),
)
)
)
).fill_xy()
}
}
impl Content for ArrangerStatusBar {
type Engine = Tui;
fn content (&self) -> impl Widget<Engine = Tui> {
"status bar"
} }
} }
impl Content for Arrangement<Tui> { impl Content for Arrangement<Tui> {