replace Phrase::looped with separate fields; draw them with backgrounds

This commit is contained in:
🪞👃🪞 2024-10-05 10:02:55 +03:00
parent 4c3ad62279
commit ea3edec96b
2 changed files with 31 additions and 21 deletions

View file

@ -694,9 +694,11 @@ pub struct Phrase {
pub name: Arc<RwLock<String>>, pub name: Arc<RwLock<String>>,
pub length: usize, pub length: usize,
pub notes: PhraseData, pub notes: PhraseData,
pub looped: Option<(usize, usize)>, pub loop_on: bool,
pub loop_start: usize,
pub loop_length: usize,
/// All notes are displayed with minimum length /// All notes are displayed with minimum length
pub percussive: bool pub percussive: bool,
} }
impl Default for Phrase { impl Default for Phrase {
fn default () -> Self { Self::new("", 0, None) } fn default () -> Self { Self::new("", 0, None) }
@ -707,10 +709,15 @@ impl Phrase {
name: Arc::new(RwLock::new(name.into())), name: Arc::new(RwLock::new(name.into())),
length, length,
notes: notes.unwrap_or(vec![Vec::with_capacity(16);length]), notes: notes.unwrap_or(vec![Vec::with_capacity(16);length]),
looped: Some((0, length)), loop_on: true,
loop_start: 0,
loop_length: length,
percussive: true, percussive: true,
} }
} }
pub fn toggle_loop (&mut self) {
self.loop_on = !self.loop_on;
}
pub fn record_event (&mut self, pulse: usize, message: MidiMessage) { pub fn record_event (&mut self, pulse: usize, message: MidiMessage) {
if pulse >= self.length { if pulse >= self.length {
panic!("extend phrase first") panic!("extend phrase first")

View file

@ -122,8 +122,8 @@ impl Handle<Tui> for Arranger<Tui> {
self.rename_selected(); self.rename_selected();
}, },
// length: add a new scene // length: add a new scene
key!(KeyCode::Char('l')) => { key!(KeyCode::Char('l')) => if let Some(phrase) = self.phrase() {
todo!(); phrase.write().unwrap().toggle_loop()
}, },
// color: set color of item at cursor // color: set color of item at cursor
key!(KeyCode::Char('c')) => { key!(KeyCode::Char('c')) => {
@ -774,22 +774,25 @@ impl Sequencer<Tui> {
impl Content for Sequencer<Tui> { impl Content for Sequencer<Tui> {
type Engine = Tui; type Engine = Tui;
fn content (&self) -> impl Widget<Engine = Tui> { fn content (&self) -> impl Widget<Engine = Tui> {
let field_bg = Color::Rgb(28, 35, 25);
let toolbar = Stack::down(move|add|{ let toolbar = Stack::down(move|add|{
add(&col!("Name:", self.name.read().unwrap().as_str()))?; let name = format!("{:>9}", self.name.read().unwrap().as_str());
add(&col!("Track:", TuiStyle::bg(name.as_str(), field_bg)))?;
if let Some(phrase) = self.viewing_phrase if let Some(phrase) = self.viewing_phrase
.map(|index|self.phrases.get(index)) .map(|index|self.phrases.get(index))
.flatten() .flatten()
{ {
let phrase = phrase.read().unwrap(); let phrase = phrase.read().unwrap();
let length = phrase.length; let length = format!("{}q{}p", phrase.length / 96, phrase.length % 96);
let looped = phrase.looped; let length = format!("{:>9}", &length);
let loop_on = format!("{:>9}", if phrase.loop_on { "on" } else { "off" });
let loop_start = format!("{:>9}", phrase.loop_start);
let loop_end = format!("{:>9}", phrase.loop_length);
add(&"")?; add(&"")?;
add(&col!("Length: ", format!("{}q{}p", length / 96, length % 96).as_str()))?; add(&col!("Length:", TuiStyle::bg(length.as_str(), field_bg)))?;
add(&"")?; add(&col!("Loop:", TuiStyle::bg(loop_on.as_str(), field_bg)))?;
add(&col!("Loop [ ]", "From: ", " 1.1.1", "Length: ", " 1.0.0"))?; add(&col!("L. start:", TuiStyle::bg(loop_start.as_str(), field_bg)))?;
add(&"")?; add(&col!("L. length:", TuiStyle::bg(loop_end.as_str(), field_bg)))?;
add(&col!("Notes: ", "C#0-C#9 ", "[ /2 ]", "[ x2 ]",
"[ Rev ]", "[ Inv ]", "[ Dup ]"))?;
} }
Ok(()) Ok(())
}).min_x(10); }).min_x(10);