mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +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)
|
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
|
||||||
|
|
|
||||||
|
|
@ -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)); },
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,16 @@ pub struct Note;
|
||||||
|
|
||||||
impl Note {
|
impl Note {
|
||||||
pub const NAMES: [&str; 128] = [
|
pub const NAMES: [&str; 128] = [
|
||||||
"C0", "C#0", "D0", "D#0", "E0", "F0", "F#0", "G0", "G#0", "A0", "A#0", "B0",
|
"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",
|
"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",
|
"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",
|
"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",
|
"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",
|
"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",
|
"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",
|
"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",
|
"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",
|
"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",
|
"C10", "C#10", "D10", "D#10", "E10", "F10", "F#10", "G10",
|
||||||
];
|
];
|
||||||
pub fn pitch_to_name (n: usize) -> &'static str {
|
pub fn pitch_to_name (n: usize) -> &'static str {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ impl Default for MidiPointModel {
|
||||||
Self {
|
Self {
|
||||||
time_pos: Arc::new(0.into()),
|
time_pos: Arc::new(0.into()),
|
||||||
note_pos: Arc::new(36.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