store updated phrase length; enter/exit phrase editor

This commit is contained in:
🪞👃🪞 2024-10-16 12:29:45 +03:00
parent ff342963a1
commit d29dd56198
3 changed files with 42 additions and 34 deletions

View file

@ -168,15 +168,17 @@ impl<E: Engine> PhrasePool<E> {
} }
pub fn append_new (&mut self, name: Option<&str>, color: Option<Color>) { pub fn append_new (&mut self, name: Option<&str>, color: Option<Color>) {
let mut phrase = Phrase::default(); let mut phrase = Phrase::default();
phrase.name = String::from(name.unwrap_or("(no name)")); phrase.name = String::from(name.unwrap_or("(no name)"));
phrase.color = color.unwrap_or_else(random_color); phrase.color = color.unwrap_or_else(random_color);
phrase.length = 4 * PPQ;
self.phrases.push(Arc::new(RwLock::new(phrase))); self.phrases.push(Arc::new(RwLock::new(phrase)));
self.phrase = self.phrases.len() - 1; self.phrase = self.phrases.len() - 1;
} }
pub fn insert_new (&mut self, name: Option<&str>, color: Option<Color>) { pub fn insert_new (&mut self, name: Option<&str>, color: Option<Color>) {
let mut phrase = Phrase::default(); let mut phrase = Phrase::default();
phrase.name = String::from(name.unwrap_or("(no name)")); phrase.name = String::from(name.unwrap_or("(no name)"));
phrase.color = color.unwrap_or_else(random_color); phrase.color = color.unwrap_or_else(random_color);
phrase.length = 4 * PPQ;
self.phrases.insert(self.phrase + 1, Arc::new(RwLock::new(phrase))); self.phrases.insert(self.phrase + 1, Arc::new(RwLock::new(phrase)));
self.phrase += 1; self.phrase += 1;
} }

View file

@ -44,12 +44,14 @@ impl Handle<Tui> for PhrasePool<Tui> {
} }
}, },
Some(PhrasePoolMode::Length(phrase, ref mut length, ref mut focus)) => { Some(PhrasePoolMode::Length(phrase, ref mut length, ref mut focus)) => {
let mut phrase = self.phrases[phrase].write().unwrap();
match from.event() { match from.event() {
key!(KeyCode::Left) => { focus.prev() }, key!(KeyCode::Left) => { focus.prev() },
key!(KeyCode::Right) => { focus.next() }, key!(KeyCode::Right) => { focus.next() },
key!(KeyCode::Esc) => { self.mode = None; }, key!(KeyCode::Esc) => { self.mode = None; },
key!(KeyCode::Enter) => { self.mode = None; }, key!(KeyCode::Enter) => {
self.phrases[phrase].write().unwrap().length = *length;
self.mode = None;
},
key!(KeyCode::Up) => match focus { key!(KeyCode::Up) => match focus {
PhraseLengthFocus::Bar => { PhraseLengthFocus::Bar => {
*length += 4 * PPQ *length += 4 * PPQ
@ -99,6 +101,8 @@ impl Handle<Tui> for PhraseEditor<Tui> {
key!(KeyCode::Char('`')) => { key!(KeyCode::Char('`')) => {
self.mode = !self.mode; self.mode = !self.mode;
}, },
key!(KeyCode::Enter) => { self.entered = true; },
key!(KeyCode::Esc) => { self.entered = false; },
key!(KeyCode::Up) => match self.entered { key!(KeyCode::Up) => match self.entered {
true => { self.note_axis.point_dec(); }, true => { self.note_axis.point_dec(); },
false => { self.note_axis.start_dec(); }, false => { self.note_axis.start_dec(); },

View file

@ -20,9 +20,9 @@ impl Content for PhrasePool<Tui> {
let Phrase { ref name, color, length, .. } = *phrase.read().unwrap(); let Phrase { ref name, color, length, .. } = *phrase.read().unwrap();
let row1 = lay!(format!(" {i}").align_w().fill_x(), let row1 = lay!(format!(" {i}").align_w().fill_x(),
if let Some(PhrasePoolMode::Length(phrase, length, focus)) = self.mode { if let Some(PhrasePoolMode::Length(phrase, new_length, focus)) = self.mode {
if self.focused && i == phrase { if self.focused && i == phrase {
PhraseLength::new(length, Some(focus)) PhraseLength::new(new_length, Some(focus))
} else { } else {
PhraseLength::new(length, None) PhraseLength::new(length, None)
} }
@ -71,25 +71,25 @@ impl Content for PhrasePool<Tui> {
impl Content for PhraseEditor<Tui> { impl Content for PhraseEditor<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 field_bg = Color::Rgb(28, 35, 25);
let toolbar = Stack::down(move|add|{ //let toolbar = Stack::down(move|add|{
//let name = format!("{:>9}", 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)))?; ////add(&col!("Track:", TuiStyle::bg(name.as_str(), field_bg)))?;
if let Some(phrase) = &self.phrase { //if let Some(phrase) = &self.phrase {
let phrase = phrase.read().unwrap(); //let phrase = phrase.read().unwrap();
let length = format!("{}q{}p", phrase.length / PPQ, phrase.length % PPQ); //let length = format!("{}q{}p", phrase.length / PPQ, phrase.length % PPQ);
let length = format!("{:>9}", &length); //let length = format!("{:>9}", &length);
let loop_on = format!("{:>9}", if phrase.loop_on { "on" } else { "off" }); //let loop_on = format!("{:>9}", if phrase.loop_on { "on" } else { "off" });
let loop_start = format!("{:>9}", phrase.loop_start); //let loop_start = format!("{:>9}", phrase.loop_start);
let loop_end = format!("{:>9}", phrase.loop_length); //let loop_end = format!("{:>9}", phrase.loop_length);
add(&"")?; //add(&"")?;
add(&col!("Length:", TuiStyle::bg(length.as_str(), field_bg)))?; //add(&col!("Length:", TuiStyle::bg(length.as_str(), field_bg)))?;
add(&col!("Loop:", TuiStyle::bg(loop_on.as_str(), field_bg)))?; //add(&col!("Loop:", TuiStyle::bg(loop_on.as_str(), field_bg)))?;
add(&col!("L. start:", TuiStyle::bg(loop_start.as_str(), field_bg)))?; //add(&col!("L. start:", TuiStyle::bg(loop_start.as_str(), field_bg)))?;
add(&col!("L. length:", TuiStyle::bg(loop_end.as_str(), field_bg)))?; //add(&col!("L. length:", TuiStyle::bg(loop_end.as_str(), field_bg)))?;
} //}
Ok(()) //Ok(())
}).min_x(10); //}).min_x(10);
let piano_roll = lay!( let piano_roll = lay!(
// keys // keys
CustomWidget::new(|_|Ok(Some([32u16,4u16])), |to: &mut TuiOutput|{ CustomWidget::new(|_|Ok(Some([32u16,4u16])), |to: &mut TuiOutput|{
@ -137,12 +137,14 @@ impl Content for PhraseEditor<Tui> {
}).fill_x(), }).fill_x(),
// note cursor // note cursor
CustomWidget::new(|_|Ok(Some([1u16,1u16])), |to: &mut TuiOutput|{ CustomWidget::new(|_|Ok(Some([1u16,1u16])), |to: &mut TuiOutput|{
let area = to.area(); if self.entered {
if let (Some(time), Some(note)) = (self.time_axis.point, self.note_axis.point) { let area = to.area();
let x = area.x() + Self::H_KEYS_OFFSET as u16 + time as u16; if let (Some(time), Some(note)) = (self.time_axis.point, self.note_axis.point) {
let y = area.y() + 1 + note as u16 / 2; let x = area.x() + Self::H_KEYS_OFFSET as u16 + time as u16;
let c = if note % 2 == 0 { "" } else { "" }; let y = area.y() + 1 + note as u16 / 2;
to.blit(&c, x, y, self.style_focus()); let c = if note % 2 == 0 { "" } else { "" };
to.blit(&c, x, y, self.style_focus());
}
} }
Ok(()) Ok(())
}), }),
@ -158,7 +160,7 @@ impl Content for PhraseEditor<Tui> {
)) ))
}), }),
); );
let content = row!(toolbar, piano_roll) let content = row!(piano_roll)
.fill_x() .fill_x()
.bg(Color::Rgb(40, 50, 30)) .bg(Color::Rgb(40, 50, 30))
.border(Lozenge(Style::default() .border(Lozenge(Style::default()