mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
always redraw grid on note length change
This commit is contained in:
parent
bcd747280c
commit
aa8eaf2e2b
5 changed files with 33 additions and 22 deletions
|
|
@ -30,21 +30,16 @@ impl<'a> ArrangerView<'a> {
|
|||
Tryptich::center(*scenes_height)
|
||||
.left(*width_side, Map::new(||self.scenes_with_scene_colors(),
|
||||
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 scene = index;
|
||||
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 {
|
||||
width: 0,
|
||||
height: 0,
|
||||
content: Fill::x(Align::w(Tui::bold(true, Bsp::e(" ⯈ ", name)))),
|
||||
colors: Tek::colors(
|
||||
&color,
|
||||
prev_color,
|
||||
&scene.color,
|
||||
previous,
|
||||
same_track && *scene_selected == Some(index),
|
||||
same_track && index > 0 && *scene_selected == Some(index - 1),
|
||||
*scene_last == index
|
||||
|
|
@ -68,7 +63,7 @@ impl<'a> ArrangerView<'a> {
|
|||
content: Fill::x(Align::w(Tui::bold(true, Bsp::e(" ⏹ ", name)))),
|
||||
colors: Tek::colors(
|
||||
&bg,
|
||||
None,
|
||||
Some(bg),
|
||||
same_track && *scene_selected == Some(scene_index),
|
||||
same_track && scene_index > 0 && *scene_selected == Some(scene_index - 1),
|
||||
*scene_last == scene_index
|
||||
|
|
|
|||
|
|
@ -232,9 +232,9 @@ impl Command<MidiEditor> for MidiEditCommand {
|
|||
let note_len = state.note_len();
|
||||
let time_zoom = state.time_zoom().get();
|
||||
state.set_note_len(x);
|
||||
if note_len / time_zoom != x / time_zoom {
|
||||
//if note_len / time_zoom != x / time_zoom {
|
||||
state.redraw();
|
||||
}
|
||||
//}
|
||||
},
|
||||
SetTimeCursor(x) => { state.set_time_pos(x); },
|
||||
SetNoteCursor(note) => { state.set_note_pos(note.min(127)); },
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@ pub struct Note;
|
|||
|
||||
impl Note {
|
||||
pub const NAMES: [&str; 128] = [
|
||||
"C0", "C#0", "D0", "D#0", "E0", "F0", "F#0", "G0", "G#0", "A0", "A#0", "B0",
|
||||
"C1", "C#1", "D1", "D#1", "E1", "F1", "F#1", "G1", "G#1", "A1", "A#1", "B1",
|
||||
"C2", "C#2", "D2", "D#2", "E2", "F2", "F#2", "G2", "G#2", "A2", "A#2", "B2",
|
||||
"C3", "C#3", "D3", "D#3", "E3", "F3", "F#3", "G3", "G#3", "A3", "A#3", "B3",
|
||||
"C4", "C#4", "D4", "D#4", "E4", "F4", "F#4", "G4", "G#4", "A4", "A#4", "B4",
|
||||
"C5", "C#5", "D5", "D#5", "E5", "F5", "F#5", "G5", "G#5", "A5", "A#5", "B5",
|
||||
"C6", "C#6", "D6", "D#6", "E6", "F6", "F#6", "G6", "G#6", "A6", "A#6", "B6",
|
||||
"C7", "C#7", "D7", "D#7", "E7", "F7", "F#7", "G7", "G#7", "A7", "A#7", "B7",
|
||||
"C8", "C#8", "D8", "D#8", "E8", "F8", "F#8", "G8", "G#8", "A8", "A#8", "B8",
|
||||
"C9", "C#9", "D9", "D#9", "E9", "F9", "F#9", "G9", "G#9", "A9", "A#9", "B9",
|
||||
"C0", "C#0", "D0", "D#0", "E0", "F0", "F#0", "G0", "G#0", "A0", "A#0", "B0",
|
||||
"C1", "C#1", "D1", "D#1", "E1", "F1", "F#1", "G1", "G#1", "A1", "A#1", "B1",
|
||||
"C2", "C#2", "D2", "D#2", "E2", "F2", "F#2", "G2", "G#2", "A2", "A#2", "B2",
|
||||
"C3", "C#3", "D3", "D#3", "E3", "F3", "F#3", "G3", "G#3", "A3", "A#3", "B3",
|
||||
"C4", "C#4", "D4", "D#4", "E4", "F4", "F#4", "G4", "G#4", "A4", "A#4", "B4",
|
||||
"C5", "C#5", "D5", "D#5", "E5", "F5", "F#5", "G5", "G#5", "A5", "A#5", "B5",
|
||||
"C6", "C#6", "D6", "D#6", "E6", "F6", "F#6", "G6", "G#6", "A6", "A#6", "B6",
|
||||
"C7", "C#7", "D7", "D#7", "E7", "F7", "F#7", "G7", "G#7", "A7", "A#7", "B7",
|
||||
"C8", "C#8", "D8", "D#8", "E8", "F8", "F#8", "G8", "G#8", "A8", "A#8", "B8",
|
||||
"C9", "C#9", "D9", "D#9", "E9", "F9", "F#9", "G9", "G#9", "A9", "A#9", "B9",
|
||||
"C10", "C#10", "D10", "D#10", "E10", "F10", "F#10", "G10",
|
||||
];
|
||||
pub fn pitch_to_name (n: usize) -> &'static str {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
//! MIDI player
|
||||
use crate::*;
|
||||
|
||||
pub trait HasPlayer {
|
||||
fn player (&self) -> &impl MidiPlayerApi;
|
||||
fn player_mut (&mut self) -> &mut impl MidiPlayerApi;
|
||||
}
|
||||
|
||||
#[macro_export] macro_rules! has_player {
|
||||
(|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => {
|
||||
impl $(<$($L),*$($T $(: $U)?),*>)? HasPlayer for $Struct $(<$($L),*$($T),*>)? {
|
||||
|
|
@ -12,8 +14,11 @@ pub trait HasPlayer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MidiPlayerApi: MidiRecordApi + MidiPlaybackApi + Send + Sync {}
|
||||
|
||||
impl MidiPlayerApi for MidiPlayer {}
|
||||
|
||||
/// Contains state for playing a clip
|
||||
pub struct MidiPlayer {
|
||||
/// State of clock and playhead
|
||||
|
|
@ -41,6 +46,7 @@ pub struct MidiPlayer {
|
|||
/// MIDI output buffer
|
||||
pub note_buf: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Default for MidiPlayer {
|
||||
fn default () -> Self {
|
||||
Self {
|
||||
|
|
@ -61,6 +67,7 @@ impl Default for MidiPlayer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MidiPlayer {
|
||||
pub fn new (
|
||||
name: impl AsRef<str>,
|
||||
|
|
@ -88,6 +95,7 @@ impl MidiPlayer {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for MidiPlayer {
|
||||
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||
f.debug_struct("MidiPlayer")
|
||||
|
|
@ -97,16 +105,20 @@ impl std::fmt::Debug for MidiPlayer {
|
|||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
has_clock!(|self: MidiPlayer|self.clock);
|
||||
|
||||
impl HasMidiIns for MidiPlayer {
|
||||
fn midi_ins (&self) -> &Vec<JackMidiIn> { &self.midi_ins }
|
||||
fn midi_ins_mut (&mut self) -> &mut Vec<JackMidiIn> { &mut self.midi_ins }
|
||||
}
|
||||
|
||||
impl HasMidiOuts for MidiPlayer {
|
||||
fn midi_outs (&self) -> &Vec<JackMidiOut> { &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 }
|
||||
}
|
||||
|
||||
/// Hosts the JACK callback for a single MIDI player
|
||||
pub struct PlayerAudio<'a, T: MidiPlayerApi>(
|
||||
/// Player
|
||||
|
|
@ -116,6 +128,7 @@ pub struct PlayerAudio<'a, T: MidiPlayerApi>(
|
|||
/// Note chunk buffer
|
||||
pub &'a mut Vec<Vec<Vec<u8>>>,
|
||||
);
|
||||
|
||||
/// JACK process callback for a sequencer's clip player/recorder.
|
||||
impl<T: MidiPlayerApi> Audio for PlayerAudio<'_, T> {
|
||||
fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
|
||||
|
|
@ -142,6 +155,7 @@ impl<T: MidiPlayerApi> Audio for PlayerAudio<'_, T> {
|
|||
Control::Continue
|
||||
}
|
||||
}
|
||||
|
||||
impl MidiRecordApi for MidiPlayer {
|
||||
fn recording (&self) -> bool {
|
||||
self.recording
|
||||
|
|
@ -165,11 +179,13 @@ impl MidiRecordApi for MidiPlayer {
|
|||
&self.notes_in
|
||||
}
|
||||
}
|
||||
|
||||
impl MidiPlaybackApi for MidiPlayer {
|
||||
fn notes_out (&self) -> &Arc<RwLock<[bool; 128]>> {
|
||||
&self.notes_out
|
||||
}
|
||||
}
|
||||
|
||||
impl HasPlayClip for MidiPlayer {
|
||||
fn reset (&self) -> bool {
|
||||
self.reset
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ impl Default for MidiPointModel {
|
|||
Self {
|
||||
time_pos: Arc::new(0.into()),
|
||||
note_pos: Arc::new(36.into()),
|
||||
note_len: Arc::new(24.into()),
|
||||
note_len: Arc::new(24.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue