diff --git a/RedBookPlayer.Common/Hardware/Player.cs b/RedBookPlayer.Common/Hardware/Player.cs index 0fdc4d4..8c4c256 100644 --- a/RedBookPlayer.Common/Hardware/Player.cs +++ b/RedBookPlayer.Common/Hardware/Player.cs @@ -181,6 +181,11 @@ namespace RedBookPlayer.Common.Hardware /// private readonly OpticalDisc _opticalDisc; + /// + /// Last volume for mute toggling + /// + private int? _lastVolume = null; + #endregion /// @@ -258,6 +263,17 @@ namespace RedBookPlayer.Common.Hardware Playing = false; } + /// + /// Toggle current playback + /// + public void TogglePlayback() + { + if(Playing == true) + Pause(); + else + Play(); + } + /// /// Stop current playback /// @@ -374,13 +390,69 @@ namespace RedBookPlayer.Common.Hardware #endregion - #region Helpers + #region Volume + + /// + /// Increment the volume value + /// + public void VolumeUp() => SetVolume(Volume + 1); + + /// + /// Decrement the volume value + /// + public void VolumeDown() => SetVolume(Volume + 1); + + /// + /// Set the value for the volume + /// + /// New volume value + public void SetVolume(int volume) => _soundOutput?.SetVolume(volume); + + /// + /// Temporarily mute playback + /// + public void ToggleMute() + { + if(_lastVolume == null) + { + _lastVolume = Volume; + SetVolume(0); + } + else + { + SetVolume(_lastVolume.Value); + _lastVolume = null; + } + } + + #endregion + + #region Emphasis + + /// + /// Enable de-emphasis + /// + public void EnableDeEmphasis() => SetDeEmphasis(true); + + /// + /// Disable de-emphasis + /// + public void DisableDeEmphasis() => SetDeEmphasis(false); + + /// + /// Toggle de-emphasis + /// + public void ToggleDeEmphasis() => SetDeEmphasis(!ApplyDeEmphasis); /// /// Set de-emphasis status /// /// - public void SetDeEmphasis(bool apply) => _soundOutput?.SetDeEmphasis(apply); + private void SetDeEmphasis(bool apply) => _soundOutput?.SetDeEmphasis(apply); + + #endregion + + #region Helpers /// /// Set the value for loading data tracks [CompactDisc only] @@ -394,12 +466,6 @@ namespace RedBookPlayer.Common.Hardware /// True to enable loading hidden tracks, false otherwise public void SetLoadHiddenTracks(bool load) => (_opticalDisc as CompactDisc)?.SetLoadHiddenTracks(load); - /// - /// Set the value for the volume - /// - /// New volume value - public void SetVolume(int volume) => _soundOutput?.SetVolume(volume); - /// /// Update the player from the current OpticalDisc /// diff --git a/RedBookPlayer.GUI/MainWindow.xaml.cs b/RedBookPlayer.GUI/MainWindow.xaml.cs index 094c53e..2172c1a 100644 --- a/RedBookPlayer.GUI/MainWindow.xaml.cs +++ b/RedBookPlayer.GUI/MainWindow.xaml.cs @@ -5,7 +5,7 @@ using System.Xml; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Markup.Xaml; -using RedBookPlayer.Common; +using RedBookPlayer.GUI.ViewModels; namespace RedBookPlayer.GUI { @@ -94,7 +94,7 @@ namespace RedBookPlayer.GUI Closing += (e, f) => { - ((PlayerView)ContentControl.Content).StopButton_Click(this, null); + ((PlayerView)ContentControl.Content).PlayerViewModel.ExecuteStop(); }; AddHandler(DragDrop.DropEvent, MainWindow_Drop); @@ -138,49 +138,49 @@ namespace RedBookPlayer.GUI // Toggle playback else if(e.Key == App.Settings.TogglePlaybackKey || e.Key == Key.MediaPlayPause) { - playerView?.PlayPauseButton_Click(this, null); + playerView?.PlayerViewModel?.ExecuteTogglePlayPause(); } // Stop playback else if(e.Key == App.Settings.StopPlaybackKey || e.Key == Key.MediaStop) { - playerView?.StopButton_Click(this, null); + playerView?.PlayerViewModel?.ExecuteStop(); } // Next Track else if(e.Key == App.Settings.NextTrackKey || e.Key == Key.MediaNextTrack) { - playerView?.NextTrackButton_Click(this, null); + playerView?.PlayerViewModel?.ExecuteNextTrack(); } // Previous Track else if(e.Key == App.Settings.PreviousTrackKey || e.Key == Key.MediaPreviousTrack) { - playerView?.PreviousTrackButton_Click(this, null); + playerView?.PlayerViewModel?.ExecutePreviousTrack(); } // Next Index else if(e.Key == App.Settings.NextIndexKey) { - playerView?.NextIndexButton_Click(this, null); + playerView?.PlayerViewModel?.ExecuteNextIndex(); } // Previous Index else if(e.Key == App.Settings.PreviousIndexKey) { - playerView?.PreviousIndexButton_Click(this, null); + playerView?.PlayerViewModel?.ExecutePreviousIndex(); } // Fast Foward else if(e.Key == App.Settings.FastForwardPlaybackKey) { - playerView?.FastForwardButton_Click(this, null); + playerView?.PlayerViewModel?.ExecuteFastForward(); } // Rewind else if(e.Key == App.Settings.RewindPlaybackKey) { - playerView?.RewindButton_Click(this, null); + playerView?.PlayerViewModel?.ExecuteRewind(); } // Volume Up @@ -193,7 +193,7 @@ namespace RedBookPlayer.GUI increment *= 5; if(playerView?.PlayerViewModel?.Volume != null) - playerView.PlayerViewModel.SetVolume(playerView.PlayerViewModel.Volume + increment); + playerView.PlayerViewModel.ExecuteSetVolume(playerView.PlayerViewModel.Volume + increment); } // Volume Down @@ -206,19 +206,19 @@ namespace RedBookPlayer.GUI decrement *= 5; if (playerView?.PlayerViewModel?.Volume != null) - playerView.PlayerViewModel.SetVolume(playerView.PlayerViewModel.Volume - decrement); + playerView.PlayerViewModel.ExecuteSetVolume(playerView.PlayerViewModel.Volume - decrement); } // Mute Toggle else if(e.Key == App.Settings.ToggleMuteKey || e.Key == Key.VolumeMute) { - playerView?.MuteToggleButton_Click(this, null); + playerView?.PlayerViewModel?.ExecuteToggleMute(); } // Emphasis Toggle else if(e.Key == App.Settings.ToggleDeEmphasisKey) { - playerView?.EnableDisableDeEmphasisButton_Click(this, null); + playerView?.PlayerViewModel?.ExecuteToggleDeEmphasis(); } } diff --git a/RedBookPlayer.GUI/PlayerView.xaml b/RedBookPlayer.GUI/PlayerView.xaml index ab9fcec..e531106 100644 --- a/RedBookPlayer.GUI/PlayerView.xaml +++ b/RedBookPlayer.GUI/PlayerView.xaml @@ -5,17 +5,17 @@ - - - + + + - - - - - Rewind - Fast Forward + + + + + Rewind + Fast Forward @@ -76,11 +76,11 @@ - - diff --git a/RedBookPlayer.GUI/PlayerView.xaml.cs b/RedBookPlayer.GUI/PlayerView.xaml.cs index b6019f7..d2af50e 100644 --- a/RedBookPlayer.GUI/PlayerView.xaml.cs +++ b/RedBookPlayer.GUI/PlayerView.xaml.cs @@ -11,7 +11,7 @@ using Avalonia.Markup.Xaml; using Avalonia.Media.Imaging; using Avalonia.Platform; using Avalonia.Threading; -using RedBookPlayer.Common; +using RedBookPlayer.GUI.ViewModels; namespace RedBookPlayer.GUI { @@ -267,44 +267,6 @@ namespace RedBookPlayer.GUI await LoadImage(path); } - public void PlayButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Play(); - - public void PauseButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Pause(); - - public void PlayPauseButton_Click(object sender, RoutedEventArgs e) - { - if(PlayerViewModel.Playing == true) - PlayerViewModel.Pause(); - else - PlayerViewModel.Play(); - } - - public void StopButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Stop(); - - public void NextTrackButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.NextTrack(); - - public void PreviousTrackButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousTrack(); - - public void NextIndexButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.NextIndex(App.Settings.IndexButtonChangeTrack); - - public void PreviousIndexButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousIndex(App.Settings.IndexButtonChangeTrack); - - public void FastForwardButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.FastForward(); - - public void RewindButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Rewind(); - - public void VolumeUpButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.SetVolume(PlayerViewModel.Volume + 1); - - public void VolumeDownButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.SetVolume(PlayerViewModel.Volume - 1); - - public void MuteToggleButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.ToggleMute(); - - public void EnableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.SetDeEmphasis(true); - - public void DisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.SetDeEmphasis(false); - - public void EnableDisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.SetDeEmphasis(!PlayerViewModel.ApplyDeEmphasis); - #endregion } } \ No newline at end of file diff --git a/RedBookPlayer.Common/PlayerViewModel.cs b/RedBookPlayer.GUI/ViewModels/PlayerViewModel.cs similarity index 60% rename from RedBookPlayer.Common/PlayerViewModel.cs rename to RedBookPlayer.GUI/ViewModels/PlayerViewModel.cs index e82ed29..2c9d466 100644 --- a/RedBookPlayer.Common/PlayerViewModel.cs +++ b/RedBookPlayer.GUI/ViewModels/PlayerViewModel.cs @@ -1,8 +1,9 @@ using System.ComponentModel; +using System.Reactive; using ReactiveUI; using RedBookPlayer.Common.Hardware; -namespace RedBookPlayer.Common +namespace RedBookPlayer.GUI.ViewModels { public class PlayerViewModel : ReactiveObject { @@ -11,11 +12,6 @@ namespace RedBookPlayer.Common /// private Player _player; - /// - /// Last volume for mute toggling - /// - private int? _lastVolume = null; - #region Player Passthrough #region OpticalDisc Passthrough @@ -181,6 +177,127 @@ namespace RedBookPlayer.Common #endregion + #region Commands + + #region Playback + + /// + /// Command for beginning playback + /// + public ReactiveCommand PlayCommand { get; } + + /// + /// Command for pausing playback + /// + public ReactiveCommand PauseCommand { get; } + + /// + /// Command for pausing playback + /// + public ReactiveCommand TogglePlayPauseCommand { get; } + + /// + /// Command for stopping playback + /// + public ReactiveCommand StopCommand { get; } + + /// + /// Command for moving to the next track + /// + public ReactiveCommand NextTrackCommand { get; } + + /// + /// Command for moving to the previous track + /// + public ReactiveCommand PreviousTrackCommand { get; } + + /// + /// Command for moving to the next index + /// + public ReactiveCommand NextIndexCommand { get; } + + /// + /// Command for moving to the previous index + /// + public ReactiveCommand PreviousIndexCommand { get; } + + /// + /// Command for fast forwarding + /// + public ReactiveCommand FastForwardCommand { get; } + + /// + /// Command for rewinding + /// + public ReactiveCommand RewindCommand { get; } + + #endregion + + #region Volume + + /// + /// Command for incrementing volume + /// + public ReactiveCommand VolumeUpCommand { get; } + + /// + /// Command for decrementing volume + /// + public ReactiveCommand VolumeDownCommand { get; } + + /// + /// Command for toggling mute + /// + public ReactiveCommand ToggleMuteCommand { get; } + + #endregion + + #region Emphasis + + /// + /// Command for enabling de-emphasis + /// + public ReactiveCommand EnableDeEmphasisCommand { get; } + + /// + /// Command for disabling de-emphasis + /// + public ReactiveCommand DisableDeEmphasisCommand { get; } + + /// + /// Command for toggling de-emphasis + /// + public ReactiveCommand ToggleDeEmphasisCommand { get; } + + #endregion + + #endregion + + /// + /// Constructor + /// + public PlayerViewModel() + { + PlayCommand = ReactiveCommand.Create(ExecutePlay); + PauseCommand = ReactiveCommand.Create(ExecutePause); + TogglePlayPauseCommand = ReactiveCommand.Create(ExecuteTogglePlayPause); + StopCommand = ReactiveCommand.Create(ExecuteStop); + NextTrackCommand = ReactiveCommand.Create(ExecuteNextTrack); + PreviousTrackCommand = ReactiveCommand.Create(ExecutePreviousTrack); + NextIndexCommand = ReactiveCommand.Create(ExecuteNextIndex); + PreviousIndexCommand = ReactiveCommand.Create(ExecutePreviousIndex); + FastForwardCommand = ReactiveCommand.Create(ExecuteFastForward); + RewindCommand = ReactiveCommand.Create(ExecuteRewind); + + VolumeUpCommand = ReactiveCommand.Create(ExecuteVolumeUp); + VolumeDownCommand = ReactiveCommand.Create(ExecuteVolumeDown); + ToggleMuteCommand = ReactiveCommand.Create(ExecuteToggleMute); + + EnableDeEmphasisCommand = ReactiveCommand.Create(ExecuteEnableDeEmphasis); + DisableDeEmphasisCommand = ReactiveCommand.Create(ExecuteDisableDeEmphasis); + ToggleDeEmphasisCommand = ReactiveCommand.Create(ExecuteToggleDeEmphasis); + } + /// /// Initialize the view model with a given image path /// @@ -193,7 +310,7 @@ namespace RedBookPlayer.Common public void Init(string path, bool generateMissingToc, bool loadHiddenTracks, bool loadDataTracks, bool autoPlay, int defaultVolume) { // Stop current playback, if necessary - if(Playing != null) Stop(); + if(Playing != null) ExecuteStop(); // Create and attempt to initialize new Player _player = new Player(path, generateMissingToc, loadHiddenTracks, loadDataTracks, autoPlay, defaultVolume); @@ -209,60 +326,101 @@ namespace RedBookPlayer.Common /// /// Begin playback /// - public void Play() => _player?.Play(); + public void ExecutePlay() => _player?.Play(); /// /// Pause current playback /// - public void Pause() => _player?.Pause(); + public void ExecutePause() => _player?.Pause(); + + /// + /// Toggle playback + /// + public void ExecuteTogglePlayPause() => _player?.TogglePlayback(); /// /// Stop current playback /// - public void Stop() => _player?.Stop(); + public void ExecuteStop() => _player?.Stop(); /// /// Move to the next playable track /// - public void NextTrack() => _player?.NextTrack(); + public void ExecuteNextTrack() => _player?.NextTrack(); /// /// Move to the previous playable track /// - public void PreviousTrack() => _player?.PreviousTrack(); + public void ExecutePreviousTrack() => _player?.PreviousTrack(); /// /// Move to the next index /// - /// True if index changes can trigger a track change, false otherwise - public void NextIndex(bool changeTrack) => _player?.NextIndex(changeTrack); + public void ExecuteNextIndex() => _player?.NextIndex(App.Settings.IndexButtonChangeTrack); /// /// Move to the previous index /// - /// True if index changes can trigger a track change, false otherwise - public void PreviousIndex(bool changeTrack) => _player?.PreviousIndex(changeTrack); + public void ExecutePreviousIndex() => _player?.PreviousIndex(App.Settings.IndexButtonChangeTrack); /// /// Fast-forward playback by 75 sectors, if possible /// - public void FastForward() => _player?.FastForward(); + public void ExecuteFastForward() => _player?.FastForward(); /// /// Rewind playback by 75 sectors, if possible /// - public void Rewind() => _player?.Rewind(); + public void ExecuteRewind() => _player?.Rewind(); + + #endregion + + #region Volume + + /// + /// Increment the volume value + /// + public void ExecuteVolumeUp() => _player?.VolumeUp(); + + /// + /// Decrement the volume value + /// + public void ExecuteVolumeDown() => _player?.VolumeDown(); + + /// + /// Set the value for the volume + /// + /// New volume value + public void ExecuteSetVolume(int volume) => _player?.SetVolume(volume); + + /// + /// Temporarily mute playback + /// + public void ExecuteToggleMute() => _player?.ToggleMute(); + + #endregion + + #region Emphasis + + /// + /// Enable de-emphasis + /// + public void ExecuteEnableDeEmphasis() => _player?.EnableDeEmphasis(); + + /// + /// Disable de-emphasis + /// + public void ExecuteDisableDeEmphasis() => _player?.DisableDeEmphasis(); + + /// + /// Toggle de-emphasis + /// + public void ExecuteToggleDeEmphasis() => _player?.ToggleDeEmphasis(); #endregion #region Helpers - /// - /// Set de-emphasis status - /// - /// - public void SetDeEmphasis(bool apply) => _player?.SetDeEmphasis(apply); - /// /// Set the value for loading data tracks [CompactDisc only] /// @@ -275,29 +433,6 @@ namespace RedBookPlayer.Common /// True to enable loading hidden tracks, false otherwise public void SetLoadHiddenTracks(bool load) => _player?.SetLoadHiddenTracks(load); - /// - /// Set the value for the volume - /// - /// New volume value - public void SetVolume(int volume) => _player?.SetVolume(volume); - - /// - /// Temporarily mute playback - /// - public void ToggleMute() - { - if(_lastVolume == null) - { - _lastVolume = Volume; - _player?.SetVolume(0); - } - else - { - _player?.SetVolume(_lastVolume.Value); - _lastVolume = null; - } - } - /// /// Update the view-model from the Player ///