always redraw grid on note length change

This commit is contained in:
🪞👃🪞 2025-04-23 09:05:34 +03:00
parent bcd747280c
commit aa8eaf2e2b
5 changed files with 33 additions and 22 deletions

View file

@ -30,21 +30,16 @@ impl<'a> ArrangerView<'a> {
Tryptich::center(*scenes_height) Tryptich::center(*scenes_height)
.left(*width_side, Map::new(||self.scenes_with_scene_colors(), .left(*width_side, Map::new(||self.scenes_with_scene_colors(),
move|(index, scene, y1, y2, previous): SceneWithColor, _|{ move|(index, scene, y1, y2, previous): SceneWithColor, _|{
let name = Some(scene.name.clone());
let color = scene.color;
let prev_color = previous;
let is_last = *scene_last == index;
let selected = *scene_selected;
let same_track = true; let same_track = true;
let scene = index;
let height = (1 + y2 - y1) as u16; let height = (1 + y2 - y1) as u16;
let name = Some(scene.name.clone());
Fill::x(map_south(y1 as u16, (1 + y2 - y1) as u16, Fixed::y(height, Phat { Fill::x(map_south(y1 as u16, (1 + y2 - y1) as u16, Fixed::y(height, Phat {
width: 0, width: 0,
height: 0, height: 0,
content: Fill::x(Align::w(Tui::bold(true, Bsp::e("", name)))), content: Fill::x(Align::w(Tui::bold(true, Bsp::e("", name)))),
colors: Tek::colors( colors: Tek::colors(
&color, &scene.color,
prev_color, previous,
same_track && *scene_selected == Some(index), same_track && *scene_selected == Some(index),
same_track && index > 0 && *scene_selected == Some(index - 1), same_track && index > 0 && *scene_selected == Some(index - 1),
*scene_last == index *scene_last == index
@ -68,7 +63,7 @@ impl<'a> ArrangerView<'a> {
content: Fill::x(Align::w(Tui::bold(true, Bsp::e("", name)))), content: Fill::x(Align::w(Tui::bold(true, Bsp::e("", name)))),
colors: Tek::colors( colors: Tek::colors(
&bg, &bg,
None, Some(bg),
same_track && *scene_selected == Some(scene_index), same_track && *scene_selected == Some(scene_index),
same_track && scene_index > 0 && *scene_selected == Some(scene_index - 1), same_track && scene_index > 0 && *scene_selected == Some(scene_index - 1),
*scene_last == scene_index *scene_last == scene_index

View file

@ -232,9 +232,9 @@ impl Command<MidiEditor> for MidiEditCommand {
let note_len = state.note_len(); let note_len = state.note_len();
let time_zoom = state.time_zoom().get(); let time_zoom = state.time_zoom().get();
state.set_note_len(x); state.set_note_len(x);
if note_len / time_zoom != x / time_zoom { //if note_len / time_zoom != x / time_zoom {
state.redraw(); state.redraw();
} //}
}, },
SetTimeCursor(x) => { state.set_time_pos(x); }, SetTimeCursor(x) => { state.set_time_pos(x); },
SetNoteCursor(note) => { state.set_note_pos(note.min(127)); }, SetNoteCursor(note) => { state.set_note_pos(note.min(127)); },

View file

@ -1,9 +1,11 @@
//! MIDI player //! MIDI player
use crate::*; use crate::*;
pub trait HasPlayer { pub trait HasPlayer {
fn player (&self) -> &impl MidiPlayerApi; fn player (&self) -> &impl MidiPlayerApi;
fn player_mut (&mut self) -> &mut impl MidiPlayerApi; fn player_mut (&mut self) -> &mut impl MidiPlayerApi;
} }
#[macro_export] macro_rules! has_player { #[macro_export] macro_rules! has_player {
(|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => { (|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
impl $(<$($L),*$($T $(: $U)?),*>)? HasPlayer for $Struct $(<$($L),*$($T),*>)? { impl $(<$($L),*$($T $(: $U)?),*>)? HasPlayer for $Struct $(<$($L),*$($T),*>)? {
@ -12,8 +14,11 @@ pub trait HasPlayer {
} }
} }
} }
pub trait MidiPlayerApi: MidiRecordApi + MidiPlaybackApi + Send + Sync {} pub trait MidiPlayerApi: MidiRecordApi + MidiPlaybackApi + Send + Sync {}
impl MidiPlayerApi for MidiPlayer {} impl MidiPlayerApi for MidiPlayer {}
/// Contains state for playing a clip /// Contains state for playing a clip
pub struct MidiPlayer { pub struct MidiPlayer {
/// State of clock and playhead /// State of clock and playhead
@ -41,6 +46,7 @@ pub struct MidiPlayer {
/// MIDI output buffer /// MIDI output buffer
pub note_buf: Vec<u8>, pub note_buf: Vec<u8>,
} }
impl Default for MidiPlayer { impl Default for MidiPlayer {
fn default () -> Self { fn default () -> Self {
Self { Self {
@ -61,6 +67,7 @@ impl Default for MidiPlayer {
} }
} }
} }
impl MidiPlayer { impl MidiPlayer {
pub fn new ( pub fn new (
name: impl AsRef<str>, name: impl AsRef<str>,
@ -88,6 +95,7 @@ impl MidiPlayer {
}) })
} }
} }
impl std::fmt::Debug for MidiPlayer { impl std::fmt::Debug for MidiPlayer {
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
f.debug_struct("MidiPlayer") f.debug_struct("MidiPlayer")
@ -97,16 +105,20 @@ impl std::fmt::Debug for MidiPlayer {
.finish() .finish()
} }
} }
has_clock!(|self: MidiPlayer|self.clock); has_clock!(|self: MidiPlayer|self.clock);
impl HasMidiIns for MidiPlayer { impl HasMidiIns for MidiPlayer {
fn midi_ins (&self) -> &Vec<JackMidiIn> { &self.midi_ins } fn midi_ins (&self) -> &Vec<JackMidiIn> { &self.midi_ins }
fn midi_ins_mut (&mut self) -> &mut Vec<JackMidiIn> { &mut self.midi_ins } fn midi_ins_mut (&mut self) -> &mut Vec<JackMidiIn> { &mut self.midi_ins }
} }
impl HasMidiOuts for MidiPlayer { impl HasMidiOuts for MidiPlayer {
fn midi_outs (&self) -> &Vec<JackMidiOut> { &self.midi_outs } fn midi_outs (&self) -> &Vec<JackMidiOut> { &self.midi_outs }
fn midi_outs_mut (&mut self) -> &mut Vec<JackMidiOut> { &mut self.midi_outs } fn midi_outs_mut (&mut self) -> &mut Vec<JackMidiOut> { &mut self.midi_outs }
fn midi_note (&mut self) -> &mut Vec<u8> { &mut self.note_buf } fn midi_note (&mut self) -> &mut Vec<u8> { &mut self.note_buf }
} }
/// Hosts the JACK callback for a single MIDI player /// Hosts the JACK callback for a single MIDI player
pub struct PlayerAudio<'a, T: MidiPlayerApi>( pub struct PlayerAudio<'a, T: MidiPlayerApi>(
/// Player /// Player
@ -116,6 +128,7 @@ pub struct PlayerAudio<'a, T: MidiPlayerApi>(
/// Note chunk buffer /// Note chunk buffer
pub &'a mut Vec<Vec<Vec<u8>>>, pub &'a mut Vec<Vec<Vec<u8>>>,
); );
/// JACK process callback for a sequencer's clip player/recorder. /// JACK process callback for a sequencer's clip player/recorder.
impl<T: MidiPlayerApi> Audio for PlayerAudio<'_, T> { impl<T: MidiPlayerApi> Audio for PlayerAudio<'_, T> {
fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control { fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
@ -142,6 +155,7 @@ impl<T: MidiPlayerApi> Audio for PlayerAudio<'_, T> {
Control::Continue Control::Continue
} }
} }
impl MidiRecordApi for MidiPlayer { impl MidiRecordApi for MidiPlayer {
fn recording (&self) -> bool { fn recording (&self) -> bool {
self.recording self.recording
@ -165,11 +179,13 @@ impl MidiRecordApi for MidiPlayer {
&self.notes_in &self.notes_in
} }
} }
impl MidiPlaybackApi for MidiPlayer { impl MidiPlaybackApi for MidiPlayer {
fn notes_out (&self) -> &Arc<RwLock<[bool; 128]>> { fn notes_out (&self) -> &Arc<RwLock<[bool; 128]>> {
&self.notes_out &self.notes_out
} }
} }
impl HasPlayClip for MidiPlayer { impl HasPlayClip for MidiPlayer {
fn reset (&self) -> bool { fn reset (&self) -> bool {
self.reset self.reset