use crate::*; impl Arranger { pub fn rename_selected (&mut self) { self.modal = Some(Box::new(ArrangerRenameModal::new( self.selected, &match self.selected { ArrangerFocus::Mix => self.name.clone(), ArrangerFocus::Track(t) => self.tracks[t].name.clone(), ArrangerFocus::Scene(s) => self.scenes[s].name.clone(), ArrangerFocus::Clip(t, s) => self.tracks[t].phrases[s].read().unwrap().name.clone(), } ))); } } /// Appears on first run (i.e. if state dir is missing). pub struct ArrangerRenameModal { done: bool, target: ArrangerFocus, value: String, result: Arc>, cursor: usize } impl ArrangerRenameModal { pub fn new (target: ArrangerFocus, value: &Arc>) -> Self { Self { done: false, target, value: value.read().unwrap().clone(), cursor: value.read().unwrap().len(), result: value.clone(), } } } impl Render for ArrangerRenameModal { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { let area = to.area(); let y = area.y() + area.h() / 2; let bg_area = [1, y - 1, area.w() - 2, 3]; to.fill_bg(bg_area, Nord::BG0); Lozenge(Style::default().bold().white().dim()).draw(to.with_rect(bg_area)); let label = match self.target { ArrangerFocus::Mix => "Rename project:", ArrangerFocus::Track(_) => "Rename track:", ArrangerFocus::Scene(_) => "Rename scene:", ArrangerFocus::Clip(_, _) => "Rename clip:", }; let style = Some(Style::default().not_bold().white().not_dim()); to.blit(&label, area.x() + 3, y, style)?; let style = Some(Style::default().bold().white().not_dim()); to.blit(&self.value, area.x() + 3 + label.len() as u16 + 1, y, style)?; let style = Some(Style::default().bold().white().not_dim().reversed()); to.blit(&"▂", area.x() + 3 + label.len() as u16 + 1 + self.cursor as u16, y, style)?; Ok(Some(area)) } } impl Handle for ArrangerRenameModal { fn handle (&mut self, from: &Tui) -> Perhaps { match from.event() { TuiEvent::Input(Event::Key(k)) => { match k.code { KeyCode::Esc => { self.exit(); }, KeyCode::Enter => { *self.result.write().unwrap() = self.value.clone(); self.exit(); }, KeyCode::Left => { self.cursor = self.cursor.saturating_sub(1); }, KeyCode::Right => { self.cursor = self.value.len().min(self.cursor + 1) }, KeyCode::Backspace => { let last = self.value.len().saturating_sub(1); self.value = format!("{}{}", &self.value[0..self.cursor.min(last)], &self.value[self.cursor.min(last)..last] ); self.cursor = self.cursor.saturating_sub(1) } KeyCode::Char(c) => { self.value.insert(self.cursor, c); self.cursor = self.value.len().min(self.cursor + 1) }, _ => {} } Ok(Some(true)) }, _ => Ok(None), } } } impl Exit for ArrangerRenameModal { fn exited (&self) -> bool { self.done } fn exit (&mut self) { self.done = true } }