From 35a88cb70f157d02a21c87127aa47d35cb560938 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Mon, 30 Dec 2024 12:54:19 +0100 Subject: [PATCH] remove LayoutSplit; merge split and bsp modules --- bin/cli_arranger.rs | 5 -- bin/cli_transport.rs | 2 +- src/arranger.rs | 6 +- src/groovebox.rs | 6 +- src/sequencer.rs | 6 +- src/space.rs | 3 +- src/space/bsp.rs | 103 ------------------------------- src/space/split.rs | 140 ++++++++++++++++++++++++++++++++----------- 8 files changed, 117 insertions(+), 154 deletions(-) delete mode 100644 src/space/bsp.rs diff --git a/bin/cli_arranger.rs b/bin/cli_arranger.rs index a29651e0..23ae086c 100644 --- a/bin/cli_arranger.rs +++ b/bin/cli_arranger.rs @@ -9,23 +9,18 @@ pub struct ArrangerCli { /// Name of JACK client #[arg(short, long)] name: Option, - /// Whether to include a transport toolbar (default: true) #[arg(short, long, default_value_t = true)] transport: bool, - /// Number of tracks #[arg(short = 'x', long, default_value_t = 4)] tracks: usize, - /// Number of scenes #[arg(short, long, default_value_t = 8)] scenes: usize, - /// MIDI outs to connect each track to. #[arg(short='i', long)] midi_from: Vec, - /// MIDI ins to connect each track to. #[arg(short='o', long)] midi_to: Vec, diff --git a/bin/cli_transport.rs b/bin/cli_transport.rs index fead5a05..5d90cad8 100644 --- a/bin/cli_transport.rs +++ b/bin/cli_transport.rs @@ -2,7 +2,7 @@ include!("./lib.rs"); /// Application entrypoint. pub fn main () -> Usually<()> { - let name = self.name.as_deref().unwrap_or("tek_transport"); + let name = "tek_transport"; Tui::run(JackConnection::new(name)?.activate_with(|jack|{ TransportTui::try_from(jack) })?)?; diff --git a/src/arranger.rs b/src/arranger.rs index 6b4ab255..502d6293 100644 --- a/src/arranger.rs +++ b/src/arranger.rs @@ -104,10 +104,10 @@ render!(|self: ArrangerTui|{ let transport = TransportView::from((self, Some(ItemPalette::from(TuiTheme::g(96))), true)); let with_transport = |x|col!([row!(![&play, &transport]), &x]); let pool_size = if self.phrases.visible { self.splits[1] } else { 0 }; - let with_pool = |x|Split::left(false, pool_size, PoolView(&self.phrases), x); + let with_pool = |x|Split::w(false, pool_size, PoolView(&self.phrases), x); let status = ArrangerStatus::from(self); - let with_editbar = |x|Tui::split_n(false, 1, MidiEditStatus(&self.editor), x); - let with_status = |x|Tui::split_n(false, 2, status, x); + let with_editbar = |x|Split::n(false, 1, MidiEditStatus(&self.editor), x); + let with_status = |x|Split::n(false, 2, status, x); let with_size = |x|lay!([&self.size, x]); let arranger = ||lay!(|add|{ let color = self.color; diff --git a/src/groovebox.rs b/src/groovebox.rs index 29498f7a..875564ec 100644 --- a/src/groovebox.rs +++ b/src/groovebox.rs @@ -132,7 +132,7 @@ render!(|self:Groovebox|{ PhraseSelector::next_phrase(&self.player), ]))), row!([ - Tui::split_n(false, 9, + Split::n(false, 9, col!([ row!(|add|{ if let Some(sample) = &self.sampler.mapped[note_pt] { @@ -152,9 +152,9 @@ render!(|self:Groovebox|{ })), ]), ]), - Tui::split_w(false, pool_w, + Split::w(false, pool_w, Tui::pull_y(1, Fill::h(Align::e(PoolView(&self.pool)))), - Tui::split_e(false, sampler_w, Fill::wh(col!([ + Split::e(false, sampler_w, Fill::wh(col!([ Meters(self.sampler.input_meter.as_ref()), GrooveboxSamples(self), ])), Fill::h(&self.editor)) diff --git a/src/sequencer.rs b/src/sequencer.rs index d24f5511..f41cb6a6 100644 --- a/src/sequencer.rs +++ b/src/sequencer.rs @@ -45,10 +45,10 @@ render!(|self: SequencerTui|{ let phrase_w = if w > 60 { 20 } else if w > 40 { 15 } else { 10 }; let pool_w = if self.phrases.visible { phrase_w } else { 0 }; let pool = Tui::pull_y(1, Fill::h(Align::e(PoolView(&self.phrases)))); - let with_pool = move|x|Tui::split_w(false, pool_w, pool, x); + let with_pool = move|x|Split::w(false, pool_w, pool, x); let status = SequencerStatus::from(self); - let with_status = |x|Tui::split_n(false, if self.status { 2 } else { 0 }, status, x); - let with_editbar = |x|Tui::split_n(false, 1, MidiEditStatus(&self.editor), x); + let with_status = |x|Split::n(false, if self.status { 2 } else { 0 }, status, x); + let with_editbar = |x|Split::n(false, 1, MidiEditStatus(&self.editor), x); let with_size = |x|lay!([self.size, x]); let editor = with_editbar(with_pool(Fill::wh(&self.editor))); let color = self.player.play_phrase().as_ref().map(|(_,p)| diff --git a/src/space.rs b/src/space.rs index cfc5a0d2..0eed3bfd 100644 --- a/src/space.rs +++ b/src/space.rs @@ -8,7 +8,6 @@ use std::fmt::{Display, Debug}; ////////////////////////////////////////////////////// pub(crate) mod align; -pub(crate) mod bsp; pub(crate) mod cond; pub(crate) use cond::*; pub(crate) mod fill; pub(crate) mod fixed; pub(crate) use fixed::*; @@ -25,8 +24,8 @@ pub(crate) mod stack; pub(crate) use stack::*; pub use self::{ align::*, - bsp::*, fill::*, + split::*, }; #[derive(Copy, Clone, PartialEq)] diff --git a/src/space/bsp.rs b/src/space/bsp.rs deleted file mode 100644 index cf778e9f..00000000 --- a/src/space/bsp.rs +++ /dev/null @@ -1,103 +0,0 @@ -use crate::*; - -pub enum Bsp, Y: Render> { - /// X is north of Y - N(Option, Option), - /// X is south of Y - S(Option, Option), - /// X is east of Y - E(Option, Option), - /// X is west of Y - W(Option, Option), - /// X is above Y - A(Option, Option), - /// X is below Y - B(Option, Option), - /// Should be avoided. - Null(PhantomData), -} - -impl, Y: Render> Bsp { - pub fn new (x: X) -> Self { Self::A(Some(x), None) } - pub fn n (x: X, y: Y) -> Self { Self::N(Some(x), Some(y)) } - pub fn s (x: X, y: Y) -> Self { Self::S(Some(x), Some(y)) } - pub fn e (x: X, y: Y) -> Self { Self::E(Some(x), Some(y)) } - pub fn w (x: X, y: Y) -> Self { Self::W(Some(x), Some(y)) } - pub fn a (x: X, y: Y) -> Self { Self::A(Some(x), Some(y)) } - pub fn b (x: X, y: Y) -> Self { Self::B(Some(x), Some(y)) } -} - -impl, Y: Render> Default for Bsp { - fn default () -> Self { - Self::Null(Default::default()) - } -} - -impl, Y: Render> Render for Bsp { - fn min_size (&self, to: E::Size) -> Perhaps { - Ok(Some(match self { - Self::Null(_) => [0.into(), 0.into()].into(), - Self::S(a, b) => { - let a = a.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); - let b = b.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); - [a.w().max(b.w()), a.h() + b.h()].into() - }, - Self::E(a, b) => { - let a = a.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); - let b = b.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); - [a.w() + b.w(), a.h().max(b.h())].into() - }, - Self::W(a, b) => { - let a = a.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); - let b = b.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); - [a.w() + b.w(), a.h().max(b.h())].into() - }, - Self::N(a, b) => { - let a = a.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); - let b = b.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); - [a.w().max(b.w()), a.h() + b.h()].into() - }, - _ => todo!() - })) - } - fn render (&self, to: &mut E::Output) -> Usually<()> { - let n = [0.into(), 0.into()].into(); - let s = to.area().wh().into(); - Ok(match self { - Self::Null(_) => {}, - Self::S(a, b) => { - let s_a = a.min_size(s)?.unwrap_or(n); - let _ = b.min_size(s)?.unwrap_or(n); - let h = s_a.h().into(); - to.render_in(to.area().clip_h(h).into(), a)?; - to.render_in(to.area().shrink_y(h).push_y(h).into(), b)?; - }, - Self::E(a, b) => { - let s_a = a.min_size(s)?.unwrap_or(n); - let _ = b.min_size(s)?.unwrap_or(n); - let w = s_a.w().into(); - to.render_in(to.area().clip_w(w).into(), a)?; - to.render_in(to.area().push_x(w).shrink_x(w).into(), b)?; - }, - Self::W(a, b) => { - let s_a = a.min_size(s)?.unwrap_or(n); - let _ = b.min_size(s)?.unwrap_or(n); - let w = (to.area().w() - s_a.w()).into(); - to.render_in(to.area().push_x(w).into(), a)?; - to.render_in(to.area().shrink_x(w).into(), b)?; - }, - Self::N(a, b) => { - let s_a = a.min_size(s)?.unwrap_or(n); - let _ = b.min_size(s)?.unwrap_or(n); - let h = to.area().h() - s_a.h(); - to.render_in(to.area().push_y(h).into(), a)?; - to.render_in(to.area().shrink_y(h).into(), b)?; - }, - _ => todo!() - }) - } -} - -#[cfg(test)] #[test] fn test_bsp () { - // TODO -} diff --git a/src/space/split.rs b/src/space/split.rs index 26faf2c1..73f9261d 100644 --- a/src/space/split.rs +++ b/src/space/split.rs @@ -1,36 +1,6 @@ use crate::*; use Direction::*; -impl LayoutSplit for E {} - -pub trait LayoutSplit { - fn split , B: Render> ( - flip: bool, direction: Direction, amount: E::Unit, a: A, b: B - ) -> Split { - Split::new(flip, direction, amount, a, b) - } - fn split_n , B: Render> ( - flip: bool, amount: E::Unit, a: A, b: B - ) -> Split { - Self::split(flip, North, amount, a, b) - } - fn split_s , B: Render> ( - flip: bool, amount: E::Unit, a: A, b: B - ) -> Split { - Self::split(flip, South, amount, a, b) - } - fn split_w , B: Render> ( - flip: bool, amount: E::Unit, a: A, b: B - ) -> Split { - Self::split(flip, West, amount, a, b) - } - fn split_e , B: Render> ( - flip: bool, amount: E::Unit, a: A, b: B - ) -> Split { - Self::split(flip, East, amount, a, b) - } -} - /// A binary split with fixed proportion pub struct Split, B: Render>( pub bool, pub Direction, pub E::Unit, A, B, PhantomData @@ -40,16 +10,16 @@ impl, B: Render> Split { pub fn new (flip: bool, direction: Direction, proportion: E::Unit, a: A, b: B) -> Self { Self(flip, direction, proportion, a, b, Default::default()) } - pub fn up (flip: bool, proportion: E::Unit, a: A, b: B) -> Self { + pub fn n (flip: bool, proportion: E::Unit, a: A, b: B) -> Self { Self(flip, North, proportion, a, b, Default::default()) } - pub fn down (flip: bool, proportion: E::Unit, a: A, b: B) -> Self { + pub fn s (flip: bool, proportion: E::Unit, a: A, b: B) -> Self { Self(flip, South, proportion, a, b, Default::default()) } - pub fn left (flip: bool, proportion: E::Unit, a: A, b: B) -> Self { + pub fn e (flip: bool, proportion: E::Unit, a: A, b: B) -> Self { Self(flip, West, proportion, a, b, Default::default()) } - pub fn right (flip: bool, proportion: E::Unit, a: A, b: B) -> Self { + pub fn w (flip: bool, proportion: E::Unit, a: A, b: B) -> Self { Self(flip, East, proportion, a, b, Default::default()) } } @@ -69,3 +39,105 @@ impl, B: Render> Render for Split { }) } } + +pub enum Bsp, Y: Render> { + /// X is north of Y + N(Option, Option), + /// X is south of Y + S(Option, Option), + /// X is east of Y + E(Option, Option), + /// X is west of Y + W(Option, Option), + /// X is above Y + A(Option, Option), + /// X is below Y + B(Option, Option), + /// Should be avoided. + Null(PhantomData), +} + +impl, Y: Render> Bsp { + pub fn new (x: X) -> Self { Self::A(Some(x), None) } + pub fn n (x: X, y: Y) -> Self { Self::N(Some(x), Some(y)) } + pub fn s (x: X, y: Y) -> Self { Self::S(Some(x), Some(y)) } + pub fn e (x: X, y: Y) -> Self { Self::E(Some(x), Some(y)) } + pub fn w (x: X, y: Y) -> Self { Self::W(Some(x), Some(y)) } + pub fn a (x: X, y: Y) -> Self { Self::A(Some(x), Some(y)) } + pub fn b (x: X, y: Y) -> Self { Self::B(Some(x), Some(y)) } +} + +impl, Y: Render> Default for Bsp { + fn default () -> Self { + Self::Null(Default::default()) + } +} + +impl, Y: Render> Render for Bsp { + fn min_size (&self, to: E::Size) -> Perhaps { + Ok(Some(match self { + Self::Null(_) => [0.into(), 0.into()].into(), + Self::S(a, b) => { + let a = a.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); + let b = b.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); + [a.w().max(b.w()), a.h() + b.h()].into() + }, + Self::E(a, b) => { + let a = a.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); + let b = b.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); + [a.w() + b.w(), a.h().max(b.h())].into() + }, + Self::W(a, b) => { + let a = a.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); + let b = b.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); + [a.w() + b.w(), a.h().max(b.h())].into() + }, + Self::N(a, b) => { + let a = a.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); + let b = b.min_size(to)?.unwrap_or([0.into(), 0.into()].into()); + [a.w().max(b.w()), a.h() + b.h()].into() + }, + _ => todo!() + })) + } + fn render (&self, to: &mut E::Output) -> Usually<()> { + let n = [0.into(), 0.into()].into(); + let s = to.area().wh().into(); + Ok(match self { + Self::Null(_) => {}, + Self::S(a, b) => { + let s_a = a.min_size(s)?.unwrap_or(n); + let _ = b.min_size(s)?.unwrap_or(n); + let h = s_a.h().into(); + to.render_in(to.area().clip_h(h).into(), a)?; + to.render_in(to.area().shrink_y(h).push_y(h).into(), b)?; + }, + Self::E(a, b) => { + let s_a = a.min_size(s)?.unwrap_or(n); + let _ = b.min_size(s)?.unwrap_or(n); + let w = s_a.w().into(); + to.render_in(to.area().clip_w(w).into(), a)?; + to.render_in(to.area().push_x(w).shrink_x(w).into(), b)?; + }, + Self::W(a, b) => { + let s_a = a.min_size(s)?.unwrap_or(n); + let _ = b.min_size(s)?.unwrap_or(n); + let w = (to.area().w() - s_a.w()).into(); + to.render_in(to.area().push_x(w).into(), a)?; + to.render_in(to.area().shrink_x(w).into(), b)?; + }, + Self::N(a, b) => { + let s_a = a.min_size(s)?.unwrap_or(n); + let _ = b.min_size(s)?.unwrap_or(n); + let h = to.area().h() - s_a.h(); + to.render_in(to.area().push_y(h).into(), a)?; + to.render_in(to.area().shrink_y(h).into(), b)?; + }, + _ => todo!() + }) + } +} + +#[cfg(test)] #[test] fn test_bsp () { + // TODO +}