mirror of
https://github.com/aaru-dps/RedBookPlayer.git
synced 2025-12-16 19:24:41 +00:00
Merge pull request #25 from mnadareski/better-theme-support
Better customizable UI support
This commit is contained in:
24
README.md
24
README.md
@@ -3,3 +3,27 @@
|
|||||||
[Audio CD](https://en.wikipedia.org/wiki/Compact_Disc_Digital_Audio) player for [Aaru format](https://github.com/aaru-dps/Aaru).
|
[Audio CD](https://en.wikipedia.org/wiki/Compact_Disc_Digital_Audio) player for [Aaru format](https://github.com/aaru-dps/Aaru).
|
||||||
|
|
||||||
* This project is fully sponsored by the [Game Preservation Society](https://www.gamepres.org/en/).
|
* This project is fully sponsored by the [Game Preservation Society](https://www.gamepres.org/en/).
|
||||||
|
|
||||||
|
## Default Player Controls
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
| --- | ------ |
|
||||||
|
| **F1** | Open Settings Window |
|
||||||
|
| **F2** | Load New Image |
|
||||||
|
| **Space** | Toggle Play / Pause |
|
||||||
|
| **Esc** | Stop Playback |
|
||||||
|
| **→** | Next Track |
|
||||||
|
| **←** | Previous Track |
|
||||||
|
| **]** | Next Index |
|
||||||
|
| **[** | Previous Index |
|
||||||
|
| **.** | Fast Forward |
|
||||||
|
| **,** | Rewind |
|
||||||
|
| **Numpad +** | Volume Up |
|
||||||
|
| **Numpad -** | Volume Down |
|
||||||
|
| **M** | Mute |
|
||||||
|
| **E** | Toggle Emphasis |
|
||||||
|
|
||||||
|
For both Volume Up and Volume Down:
|
||||||
|
- Holding **Ctrl** will move in increments of 2
|
||||||
|
- Holding **Shift** will move in increments of 5
|
||||||
|
- Holding both will move in increments of 10
|
||||||
@@ -79,8 +79,8 @@ namespace RedBookPlayer.Discs
|
|||||||
|
|
||||||
// Ensure that the value is valid, wrapping around if necessary
|
// Ensure that the value is valid, wrapping around if necessary
|
||||||
if(value > track.Indexes.Keys.Max())
|
if(value > track.Indexes.Keys.Max())
|
||||||
_currentTrackIndex = 0;
|
_currentTrackIndex = track.Indexes.Keys.Min();
|
||||||
else if(value < 0)
|
else if(value < track.Indexes.Keys.Min())
|
||||||
_currentTrackIndex = track.Indexes.Keys.Max();
|
_currentTrackIndex = track.Indexes.Keys.Max();
|
||||||
else
|
else
|
||||||
_currentTrackIndex = value;
|
_currentTrackIndex = value;
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ namespace RedBookPlayer.GUI
|
|||||||
|
|
||||||
Closing += (e, f) =>
|
Closing += (e, f) =>
|
||||||
{
|
{
|
||||||
PlayerView.Player.Stop();
|
((PlayerView)ContentControl.Content).StopButton_Click(this, null);
|
||||||
};
|
};
|
||||||
|
|
||||||
AddHandler(DragDrop.DropEvent, MainWindow_Drop);
|
AddHandler(DragDrop.DropEvent, MainWindow_Drop);
|
||||||
@@ -115,11 +115,106 @@ namespace RedBookPlayer.GUI
|
|||||||
|
|
||||||
public void OnKeyDown(object sender, KeyEventArgs e)
|
public void OnKeyDown(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
if(e.Key == Key.F1)
|
PlayerView playerView = ContentControl.Content as PlayerView;
|
||||||
|
|
||||||
|
// Open settings window
|
||||||
|
if(e.Key == App.Settings.OpenSettingsKey)
|
||||||
{
|
{
|
||||||
settingsWindow = new SettingsWindow(App.Settings);
|
settingsWindow = new SettingsWindow(App.Settings);
|
||||||
settingsWindow.Show();
|
settingsWindow.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load image
|
||||||
|
else if (e.Key == App.Settings.LoadImageKey)
|
||||||
|
{
|
||||||
|
playerView?.LoadButton_Click(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle playback
|
||||||
|
else if(e.Key == App.Settings.TogglePlaybackKey || e.Key == Key.MediaPlayPause)
|
||||||
|
{
|
||||||
|
playerView?.PlayPauseButton_Click(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop playback
|
||||||
|
else if(e.Key == App.Settings.StopPlaybackKey || e.Key == Key.MediaStop)
|
||||||
|
{
|
||||||
|
playerView?.StopButton_Click(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next Track
|
||||||
|
else if(e.Key == App.Settings.NextTrackKey || e.Key == Key.MediaNextTrack)
|
||||||
|
{
|
||||||
|
playerView?.NextTrackButton_Click(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Previous Track
|
||||||
|
else if(e.Key == App.Settings.PreviousTrackKey || e.Key == Key.MediaPreviousTrack)
|
||||||
|
{
|
||||||
|
playerView?.PreviousTrackButton_Click(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next Index
|
||||||
|
else if(e.Key == App.Settings.NextIndexKey)
|
||||||
|
{
|
||||||
|
playerView?.NextIndexButton_Click(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Previous Index
|
||||||
|
else if(e.Key == App.Settings.PreviousIndexKey)
|
||||||
|
{
|
||||||
|
playerView?.PreviousIndexButton_Click(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fast Foward
|
||||||
|
else if(e.Key == App.Settings.FastForwardPlaybackKey)
|
||||||
|
{
|
||||||
|
playerView?.FastForwardButton_Click(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rewind
|
||||||
|
else if(e.Key == App.Settings.RewindPlaybackKey)
|
||||||
|
{
|
||||||
|
playerView?.RewindButton_Click(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Volume Up
|
||||||
|
else if(e.Key == App.Settings.VolumeUpKey || e.Key == Key.VolumeUp)
|
||||||
|
{
|
||||||
|
int increment = 1;
|
||||||
|
if(e.KeyModifiers.HasFlag(KeyModifiers.Control))
|
||||||
|
increment *= 2;
|
||||||
|
if(e.KeyModifiers.HasFlag(KeyModifiers.Shift))
|
||||||
|
increment *= 5;
|
||||||
|
|
||||||
|
if(playerView?.PlayerViewModel?.Volume != null)
|
||||||
|
playerView.PlayerViewModel.Volume += increment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Volume Down
|
||||||
|
else if(e.Key == App.Settings.VolumeDownKey || e.Key == Key.VolumeDown)
|
||||||
|
{
|
||||||
|
int decrement = 1;
|
||||||
|
if(e.KeyModifiers.HasFlag(KeyModifiers.Control))
|
||||||
|
decrement *= 2;
|
||||||
|
if(e.KeyModifiers.HasFlag(KeyModifiers.Shift))
|
||||||
|
decrement *= 5;
|
||||||
|
|
||||||
|
if (playerView?.PlayerViewModel?.Volume != null)
|
||||||
|
playerView.PlayerViewModel.Volume -= decrement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mute Toggle
|
||||||
|
else if(e.Key == App.Settings.ToggleMuteKey || e.Key == Key.VolumeMute)
|
||||||
|
{
|
||||||
|
playerView?.MuteToggleButton_Click(this, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emphasis Toggle
|
||||||
|
else if(e.Key == App.Settings.ToggleDeEmphasisKey)
|
||||||
|
{
|
||||||
|
playerView?.EnableDisableDeEmphasisButton_Click(this, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -11,16 +11,15 @@ using Avalonia.Markup.Xaml;
|
|||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
using Avalonia.Platform;
|
using Avalonia.Platform;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using RedBookPlayer.Hardware;
|
|
||||||
|
|
||||||
namespace RedBookPlayer.GUI
|
namespace RedBookPlayer.GUI
|
||||||
{
|
{
|
||||||
public class PlayerView : UserControl
|
public class PlayerView : UserControl
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Player representing the internal state
|
/// Read-only access to the view model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Player Player = new Player();
|
public PlayerViewModel PlayerViewModel => DataContext as PlayerViewModel;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set of images representing the digits for the UI
|
/// Set of images representing the digits for the UI
|
||||||
@@ -64,10 +63,10 @@ namespace RedBookPlayer.GUI
|
|||||||
/// <param name="path">Path to the image to load</param>
|
/// <param name="path">Path to the image to load</param>
|
||||||
public async Task<bool> LoadImage(string path)
|
public async Task<bool> LoadImage(string path)
|
||||||
{
|
{
|
||||||
bool result = await Task.Run(() =>
|
bool result = await Dispatcher.UIThread.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
Player.Init(path, App.Settings.AutoPlay);
|
PlayerViewModel.Init(path, App.Settings.AutoPlay, App.Settings.Volume);
|
||||||
return Player.Initialized;
|
return PlayerViewModel.Initialized;
|
||||||
});
|
});
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
@@ -114,10 +113,17 @@ namespace RedBookPlayer.GUI
|
|||||||
DataContext = new PlayerViewModel();
|
DataContext = new PlayerViewModel();
|
||||||
|
|
||||||
// Load the theme
|
// Load the theme
|
||||||
|
try
|
||||||
|
{
|
||||||
if(xaml != null)
|
if(xaml != null)
|
||||||
new AvaloniaXamlLoader().Load(xaml, null, this);
|
new AvaloniaXamlLoader().Load(xaml, null, this);
|
||||||
else
|
else
|
||||||
AvaloniaXamlLoader.Load(this);
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
InitializeDigits();
|
InitializeDigits();
|
||||||
|
|
||||||
@@ -181,14 +187,14 @@ namespace RedBookPlayer.GUI
|
|||||||
{
|
{
|
||||||
Dispatcher.UIThread.InvokeAsync(() =>
|
Dispatcher.UIThread.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
string digitString = Player.GenerateDigitString();
|
string digitString = PlayerViewModel.GenerateDigitString();
|
||||||
for (int i = 0; i < _digits.Length; i++)
|
for (int i = 0; i < _digits.Length; i++)
|
||||||
{
|
{
|
||||||
if (_digits[i] != null)
|
if (_digits[i] != null)
|
||||||
_digits[i].Source = GetBitmap(digitString[i]);
|
_digits[i].Source = GetBitmap(digitString[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Player.UpdateDataContext(DataContext as PlayerViewModel);
|
PlayerViewModel?.UpdateView();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,32 +208,40 @@ namespace RedBookPlayer.GUI
|
|||||||
if (path == null)
|
if (path == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LoadImage(path);
|
await LoadImage(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PlayButton_Click(object sender, RoutedEventArgs e) => Player.TogglePlayPause(true);
|
public void PlayButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Playing = true;
|
||||||
|
|
||||||
public void PauseButton_Click(object sender, RoutedEventArgs e) => Player.TogglePlayPause(false);
|
public void PauseButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Playing = false;
|
||||||
|
|
||||||
public void PlayPauseButton_Click(object sender, RoutedEventArgs e) => Player.TogglePlayPause(!Player.Playing);
|
public void PlayPauseButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Playing = !(PlayerViewModel.Playing ?? false);
|
||||||
|
|
||||||
public void StopButton_Click(object sender, RoutedEventArgs e) => Player.Stop();
|
public void StopButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Playing = null;
|
||||||
|
|
||||||
public void NextTrackButton_Click(object sender, RoutedEventArgs e) => Player.NextTrack();
|
public void NextTrackButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.NextTrack();
|
||||||
|
|
||||||
public void PreviousTrackButton_Click(object sender, RoutedEventArgs e) => Player.PreviousTrack();
|
public void PreviousTrackButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousTrack();
|
||||||
|
|
||||||
public void NextIndexButton_Click(object sender, RoutedEventArgs e) => Player.NextIndex(App.Settings.IndexButtonChangeTrack);
|
public void NextIndexButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.NextIndex(App.Settings.IndexButtonChangeTrack);
|
||||||
|
|
||||||
public void PreviousIndexButton_Click(object sender, RoutedEventArgs e) => Player.PreviousIndex(App.Settings.IndexButtonChangeTrack);
|
public void PreviousIndexButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousIndex(App.Settings.IndexButtonChangeTrack);
|
||||||
|
|
||||||
public void FastForwardButton_Click(object sender, RoutedEventArgs e) => Player.FastForward();
|
public void FastForwardButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.FastForward();
|
||||||
|
|
||||||
public void RewindButton_Click(object sender, RoutedEventArgs e) => Player.Rewind();
|
public void RewindButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Rewind();
|
||||||
|
|
||||||
public void EnableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => Player.ToggleDeEmphasis(true);
|
public void VolumeUpButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Volume++;
|
||||||
|
|
||||||
public void DisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => Player.ToggleDeEmphasis(false);
|
public void VolumeDownButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Volume--;
|
||||||
|
|
||||||
|
public void MuteToggleButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.ToggleMute();
|
||||||
|
|
||||||
|
public void EnableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.ApplyDeEmphasis = true;
|
||||||
|
|
||||||
|
public void DisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.ApplyDeEmphasis = false;
|
||||||
|
|
||||||
|
public void EnableDisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.ApplyDeEmphasis = !PlayerViewModel.ApplyDeEmphasis;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,98 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Aaru.CommonTypes.Enums;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
|
using RedBookPlayer.Discs;
|
||||||
|
using RedBookPlayer.Hardware;
|
||||||
|
|
||||||
namespace RedBookPlayer.GUI
|
namespace RedBookPlayer.GUI
|
||||||
{
|
{
|
||||||
public class PlayerViewModel : ReactiveObject
|
public class PlayerViewModel : ReactiveObject
|
||||||
{
|
{
|
||||||
private bool _applyDeEmphasis;
|
/// <summary>
|
||||||
|
/// Player representing the internal state
|
||||||
|
/// </summary>
|
||||||
|
private Player _player;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Last volume for mute toggling
|
||||||
|
/// </summary>
|
||||||
|
private int? _lastVolume = null;
|
||||||
|
|
||||||
|
#region Player Status
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicate if the model is ready to be used
|
||||||
|
/// </summary>
|
||||||
|
public bool Initialized => _player?.Initialized ?? false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicate the player state
|
||||||
|
/// </summary>
|
||||||
|
public bool? Playing
|
||||||
|
{
|
||||||
|
get => _player?.Playing ?? false;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if(_player != null)
|
||||||
|
_player.Playing = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicate the current playback volume
|
||||||
|
/// </summary>
|
||||||
|
public int Volume
|
||||||
|
{
|
||||||
|
get => _player?.Volume ?? 100;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if(_player != null)
|
||||||
|
_player.Volume = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates if de-emphasis should be applied
|
||||||
|
/// </summary>
|
||||||
public bool ApplyDeEmphasis
|
public bool ApplyDeEmphasis
|
||||||
{
|
{
|
||||||
get => _applyDeEmphasis;
|
get => _player?.ApplyDeEmphasis ?? false;
|
||||||
set => this.RaiseAndSetIfChanged(ref _applyDeEmphasis, value);
|
set
|
||||||
|
{
|
||||||
|
if(_player != null)
|
||||||
|
_player.ApplyDeEmphasis = value;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Model-Provided Playback Information
|
||||||
|
|
||||||
|
private ulong _currentSector;
|
||||||
|
public ulong CurrentSector
|
||||||
|
{
|
||||||
|
get => _currentSector;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _currentSector, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CurrentFrame => (int)(_currentSector / (75 * 60));
|
||||||
|
public int CurrentSecond => (int)(_currentSector / 75 % 60);
|
||||||
|
public int CurrentMinute => (int)(_currentSector % 75);
|
||||||
|
|
||||||
|
private ulong _totalSectors;
|
||||||
|
public ulong TotalSectors
|
||||||
|
{
|
||||||
|
get => _totalSectors;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _totalSectors, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int TotalFrames => (int)(_totalSectors / (75 * 60));
|
||||||
|
public int TotalSeconds => (int)(_totalSectors / 75 % 60);
|
||||||
|
public int TotalMinutes => (int)(_totalSectors % 75);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Disc Flags
|
||||||
|
|
||||||
private bool _quadChannel;
|
private bool _quadChannel;
|
||||||
public bool QuadChannel
|
public bool QuadChannel
|
||||||
@@ -45,5 +128,143 @@ namespace RedBookPlayer.GUI
|
|||||||
get => _hiddenTrack;
|
get => _hiddenTrack;
|
||||||
set => this.RaiseAndSetIfChanged(ref _hiddenTrack, value);
|
set => this.RaiseAndSetIfChanged(ref _hiddenTrack, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize the view model with a given image path
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Path to the disc image</param>
|
||||||
|
/// <param name="autoPlay">True if playback should begin immediately, false otherwise</param>
|
||||||
|
/// <param name="defaultVolume">Default volume between 0 and 100 to use when starting playback</param>
|
||||||
|
public void Init(string path, bool autoPlay, int defaultVolume)
|
||||||
|
{
|
||||||
|
// Stop current playback, if necessary
|
||||||
|
if(Playing != null) Playing = null;
|
||||||
|
|
||||||
|
// Create and attempt to initialize new Player
|
||||||
|
_player = new Player(path, autoPlay, defaultVolume);
|
||||||
|
if(Initialized)
|
||||||
|
UpdateView();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Playback
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Move to the next playable track
|
||||||
|
/// </summary>
|
||||||
|
public void NextTrack() => _player?.NextTrack();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Move to the previous playable track
|
||||||
|
/// </summary>
|
||||||
|
public void PreviousTrack() => _player?.PreviousTrack();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Move to the next index
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="changeTrack">True if index changes can trigger a track change, false otherwise</param>
|
||||||
|
public void NextIndex(bool changeTrack) => _player?.NextIndex(changeTrack);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Move to the previous index
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="changeTrack">True if index changes can trigger a track change, false otherwise</param>
|
||||||
|
public void PreviousIndex(bool changeTrack) => _player?.PreviousIndex(changeTrack);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fast-forward playback by 75 sectors, if possible
|
||||||
|
/// </summary>
|
||||||
|
public void FastForward() => _player?.FastForward();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rewind playback by 75 sectors, if possible
|
||||||
|
/// </summary>
|
||||||
|
public void Rewind() => _player?.Rewind();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Helpers
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate the digit string to be interpreted by the frontend
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>String representing the digits for the frontend</returns>
|
||||||
|
public string GenerateDigitString()
|
||||||
|
{
|
||||||
|
// If the disc isn't initialized, return all '-' characters
|
||||||
|
if(_player?.OpticalDisc == null || !_player.OpticalDisc.Initialized)
|
||||||
|
return string.Empty.PadLeft(20, '-');
|
||||||
|
|
||||||
|
// Otherwise, take the current time into account
|
||||||
|
ulong sectorTime = _player.GetCurrentSectorTime();
|
||||||
|
|
||||||
|
int[] numbers = new int[]
|
||||||
|
{
|
||||||
|
_player.OpticalDisc.CurrentTrackNumber + 1,
|
||||||
|
_player.OpticalDisc.CurrentTrackIndex,
|
||||||
|
|
||||||
|
(int)(sectorTime / (75 * 60)),
|
||||||
|
(int)(sectorTime / 75 % 60),
|
||||||
|
(int)(sectorTime % 75),
|
||||||
|
|
||||||
|
_player.OpticalDisc.TotalTracks,
|
||||||
|
_player.OpticalDisc.TotalIndexes,
|
||||||
|
|
||||||
|
(int)(_player.OpticalDisc.TotalTime / (75 * 60)),
|
||||||
|
(int)(_player.OpticalDisc.TotalTime / 75 % 60),
|
||||||
|
(int)(_player.OpticalDisc.TotalTime % 75),
|
||||||
|
};
|
||||||
|
|
||||||
|
return string.Join("", numbers.Select(i => i.ToString().PadLeft(2, '0').Substring(0, 2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Temporarily mute playback
|
||||||
|
/// </summary>
|
||||||
|
public void ToggleMute()
|
||||||
|
{
|
||||||
|
if(_lastVolume == null)
|
||||||
|
{
|
||||||
|
_lastVolume = Volume;
|
||||||
|
Volume = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Volume = _lastVolume.Value;
|
||||||
|
_lastVolume = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update the UI from the internal player
|
||||||
|
/// </summary>
|
||||||
|
public void UpdateView()
|
||||||
|
{
|
||||||
|
if(_player?.Initialized != true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CurrentSector = _player.GetCurrentSectorTime();
|
||||||
|
TotalSectors = _player.OpticalDisc.TotalTime;
|
||||||
|
|
||||||
|
HiddenTrack = _player.OpticalDisc.TimeOffset > 150;
|
||||||
|
|
||||||
|
if(_player.OpticalDisc is CompactDisc compactDisc)
|
||||||
|
{
|
||||||
|
QuadChannel = compactDisc.QuadChannel;
|
||||||
|
IsDataTrack = compactDisc.IsDataTrack;
|
||||||
|
CopyAllowed = compactDisc.CopyAllowed;
|
||||||
|
TrackHasEmphasis = compactDisc.TrackHasEmphasis;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QuadChannel = false;
|
||||||
|
IsDataTrack = _player.OpticalDisc.TrackType != TrackType.Audio;
|
||||||
|
CopyAllowed = false;
|
||||||
|
TrackHasEmphasis = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800"
|
||||||
d:DesignHeight="450" x:Class="RedBookPlayer.GUI.SettingsWindow" Title="Settings" Width="450" Height="600">
|
d:DesignHeight="450" x:Class="RedBookPlayer.GUI.SettingsWindow" Title="Settings" SizeToContent="WidthAndHeight">
|
||||||
|
<StackPanel>
|
||||||
|
<TabControl>
|
||||||
|
<TabItem Header="UI Settings">
|
||||||
<DockPanel Margin="16">
|
<DockPanel Margin="16">
|
||||||
<TextBlock DockPanel.Dock="Top" Margin="0,0,0,4">Themes</TextBlock>
|
<TextBlock DockPanel.Dock="Top" Margin="0,0,0,4">Themes</TextBlock>
|
||||||
<StackPanel DockPanel.Dock="Bottom">
|
<StackPanel DockPanel.Dock="Bottom">
|
||||||
@@ -26,15 +29,94 @@
|
|||||||
<TextBlock VerticalAlignment="Center">Generate a TOC if the disc is missing one</TextBlock>
|
<TextBlock VerticalAlignment="Center">Generate a TOC if the disc is missing one</TextBlock>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<DockPanel Margin="0,0,0,16">
|
<DockPanel Margin="0,0,0,16">
|
||||||
<TextBlock VerticalAlignment="Center" Margin="0,0,8,0" DockPanel.Dock="Left">Volume</TextBlock>
|
<TextBlock VerticalAlignment="Center" Margin="0,0,8,0" DockPanel.Dock="Left">Default Volume</TextBlock>
|
||||||
<TextBlock VerticalAlignment="Center" DockPanel.Dock="Right" Text="%" />
|
<TextBlock VerticalAlignment="Center" DockPanel.Dock="Right" Text="%" />
|
||||||
<TextBlock VerticalAlignment="Center" Margin="8,0,0,0" DockPanel.Dock="Right" Text="{Binding Volume}"
|
<TextBlock VerticalAlignment="Center" Margin="8,0,0,0" DockPanel.Dock="Right" Text="{Binding Volume}"
|
||||||
Name="VolumeLabel" />
|
Name="VolumeLabel" />
|
||||||
<Slider Minimum="0" Maximum="100" SmallChange="1" LargeChange="10" Value="{Binding Volume}"
|
<Slider Minimum="0" Maximum="100" SmallChange="1" LargeChange="10" Value="{Binding Volume}"
|
||||||
Name="VolumeSlider" />
|
Name="VolumeSlider" />
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
<Button Name="ApplyButton">Apply</Button>
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<ListBox Name="ThemeList" SelectionMode="Single" Margin="0,0,0,16" />
|
<ListBox Name="ThemeList" SelectionMode="Single" Margin="0,0,0,16" />
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
|
</TabItem>
|
||||||
|
<TabItem Header="Keyboard Bindings">
|
||||||
|
<Grid Margin="16">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- Load Image-->
|
||||||
|
<TextBlock Grid.Row="0" Grid.Column="0" Width="120">Load Image</TextBlock>
|
||||||
|
<ComboBox Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Name="LoadImageKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||||
|
|
||||||
|
<!-- Toggle Play/Pause -->
|
||||||
|
<TextBlock Grid.Row="1" Grid.Column="0" Width="120">Toggle Play/Pause</TextBlock>
|
||||||
|
<ComboBox Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Name="TogglePlaybackKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||||
|
|
||||||
|
<!-- Stop Playback-->
|
||||||
|
<TextBlock Grid.Row="2" Grid.Column="0" Width="120">Stop Playback</TextBlock>
|
||||||
|
<ComboBox Grid.Row="2" Grid.Column="1" HorizontalAlignment="Right" Name="StopPlaybackKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||||
|
|
||||||
|
<!-- Next Track -->
|
||||||
|
<TextBlock Grid.Row="3" Grid.Column="0" Width="120">Next Track</TextBlock>
|
||||||
|
<ComboBox Grid.Row="3" Grid.Column="1" HorizontalAlignment="Right" Name="NextTrackKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||||
|
|
||||||
|
<!-- Previous Track -->
|
||||||
|
<TextBlock Grid.Row="4" Grid.Column="0" Width="120">Previous Track</TextBlock>
|
||||||
|
<ComboBox Grid.Row="4" Grid.Column="1" HorizontalAlignment="Right" Name="PreviousTrackKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||||
|
|
||||||
|
<!-- Next Index -->
|
||||||
|
<TextBlock Grid.Row="5" Grid.Column="0" Width="120">Next Index</TextBlock>
|
||||||
|
<ComboBox Grid.Row="5" Grid.Column="1" HorizontalAlignment="Right" Name="NextIndexKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||||
|
|
||||||
|
<!-- Previous Index -->
|
||||||
|
<TextBlock Grid.Row="6" Grid.Column="0" Width="120">Previous Index</TextBlock>
|
||||||
|
<ComboBox Grid.Row="6" Grid.Column="1" HorizontalAlignment="Right" Name="PreviousIndexKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||||
|
|
||||||
|
<!-- Fast Forward -->
|
||||||
|
<TextBlock Grid.Row="7" Grid.Column="0" Width="120">Fast-Forward</TextBlock>
|
||||||
|
<ComboBox Grid.Row="7" Grid.Column="1" HorizontalAlignment="Right" Name="FastForwardPlaybackKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||||
|
|
||||||
|
<!-- Rewind -->
|
||||||
|
<TextBlock Grid.Row="8" Grid.Column="0" Width="120">Rewind</TextBlock>
|
||||||
|
<ComboBox Grid.Row="8" Grid.Column="1" HorizontalAlignment="Right" Name="RewindPlaybackKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||||
|
|
||||||
|
<!-- Volume Up -->
|
||||||
|
<TextBlock Grid.Row="9" Grid.Column="0" Width="120">Volume Up</TextBlock>
|
||||||
|
<ComboBox Grid.Row="9" Grid.Column="1" HorizontalAlignment="Right" Name="VolumeUpKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||||
|
|
||||||
|
<!-- Volume Down -->
|
||||||
|
<TextBlock Grid.Row="10" Grid.Column="0" Width="120">Volume Down</TextBlock>
|
||||||
|
<ComboBox Grid.Row="10" Grid.Column="1" HorizontalAlignment="Right" Name="VolumeDownKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||||
|
|
||||||
|
<!-- Mute Toggle -->
|
||||||
|
<TextBlock Grid.Row="11" Grid.Column="0" Width="120">Toggle Mute</TextBlock>
|
||||||
|
<ComboBox Grid.Row="11" Grid.Column="1" HorizontalAlignment="Right" Name="ToggleMuteKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||||
|
|
||||||
|
<!-- De-Emphasis Toggle -->
|
||||||
|
<TextBlock Grid.Row="12" Grid.Column="0" Width="120">Toggle De-Emphasis</TextBlock>
|
||||||
|
<ComboBox Grid.Row="12" Grid.Column="1" HorizontalAlignment="Right" Name="ToggleDeEmphasisKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||||
|
</Grid>
|
||||||
|
</TabItem>
|
||||||
|
</TabControl>
|
||||||
|
<Button Name="ApplyButton">Apply</Button>
|
||||||
|
</StackPanel>
|
||||||
</Window>
|
</Window>
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Input;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
|
|
||||||
@@ -36,6 +38,7 @@ namespace RedBookPlayer.GUI
|
|||||||
MainWindow.ApplyTheme(_selectedTheme);
|
MainWindow.ApplyTheme(_selectedTheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SaveKeyboardList();
|
||||||
_settings.Save();
|
_settings.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,6 +49,7 @@ namespace RedBookPlayer.GUI
|
|||||||
AvaloniaXamlLoader.Load(this);
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
|
||||||
PopulateThemes();
|
PopulateThemes();
|
||||||
|
PopulateKeyboardList();
|
||||||
|
|
||||||
this.FindControl<Button>("ApplyButton").Click += ApplySettings;
|
this.FindControl<Button>("ApplyButton").Click += ApplySettings;
|
||||||
this.FindControl<Slider>("VolumeSlider").PropertyChanged += (s, e) => UpdateView();
|
this.FindControl<Slider>("VolumeSlider").PropertyChanged += (s, e) => UpdateView();
|
||||||
@@ -81,5 +85,102 @@ namespace RedBookPlayer.GUI
|
|||||||
|
|
||||||
_themeList.Items = items;
|
_themeList.Items = items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Populate all of the keyboard bindings
|
||||||
|
/// </summary>
|
||||||
|
private void PopulateKeyboardList()
|
||||||
|
{
|
||||||
|
// Access all of the combo boxes
|
||||||
|
ComboBox loadImageKeyBind = this.FindControl<ComboBox>("LoadImageKeyBind");
|
||||||
|
ComboBox togglePlaybackKeyBind = this.FindControl<ComboBox>("TogglePlaybackKeyBind");
|
||||||
|
ComboBox stopPlaybackKeyBind = this.FindControl<ComboBox>("StopPlaybackKeyBind");
|
||||||
|
ComboBox nextTrackKeyBind = this.FindControl<ComboBox>("NextTrackKeyBind");
|
||||||
|
ComboBox previousTrackKeyBind = this.FindControl<ComboBox>("PreviousTrackKeyBind");
|
||||||
|
ComboBox nextIndexKeyBind = this.FindControl<ComboBox>("NextIndexKeyBind");
|
||||||
|
ComboBox previousIndexKeyBind = this.FindControl<ComboBox>("PreviousIndexKeyBind");
|
||||||
|
ComboBox fastForwardPlaybackKeyBind = this.FindControl<ComboBox>("FastForwardPlaybackKeyBind");
|
||||||
|
ComboBox rewindPlaybackKeyBind = this.FindControl<ComboBox>("RewindPlaybackKeyBind");
|
||||||
|
ComboBox volumeUpKeyBind = this.FindControl<ComboBox>("VolumeUpKeyBind");
|
||||||
|
ComboBox volumeDownKeyBind = this.FindControl<ComboBox>("VolumeDownKeyBind");
|
||||||
|
ComboBox toggleMuteKeyBind = this.FindControl<ComboBox>("ToggleMuteKeyBind");
|
||||||
|
ComboBox toggleDeEmphasisKeyBind = this.FindControl<ComboBox>("ToggleDeEmphasisKeyBind");
|
||||||
|
|
||||||
|
// Assign the list of values to all of them
|
||||||
|
Array keyboardList = GenerateKeyboardList();
|
||||||
|
loadImageKeyBind.Items = keyboardList;
|
||||||
|
togglePlaybackKeyBind.Items = keyboardList;
|
||||||
|
stopPlaybackKeyBind.Items = keyboardList;
|
||||||
|
nextTrackKeyBind.Items = keyboardList;
|
||||||
|
previousTrackKeyBind.Items = keyboardList;
|
||||||
|
nextIndexKeyBind.Items = keyboardList;
|
||||||
|
previousIndexKeyBind.Items = keyboardList;
|
||||||
|
fastForwardPlaybackKeyBind.Items = keyboardList;
|
||||||
|
rewindPlaybackKeyBind.Items = keyboardList;
|
||||||
|
volumeUpKeyBind.Items = keyboardList;
|
||||||
|
volumeDownKeyBind.Items = keyboardList;
|
||||||
|
toggleMuteKeyBind.Items = keyboardList;
|
||||||
|
toggleDeEmphasisKeyBind.Items = keyboardList;
|
||||||
|
|
||||||
|
// Set all of the currently selected items
|
||||||
|
loadImageKeyBind.SelectedItem = _settings.LoadImageKey;
|
||||||
|
togglePlaybackKeyBind.SelectedItem = _settings.TogglePlaybackKey;
|
||||||
|
stopPlaybackKeyBind.SelectedItem = _settings.StopPlaybackKey;
|
||||||
|
nextTrackKeyBind.SelectedItem = _settings.NextTrackKey;
|
||||||
|
previousTrackKeyBind.SelectedItem = _settings.PreviousTrackKey;
|
||||||
|
nextIndexKeyBind.SelectedItem = _settings.NextIndexKey;
|
||||||
|
previousIndexKeyBind.SelectedItem = _settings.PreviousIndexKey;
|
||||||
|
fastForwardPlaybackKeyBind.SelectedItem = _settings.FastForwardPlaybackKey;
|
||||||
|
rewindPlaybackKeyBind.SelectedItem = _settings.RewindPlaybackKey;
|
||||||
|
volumeUpKeyBind.SelectedItem = _settings.VolumeUpKey;
|
||||||
|
volumeDownKeyBind.SelectedItem = _settings.VolumeDownKey;
|
||||||
|
toggleMuteKeyBind.SelectedItem = _settings.ToggleMuteKey;
|
||||||
|
toggleDeEmphasisKeyBind.SelectedItem = _settings.ToggleDeEmphasisKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Save back all values from keyboard bindings
|
||||||
|
/// </summary>
|
||||||
|
private void SaveKeyboardList()
|
||||||
|
{
|
||||||
|
// Access all of the combo boxes
|
||||||
|
ComboBox loadImageKeyBind = this.FindControl<ComboBox>("LoadImageKeyBind");
|
||||||
|
ComboBox togglePlaybackKeyBind = this.FindControl<ComboBox>("TogglePlaybackKeyBind");
|
||||||
|
ComboBox stopPlaybackKeyBind = this.FindControl<ComboBox>("StopPlaybackKeyBind");
|
||||||
|
ComboBox nextTrackKeyBind = this.FindControl<ComboBox>("NextTrackKeyBind");
|
||||||
|
ComboBox previousTrackKeyBind = this.FindControl<ComboBox>("PreviousTrackKeyBind");
|
||||||
|
ComboBox nextIndexKeyBind = this.FindControl<ComboBox>("NextIndexKeyBind");
|
||||||
|
ComboBox previousIndexKeyBind = this.FindControl<ComboBox>("PreviousIndexKeyBind");
|
||||||
|
ComboBox fastForwardPlaybackKeyBind = this.FindControl<ComboBox>("FastForwardPlaybackKeyBind");
|
||||||
|
ComboBox rewindPlaybackKeyBind = this.FindControl<ComboBox>("RewindPlaybackKeyBind");
|
||||||
|
ComboBox volumeUpKeyBind = this.FindControl<ComboBox>("VolumeUpKeyBind");
|
||||||
|
ComboBox volumeDownKeyBind = this.FindControl<ComboBox>("VolumeDownKeyBind");
|
||||||
|
ComboBox toggleMuteKeyBind = this.FindControl<ComboBox>("ToggleMuteKeyBind");
|
||||||
|
ComboBox toggleDeEmphasisKeyBind = this.FindControl<ComboBox>("ToggleDeEmphasisKeyBind");
|
||||||
|
|
||||||
|
// Set all of the currently selected items
|
||||||
|
_settings.LoadImageKey = (Key)loadImageKeyBind.SelectedItem;
|
||||||
|
_settings.TogglePlaybackKey = (Key)togglePlaybackKeyBind.SelectedItem;
|
||||||
|
_settings.StopPlaybackKey = (Key)stopPlaybackKeyBind.SelectedItem;
|
||||||
|
_settings.NextTrackKey = (Key)nextTrackKeyBind.SelectedItem;
|
||||||
|
_settings.PreviousTrackKey = (Key)previousTrackKeyBind.SelectedItem;
|
||||||
|
_settings.NextIndexKey = (Key)nextIndexKeyBind.SelectedItem;
|
||||||
|
_settings.PreviousIndexKey = (Key)previousIndexKeyBind.SelectedItem;
|
||||||
|
_settings.FastForwardPlaybackKey = (Key)fastForwardPlaybackKeyBind.SelectedItem;
|
||||||
|
_settings.RewindPlaybackKey = (Key)rewindPlaybackKeyBind.SelectedItem;
|
||||||
|
_settings.VolumeUpKey = (Key)volumeUpKeyBind.SelectedItem;
|
||||||
|
_settings.VolumeDownKey = (Key)volumeDownKeyBind.SelectedItem;
|
||||||
|
_settings.ToggleMuteKey = (Key)toggleMuteKeyBind.SelectedItem;
|
||||||
|
_settings.ToggleDeEmphasisKey = (Key)toggleDeEmphasisKeyBind.SelectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate a list of keyboard keys for mapping
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private Array GenerateKeyboardList()
|
||||||
|
{
|
||||||
|
return Enum.GetValues(typeof(Key));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using Aaru.CommonTypes.Enums;
|
|
||||||
using Aaru.DiscImages;
|
using Aaru.DiscImages;
|
||||||
using Aaru.Filters;
|
using Aaru.Filters;
|
||||||
using RedBookPlayer.Discs;
|
using RedBookPlayer.Discs;
|
||||||
using RedBookPlayer.GUI;
|
|
||||||
|
|
||||||
namespace RedBookPlayer.Hardware
|
namespace RedBookPlayer.Hardware
|
||||||
{
|
{
|
||||||
@@ -18,20 +15,69 @@ namespace RedBookPlayer.Hardware
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Initialized { get; private set; } = false;
|
public bool Initialized { get; private set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// OpticalDisc object
|
||||||
|
/// </summary>
|
||||||
|
public OpticalDisc OpticalDisc { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicate if the disc is playing
|
/// Indicate if the disc is playing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Playing => _soundOutput?.Playing ?? false;
|
public bool? Playing
|
||||||
|
{
|
||||||
|
get => _soundOutput?.Playing;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if(OpticalDisc == null || !OpticalDisc.Initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If the playing state has not changed, do nothing
|
||||||
|
if(value == _soundOutput?.Playing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(value == true)
|
||||||
|
{
|
||||||
|
_soundOutput.Play();
|
||||||
|
OpticalDisc.SetTotalIndexes();
|
||||||
|
}
|
||||||
|
else if(value == false)
|
||||||
|
{
|
||||||
|
_soundOutput.Stop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_soundOutput.Stop();
|
||||||
|
OpticalDisc.LoadFirstTrack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicate the current playback volume
|
||||||
|
/// </summary>
|
||||||
|
public int Volume
|
||||||
|
{
|
||||||
|
get => _soundOutput?.Volume ?? 100;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if(_soundOutput != null)
|
||||||
|
_soundOutput.Volume = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates if de-emphasis should be applied
|
||||||
|
/// </summary>
|
||||||
|
public bool ApplyDeEmphasis
|
||||||
|
{
|
||||||
|
get => _soundOutput?.ApplyDeEmphasis ?? false;
|
||||||
|
set => _soundOutput?.SetDeEmphasis(value);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private State Variables
|
#region Private State Variables
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// OpticalDisc object
|
|
||||||
/// </summary>
|
|
||||||
private OpticalDisc _opticalDisc;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sound output handling class
|
/// Sound output handling class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -40,17 +86,18 @@ namespace RedBookPlayer.Hardware
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize the player with a given image path
|
/// Create a new Player from a given image path
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">Path to the disc image</param>
|
/// <param name="path">Path to the disc image</param>
|
||||||
/// <param name="autoPlay">True if playback should begin immediately, false otherwise</param>
|
/// <param name="autoPlay">True if playback should begin immediately, false otherwise</param>
|
||||||
public void Init(string path, bool autoPlay = false)
|
/// <param name="defaultVolume">Default volume between 0 and 100 to use when starting playback</param>
|
||||||
|
public Player(string path, bool autoPlay = false, int defaultVolume = 100)
|
||||||
{
|
{
|
||||||
// Reset the internal state for initialization
|
// Set the internal state for initialization
|
||||||
Initialized = false;
|
Initialized = false;
|
||||||
_soundOutput = new SoundOutput();
|
_soundOutput = new SoundOutput();
|
||||||
_soundOutput.ApplyDeEmphasis = false;
|
_soundOutput.ApplyDeEmphasis = false;
|
||||||
_opticalDisc = null;
|
OpticalDisc = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -65,7 +112,7 @@ namespace RedBookPlayer.Hardware
|
|||||||
image.Open(filter);
|
image.Open(filter);
|
||||||
|
|
||||||
// Generate and instantiate the disc
|
// Generate and instantiate the disc
|
||||||
_opticalDisc = OpticalDiscFactory.GenerateFromImage(image, App.Settings.AutoPlay);
|
OpticalDisc = OpticalDiscFactory.GenerateFromImage(image, autoPlay);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -74,7 +121,7 @@ namespace RedBookPlayer.Hardware
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the sound output
|
// Initialize the sound output
|
||||||
_soundOutput.Init(_opticalDisc, autoPlay);
|
_soundOutput.Init(OpticalDisc, autoPlay, defaultVolume);
|
||||||
if(_soundOutput == null || !_soundOutput.Initialized)
|
if(_soundOutput == null || !_soundOutput.Initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -84,54 +131,22 @@ namespace RedBookPlayer.Hardware
|
|||||||
|
|
||||||
#region Playback
|
#region Playback
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Toggle audio playback
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="start">True to start playback, false to pause</param>
|
|
||||||
public void TogglePlayPause(bool start)
|
|
||||||
{
|
|
||||||
if(_opticalDisc == null || !_opticalDisc.Initialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(start)
|
|
||||||
{
|
|
||||||
_soundOutput.Play();
|
|
||||||
_opticalDisc.SetTotalIndexes();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_soundOutput.Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Stop the current audio playback
|
|
||||||
/// </summary>
|
|
||||||
public void Stop()
|
|
||||||
{
|
|
||||||
if(_opticalDisc == null || !_opticalDisc.Initialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_soundOutput.Stop();
|
|
||||||
_opticalDisc.LoadFirstTrack();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Move to the next playable track
|
/// Move to the next playable track
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void NextTrack()
|
public void NextTrack()
|
||||||
{
|
{
|
||||||
if(_opticalDisc == null || !_opticalDisc.Initialized)
|
if(OpticalDisc == null || !OpticalDisc.Initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool wasPlaying = Playing;
|
bool? wasPlaying = Playing;
|
||||||
if(wasPlaying) TogglePlayPause(false);
|
if(wasPlaying == true) Playing = false;
|
||||||
|
|
||||||
_opticalDisc.NextTrack();
|
OpticalDisc.NextTrack();
|
||||||
if(_opticalDisc is CompactDisc compactDisc)
|
if(OpticalDisc is CompactDisc compactDisc)
|
||||||
_soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis;
|
_soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis;
|
||||||
|
|
||||||
if(wasPlaying) TogglePlayPause(true);
|
if(wasPlaying == true) Playing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -139,17 +154,17 @@ namespace RedBookPlayer.Hardware
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void PreviousTrack()
|
public void PreviousTrack()
|
||||||
{
|
{
|
||||||
if(_opticalDisc == null || !_opticalDisc.Initialized)
|
if(OpticalDisc == null || !OpticalDisc.Initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool wasPlaying = Playing;
|
bool? wasPlaying = Playing;
|
||||||
if(wasPlaying) TogglePlayPause(false);
|
if(wasPlaying == true) Playing = false;
|
||||||
|
|
||||||
_opticalDisc.PreviousTrack();
|
OpticalDisc.PreviousTrack();
|
||||||
if(_opticalDisc is CompactDisc compactDisc)
|
if(OpticalDisc is CompactDisc compactDisc)
|
||||||
_soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis;
|
_soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis;
|
||||||
|
|
||||||
if(wasPlaying) TogglePlayPause(true);
|
if(wasPlaying == true) Playing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -158,17 +173,17 @@ namespace RedBookPlayer.Hardware
|
|||||||
/// <param name="changeTrack">True if index changes can trigger a track change, false otherwise</param>
|
/// <param name="changeTrack">True if index changes can trigger a track change, false otherwise</param>
|
||||||
public void NextIndex(bool changeTrack)
|
public void NextIndex(bool changeTrack)
|
||||||
{
|
{
|
||||||
if(_opticalDisc == null || !_opticalDisc.Initialized)
|
if(OpticalDisc == null || !OpticalDisc.Initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool wasPlaying = Playing;
|
bool? wasPlaying = Playing;
|
||||||
if(wasPlaying) TogglePlayPause(false);
|
if(wasPlaying == true) Playing = false;
|
||||||
|
|
||||||
_opticalDisc.NextIndex(changeTrack);
|
OpticalDisc.NextIndex(changeTrack);
|
||||||
if(_opticalDisc is CompactDisc compactDisc)
|
if(OpticalDisc is CompactDisc compactDisc)
|
||||||
_soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis;
|
_soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis;
|
||||||
|
|
||||||
if(wasPlaying) TogglePlayPause(true);
|
if(wasPlaying == true) Playing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -177,17 +192,17 @@ namespace RedBookPlayer.Hardware
|
|||||||
/// <param name="changeTrack">True if index changes can trigger a track change, false otherwise</param>
|
/// <param name="changeTrack">True if index changes can trigger a track change, false otherwise</param>
|
||||||
public void PreviousIndex(bool changeTrack)
|
public void PreviousIndex(bool changeTrack)
|
||||||
{
|
{
|
||||||
if(_opticalDisc == null || !_opticalDisc.Initialized)
|
if(OpticalDisc == null || !OpticalDisc.Initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool wasPlaying = Playing;
|
bool? wasPlaying = Playing;
|
||||||
if(wasPlaying) TogglePlayPause(false);
|
if(wasPlaying == true) Playing = false;
|
||||||
|
|
||||||
_opticalDisc.PreviousIndex(changeTrack);
|
OpticalDisc.PreviousIndex(changeTrack);
|
||||||
if(_opticalDisc is CompactDisc compactDisc)
|
if(OpticalDisc is CompactDisc compactDisc)
|
||||||
_soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis;
|
_soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis;
|
||||||
|
|
||||||
if(wasPlaying) TogglePlayPause(true);
|
if(wasPlaying == true) Playing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -195,10 +210,10 @@ namespace RedBookPlayer.Hardware
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void FastForward()
|
public void FastForward()
|
||||||
{
|
{
|
||||||
if(_opticalDisc == null || !_opticalDisc.Initialized)
|
if(OpticalDisc == null || !OpticalDisc.Initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_opticalDisc.CurrentSector = Math.Min(_opticalDisc.TotalSectors, _opticalDisc.CurrentSector + 75);
|
OpticalDisc.CurrentSector = Math.Min(OpticalDisc.TotalSectors, OpticalDisc.CurrentSector + 75);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -206,11 +221,11 @@ namespace RedBookPlayer.Hardware
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Rewind()
|
public void Rewind()
|
||||||
{
|
{
|
||||||
if(_opticalDisc == null || !_opticalDisc.Initialized)
|
if(OpticalDisc == null || !OpticalDisc.Initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(_opticalDisc.CurrentSector >= 75)
|
if(OpticalDisc.CurrentSector >= 75)
|
||||||
_opticalDisc.CurrentSector -= 75;
|
OpticalDisc.CurrentSector -= 75;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -218,75 +233,25 @@ namespace RedBookPlayer.Hardware
|
|||||||
#region Helpers
|
#region Helpers
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate the digit string to be interpreted by the frontend
|
/// Get current sector time, accounting for offsets
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>String representing the digits for the frontend</returns>
|
/// <returns>ulong representing the current sector time</returns>
|
||||||
public string GenerateDigitString()
|
public ulong GetCurrentSectorTime()
|
||||||
{
|
{
|
||||||
// If the disc isn't initialized, return all '-' characters
|
ulong sectorTime = OpticalDisc.CurrentSector;
|
||||||
if(_opticalDisc == null || !_opticalDisc.Initialized)
|
if (OpticalDisc.SectionStartSector != 0)
|
||||||
return string.Empty.PadLeft(20, '-');
|
sectorTime -= OpticalDisc.SectionStartSector;
|
||||||
|
|
||||||
// Otherwise, take the current time into account
|
|
||||||
ulong sectorTime = _opticalDisc.CurrentSector;
|
|
||||||
if(_opticalDisc.SectionStartSector != 0)
|
|
||||||
sectorTime -= _opticalDisc.SectionStartSector;
|
|
||||||
else
|
else
|
||||||
sectorTime += _opticalDisc.TimeOffset;
|
sectorTime += OpticalDisc.TimeOffset;
|
||||||
|
|
||||||
int[] numbers = new int[]
|
return sectorTime;
|
||||||
{
|
|
||||||
_opticalDisc.CurrentTrackNumber + 1,
|
|
||||||
_opticalDisc.CurrentTrackIndex,
|
|
||||||
|
|
||||||
(int)(sectorTime / (75 * 60)),
|
|
||||||
(int)(sectorTime / 75 % 60),
|
|
||||||
(int)(sectorTime % 75),
|
|
||||||
|
|
||||||
_opticalDisc.TotalTracks,
|
|
||||||
_opticalDisc.TotalIndexes,
|
|
||||||
|
|
||||||
(int)(_opticalDisc.TotalTime / (75 * 60)),
|
|
||||||
(int)(_opticalDisc.TotalTime / 75 % 60),
|
|
||||||
(int)(_opticalDisc.TotalTime % 75),
|
|
||||||
};
|
|
||||||
|
|
||||||
return string.Join("", numbers.Select(i => i.ToString().PadLeft(2, '0').Substring(0, 2)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Toggle de-emphasis processing
|
/// Set if de-emphasis should be applied
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="enable">True to apply de-emphasis, false otherwise</param>
|
/// <param name="apply">True to enable, false to disable</param>
|
||||||
public void ToggleDeEmphasis(bool enable) => _soundOutput.ToggleDeEmphasis(enable);
|
public void SetDeEmphasis(bool apply) => _soundOutput?.SetDeEmphasis(apply);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Update the data context for the frontend
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dataContext">Data context to be updated</param>
|
|
||||||
public void UpdateDataContext(PlayerViewModel dataContext)
|
|
||||||
{
|
|
||||||
if(!Initialized || dataContext == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dataContext.HiddenTrack = _opticalDisc.TimeOffset > 150;
|
|
||||||
dataContext.ApplyDeEmphasis = _soundOutput.ApplyDeEmphasis;
|
|
||||||
|
|
||||||
if(_opticalDisc is CompactDisc compactDisc)
|
|
||||||
{
|
|
||||||
dataContext.QuadChannel = compactDisc.QuadChannel;
|
|
||||||
dataContext.IsDataTrack = compactDisc.IsDataTrack;
|
|
||||||
dataContext.CopyAllowed = compactDisc.CopyAllowed;
|
|
||||||
dataContext.TrackHasEmphasis = compactDisc.TrackHasEmphasis;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dataContext.QuadChannel = false;
|
|
||||||
dataContext.IsDataTrack = _opticalDisc.TrackType != TrackType.Audio;
|
|
||||||
dataContext.CopyAllowed = false;
|
|
||||||
dataContext.TrackHasEmphasis = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,23 @@ namespace RedBookPlayer.Hardware
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Playing => _soundOut.PlaybackState == PlaybackState.Playing;
|
public bool Playing => _soundOut.PlaybackState == PlaybackState.Playing;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Current playback volume
|
||||||
|
/// </summary>
|
||||||
|
public int Volume
|
||||||
|
{
|
||||||
|
get => _volume;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if(value > 100)
|
||||||
|
_volume = 100;
|
||||||
|
else if(value < 0)
|
||||||
|
_volume = 0;
|
||||||
|
else
|
||||||
|
_volume = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private State Variables
|
#region Private State Variables
|
||||||
@@ -44,6 +61,11 @@ namespace RedBookPlayer.Hardware
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
private OpticalDisc _opticalDisc;
|
private OpticalDisc _opticalDisc;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Internal value for the volume
|
||||||
|
/// </summary>
|
||||||
|
private int _volume;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Data provider for sound output
|
/// Data provider for sound output
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -76,7 +98,8 @@ namespace RedBookPlayer.Hardware
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="opticalDisc">OpticalDisc to load from</param>
|
/// <param name="opticalDisc">OpticalDisc to load from</param>
|
||||||
/// <param name="autoPlay">True if playback should begin immediately, false otherwise</param>
|
/// <param name="autoPlay">True if playback should begin immediately, false otherwise</param>
|
||||||
public void Init(OpticalDisc opticalDisc, bool autoPlay = false)
|
/// <param name="defaultVolume">Default volume between 0 and 100 to use when starting playback</param>
|
||||||
|
public void Init(OpticalDisc opticalDisc, bool autoPlay = false, int defaultVolume = 100)
|
||||||
{
|
{
|
||||||
// If we have an unusable disc, just return
|
// If we have an unusable disc, just return
|
||||||
if(opticalDisc == null || !opticalDisc.Initialized)
|
if(opticalDisc == null || !opticalDisc.Initialized)
|
||||||
@@ -85,6 +108,9 @@ namespace RedBookPlayer.Hardware
|
|||||||
// Save a reference to the disc
|
// Save a reference to the disc
|
||||||
_opticalDisc = opticalDisc;
|
_opticalDisc = opticalDisc;
|
||||||
|
|
||||||
|
// Set the initial playback volume
|
||||||
|
Volume = defaultVolume;
|
||||||
|
|
||||||
// Enable de-emphasis for CDs, if necessary
|
// Enable de-emphasis for CDs, if necessary
|
||||||
if(opticalDisc is CompactDisc compactDisc)
|
if(opticalDisc is CompactDisc compactDisc)
|
||||||
ApplyDeEmphasis = compactDisc.TrackHasEmphasis;
|
ApplyDeEmphasis = compactDisc.TrackHasEmphasis;
|
||||||
@@ -116,7 +142,7 @@ namespace RedBookPlayer.Hardware
|
|||||||
public int ProviderRead(byte[] buffer, int offset, int count)
|
public int ProviderRead(byte[] buffer, int offset, int count)
|
||||||
{
|
{
|
||||||
// Set the current volume
|
// Set the current volume
|
||||||
_soundOut.Volume = (float)App.Settings.Volume / 100;
|
_soundOut.Volume = (float)Volume / 100;
|
||||||
|
|
||||||
// Determine how many sectors we can read
|
// Determine how many sectors we can read
|
||||||
ulong sectorsToRead;
|
ulong sectorsToRead;
|
||||||
@@ -243,7 +269,7 @@ namespace RedBookPlayer.Hardware
|
|||||||
/// Toggle de-emphasis processing
|
/// Toggle de-emphasis processing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="enable">True to apply de-emphasis, false otherwise</param>
|
/// <param name="enable">True to apply de-emphasis, false otherwise</param>
|
||||||
public void ToggleDeEmphasis(bool enable) => ApplyDeEmphasis = enable;
|
public void SetDeEmphasis(bool enable) => ApplyDeEmphasis = enable;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets or resets the de-emphasis filters
|
/// Sets or resets the de-emphasis filters
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using Avalonia.Input;
|
||||||
using RedBookPlayer.GUI;
|
using RedBookPlayer.GUI;
|
||||||
|
|
||||||
namespace RedBookPlayer
|
namespace RedBookPlayer
|
||||||
{
|
{
|
||||||
public class Settings
|
public class Settings
|
||||||
{
|
{
|
||||||
|
#region Player Settings
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates if discs should start playing on load
|
/// Indicates if discs should start playing on load
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -35,18 +38,111 @@ namespace RedBookPlayer
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates the default playback volume
|
/// Indicates the default playback volume
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Volume { get; set; } = 100;
|
public int Volume
|
||||||
|
{
|
||||||
|
get => _volume;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if(value > 100)
|
||||||
|
_volume = 100;
|
||||||
|
else if(value < 0)
|
||||||
|
_volume = 0;
|
||||||
|
else
|
||||||
|
_volume = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates the currently selected theme
|
/// Indicates the currently selected theme
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SelectedTheme { get; set; } = "default";
|
public string SelectedTheme { get; set; } = "default";
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Key Mappings
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to open settings
|
||||||
|
/// </summary>
|
||||||
|
public Key OpenSettingsKey { get; set; } = Key.F1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to load a new image
|
||||||
|
/// </summary>
|
||||||
|
public Key LoadImageKey { get; set; } = Key.F2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to toggle play and pause
|
||||||
|
/// </summary>
|
||||||
|
public Key TogglePlaybackKey { get; set; } = Key.Space;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to stop playback
|
||||||
|
/// </summary>
|
||||||
|
public Key StopPlaybackKey { get; set; } = Key.Escape;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to move to the next track
|
||||||
|
/// </summary>
|
||||||
|
public Key NextTrackKey { get; set; } = Key.Right;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to move to the previous track
|
||||||
|
/// </summary>
|
||||||
|
public Key PreviousTrackKey { get; set; } = Key.Left;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to move to the next index
|
||||||
|
/// </summary>
|
||||||
|
public Key NextIndexKey { get; set; } = Key.OemCloseBrackets;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to move to the previous index
|
||||||
|
/// </summary>
|
||||||
|
public Key PreviousIndexKey { get; set; } = Key.OemOpenBrackets;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to fast forward playback
|
||||||
|
/// </summary>
|
||||||
|
public Key FastForwardPlaybackKey { get; set; } = Key.OemPeriod;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to rewind playback
|
||||||
|
/// </summary>
|
||||||
|
public Key RewindPlaybackKey { get; set; } = Key.OemComma;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to raise volume
|
||||||
|
/// </summary>
|
||||||
|
public Key VolumeUpKey { get; set; } = Key.Add;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to lower volume
|
||||||
|
/// </summary>
|
||||||
|
public Key VolumeDownKey { get; set; } = Key.Subtract;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to toggle mute
|
||||||
|
/// </summary>
|
||||||
|
public Key ToggleMuteKey { get; set; } = Key.M;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Key assigned to toggle de-emphasis
|
||||||
|
/// </summary>
|
||||||
|
public Key ToggleDeEmphasisKey { get; set; } = Key.E;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Path to the settings file
|
/// Path to the settings file
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private string _filePath;
|
private string _filePath;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Internal value for the volume
|
||||||
|
/// </summary>
|
||||||
|
private int _volume = 100;
|
||||||
|
|
||||||
public Settings() {}
|
public Settings() {}
|
||||||
|
|
||||||
public Settings(string filePath) => _filePath = filePath;
|
public Settings(string filePath) => _filePath = filePath;
|
||||||
|
|||||||
Reference in New Issue
Block a user