diff --git a/crates/tek_core/src/focus.rs b/crates/tek_core/src/focus.rs index 2d4664af..8839d6bd 100644 --- a/crates/tek_core/src/focus.rs +++ b/crates/tek_core/src/focus.rs @@ -9,6 +9,11 @@ pub trait FocusGrid { let (x, y) = self.cursor(); &self.layout()[y][x] } + fn focus (&mut self, target: T) { + while self.focused() != &target { + self.focus_next() + } + } fn focus_up (&mut self) { let layout = self.layout(); let (x, y) = self.cursor(); diff --git a/crates/tek_core/src/space.rs b/crates/tek_core/src/space.rs index 6711252b..b76edd07 100644 --- a/crates/tek_core/src/space.rs +++ b/crates/tek_core/src/space.rs @@ -130,124 +130,52 @@ impl Area for [N;4] { } pub trait Layout: Widget + Sized { - fn align_center (self) -> Align { - Align::Center(self) - } - fn align_w (self) -> Align { - Align::W(self) - } - fn align_e (self) -> Align { - Align::E(self) - } - fn align_x (self) -> Align { - Align::X(self) - } - fn align_y (self) -> Align { - Align::Y(self) - } - fn fixed_x (self, x: E::Unit) -> Fixed { - Fixed::X(x, self) - } - fn fixed_y (self, y: E::Unit) -> Fixed { - Fixed::Y(y, self) - } - fn fixed_xy (self, x: E::Unit, y: E::Unit) -> Fixed { - Fixed::XY(x, y, self) - } - fn min_x (self, x: E::Unit) -> Min { - Min::X(x, self) - } - fn min_y (self, y: E::Unit) -> Min { - Min::Y(y, self) - } - fn min_xy (self, x: E::Unit, y: E::Unit) -> Min { - Min::XY(x, y, self) - } - fn max_x (self, x: E::Unit) -> Max { - Max::X(x, self) - } - fn max_y (self, y: E::Unit) -> Max { - Max::Y(y, self) - } - fn max_xy (self, x: E::Unit, y: E::Unit) -> Max { - Max::XY(x, y, self) - } - fn push_x (self, x: E::Unit) -> Push { - Push::X(x, self) - } - fn push_y (self, y: E::Unit) -> Push { - Push::Y(y, self) - } - fn push_xy (self, x: E::Unit, y: E::Unit) -> Push { - Push::XY(x, y, self) - } - fn pull_x (self, x: E::Unit) -> Pull { - Pull::X(x, self) - } - fn pull_y (self, y: E::Unit) -> Pull { - Pull::Y(y, self) - } - fn pull_xy (self, x: E::Unit, y: E::Unit) -> Pull { - Pull::XY(x, y, self) - } - fn grow_x (self, x: E::Unit) -> Grow { - Grow::X(x, self) - } - fn grow_y (self, y: E::Unit) -> Grow { - Grow::Y(y, self) - } - fn grow_xy (self, x: E::Unit, y: E::Unit) -> Grow { - Grow::XY(x, y, self) - } - fn shrink_x (self, x: E::Unit) -> Shrink { - Shrink::X(x, self) - } - fn shrink_y (self, y: E::Unit) -> Shrink { - Shrink::Y(y, self) - } - fn shrink_xy (self, x: E::Unit, y: E::Unit) -> Shrink { - Shrink::XY(x, y, self) - } - fn inset_x (self, x: E::Unit) -> Inset { - Inset::X(x, self) - } - fn inset_y (self, y: E::Unit) -> Inset { - Inset::Y(y, self) - } - fn inset_xy (self, x: E::Unit, y: E::Unit) -> Inset { - Inset::XY(x, y, self) - } - fn outset_x (self, x: E::Unit) -> Outset { - Outset::X(x, self) - } - fn outset_y (self, y: E::Unit) -> Outset { - Outset::Y(y, self) - } - fn outset_xy (self, x: E::Unit, y: E::Unit) -> Outset { - Outset::XY(x, y, self) - } - fn fill_x (self) -> Fill { - Fill::X(self) - } - fn fill_y (self) -> Fill { - Fill::Y(self) - } - fn fill_xy (self) -> Fill { - Fill::XY(self) - } - fn debug (self) -> DebugOverlay { - DebugOverlay(self) - } + fn align_center (self) -> Align { Align::Center(self) } + fn align_nw (self) -> Align { Align::NW(self) } + fn align_w (self) -> Align { Align::W(self) } + fn align_sw (self) -> Align { Align::SW(self) } + fn align_ne (self) -> Align { Align::NE(self) } + fn align_e (self) -> Align { Align::E(self) } + fn align_se (self) -> Align { Align::SE(self) } + fn align_x (self) -> Align { Align::X(self) } + fn align_y (self) -> Align { Align::Y(self) } + fn fixed_x (self, x: E::Unit) -> Fixed { Fixed::X(x, self) } + fn fixed_y (self, y: E::Unit) -> Fixed { Fixed::Y(y, self) } + fn fixed_xy (self, x: E::Unit, y: E::Unit) -> Fixed { Fixed::XY(x, y, self) } + fn min_x (self, x: E::Unit) -> Min { Min::X(x, self) } + fn min_y (self, y: E::Unit) -> Min { Min::Y(y, self) } + fn min_xy (self, x: E::Unit, y: E::Unit) -> Min { Min::XY(x, y, self) } + fn max_x (self, x: E::Unit) -> Max { Max::X(x, self) } + fn max_y (self, y: E::Unit) -> Max { Max::Y(y, self) } + fn max_xy (self, x: E::Unit, y: E::Unit) -> Max { Max::XY(x, y, self) } + fn push_x (self, x: E::Unit) -> Push { Push::X(x, self) } + fn push_y (self, y: E::Unit) -> Push { Push::Y(y, self) } + fn push_xy (self, x: E::Unit, y: E::Unit) -> Push { Push::XY(x, y, self) } + fn pull_x (self, x: E::Unit) -> Pull { Pull::X(x, self) } + fn pull_y (self, y: E::Unit) -> Pull { Pull::Y(y, self) } + fn pull_xy (self, x: E::Unit, y: E::Unit) -> Pull { Pull::XY(x, y, self) } + fn grow_x (self, x: E::Unit) -> Grow { Grow::X(x, self) } + fn grow_y (self, y: E::Unit) -> Grow { Grow::Y(y, self) } + fn grow_xy (self, x: E::Unit, y: E::Unit) -> Grow { Grow::XY(x, y, self) } + fn shrink_x (self, x: E::Unit) -> Shrink { Shrink::X(x, self) } + fn shrink_y (self, y: E::Unit) -> Shrink { Shrink::Y(y, self) } + fn shrink_xy (self, x: E::Unit, y: E::Unit) -> Shrink { Shrink::XY(x, y, self) } + fn inset_x (self, x: E::Unit) -> Inset { Inset::X(x, self) } + fn inset_y (self, y: E::Unit) -> Inset { Inset::Y(y, self) } + fn inset_xy (self, x: E::Unit, y: E::Unit) -> Inset { Inset::XY(x, y, self) } + fn outset_x (self, x: E::Unit) -> Outset { Outset::X(x, self) } + fn outset_y (self, y: E::Unit) -> Outset { Outset::Y(y, self) } + fn outset_xy (self, x: E::Unit, y: E::Unit) -> Outset { Outset::XY(x, y, self) } + fn fill_x (self) -> Fill { Fill::X(self) } + fn fill_y (self) -> Fill { Fill::Y(self) } + fn fill_xy (self) -> Fill { Fill::XY(self) } + fn debug (self) -> DebugOverlay { DebugOverlay(self) } fn split > ( self, direction: Direction, amount: E::Unit, other: W - ) -> Split { - Split::new(direction, amount, self, other) - } + ) -> Split { Split::new(direction, amount, self, other) } fn split_flip > ( self, direction: Direction, amount: E::Unit, other: W - ) -> Split { - Split::new(direction, amount, other, self) - } + ) -> Split { Split::new(direction, amount, other, self) } } impl> Layout for W {} diff --git a/crates/tek_sequencer/src/arranger_cmd.rs b/crates/tek_sequencer/src/arranger_cmd.rs index 3bac036d..b63ef457 100644 --- a/crates/tek_sequencer/src/arranger_cmd.rs +++ b/crates/tek_sequencer/src/arranger_cmd.rs @@ -34,7 +34,7 @@ impl Handle for Arranger { key!(KeyCode::Right) => { self.focus_right(); }, key!(KeyCode::Char('e')) => { self.editor.phrase = self.arrangement.phrase().clone(); - self.focus_cursor = (1, 2); + self.focus(ArrangerFocus::PhraseEditor); } // Global play/pause binding key!(KeyCode::Char(' ')) => match self.transport { diff --git a/crates/tek_sequencer/src/arranger_tui.rs b/crates/tek_sequencer/src/arranger_tui.rs index 9ba43add..62f735f8 100644 --- a/crates/tek_sequencer/src/arranger_tui.rs +++ b/crates/tek_sequencer/src/arranger_tui.rs @@ -54,10 +54,8 @@ impl Content for Arrangement { ArrangementViewMode::Horizontal => add(&HorizontalArranger(&self)), ArrangementViewMode::Vertical(factor) => add(&VerticalArranger(&self, factor)) }?; - add(&Align::SE(self.selected.description( - &self.tracks, - &self.scenes, - ).as_str())) + let description = self.selected.description(&self.tracks, &self.scenes); + add(&Align::SE(description.as_str())) }) } } diff --git a/crates/tek_sequencer/src/sequencer_tui.rs b/crates/tek_sequencer/src/sequencer_tui.rs index 5485cb7f..a0d09ba6 100644 --- a/crates/tek_sequencer/src/sequencer_tui.rs +++ b/crates/tek_sequencer/src/sequencer_tui.rs @@ -94,7 +94,7 @@ impl Content for PhraseEditor { // keys CustomWidget::new(|_|Ok(Some([32u16,4u16])), |to: &mut TuiOutput|{ if to.area().h() < 2 { return Ok(()) } - Ok(to.buffer_update(to.area().set_w(5).shrink_y(2), &|cell, x, y|{ + Ok(to.buffer_update(to.area().set_w(5), &|cell, x, y|{ let y = y + self.note_axis.start as u16; if x < self.keys.area.width && y < self.keys.area.height { *cell = self.keys.get(x, y).clone() @@ -124,7 +124,7 @@ impl Content for PhraseEditor { CustomWidget::new(|_|Ok(Some([32u16,4u16])), |to: &mut TuiOutput|{ let offset = Self::H_KEYS_OFFSET as u16; if to.area().h() < 2 || to.area().w() < offset { return Ok(()) } - let area = to.area().push_x(offset).shrink_x(offset).shrink_y(2); + let area = to.area().push_x(offset).shrink_x(offset); Ok(to.buffer_update(area, &move |cell, x, y|{ cell.set_bg(Color::Rgb(20, 20, 20)); let src_x = ((x as usize + self.time_axis.start) * self.time_axis.scale) as usize; @@ -148,33 +148,27 @@ impl Content for PhraseEditor { } Ok(()) }), - // zoom - CustomWidget::new(|_|Ok(Some([10u16,1u16])), |to: &mut TuiOutput|{ - let [x, y, w, h] = to.area.xywh(); - let quant = ppq_to_name(self.time_axis.scale); - Ok(to.blit( - &quant, - x + w - 1 - quant.len() as u16, - y + h - 2, - self.style_focus() - )) - }), ); - let content = row!(piano_roll) - .fill_x() - .bg(Color::Rgb(40, 50, 30)) - .border(Lozenge(Style::default() - .bg(Color::Rgb(40, 50, 30)) - .fg(if self.focused { - Color::Rgb(100, 110, 40) - } else { - Color::Rgb(70, 80, 50) - }))); - lay!(content, TuiStyle::fg("Sequencer", if self.focused { - Color::Rgb(150, 160, 90) - } else { - Color::Rgb(120, 130, 100) - }).push_x(1)) + let border_color = + if self.focused { Color::Rgb(100, 110, 40) } else { Color::Rgb(70, 80, 50) }; + let title_color = + if self.focused { Color::Rgb(150, 160, 90) } else { Color::Rgb(120, 130, 100) }; + let border = + Lozenge(Style::default().bg(Color::Rgb(40, 50, 30)).fg(border_color)); + let content = + piano_roll.fill_x().bg(Color::Rgb(40, 50, 30)).border(border); + let title = TuiStyle::fg("Sequencer", title_color) + .push_x(1); + let zoom = TuiStyle::fg(format!("{}Zoom: {}", + if self.focused && !self.entered { "[,.] " } else { "" }, + ppq_to_name(self.time_axis.scale), + ), title_color).pull_x(1).align_se().fill_xy(); + let enter = TuiStyle::fg(if self.focused { + if self.entered { "[Esc] Exit edit mode [A]ppend [I]nsert" } else { + "[Enter] Edit notes" + } + } else { "" }, title_color).push_x(1).align_sw().fill_xy(); + lay!(content, title, enter, zoom) } } impl PhraseEditor {