diff --git a/audio/src/conn.rs b/audio/src/conn.rs index f460103..d155471 100644 --- a/audio/src/conn.rs +++ b/audio/src/conn.rs @@ -228,6 +228,14 @@ impl Conn { *self.export_state.lock() != ExportState::NotExporting } + /// When a new save file is loaded or a new file is opened, stop playing music if any music is playing. + pub fn on_new_file(&mut self, state: &State) { + let play_state = *self.play_state.lock(); + if let PlayState::Playing(_) = play_state { + self.stop_music(&state.music); + } + } + /// Schedule MIDI events and start to play music. fn start_music(&mut self, state: &State) { // Get the start time. diff --git a/changelog.md b/changelog.md index baa09ae..ee9027a 100644 --- a/changelog.md +++ b/changelog.md @@ -2,7 +2,8 @@ ## 0.2.2 -- There was an input bug where the play/start key (spacebar) was sometimes unresponsive for the first few presses. This is because audio was still decaying from a previous play, meaning that technically the previous play was still ongoing. I fixed it. +- Fixed: There was an input bug where the play/start key (spacebar) was sometimes unresponsive for the first few presses. This is because audio was still decaying from a previous play, meaning that technically the previous play was still ongoing. +- Fixed: When a new file is created or when a new save file loaded, the app didn't reset correctly. ## 0.2.1 diff --git a/common/src/time.rs b/common/src/time.rs index a8ff7d6..9528341 100644 --- a/common/src/time.rs +++ b/common/src/time.rs @@ -47,6 +47,11 @@ impl Time { pub fn samples_to_ppq(&self, samples: u64, framerate: f32) -> u64 { ((self.bpm.get_f() * samples as f32) / (BPM_TO_SECONDS * framerate) * PPQ_F) as u64 } + + pub fn reset(&mut self) { + self.cursor = 0; + self.playback = 0; + } } impl Default for Time { diff --git a/common/src/view.rs b/common/src/view.rs index 6fff077..0aeafc1 100644 --- a/common/src/view.rs +++ b/common/src/view.rs @@ -29,6 +29,8 @@ pub struct View { zoom_increments: HashMap, /// The default zoom index. initial_zoom_index: usize, + #[serde(skip)] + initial_dn: [u8; 2], } impl View { @@ -95,6 +97,7 @@ impl View { zoom_index, zoom_increments, initial_zoom_index, + initial_dn: dn, } } @@ -172,7 +175,20 @@ impl View { } // Get the time delta. let dt = self.zoom_levels[self.zoom_index.get()]; - self.dt = [self.dt[0], dt]; + self.dt = [self.dt[0], self.dt[0] + dt]; + } + + /// Reset the view. + pub fn reset(&mut self) { + // Reset the zoom. + self.zoom_index.set(self.initial_zoom_index); + // Reset the time. + let dt = self.zoom_levels[self.initial_zoom_index]; + self.dt = [0, dt]; + // Reset the notes. + self.dn = self.initial_dn; + // Single track view. + self.single_track = true; } /// Returns the note delta. diff --git a/io/src/lib.rs b/io/src/lib.rs index 5d4d05f..94fa381 100644 --- a/io/src/lib.rs +++ b/io/src/lib.rs @@ -282,8 +282,22 @@ impl IO { } // New file. if input.happened(&InputEvent::NewFile) { + // This prevents the previous file from being overwritten. paths_state.saves.filename = None; + // Stop playing music. + conn.on_new_file(state); + // Reset the music. state.music = Music::default(); + // Clear the selection. + state.select_mode = SelectMode::Single(None); + // Reset the view. + state.view.reset(); + // Reset the time. + state.time.reset(); + // Clear the undo/redo stacks. + self.undo.clear(); + self.redo.clear(); + state.unsaved_changes = false; } // Open file. else if input.happened(&InputEvent::OpenFile) { @@ -416,7 +430,7 @@ impl IO { false } - /// Open a save file from a path. + /// Open a save file from a path. This is called from main.rs pub fn load_save( &self, save_path: &Path, diff --git a/io/src/open_file_panel.rs b/io/src/open_file_panel.rs index 402db72..7aec5ad 100644 --- a/io/src/open_file_panel.rs +++ b/io/src/open_file_panel.rs @@ -279,6 +279,8 @@ impl Panel for OpenFilePanel { if let Some(selected) = paths_state.children.selected { // Disable the panel. self.disable(state); + // Stop the music. + conn.on_new_file(state); // Get the path. let path = paths_state.children.children[selected].path.clone(); // Read the save file.