public PlaybackViewModel(IPlaybackController playbackController, Settings settings, IMixViewModelFactory mixViewModelFactory) { this.playbackController = playbackController; this.settings = settings; var volumeString = (string)settings[volumeKey] ?? "50"; Volume = Double.Parse(volumeString); _CurrentPosition = playbackController.CurrentPositionObservable .ToProperty(this, x => x.CurrentPosition); _CurrentPositionAsString = playbackController.CurrentPositionObservable .Select(TimeSpan.FromSeconds) .Select(DurationToString) .ToProperty(this, x => x.CurrentPositionAsString); // connecting current mix being played to the viewmodel IObservable <MixViewModel> currentMixViewModelObservable = playbackController.CurrentMixObservable.Select(mixViewModelFactory.CreateMixViewModel); _CurrentMixViewModel = currentMixViewModelObservable .ToProperty(this, x => x.CurrentMixViewModel); IObservable <bool> _CurrentMixViewModelPresent = this.WhenAny( x => x.CurrentMixViewModel, mixViewModel => mixViewModel.Value != null && mixViewModel.Value.Model != Mix.NoMixAvailable); _CurrentTrackDurationAsString = playbackController.CurrentDurationObservable .Select(duration => DurationToString(TimeSpan.FromSeconds(duration))) .ToProperty(this, x => x.CurrentTrackDurationAsString); _CurrentTrackDuration = playbackController.CurrentDurationObservable .ToProperty(this, x => x.CurrentTrackDuration); // commands // going to the next song only if there is a mix currently loaded _NextSong = currentMixViewModelObservable .Select(x => x.NextSong) .ToProperty(this, x => x.NextSong); var audioPlayerState = playbackController.PlayerStateObservable; // both having a current mix and not running var audioPlayerNotRunning = audioPlayerState.Select(status => status == MediaStatus.Stopped || status == MediaStatus.Paused).CombineLatest( _CurrentMixViewModelPresent, (x, y) => x && y); Continue = new ReactiveAsyncCommand(audioPlayerNotRunning, 1); Continue.Subscribe(_ => playbackController.Continue()); var audioPlayerRunning = audioPlayerState.Select(status => status == MediaStatus.Running); Pause = new ReactiveAsyncCommand(audioPlayerRunning, 1); Pause.Subscribe(_ => playbackController.Pause()); var audioPlayerRunningOrPaused = audioPlayerState.Select(status => status == MediaStatus.Running || status == MediaStatus.Paused); Stop = new ReactiveAsyncCommand(audioPlayerRunningOrPaused, 1); Stop.Subscribe(_ => playbackController.Stop()); NextMix = new ReactiveAsyncCommand(_CurrentMixViewModelPresent, 1); NextMix.RegisterAsyncAction(_ => { try { playbackController.NextMix(); } catch (Exception e) { log.Error("Unable to go to the next mix", e); } } ); bool debugModeOn = ConfigurationManager.AppSettings["AudioPlayer"] != null && ConfigurationManager.AppSettings["AudioPlayer"].Equals("DirectX WMI 3.14169"); _IsPositionSliderEnabled = audioPlayerRunningOrPaused .Select(a => a && debugModeOn) .ToProperty(this, x => x.IsPositionSliderEnabled); GoToTrack = new ReactiveAsyncCommand(_CurrentMixViewModelPresent, 1); GoToTrack.Subscribe(_ => { if (debugModeOn) { try { playbackController.GoToTrack(SelectedTrackIndex); } catch (Exception e) { log.Error("Unable to go to track " + SelectedTrackIndex, e); } } }); Skip = new ReactiveAsyncCommand(audioPlayerRunningOrPaused, 1); Skip.Subscribe(step => { double newPosition = CurrentPosition + Double.Parse((string)step); if (newPosition >= 0 && newPosition <= CurrentTrackDuration) { CurrentPosition = newPosition; } }); ChangeVolume = new ReactiveAsyncCommand(null, 1); ChangeVolume.Subscribe(step => { double newVolume = Volume + Double.Parse((string)step); if (newVolume >= 0 && newVolume <= 100) { Volume = newVolume; } }); }
private void TheApplicationIssuesACommandToContinueTheMix() { playbackController.Continue(); }