mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
sequencer: despaghettify
This commit is contained in:
parent
1dbe151ae6
commit
654aa0f041
7 changed files with 268 additions and 218 deletions
|
|
@ -16,7 +16,6 @@ pub struct Arranger {
|
|||
/// Display mode of arranger
|
||||
pub mode: ArrangerViewMode,
|
||||
|
||||
|
||||
pub focused: bool,
|
||||
pub entered: bool,
|
||||
pub focus_sequencer: bool,
|
||||
|
|
@ -68,83 +67,6 @@ impl Arranger {
|
|||
//self.sequencer.show(phrase)
|
||||
Ok(())
|
||||
}
|
||||
pub fn phrase (&self) -> Option<&Arc<RwLock<Phrase>>> {
|
||||
let track_id = self.selected.track()?;
|
||||
self.tracks.get(track_id)?.phrases.get((*self.scene()?.clips.get(track_id)?)?)
|
||||
}
|
||||
pub fn phrase_next (&mut self) {
|
||||
let track_index = self.selected.track();
|
||||
let scene_index = self.selected.scene();
|
||||
track_index
|
||||
.and_then(|index|self.tracks.get_mut(index).map(|track|(index, track)))
|
||||
.and_then(|(track_index, track)|{
|
||||
let phrases = track.phrases.len();
|
||||
scene_index
|
||||
.and_then(|index|self.scenes.get_mut(index))
|
||||
.and_then(|scene|{
|
||||
if let Some(phrase_index) = scene.clips[track_index] {
|
||||
if phrase_index >= phrases - 1 {
|
||||
scene.clips[track_index] = None;
|
||||
} else {
|
||||
scene.clips[track_index] = Some(phrase_index + 1);
|
||||
}
|
||||
} else if phrases > 0 {
|
||||
scene.clips[track_index] = Some(0);
|
||||
}
|
||||
Some(())
|
||||
})
|
||||
});
|
||||
}
|
||||
pub fn phrase_prev (&mut self) {
|
||||
let track_index = self.selected.track();
|
||||
let scene_index = self.selected.scene();
|
||||
track_index
|
||||
.and_then(|index|self.tracks.get_mut(index).map(|track|(index, track)))
|
||||
.and_then(|(track_index, track)|{
|
||||
let phrases = track.phrases.len();
|
||||
scene_index
|
||||
.and_then(|index|self.scenes.get_mut(index))
|
||||
.and_then(|scene|{
|
||||
if let Some(phrase_index) = scene.clips[track_index] {
|
||||
scene.clips[track_index] = if phrase_index == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(phrase_index - 1)
|
||||
};
|
||||
} else if phrases > 0 {
|
||||
scene.clips[track_index] = Some(phrases - 1);
|
||||
}
|
||||
Some(())
|
||||
})
|
||||
});
|
||||
}
|
||||
pub fn scene (&self) -> Option<&Scene> {
|
||||
self.selected.scene().map(|s|self.scenes.get(s)).flatten()
|
||||
}
|
||||
pub fn scene_mut (&mut self) -> Option<&mut Scene> {
|
||||
self.selected.scene().map(|s|self.scenes.get_mut(s)).flatten()
|
||||
}
|
||||
pub fn scene_next (&mut self) {
|
||||
self.selected.scene_next(self.scenes.len() - 1)
|
||||
}
|
||||
pub fn scene_prev (&mut self) {
|
||||
self.selected.scene_prev()
|
||||
}
|
||||
pub fn scene_add (&mut self, name: Option<&str>) -> Usually<&mut Scene> {
|
||||
let clips = vec![None;self.tracks.len()];
|
||||
self.scenes.push(match name {
|
||||
Some(name) => Scene::new(name, clips),
|
||||
None => Scene::new(&self.scene_default_name(), clips),
|
||||
});
|
||||
let index = self.scenes.len() - 1;
|
||||
Ok(&mut self.scenes[index])
|
||||
}
|
||||
pub fn scene_del (&mut self) {
|
||||
unimplemented!("Arranger::scene_del");
|
||||
}
|
||||
pub fn scene_default_name (&self) -> String {
|
||||
format!("Scene {}", self.scenes.len() + 1)
|
||||
}
|
||||
pub fn rename_selected (&mut self) {
|
||||
self.modal = Some(Box::new(ArrangerRenameModal::new(
|
||||
self.selected,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ submod! {
|
|||
sequencer
|
||||
sequencer_cli
|
||||
sequencer_handle
|
||||
sequencer_render
|
||||
sequencer_view
|
||||
transport
|
||||
transport_focus
|
||||
transport_handle
|
||||
|
|
@ -30,4 +30,6 @@ submod! {
|
|||
pubmod! {
|
||||
arranger_view_h
|
||||
arranger_view_v
|
||||
sequencer_view_h
|
||||
sequencer_view_v
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,3 +145,56 @@ impl Phrase {
|
|||
phrase
|
||||
}}
|
||||
}
|
||||
|
||||
impl Arranger {
|
||||
pub fn phrase (&self) -> Option<&Arc<RwLock<Phrase>>> {
|
||||
let track_id = self.selected.track()?;
|
||||
self.tracks.get(track_id)?.phrases.get((*self.scene()?.clips.get(track_id)?)?)
|
||||
}
|
||||
pub fn phrase_next (&mut self) {
|
||||
let track_index = self.selected.track();
|
||||
let scene_index = self.selected.scene();
|
||||
track_index
|
||||
.and_then(|index|self.tracks.get_mut(index).map(|track|(index, track)))
|
||||
.and_then(|(track_index, track)|{
|
||||
let phrases = track.phrases.len();
|
||||
scene_index
|
||||
.and_then(|index|self.scenes.get_mut(index))
|
||||
.and_then(|scene|{
|
||||
if let Some(phrase_index) = scene.clips[track_index] {
|
||||
if phrase_index >= phrases - 1 {
|
||||
scene.clips[track_index] = None;
|
||||
} else {
|
||||
scene.clips[track_index] = Some(phrase_index + 1);
|
||||
}
|
||||
} else if phrases > 0 {
|
||||
scene.clips[track_index] = Some(0);
|
||||
}
|
||||
Some(())
|
||||
})
|
||||
});
|
||||
}
|
||||
pub fn phrase_prev (&mut self) {
|
||||
let track_index = self.selected.track();
|
||||
let scene_index = self.selected.scene();
|
||||
track_index
|
||||
.and_then(|index|self.tracks.get_mut(index).map(|track|(index, track)))
|
||||
.and_then(|(track_index, track)|{
|
||||
let phrases = track.phrases.len();
|
||||
scene_index
|
||||
.and_then(|index|self.scenes.get_mut(index))
|
||||
.and_then(|scene|{
|
||||
if let Some(phrase_index) = scene.clips[track_index] {
|
||||
scene.clips[track_index] = if phrase_index == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(phrase_index - 1)
|
||||
};
|
||||
} else if phrases > 0 {
|
||||
scene.clips[track_index] = Some(phrases - 1);
|
||||
}
|
||||
Some(())
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,29 @@ pub struct Scene {
|
|||
}
|
||||
|
||||
impl Scene {
|
||||
pub fn from_edn <'a, 'e> (args: &[Edn<'e>]) -> Usually<Self> {
|
||||
let mut name = None;
|
||||
let mut clips = vec![];
|
||||
edn!(edn in args {
|
||||
Edn::Map(map) => {
|
||||
let key = map.get(&Edn::Key(":name"));
|
||||
if let Some(Edn::Str(n)) = key {
|
||||
name = Some(*n);
|
||||
} else {
|
||||
panic!("unexpected key in scene '{name:?}': {key:?}")
|
||||
}
|
||||
},
|
||||
Edn::Symbol("_") => {
|
||||
clips.push(None);
|
||||
},
|
||||
Edn::Int(i) => {
|
||||
clips.push(Some(*i as usize));
|
||||
},
|
||||
_ => panic!("unexpected in scene '{name:?}': {edn:?}")
|
||||
});
|
||||
let scene = Self::new(name.unwrap_or(""), clips);
|
||||
Ok(scene)
|
||||
}
|
||||
pub fn new (name: impl AsRef<str>, clips: impl AsRef<[Option<usize>]>) -> Self {
|
||||
let name = name.as_ref().into();
|
||||
let clips = clips.as_ref().iter().map(|x|x.clone()).collect();
|
||||
|
|
@ -47,28 +70,32 @@ pub fn scene_ppqs (tracks: &[Sequencer], scenes: &[Scene]) -> Vec<(usize, usize)
|
|||
scenes
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
pub fn from_edn <'a, 'e> (args: &[Edn<'e>]) -> Usually<Self> {
|
||||
let mut name = None;
|
||||
let mut clips = vec![];
|
||||
edn!(edn in args {
|
||||
Edn::Map(map) => {
|
||||
let key = map.get(&Edn::Key(":name"));
|
||||
if let Some(Edn::Str(n)) = key {
|
||||
name = Some(*n);
|
||||
} else {
|
||||
panic!("unexpected key in scene '{name:?}': {key:?}")
|
||||
}
|
||||
},
|
||||
Edn::Symbol("_") => {
|
||||
clips.push(None);
|
||||
},
|
||||
Edn::Int(i) => {
|
||||
clips.push(Some(*i as usize));
|
||||
},
|
||||
_ => panic!("unexpected in scene '{name:?}': {edn:?}")
|
||||
impl Arranger {
|
||||
pub fn scene (&self) -> Option<&Scene> {
|
||||
self.selected.scene().map(|s|self.scenes.get(s)).flatten()
|
||||
}
|
||||
pub fn scene_mut (&mut self) -> Option<&mut Scene> {
|
||||
self.selected.scene().map(|s|self.scenes.get_mut(s)).flatten()
|
||||
}
|
||||
pub fn scene_next (&mut self) {
|
||||
self.selected.scene_next(self.scenes.len() - 1)
|
||||
}
|
||||
pub fn scene_prev (&mut self) {
|
||||
self.selected.scene_prev()
|
||||
}
|
||||
pub fn scene_add (&mut self, name: Option<&str>) -> Usually<&mut Scene> {
|
||||
let clips = vec![None;self.tracks.len()];
|
||||
self.scenes.push(match name {
|
||||
Some(name) => Scene::new(name, clips),
|
||||
None => Scene::new(&self.scene_default_name(), clips),
|
||||
});
|
||||
let scene = Self::new(name.unwrap_or(""), clips);
|
||||
Ok(scene)
|
||||
let index = self.scenes.len() - 1;
|
||||
Ok(&mut self.scenes[index])
|
||||
}
|
||||
pub fn scene_del (&mut self) {
|
||||
unimplemented!("Arranger::scene_del");
|
||||
}
|
||||
pub fn scene_default_name (&self) -> String {
|
||||
format!("Scene {}", self.scenes.len() + 1)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ impl Sequencer {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn style_focus (&self) -> Option<Style> {
|
||||
pub(crate) fn style_focus (&self) -> Option<Style> {
|
||||
Some(if self.focused {
|
||||
Style::default().green().not_dim()
|
||||
} else {
|
||||
|
|
@ -33,7 +33,7 @@ impl Sequencer {
|
|||
})
|
||||
}
|
||||
|
||||
fn style_timer_step (now: usize, step: usize, next_step: usize) -> Style {
|
||||
pub(crate) fn style_timer_step (now: usize, step: usize, next_step: usize) -> Style {
|
||||
if step <= now && now < next_step {
|
||||
Style::default().yellow().bold().not_dim()
|
||||
} else {
|
||||
|
|
@ -53,121 +53,6 @@ impl Sequencer {
|
|||
default
|
||||
}
|
||||
}
|
||||
|
||||
const H_KEYS_OFFSET: usize = 5;
|
||||
|
||||
fn horizontal_draw (&self, buf: &mut Buffer, mut area: Rect) -> Usually<()> {
|
||||
Lozenge(Style::default().fg(Nord::BG2)).draw(buf, Rect {
|
||||
x: area.x, y: area.y + 1, width: 15, height: 4
|
||||
})?;
|
||||
"Start 1.1.1".blit(buf, area.x + 1, area.y + 2, None)?;
|
||||
"End 2.1.1".blit(buf, area.x + 1, area.y + 3, None)?;
|
||||
|
||||
Lozenge(Style::default().fg(Nord::BG2)).draw(buf, Rect {
|
||||
x: area.x, y: area.y + 5, width: 15, height: 5
|
||||
})?;
|
||||
"[ Loop off ] ".blit(buf, area.x + 1, area.y + 6, None)?;
|
||||
"Loop 1.1.1".blit(buf, area.x + 1, area.y + 7, None)?;
|
||||
"Length 1.0.0".blit(buf, area.x + 1, area.y + 8, None)?;
|
||||
|
||||
Lozenge(Style::default().fg(Nord::BG2)).draw(buf, Rect {
|
||||
x: area.x, y: area.y + 10, width: 15, height: 7
|
||||
})?;
|
||||
"Notes -------".blit(buf, area.x + 1, area.y + 11, None)?;
|
||||
"[ /2 ] [ x2 ]".blit(buf, area.x + 1, area.y + 12, None)?;
|
||||
"[ Reverse ]".blit(buf, area.x + 1, area.y + 13, None)?;
|
||||
"[ Invert ]".blit(buf, area.x + 1, area.y + 14, None)?;
|
||||
"[ Duplicate ]".blit(buf, area.x + 1, area.y + 15, None)?;
|
||||
|
||||
area.x = area.x + 15;
|
||||
area.width = area.width.saturating_sub(12);
|
||||
self.horizontal_keys(buf, area)?;
|
||||
if let Some(ref phrase) = self.phrase {
|
||||
self.horizontal_timer(buf, area, phrase)?;
|
||||
}
|
||||
self.horizontal_notes(buf, area)?;
|
||||
self.horizontal_cursor(buf, area)?;
|
||||
self.horizontal_quant(buf, area)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn horizontal_notes (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
if area.height < 2 {
|
||||
return Ok(area)
|
||||
}
|
||||
let area = Rect {
|
||||
x: area.x + Self::H_KEYS_OFFSET as u16,
|
||||
y: area.y + 1,
|
||||
width: area.width - Self::H_KEYS_OFFSET as u16,
|
||||
height: area.height - 2
|
||||
};
|
||||
buffer_update(buf, area, &move |cell, x, y|{
|
||||
let src_x = ((x as usize + self.time_axis.start) * self.time_axis.scale) as usize;
|
||||
let src_y = (y as usize + self.note_axis.start) as usize;
|
||||
if src_x < self.buffer.width && src_y < self.buffer.height - 1 {
|
||||
let src = self.buffer.get(src_x, self.buffer.height - src_y);
|
||||
src.map(|src|{
|
||||
cell.set_symbol(src.symbol());
|
||||
cell.set_fg(src.fg);
|
||||
});
|
||||
}
|
||||
});
|
||||
Ok(area)
|
||||
}
|
||||
|
||||
fn horizontal_keys (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
if area.height < 2 {
|
||||
return Ok(area)
|
||||
}
|
||||
let area = Rect {
|
||||
x: area.x,
|
||||
y: area.y + 1,
|
||||
width: 5,
|
||||
height: area.height - 2
|
||||
};
|
||||
buffer_update(buf, area, &|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()
|
||||
}
|
||||
});
|
||||
Ok(area)
|
||||
}
|
||||
|
||||
fn horizontal_quant (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
let quant = ppq_to_name(self.time_axis.scale);
|
||||
let quant_x = area.x + area.width - 1 - quant.len() as u16;
|
||||
let quant_y = area.y + area.height - 2;
|
||||
quant.blit(buf, quant_x, quant_y, self.style_focus())
|
||||
}
|
||||
|
||||
fn horizontal_cursor (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
if let (Some(time), Some(note)) = (self.time_axis.point, self.note_axis.point) {
|
||||
let x = area.x + Self::H_KEYS_OFFSET as u16 + time as u16;
|
||||
let y = area.y + 1 + note as u16 / 2;
|
||||
let c = if note % 2 == 0 { "▀" } else { "▄" };
|
||||
c.blit(buf, x, y, self.style_focus())
|
||||
} else {
|
||||
Ok(Rect::default())
|
||||
}
|
||||
}
|
||||
|
||||
fn horizontal_timer (
|
||||
&self, buf: &mut Buffer, area: Rect, phrase: &RwLock<Phrase>
|
||||
) -> Usually<Rect> {
|
||||
let phrase = phrase.read().unwrap();
|
||||
let (time0, time_z, now) = (self.time_axis.start, self.time_axis.scale, self.now % phrase.length);
|
||||
let Rect { x, width, .. } = area;
|
||||
let x2 = x as usize + Self::H_KEYS_OFFSET;
|
||||
let x3 = x as usize + width as usize;
|
||||
for x in x2..x3 {
|
||||
let step = (time0 + x2) * time_z;
|
||||
let next_step = (time0 + x2 + 1) * time_z;
|
||||
let style = Self::style_timer_step(now, step as usize, next_step as usize);
|
||||
"-".blit(buf, x as u16, area.y, Some(style))?;
|
||||
}
|
||||
return Ok(Rect { x: area.x, y: area.y, width: area.width, height: 1 })
|
||||
}
|
||||
}
|
||||
|
||||
fn nth_octave (index: u16) -> &'static str {
|
||||
161
crates/tek_sequencer/src/sequencer_view_h.rs
Normal file
161
crates/tek_sequencer/src/sequencer_view_h.rs
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
use crate::*;
|
||||
|
||||
impl Sequencer {
|
||||
|
||||
const H_KEYS_OFFSET: usize = 5;
|
||||
|
||||
pub(crate) fn horizontal_draw (&self, buf: &mut Buffer, mut area: Rect) -> Usually<()> {
|
||||
SequenceStartEnd.render(buf, area)?;
|
||||
SequenceLoop.render(buf, area)?;
|
||||
SequenceRange.render(buf, area)?;
|
||||
area.x = area.x + 15;
|
||||
area.width = area.width.saturating_sub(12);
|
||||
SequenceKeys(&self).render(buf, area)?;
|
||||
if let Some(ref phrase) = self.phrase {
|
||||
SequenceTimer(&self, phrase).render(buf, area)?;
|
||||
}
|
||||
SequenceNotes(&self).render(buf, area)?;
|
||||
SequenceCursor(&self).render(buf, area)?;
|
||||
SequenceZoom(&self).render(buf, area)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct SequenceStartEnd;
|
||||
|
||||
impl Render for SequenceStartEnd {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
let frame = Rect { x: area.x, y: area.y, width: 15, height: 4 };
|
||||
Lozenge(Style::default().fg(Nord::BG2)).draw(buf, frame)?;
|
||||
"Start 1.1.1".blit(buf, area.x + 1, area.y + 1, None)?;
|
||||
"End 2.1.1".blit(buf, area.x + 1, area.y + 2, None)?;
|
||||
Ok(frame)
|
||||
}
|
||||
}
|
||||
|
||||
struct SequenceLoop;
|
||||
|
||||
impl Render for SequenceLoop {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
let range = Rect { x: area.x, y: area.y + 4, width: 15, height: 5 };
|
||||
Lozenge(Style::default().fg(Nord::BG2)).draw(buf, range)?;
|
||||
"[ Loop off ] ".blit(buf, area.x + 1, area.y + 5, None)?;
|
||||
"Loop 1.1.1".blit(buf, area.x + 1, area.y + 6, None)?;
|
||||
"Length 1.0.0".blit(buf, area.x + 1, area.y + 7, None)?;
|
||||
Ok(range)
|
||||
}
|
||||
}
|
||||
|
||||
struct SequenceRange;
|
||||
|
||||
impl Render for SequenceRange {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
let range = Rect { x: area.x, y: area.y + 9, width: 15, height: 7 };
|
||||
Lozenge(Style::default().fg(Nord::BG2)).draw(buf, range)?;
|
||||
"Notes -------".blit(buf, area.x + 1, area.y + 10, None)?;
|
||||
"[ /2 ] [ x2 ]".blit(buf, area.x + 1, area.y + 11, None)?;
|
||||
"[ Reverse ]".blit(buf, area.x + 1, area.y + 12, None)?;
|
||||
"[ Invert ]".blit(buf, area.x + 1, area.y + 13, None)?;
|
||||
"[ Duplicate ]".blit(buf, area.x + 1, area.y + 14, None)?;
|
||||
Ok(area)
|
||||
}
|
||||
}
|
||||
|
||||
struct SequenceKeys<'a>(&'a Sequencer);
|
||||
|
||||
impl<'a> Render for SequenceKeys<'a> {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
if area.height < 2 {
|
||||
return Ok(area)
|
||||
}
|
||||
let area = Rect {
|
||||
x: area.x,
|
||||
y: area.y + 1,
|
||||
width: 5,
|
||||
height: area.height - 2
|
||||
};
|
||||
buffer_update(buf, area, &|cell, x, y|{
|
||||
let y = y + self.0.note_axis.start as u16;
|
||||
if x < self.0.keys.area.width && y < self.0.keys.area.height {
|
||||
*cell = self.0.keys.get(x, y).clone()
|
||||
}
|
||||
});
|
||||
Ok(area)
|
||||
}
|
||||
}
|
||||
|
||||
struct SequenceNotes<'a>(&'a Sequencer);
|
||||
|
||||
impl<'a> Render for SequenceNotes<'a> {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
if area.height < 2 {
|
||||
return Ok(area)
|
||||
}
|
||||
let area = Rect {
|
||||
x: area.x + Sequencer::H_KEYS_OFFSET as u16,
|
||||
y: area.y + 1,
|
||||
width: area.width - Sequencer::H_KEYS_OFFSET as u16,
|
||||
height: area.height - 2
|
||||
};
|
||||
buffer_update(buf, area, &move |cell, x, y|{
|
||||
let src_x = ((x as usize + self.0.time_axis.start) * self.0.time_axis.scale) as usize;
|
||||
let src_y = (y as usize + self.0.note_axis.start) as usize;
|
||||
if src_x < self.0.buffer.width && src_y < self.0.buffer.height - 1 {
|
||||
let src = self.0.buffer.get(src_x, self.0.buffer.height - src_y);
|
||||
src.map(|src|{
|
||||
cell.set_symbol(src.symbol());
|
||||
cell.set_fg(src.fg);
|
||||
});
|
||||
}
|
||||
});
|
||||
Ok(area)
|
||||
}
|
||||
}
|
||||
|
||||
struct SequenceCursor<'a>(&'a Sequencer);
|
||||
|
||||
impl<'a> Render for SequenceCursor<'a> {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
if let (Some(time), Some(note)) = (self.0.time_axis.point, self.0.note_axis.point) {
|
||||
let x = area.x + Sequencer::H_KEYS_OFFSET as u16 + time as u16;
|
||||
let y = area.y + 1 + note as u16 / 2;
|
||||
let c = if note % 2 == 0 { "▀" } else { "▄" };
|
||||
c.blit(buf, x, y, self.0.style_focus())
|
||||
} else {
|
||||
Ok(Rect::default())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SequenceZoom<'a>(&'a Sequencer);
|
||||
|
||||
impl<'a> Render for SequenceZoom<'a> {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
let quant = ppq_to_name(self.0.time_axis.scale);
|
||||
let quant_x = area.x + area.width - 1 - quant.len() as u16;
|
||||
let quant_y = area.y + area.height - 2;
|
||||
quant.blit(buf, quant_x, quant_y, self.0.style_focus())
|
||||
}
|
||||
}
|
||||
|
||||
struct SequenceTimer<'a>(&'a Sequencer, &'a Arc<RwLock<Phrase>>);
|
||||
|
||||
impl<'a> Render for SequenceTimer<'a> {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
let phrase = self.1.read().unwrap();
|
||||
let (time0, time_z, now) = (
|
||||
self.0.time_axis.start, self.0.time_axis.scale, self.0.now % phrase.length
|
||||
);
|
||||
let Rect { x, width, .. } = area;
|
||||
let x2 = x as usize + Sequencer::H_KEYS_OFFSET;
|
||||
let x3 = x as usize + width as usize;
|
||||
for x in x2..x3 {
|
||||
let step = (time0 + x2) * time_z;
|
||||
let next_step = (time0 + x2 + 1) * time_z;
|
||||
let style = Sequencer::style_timer_step(now, step as usize, next_step as usize);
|
||||
"-".blit(buf, x as u16, area.y, Some(style))?;
|
||||
}
|
||||
return Ok(Rect { x: area.x, y: area.y, width: area.width, height: 1 })
|
||||
}
|
||||
}
|
||||
0
crates/tek_sequencer/src/sequencer_view_v.rs
Normal file
0
crates/tek_sequencer/src/sequencer_view_v.rs
Normal file
Loading…
Add table
Add a link
Reference in a new issue