mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
refactor vertical arranger
This commit is contained in:
parent
e62fcc333e
commit
a7a798b484
3 changed files with 116 additions and 180 deletions
|
|
@ -92,19 +92,19 @@
|
|||
(:90 (42 70)))
|
||||
|
||||
(sampler { :name "DrumKit1" :dir "/home/user/Lab/Music/pak" }
|
||||
(sample { :midi 34 :name "808" :file "808.wav" })
|
||||
(sample { :midi 35 :name "KC1" :file "kik.wav" })
|
||||
(sample { :midi 36 :name "KC2" :file "kik2.wav" })
|
||||
(sample { :midi 37 :name "RIM" :file "rim.wav" })
|
||||
(sample { :midi 38 :name "SN1" :file "sna.wav" })
|
||||
(sample { :midi 39 :name "SHK" :file "shk.wav" })
|
||||
(sample { :midi 40 :name "SN2" :file "sna2.wav" })
|
||||
(sample { :midi 42 :name "HH1" :file "chh.wav" })
|
||||
(sample { :midi 45 :name "HH1" :file "ohh.wav" })
|
||||
(sample { :midi 46 :name "HH1" :file "ohh1.wav" })
|
||||
(sample { :midi 47 :name "HH1" :file "ohh2.wav" })
|
||||
(sample { :midi 44 :name "HH2" :file "chh2.wav" })
|
||||
(sample { :midi 49 :name "CRS" :file "crs.wav" })))
|
||||
(sample { :midi 34 :name "808 D" :file "808.wav" })
|
||||
(sample { :midi 35 :name "Kick 1" :file "kik.wav" })
|
||||
(sample { :midi 36 :name "Kick 2" :file "kik2.wav" })
|
||||
(sample { :midi 37 :name "Rim" :file "rim.wav" })
|
||||
(sample { :midi 38 :name "Snare 1" :file "sna.wav" })
|
||||
(sample { :midi 39 :name "Shaker" :file "shk.wav" })
|
||||
(sample { :midi 40 :name "Snare 2" :file "sna2.wav" })
|
||||
(sample { :midi 42 :name "Closed HH 1" :file "chh.wav" })
|
||||
(sample { :midi 44 :name "Closed HH 2" :file "chh2.wav" })
|
||||
(sample { :midi 45 :name "Open HH 0" :file "ohh.wav" })
|
||||
(sample { :midi 46 :name "Open HH 1" :file "ohh1.wav" })
|
||||
(sample { :midi 47 :name "Open HH 2" :file "ohh2.wav" })
|
||||
(sample { :midi 49 :name "Crash" :file "crs.wav" })))
|
||||
|
||||
(track { :name "Bass" :gain +0.0 }
|
||||
(phrase { :name "Bass 1" :beats 4 })
|
||||
|
|
|
|||
|
|
@ -96,30 +96,18 @@ impl Track {
|
|||
reset: true,
|
||||
})
|
||||
}
|
||||
fn get_device (&self, i: usize) -> Option<RwLockReadGuard<Box<dyn Device>>> {
|
||||
self.devices.get(i).map(|d|d.state.read().unwrap())
|
||||
}
|
||||
fn get_device_mut (&self, i: usize) -> Option<RwLockWriteGuard<Box<dyn Device>>> {
|
||||
self.devices.get(i).map(|d|d.state.write().unwrap())
|
||||
}
|
||||
fn device (&self) -> Option<RwLockReadGuard<Box<dyn Device>>> {
|
||||
self.get_device(self.device)
|
||||
}
|
||||
pub fn device_mut (&self) -> Option<RwLockWriteGuard<Box<dyn Device>>> {
|
||||
self.get_device_mut(self.device)
|
||||
}
|
||||
fn first_device (&self) -> Option<RwLockReadGuard<Box<dyn Device>>> {
|
||||
self.get_device(0)
|
||||
}
|
||||
pub fn connect_first_device (&self) -> Usually<()> {
|
||||
if let (Some(port), Some(device)) = (&self.midi_out, self.devices.get(0)) {
|
||||
device.client.as_client().connect_ports(&port, &device.midi_ins()?[0])?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn last_device (&self) -> Option<RwLockReadGuard<Box<dyn Device>>> {
|
||||
self.get_device(self.devices.len().saturating_sub(1))
|
||||
}
|
||||
pub fn connect_last_device (&self, app: &App) -> Usually<()> {
|
||||
Ok(match self.devices.get(self.devices.len().saturating_sub(1)) {
|
||||
Some(device) => {
|
||||
|
|
@ -135,37 +123,6 @@ impl Track {
|
|||
let index = self.devices.len() - 1;
|
||||
Ok(&mut self.devices[index])
|
||||
}
|
||||
fn add_device_with_cb (
|
||||
&mut self,
|
||||
mut device: JackDevice,
|
||||
init: impl Fn(&Self, &mut JackDevice)->Usually<()>
|
||||
) -> Usually<&mut JackDevice> {
|
||||
init(&self, &mut device)?;
|
||||
self.devices.push(device);
|
||||
let index = self.devices.len() - 1;
|
||||
Ok(&mut self.devices[index])
|
||||
}
|
||||
fn phrase (&self) -> Option<&Phrase> {
|
||||
if let Some(phrase) = self.sequence {
|
||||
return self.phrases.get(phrase)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn phrase_mut (&mut self) -> Option<&mut Phrase> {
|
||||
if let Some(phrase) = self.sequence {
|
||||
return self.phrases.get_mut(phrase)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn add_phrase (
|
||||
&mut self, name: &str, length: usize, data: Option<PhraseData>
|
||||
) -> &mut Phrase {
|
||||
self.phrases.push(Phrase::new(name, length, data));
|
||||
let index = self.phrases.len() - 1;
|
||||
&mut self.phrases[index]
|
||||
}
|
||||
pub fn toggle_monitor (&mut self) {
|
||||
self.monitoring = !self.monitoring;
|
||||
}
|
||||
|
|
@ -201,8 +158,6 @@ impl Track {
|
|||
all_notes_off(&mut self.midi_out_buf);
|
||||
}
|
||||
}
|
||||
// For highlighting keys and note repeat
|
||||
// Currently playing phrase
|
||||
if let (
|
||||
Some(TransportState::Rolling), Some((start_frame, _)), Some(phrase)
|
||||
) = (
|
||||
|
|
|
|||
|
|
@ -59,8 +59,8 @@ impl<'a> ArrangerView<'a> {
|
|||
|
||||
impl<'a> Render for ArrangerView<'a> {
|
||||
fn render (&self, buf: &mut Buffer, mut area: Rect) -> Usually<Rect> {
|
||||
area.height = area.height.min(if self.vertical {
|
||||
self.scenes.len() as u16 + 3
|
||||
area.height = area.height.min(1 + if self.vertical {
|
||||
self.scenes.len() as u16 * 2
|
||||
} else {
|
||||
self.tracks.len() as u16 * 2
|
||||
});
|
||||
|
|
@ -82,36 +82,6 @@ impl<'a> Render for ArrangerView<'a> {
|
|||
|
||||
impl<'a> ArrangerView<'a> {
|
||||
|
||||
fn vertical_scenes (&self, buf: &mut Buffer, x: u16, y: u16, height: u16) -> Usually<u16> {
|
||||
let mut index = 0usize;
|
||||
loop {
|
||||
if index >= self.scenes.len() {
|
||||
break
|
||||
}
|
||||
if y + index as u16 >= height {
|
||||
break
|
||||
}
|
||||
self.vertical_scene(buf, x, y + index as u16, index)?;
|
||||
index = index + 1;
|
||||
}
|
||||
Ok(self.scenes
|
||||
.iter()
|
||||
.map(|x|&x.name)
|
||||
.fold(0, |x,y|x.max(y.len() as u16)))
|
||||
}
|
||||
|
||||
fn vertical_scene (&self, buf: &mut Buffer, x: u16, y: u16, index: usize) -> Usually<()> {
|
||||
if let Some(scene) = self.scenes.get(index) {
|
||||
let style = Some(highlight(
|
||||
self.focused,
|
||||
(0 == self.cursor.0) && (index + 1 == self.cursor.1)
|
||||
).bold());
|
||||
"⯈".blit(buf, x, y, style)?;
|
||||
scene.name.blit(buf, x + 2, y, style)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn vertical_clips (&self, buf: &mut Buffer, x: u16, y: u16, height: u16, track: usize) -> Usually<u16> {
|
||||
let mut index = 0;
|
||||
let mut width = 10;
|
||||
|
|
@ -122,104 +92,115 @@ impl<'a> ArrangerView<'a> {
|
|||
if y + index as u16 >= height {
|
||||
break
|
||||
}
|
||||
width = 10.max(self.vertical_clip(buf, x, y, track, index)?);
|
||||
width = 10.max(if let Some(scene) = self.scenes.get(index) {
|
||||
let hi = (track + 1 == self.cursor.0) &&
|
||||
(index + 1 == self.cursor.1);
|
||||
let style = Some(highlight(self.focused, hi));
|
||||
let clip = scene.clips.get(track);
|
||||
let index = index as u16;
|
||||
let label = if let Some(Some(clip)) = clip {
|
||||
if let Some(phrase) = self.tracks[track].phrases.get(*clip) {
|
||||
format!("{} {}", if self.tracks[track].sequence == Some(*clip) {
|
||||
""
|
||||
} else {
|
||||
" "
|
||||
}, phrase.name)
|
||||
} else {
|
||||
format!(" ??? ")
|
||||
}
|
||||
} else {
|
||||
format!(" ·········")
|
||||
};
|
||||
label.blit(buf, x, y + index, style)?;
|
||||
label.len() as u16
|
||||
} else {
|
||||
0u16
|
||||
});
|
||||
index = index + 1;
|
||||
}
|
||||
Ok(width)
|
||||
}
|
||||
|
||||
fn vertical_clip (&self, buf: &mut Buffer, x: u16, y: u16, track: usize, index: usize) -> Usually<u16> {
|
||||
Ok(if let Some(scene) = self.scenes.get(index) {
|
||||
let hi = (track + 1 == self.cursor.0) &&
|
||||
(index + 1 == self.cursor.1);
|
||||
let style = Some(highlight(self.focused, hi));
|
||||
let clip = scene.clips.get(track);
|
||||
let index = index as u16;
|
||||
let label = if let Some(Some(clip)) = clip {
|
||||
if let Some(phrase) = self.tracks[track].phrases.get(*clip) {
|
||||
format!("{} {}", if self.tracks[track].sequence == Some(*clip) {
|
||||
"⯈"
|
||||
} else {
|
||||
" "
|
||||
}, phrase.name)
|
||||
} else {
|
||||
format!(" ??? ")
|
||||
}
|
||||
} else {
|
||||
format!(" ·········")
|
||||
};
|
||||
label.blit(buf, x, y + index, style)?;
|
||||
label.len() as u16
|
||||
} else {
|
||||
0u16
|
||||
})
|
||||
}
|
||||
|
||||
fn draw_vertical (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
let Rect { x, y, width, height } = area;
|
||||
let mut x2 = x;
|
||||
let bg_color = self.bg_color_hi();
|
||||
for (i, w) in self.track_widths().iter().enumerate() {
|
||||
let focus_column = i == self.cursor.0;
|
||||
if x2 >= x + width {
|
||||
break
|
||||
}
|
||||
if focus_column {
|
||||
let bg_area = Rect { x: x2, y, width: *w, height };
|
||||
fill_bg(buf, bg_area, bg_color);
|
||||
}
|
||||
x2 = x2 + w;
|
||||
}
|
||||
let (mut x2, y2) = (x, y);
|
||||
let columns = self.track_names();
|
||||
for (i, title) in columns.iter().enumerate() {
|
||||
let focus_column = i == self.cursor.0;
|
||||
if x2 >= x + width {
|
||||
break
|
||||
}
|
||||
let w = (title.len() as u16).max(10);
|
||||
let bg_area = Rect { x: x2, y: if self.cursor.1 == 0 {
|
||||
y2
|
||||
} else {
|
||||
y2 + 1 + self.cursor.1 as u16
|
||||
}, width: w + 3, height: 1 };
|
||||
fill_bg(buf, bg_area, bg_color);
|
||||
if i == 0 {
|
||||
self.vertical_scenes(buf, x2+1, y2+2, area.height)?;
|
||||
} else if i < columns.len() {
|
||||
self.vertical_clips(buf, x2+1, y2+2, area.height, i - 1)?;
|
||||
};
|
||||
let style = Some(highlight(self.focused, focus_column).bold());
|
||||
if i > 0 {
|
||||
"⏺".blit(buf, x2, y2, Some(if self.tracks[i-1].recording {
|
||||
Style::default().red()
|
||||
} else if self.tracks[i-1].monitoring {
|
||||
Style::default().yellow()
|
||||
} else {
|
||||
Style::default().black()
|
||||
}))?;
|
||||
}
|
||||
title.blit(buf, x2+2, y2, style)?;
|
||||
x2 = x2 + w + 3;
|
||||
}
|
||||
let bg_area = Rect { x: x2, y: if self.cursor.1 == 0 {
|
||||
y2
|
||||
} else {
|
||||
y2 + 1 + self.cursor.1 as u16
|
||||
}, width: width - x2, height: 1 };
|
||||
fill_bg(buf, bg_area, bg_color);
|
||||
Ok(area)
|
||||
}
|
||||
|
||||
fn draw_vertical_2 (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
Split::right([
|
||||
// Scene list
|
||||
&|buf: &mut Buffer, mut area: Rect|Ok(Rect::default()),
|
||||
return Split::right([
|
||||
|
||||
// Scene column
|
||||
&|buf: &mut Buffer, area: Rect|{
|
||||
let Rect { x, y, height, .. } = area;
|
||||
for (scene_index, scene) in self.scenes.iter().enumerate() {
|
||||
if y + 2 * scene_index as u16 >= height {
|
||||
break
|
||||
}
|
||||
let style = Some(highlight(
|
||||
self.focused,
|
||||
(0 == self.cursor.0) && (scene_index + 1 == self.cursor.1)
|
||||
).bold());
|
||||
let y = 1 + y + 2 * scene_index as u16;
|
||||
"⯈".blit(buf, x+1, y, style)?;
|
||||
scene.name.blit(buf, x + 2, y, style)?;
|
||||
}
|
||||
let width = 2+self.scenes.iter()
|
||||
.map(|x|&x.name).fold(0, |x,y|x.max(y.len() as u16+1));
|
||||
Ok(Rect { width, ..area })
|
||||
},
|
||||
|
||||
// Track columns
|
||||
&|buf: &mut Buffer, mut area: Rect|Ok(Rect::default()),
|
||||
&|buf: &mut Buffer, mut area: Rect|Ok(Rect::default()),
|
||||
&|buf: &mut Buffer, mut area: Rect|Ok(Rect::default()),
|
||||
]).render(buf, area)
|
||||
&|buf: &mut Buffer, area: Rect|{
|
||||
let Rect { mut x, y, width, height } = area;
|
||||
for (track_index, track) in self.tracks.iter().enumerate() {
|
||||
if x >= width {
|
||||
break
|
||||
}
|
||||
let mut width = 16u16;
|
||||
track.name.blit(buf, x, y, Some(Style::default().bold()))?;
|
||||
for (scene_index, scene) in self.scenes.iter().enumerate() {
|
||||
if y + 2 * scene_index as u16 >= height {
|
||||
break
|
||||
}
|
||||
let label = if let Some(Some(clip)) = scene.clips.get(track_index) {
|
||||
if let Some(phrase) = track.phrases.get(*clip) {
|
||||
format!("{} {}", if track.sequence == Some(*clip) {
|
||||
""
|
||||
} else {
|
||||
"┊"
|
||||
}, phrase.name)
|
||||
} else {
|
||||
format!(" ??? ")
|
||||
}
|
||||
} else {
|
||||
format!("┊ ········")
|
||||
};
|
||||
let hi = (track_index + 1 == self.cursor.0) && (scene_index + 1 == self.cursor.1);
|
||||
let style = Some(highlight(self.focused, hi));
|
||||
let y = 1 + y + 2 * scene_index as u16;
|
||||
"┊".blit(buf, x, y, Some(Style::default().dim()))?;
|
||||
"┊".blit(buf, x, y + 1, Some(Style::default().dim()))?;
|
||||
label.blit(buf, x, y, style)?;
|
||||
//width = width.max(2label.len() as u16 + 3);
|
||||
}
|
||||
if track_index + 1 == self.cursor.0 {
|
||||
if self.cursor.1 == 0 {
|
||||
let y = area.y;
|
||||
fill_bg(buf, Rect { x, y, width, height: 1 }, if self.focused {
|
||||
Color::Rgb(30, 90, 25)
|
||||
} else {
|
||||
Color::Rgb(25, 60, 15)
|
||||
})
|
||||
} else {
|
||||
let y = 1 + area.y + 2 * (self.cursor.1 as u16 - 1);
|
||||
fill_bg(buf, Rect { x, y, width, height: 2 }, if self.focused {
|
||||
Color::Rgb(30, 90, 25)
|
||||
} else {
|
||||
Color::Rgb(25, 60, 15)
|
||||
})
|
||||
}
|
||||
};
|
||||
x = x + width as u16;
|
||||
}
|
||||
Ok(Rect { x: area.x, y, width: x - area.x, height })
|
||||
}
|
||||
]).render(buf, area);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue