mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
Tui::fixed_ -> Fixed::w/h/wh
This commit is contained in:
parent
9bd898ab33
commit
da39c84ba4
9 changed files with 49 additions and 35 deletions
|
|
@ -1,21 +1,7 @@
|
|||
use crate::*;
|
||||
|
||||
impl<E: Engine> LayoutFixed<E> for E {}
|
||||
|
||||
pub trait LayoutFixed<E: Engine> {
|
||||
fn fixed_x <W: Render<E>> (x: E::Unit, w: W) -> Fixed<E, W> {
|
||||
Fixed::X(x, w)
|
||||
}
|
||||
fn fixed_y <W: Render<E>> (y: E::Unit, w: W) -> Fixed<E, W> {
|
||||
Fixed::Y(y, w)
|
||||
}
|
||||
fn fixed_xy <W: Render<E>> (x: E::Unit, y: E::Unit, w: W) -> Fixed<E, W> {
|
||||
Fixed::XY(x, y, w)
|
||||
}
|
||||
}
|
||||
|
||||
/// Enforce fixed size of drawing area
|
||||
pub enum Fixed<E: Engine, T> {
|
||||
pub enum Fixed<E: Engine, T: Render<E>> {
|
||||
_Unused(PhantomData<E>),
|
||||
/// Enforce fixed width
|
||||
X(E::Unit, T),
|
||||
|
|
@ -25,7 +11,7 @@ pub enum Fixed<E: Engine, T> {
|
|||
XY(E::Unit, E::Unit, T),
|
||||
}
|
||||
|
||||
impl<E: Engine, T> Fixed<E, T> {
|
||||
impl<E: Engine, T: Render<E>> Fixed<E, T> {
|
||||
pub fn inner (&self) -> &T {
|
||||
match self {
|
||||
Self::X(_, i) => i,
|
||||
|
|
@ -34,7 +20,17 @@ impl<E: Engine, T> Fixed<E, T> {
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
pub fn w (x: E::Unit, w: T) -> Fixed<E, T> {
|
||||
Self::X(x, w)
|
||||
}
|
||||
pub fn h (y: E::Unit, w: T) -> Fixed<E, T> {
|
||||
Self::Y(y, w)
|
||||
}
|
||||
pub fn wh (x: E::Unit, y: E::Unit, w: T) -> Fixed<E, T> {
|
||||
Self::XY(x, y, w)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine, T: Render<E>> Render<E> for Fixed<E, T> {
|
||||
fn min_size (&self, to: E::Size) -> Perhaps<E::Size> {
|
||||
Ok(match self {
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ render!(|self: ArrangerTui|{
|
|||
add(&self.size)
|
||||
})));
|
||||
with_transport(col!([
|
||||
Tui::fixed_y(self.splits[0], lay!([
|
||||
Fixed::h(self.splits[0], lay!([
|
||||
arranger(),
|
||||
Tui::push_x(1, Tui::fg(
|
||||
TuiTheme::title_fg(arranger_focused),
|
||||
|
|
@ -877,16 +877,16 @@ impl<'a> From<(&'a ArrangerTui, usize)> for ArrangerVerticalContent<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
render!(|self: ArrangerVerticalContent<'a>|Tui::fixed_y(
|
||||
render!(|self: ArrangerVerticalContent<'a>|Fixed::h(
|
||||
(self.size.h() as u16).saturating_sub(self.header_h),
|
||||
col!((scene, pulses) in self.scenes.iter().zip(self.rows.iter().map(|row|row.0)) => {
|
||||
let height = 1.max((pulses / PPQ) as u16);
|
||||
let playing = scene.is_playing(self.tracks);
|
||||
Tui::fixed_y(height, row!([
|
||||
Fixed::h(height, row!([
|
||||
if playing { "▶ " } else { " " },
|
||||
Tui::bold(true, scene.name.read().unwrap().as_str()),
|
||||
row!((track, w) in self.cols.iter().map(|col|col.0).enumerate() => {
|
||||
Tui::fixed_xy(w as u16, height, Layers::new(move |add|{
|
||||
Fixed::wh(w as u16, height, Layers::new(move |add|{
|
||||
let mut bg = TuiTheme::border_bg();
|
||||
match (self.tracks.get(track), scene.clips.get(track)) {
|
||||
(Some(track), Some(Some(phrase))) => {
|
||||
|
|
@ -900,7 +900,7 @@ render!(|self: ArrangerVerticalContent<'a>|Tui::fixed_y(
|
|||
bg = color.light.rgb
|
||||
}
|
||||
};
|
||||
add(&Tui::fixed_x(w as u16, Tui::push_x(1, &name.as_str()[0..max_w])))?;
|
||||
add(&Fixed::w(w as u16, Tui::push_x(1, &name.as_str()[0..max_w])))?;
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,7 +26,10 @@ pub enum GrooveboxCommand {
|
|||
Sampler(SamplerCommand),
|
||||
}
|
||||
|
||||
render!(|self:GrooveboxTui|Bsp::s(Tui::fixed_y(self.split, &self.sequencer), &self.sampler));
|
||||
render!(|self:GrooveboxTui|Bsp::n(
|
||||
Fixed::h(2, SequencerStatusBar::from(&self.sequencer)),
|
||||
Bsp::s(Fixed::h(self.split, &self.sequencer), &self.sampler),
|
||||
));
|
||||
audio!(|self:GrooveboxTui,_client,_process|Control::Continue);
|
||||
handle!(<Tui>|self:GrooveboxTui,input|GrooveboxCommand::execute_with_state(self, input));
|
||||
input_to_command!(GrooveboxCommand: <Tui>|state:GrooveboxTui,input|match input.event() {
|
||||
|
|
@ -34,4 +37,9 @@ input_to_command!(GrooveboxCommand: <Tui>|state:GrooveboxTui,input|match input.e
|
|||
key_pat!(Char('l')) => GrooveboxCommand::Sampler(SamplerCommand::Import),
|
||||
_ => GrooveboxCommand::Sequencer(SequencerCommand::input_to_command(&state.sequencer, input)?),
|
||||
});
|
||||
command!(|self:GrooveboxCommand,state:GrooveboxTui|todo!());
|
||||
command!(|self:GrooveboxCommand,state:GrooveboxTui|match self {
|
||||
GrooveboxCommand::Sequencer(command) =>
|
||||
command.execute(&mut state.sequencer)?.map(GrooveboxCommand::Sequencer),
|
||||
GrooveboxCommand::Sampler(command) =>
|
||||
command.execute(&mut state.sampler)?.map(GrooveboxCommand::Sampler),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,6 +11,16 @@ use symphonia::default::get_codecs;
|
|||
pub enum SamplerCommand {
|
||||
Import
|
||||
}
|
||||
input_to_command!(SamplerCommand: <Tui>|state:SamplerTui,input|match input.event() {
|
||||
_ => return None
|
||||
});
|
||||
command!(|self:SamplerCommand,state:SamplerTui|match self {
|
||||
SamplerCommand::Import => {
|
||||
None
|
||||
},
|
||||
_ => todo!()
|
||||
});
|
||||
|
||||
|
||||
impl TryFrom<&Arc<RwLock<JackClient>>> for SamplerTui {
|
||||
type Error = Box<dyn std::error::Error>;
|
||||
|
|
|
|||
|
|
@ -148,8 +148,8 @@ render!(|self: SequencerTui|{
|
|||
let with_size = |x|lay!([self.size, x]);
|
||||
let editor = with_editbar(with_pool(Tui::fill_xy(&self.editor)));
|
||||
let color = self.player.play_phrase().as_ref().map(|(_,p)|p.as_ref().map(|p|p.read().unwrap().color)).flatten().clone();
|
||||
let play = Tui::fixed_xy(5, 2, PlayPause(self.clock.is_rolling()));
|
||||
let transport = Tui::fixed_y(2, TransportView::from((self, color, true)));
|
||||
let play = Fixed::wh(5, 2, PlayPause(self.clock.is_rolling()));
|
||||
let transport = Fixed::h(2, TransportView::from((self, color, true)));
|
||||
let toolbar = row!([play, col!([
|
||||
PhraseSelector::play_phrase(&self.player),
|
||||
PhraseSelector::next_phrase(&self.player),
|
||||
|
|
@ -225,7 +225,7 @@ impl From<&SequencerTui> for SequencerStatusBar {
|
|||
}
|
||||
}
|
||||
|
||||
render!(|self: SequencerStatusBar|Tui::fixed_y(2, lay!([
|
||||
render!(|self: SequencerStatusBar|Fixed::h(2, lay!([
|
||||
{
|
||||
let single = |binding, command|row!([" ", col!([
|
||||
Tui::fg(TuiTheme::yellow(), binding),
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ render!(|self: TransportView|{
|
|||
pub struct PlayPause(pub bool);
|
||||
render!(|self: PlayPause|Tui::bg(
|
||||
if self.0{Color::Rgb(0,128,0)}else{Color::Rgb(128,64,0)},
|
||||
Tui::fixed_x(5, col!(|add|if self.0 {
|
||||
Fixed::w(5, col!(|add|if self.0 {
|
||||
add(&Tui::fg(Color::Rgb(0, 255, 0), col!([
|
||||
" 🭍🭑🬽 ",
|
||||
" 🭞🭜🭘 ",
|
||||
|
|
|
|||
|
|
@ -245,12 +245,12 @@ render!(|self:PhraseEditStatus<'a>|row!(|add|{
|
|||
&y
|
||||
]);
|
||||
add(&Tui::fill_x(Tui::fg_bg(fg, bg, row!(|add|{
|
||||
add(&Tui::fixed_xy(26, 3, col!(![
|
||||
add(&Fixed::wh(26, 3, col!(![
|
||||
field(" Edit", format!("{name}")),
|
||||
field(" Length", format!("{length}")),
|
||||
field(" Loop", format!("{looped}")),
|
||||
])))?;
|
||||
add(&Tui::fixed_xy(25, 3, col!(![
|
||||
add(&Fixed::wh(25, 3, col!(![
|
||||
field(" Time", format!("{}",
|
||||
self.0.time_point())),
|
||||
field(" View", format!("{}-{} ({}*{})",
|
||||
|
|
@ -259,7 +259,7 @@ render!(|self:PhraseEditStatus<'a>|row!(|add|{
|
|||
self.0.time_axis(),
|
||||
self.0.time_zoom()))
|
||||
])))?;
|
||||
add(&Tui::fixed_xy(25, 3, col!(![
|
||||
add(&Fixed::wh(25, 3, col!(![
|
||||
field(" Note", format!("{:4} ({:3}) {:4}",
|
||||
to_note_name(self.0.note_point()),
|
||||
self.0.note_point(),
|
||||
|
|
@ -269,7 +269,7 @@ render!(|self:PhraseEditStatus<'a>|row!(|add|{
|
|||
to_note_name(self.0.note_hi()),
|
||||
self.0.note_axis()))
|
||||
])))?;
|
||||
add(&Tui::fixed_xy(16, 3, col!(![
|
||||
add(&Fixed::wh(16, 3, col!(![
|
||||
row!(!["TimeLock ", Tui::bold(true, format!("{}", self.0.time_lock()))])])))?;
|
||||
Ok(())
|
||||
}))))
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ pub struct PhraseSelector {
|
|||
}
|
||||
|
||||
// TODO: Display phrases always in order of appearance
|
||||
render!(|self: PhraseSelector|Tui::fixed_xy(24, 1, row!([
|
||||
render!(|self: PhraseSelector|Fixed::wh(24, 1, row!([
|
||||
Tui::fg(self.color.lightest.rgb, Tui::bold(true, &self.title)),
|
||||
Tui::fg_bg(self.color.lighter.rgb, self.color.base.rgb, row!([
|
||||
format!("{:8}", &self.name[0..8.min(self.name.len())]),
|
||||
|
|
|
|||
|
|
@ -68,12 +68,12 @@ render!(|self: PianoHorizontal|{
|
|||
let keys_width = 5;
|
||||
Tui::fill_xy(Tui::bg(color.darker.rgb,
|
||||
Bsp::s(
|
||||
Tui::fixed_y(1, Bsp::e(
|
||||
Tui::fixed_x(keys_width, ""),
|
||||
Fixed::h(1, Bsp::e(
|
||||
Fixed::w(keys_width, ""),
|
||||
Tui::fill_x(timeline()),
|
||||
)),
|
||||
Bsp::e(
|
||||
Tui::fixed_x(keys_width, keys()),
|
||||
Fixed::w(keys_width, keys()),
|
||||
Tui::fill_xy(lay!([&self.size, Tui::fill_xy(lay!([
|
||||
Tui::fill_xy(notes()),
|
||||
Tui::fill_xy(cursor()),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue