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
///