From 321490bbb4607f0513652a9e5cf19b27e8d91813 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Tue, 5 Oct 2021 11:17:19 -0700 Subject: [PATCH] Allow loading multiple images at once --- RedBookPlayer.GUI/ViewModels/MainViewModel.cs | 27 ++++++++-- .../ViewModels/PlayerViewModel.cs | 42 ++++++++++++--- RedBookPlayer.Models/Hardware/Player.cs | 51 +++++++++++++++++++ 3 files changed, 108 insertions(+), 12 deletions(-) diff --git a/RedBookPlayer.GUI/ViewModels/MainViewModel.cs b/RedBookPlayer.GUI/ViewModels/MainViewModel.cs index 06d6099..79a8ef0 100644 --- a/RedBookPlayer.GUI/ViewModels/MainViewModel.cs +++ b/RedBookPlayer.GUI/ViewModels/MainViewModel.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Linq; using Avalonia.Controls; using Avalonia.Input; using RedBookPlayer.GUI.Views; @@ -163,19 +164,35 @@ namespace RedBookPlayer.GUI.ViewModels } /// - /// Load the first valid drag-and-dropped disc image + /// Load the all valid drag-and-dropped disc images /// + /// If more than the number of discs in the changer are added, it will begin to overwrite public async void ExecuteLoadDragDrop(object sender, DragEventArgs e) { if(PlayerView?.ViewModel == null) return; IEnumerable fileNames = e.Data.GetFileNames(); - foreach(string filename in fileNames) + if(fileNames == null || fileNames.Count() == 0) { - bool loaded = await PlayerView.ViewModel.LoadImage(filename); - if(loaded) - break; + return; + } + else if(fileNames.Count() == 1) + { + await PlayerView.ViewModel.LoadImage(fileNames.FirstOrDefault()); + } + else + { + int lastDisc = PlayerView.ViewModel.CurrentDisc; + foreach(string path in fileNames) + { + await PlayerView.ViewModel.LoadImage(path); + + if(PlayerView.ViewModel.Initialized) + PlayerView.ViewModel.ExecuteNextDisc(); + } + + PlayerView.ViewModel.SelectDisc(lastDisc); } } diff --git a/RedBookPlayer.GUI/ViewModels/PlayerViewModel.cs b/RedBookPlayer.GUI/ViewModels/PlayerViewModel.cs index 3a15593..2a1ac21 100644 --- a/RedBookPlayer.GUI/ViewModels/PlayerViewModel.cs +++ b/RedBookPlayer.GUI/ViewModels/PlayerViewModel.cs @@ -17,6 +17,7 @@ using RedBookPlayer.Models.Hardware; namespace RedBookPlayer.GUI.ViewModels { + // TODO: Add direct index selection by number public class PlayerViewModel : ReactiveObject { /// @@ -583,11 +584,28 @@ namespace RedBookPlayer.GUI.ViewModels /// public async void ExecuteLoad() { - string path = await GetPath(); - if(path == null) + string[] paths = await GetPaths(); + if(paths == null || paths.Length == 0) + { return; + } + else if(paths.Length == 1) + { + await LoadImage(paths[0]); + } + else + { + int lastDisc = CurrentDisc; + foreach(string path in paths) + { + await LoadImage(path); + + if(Initialized) + ExecuteNextDisc(); + } - await LoadImage(path); + SelectDisc(lastDisc); + } } /// @@ -680,6 +698,16 @@ namespace RedBookPlayer.GUI.ViewModels /// Output path to write data to public void ExtractAllTracksToWav(string outputDirectory) => _player?.ExtractAllTracksToWav(outputDirectory); + /// + /// Select a particular disc by number + /// + public void SelectDisc(int discNumber) => _player?.SelectDisc(discNumber); + + /// + /// Select a particular track by number + /// + public void SelectTrack(int trackNumber) => _player?.SelectTrack(trackNumber); + /// /// Set data playback method [CompactDisc only] /// @@ -780,12 +808,12 @@ namespace RedBookPlayer.GUI.ViewModels /// /// Generate a path selection dialog box /// - /// User-selected path, if possible - private async Task GetPath() + /// User-selected paths, if possible + private async Task GetPaths() { return await Dispatcher.UIThread.InvokeAsync(async () => { - var dialog = new OpenFileDialog { AllowMultiple = false }; + var dialog = new OpenFileDialog { AllowMultiple = true }; List knownExtensions = new Aaru.DiscImages.AaruFormat().KnownExtensions.ToList(); dialog.Filters.Add(new FileDialogFilter() { @@ -793,7 +821,7 @@ namespace RedBookPlayer.GUI.ViewModels Extensions = knownExtensions.ConvertAll(e => e.TrimStart('.')) }); - return (await dialog.ShowAsync(App.MainWindow))?.FirstOrDefault(); + return (await dialog.ShowAsync(App.MainWindow)); }); } diff --git a/RedBookPlayer.Models/Hardware/Player.cs b/RedBookPlayer.Models/Hardware/Player.cs index 0d04f33..425e5ff 100644 --- a/RedBookPlayer.Models/Hardware/Player.cs +++ b/RedBookPlayer.Models/Hardware/Player.cs @@ -6,6 +6,7 @@ using RedBookPlayer.Models.Factories; namespace RedBookPlayer.Models.Hardware { + // TODO: Add direct index selection by number public class Player : ReactiveObject { /// @@ -404,6 +405,32 @@ namespace RedBookPlayer.Models.Hardware Initialized = false; } + /// + /// Select a particular disc by number + /// + public void SelectDisc(int discNumber) + { + PlayerState wasPlaying = PlayerState; + if (wasPlaying == PlayerState.Playing) + Stop(); + + CurrentDisc = discNumber; + if (_opticalDiscs[CurrentDisc] != null && _opticalDiscs[CurrentDisc].Initialized) + { + Initialized = true; + OpticalDiscStateChanged(this, null); + SoundOutputStateChanged(this, null); + + if(wasPlaying == PlayerState.Playing) + Play(); + } + else + { + PlayerState = PlayerState.NoDisc; + Initialized = false; + } + } + /// /// Move to the next disc /// @@ -456,6 +483,30 @@ namespace RedBookPlayer.Models.Hardware } } + /// + /// Select a particular track by number + /// + public void SelectTrack(int trackNumber) + { + if(_opticalDiscs[CurrentDisc] == null || !_opticalDiscs[CurrentDisc].Initialized) + return; + + PlayerState wasPlaying = PlayerState; + if(wasPlaying == PlayerState.Playing) + Pause(); + + if(trackNumber < (HiddenTrack ? 0 : 1) || trackNumber > TotalTracks) + _opticalDiscs[CurrentDisc].LoadFirstTrack(); + else + _opticalDiscs[CurrentDisc].LoadTrack(trackNumber); + + if(_opticalDiscs[CurrentDisc] is CompactDisc compactDisc) + _soundOutputs[CurrentDisc].SetDeEmphasis(compactDisc.TrackHasEmphasis); + + if(wasPlaying == PlayerState.Playing) + Play(); + } + /// /// Move to the next playable track ///