Player controls now get dynamically assigned to view model base classes.
This gives view models more freedom in how play events from the player are handled
This commit is contained in:
parent
759c05e53b
commit
794b4739b1
@ -14,8 +14,10 @@
|
||||
<StackLayout
|
||||
Grid.Column="0">
|
||||
<Label
|
||||
x:Name="SongTitleLabel"
|
||||
Text="{Binding SongTitle}"/>
|
||||
<Label
|
||||
x:Name="ArtistNameLabel"
|
||||
Text="{Binding ArtistName}"/>
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
@ -23,16 +25,19 @@
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
Text="Previous"
|
||||
x:Name="PreviousButton"
|
||||
Command="{Binding PreviousCommand}"
|
||||
WidthRequest="100"
|
||||
HeightRequest="50"/>
|
||||
<Button
|
||||
x:Name="PlayButton"
|
||||
Text="{Binding PlayButtonText}"
|
||||
Command="{Binding PlayCommand}"
|
||||
WidthRequest="100"
|
||||
HeightRequest="50"/>
|
||||
<Button
|
||||
Text="Next"
|
||||
x:Name="NextButton"
|
||||
Command="{Binding NextCommand}"
|
||||
WidthRequest="100"
|
||||
HeightRequest="50"/>
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Aurora.Design.Components.MediaPlayer
|
||||
@ -8,8 +7,276 @@ namespace Aurora.Design.Components.MediaPlayer
|
||||
{
|
||||
public Player()
|
||||
{
|
||||
BindingContext = new PlayerViewModel();
|
||||
// this.PreviousButton.Clicked += OnPreviousButtonClicked;
|
||||
// this.PlayButton.Clicked += OnPlayButtonClicked;
|
||||
// this.NextButton.Clicked += OnNextButtonClicked;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
#region SongTitle Bindable
|
||||
public static readonly BindableProperty SongTitleProperty =
|
||||
BindableProperty.Create(propertyName: "SongTitle",
|
||||
returnType: typeof(string),
|
||||
declaringType: typeof(Player),
|
||||
propertyChanged: OnSongTitlePropertyChanged);
|
||||
|
||||
public string SongTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)GetValue(SongTitleProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(SongTitleProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnSongTitlePropertyChanged(BindableObject bindable, object newValue, object oldValue)
|
||||
{
|
||||
Player component = bindable as Player;
|
||||
component.SongTitleLabel.Text = (string)newValue;
|
||||
}
|
||||
|
||||
#endregion SongTitle Bindable
|
||||
|
||||
#region ArtistName Bindable
|
||||
public static readonly BindableProperty ArtistNameProperty =
|
||||
BindableProperty.Create(propertyName: "ArtistName",
|
||||
returnType: typeof(string),
|
||||
declaringType: typeof(Player),
|
||||
propertyChanged: OnArtistNamePropertyChanged);
|
||||
|
||||
public string ArtistName
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)GetValue(ArtistNameProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(ArtistNameProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnArtistNamePropertyChanged(BindableObject bindable, object newValue, object oldValue)
|
||||
{
|
||||
Player component = bindable as Player;
|
||||
component.ArtistNameLabel.Text = (string)newValue;
|
||||
}
|
||||
|
||||
#endregion ArtistName Bindable
|
||||
|
||||
#region PreviousButton
|
||||
public static readonly BindableProperty PreviousButtonCommandProperty =
|
||||
BindableProperty.Create(propertyName: "PreviousButtonCommand",
|
||||
returnType: typeof(Command),
|
||||
propertyChanged: OnPreviousButtonPropertyChanged,
|
||||
declaringType: typeof(Player));
|
||||
|
||||
public Command PreviousButtonCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Command)GetValue(PreviousButtonCommandProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(PreviousButtonCommandProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPreviousButtonClicked(object sender, EventArgs args)
|
||||
{
|
||||
if (PreviousButtonCommand.CanExecute(null))
|
||||
{
|
||||
PreviousButtonCommand.Execute(null);
|
||||
PreviousButtonCommand.ChangeCanExecute();
|
||||
PlayButtonCommand.ChangeCanExecute();
|
||||
NextButtonCommand.ChangeCanExecute();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler to hook up can execute events on property changed
|
||||
/// </summary>
|
||||
/// <param name="bindable"></param>
|
||||
/// <param name="newValue"></param>
|
||||
/// <param name="oldValue"></param>
|
||||
private static void OnPreviousButtonPropertyChanged(BindableObject bindable, object oldValue, object newValue)
|
||||
{
|
||||
Player component = bindable as Player;
|
||||
if (newValue is Command)
|
||||
{
|
||||
Command cmd = newValue as Command;
|
||||
component.PreviousButton.Clicked += component.OnPreviousButtonClicked;
|
||||
cmd.CanExecuteChanged += (sender, e) => OnPreviousButtonCanExecuteChanged(sender, e, component, cmd);
|
||||
}
|
||||
|
||||
if (oldValue is Command && oldValue != null)
|
||||
{
|
||||
Command cmd = newValue as Command;
|
||||
component.PreviousButton.Clicked -= component.OnPreviousButtonClicked;
|
||||
cmd.CanExecuteChanged -= (sender, e) => OnPreviousButtonCanExecuteChanged(sender, e, component, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can execute changed event handler
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="eventArgs"></param>
|
||||
/// <param name="component"></param>
|
||||
/// <param name="cmd"></param>
|
||||
private static void OnPreviousButtonCanExecuteChanged(object sender,
|
||||
EventArgs eventArgs,
|
||||
Player component,
|
||||
Command cmd)
|
||||
{
|
||||
component.NextButton.IsEnabled = cmd.CanExecute(null);
|
||||
}
|
||||
#endregion PreviousButton
|
||||
|
||||
#region PlayButton
|
||||
public static readonly BindableProperty PlayButtonCommandProperty =
|
||||
BindableProperty.Create(propertyName: "PlayButtonCommand",
|
||||
returnType: typeof(Command),
|
||||
propertyChanged: OnPlayButtonPropertyChanged,
|
||||
declaringType: typeof(Player));
|
||||
|
||||
public Command PlayButtonCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Command)GetValue(PlayButtonCommandProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(PlayButtonCommandProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlayButtonClicked(object sender, EventArgs args)
|
||||
{
|
||||
if (PlayButtonCommand.CanExecute(null))
|
||||
{
|
||||
PlayButtonCommand.Execute(null);
|
||||
PreviousButtonCommand.ChangeCanExecute();
|
||||
PlayButtonCommand.ChangeCanExecute();
|
||||
NextButtonCommand.ChangeCanExecute();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler to hook up can execute events on property changed
|
||||
/// </summary>
|
||||
/// <param name="bindable"></param>
|
||||
/// <param name="newValue"></param>
|
||||
/// <param name="oldValue"></param>
|
||||
private static void OnPlayButtonPropertyChanged(BindableObject bindable, object oldValue, object newValue)
|
||||
{
|
||||
Player component = bindable as Player;
|
||||
if (newValue is Command)
|
||||
{
|
||||
Command cmd = newValue as Command;
|
||||
component.PlayButton.Clicked += component.OnPlayButtonClicked;
|
||||
cmd.CanExecuteChanged += (sender, e) => OnPlayButtonCanExecuteChanged(sender, e, component, cmd);
|
||||
}
|
||||
|
||||
if (oldValue is Command && oldValue != null)
|
||||
{
|
||||
Command cmd = newValue as Command;
|
||||
component.PlayButton.Clicked -= component.OnPlayButtonClicked;
|
||||
cmd.CanExecuteChanged -= (sender, e) => OnPlayButtonCanExecuteChanged(sender, e, component, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can execute changed event handler
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="eventArgs"></param>
|
||||
/// <param name="component"></param>
|
||||
/// <param name="cmd"></param>
|
||||
private static void OnPlayButtonCanExecuteChanged(object sender,
|
||||
EventArgs eventArgs,
|
||||
Player component,
|
||||
Command cmd)
|
||||
{
|
||||
component.NextButton.IsEnabled = cmd.CanExecute(null);
|
||||
}
|
||||
#endregion PlayButton
|
||||
|
||||
#region NextButton
|
||||
public static readonly BindableProperty NextButtonCommandProperty =
|
||||
BindableProperty.Create(propertyName: "NextButtonCommand",
|
||||
returnType: typeof(Command),
|
||||
declaringType: typeof(Player),
|
||||
propertyChanged: OnNextButtonPropertyChanged);
|
||||
|
||||
public Command NextButtonCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Command)GetValue(NextButtonCommandProperty);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue(NextButtonCommandProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnNextButtonClicked(object sender, EventArgs args)
|
||||
{
|
||||
if (NextButtonCommand.CanExecute(null))
|
||||
{
|
||||
NextButtonCommand.Execute(null);
|
||||
PreviousButtonCommand.ChangeCanExecute();
|
||||
PlayButtonCommand.ChangeCanExecute();
|
||||
NextButtonCommand.ChangeCanExecute();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler to hook up can execute events on property changed
|
||||
/// </summary>
|
||||
/// <param name="bindable"></param>
|
||||
/// <param name="newValue"></param>
|
||||
/// <param name="oldValue"></param>
|
||||
private static void OnNextButtonPropertyChanged(BindableObject bindable, object oldValue, object newValue)
|
||||
{
|
||||
Player component = bindable as Player;
|
||||
if (newValue is Command)
|
||||
{
|
||||
Command cmd = newValue as Command;
|
||||
component.NextButton.Clicked += component.OnNextButtonClicked;
|
||||
cmd.CanExecuteChanged += (sender, e) => OnNextButtonCanExecuteChanged(sender, e, component, cmd);
|
||||
}
|
||||
|
||||
if (oldValue is Command && oldValue != null)
|
||||
{
|
||||
Command cmd = oldValue as Command;
|
||||
component.NextButton.Clicked -= component.OnNextButtonClicked;
|
||||
cmd.CanExecuteChanged -= (sender, e) => OnNextButtonCanExecuteChanged(sender, e, component, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can execute changed event handler
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="eventArgs"></param>
|
||||
/// <param name="component"></param>
|
||||
/// <param name="cmd"></param>
|
||||
private static void OnNextButtonCanExecuteChanged(object sender,
|
||||
EventArgs eventArgs,
|
||||
Player component,
|
||||
Command cmd)
|
||||
{
|
||||
|
||||
component.NextButton.IsEnabled = cmd.CanExecute(null);
|
||||
}
|
||||
#endregion PlayButton
|
||||
}
|
||||
}
|
||||
|
@ -1,163 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
using Aurora.Design.Views;
|
||||
using Aurora.Services.PlayerService;
|
||||
using Aurora.Models.Media;
|
||||
|
||||
namespace Aurora.Design.Components.MediaPlayer
|
||||
{
|
||||
public class PlayerViewModel : BaseViewModel
|
||||
{
|
||||
PlayerService _playerService;
|
||||
BaseMetadata _metadata;
|
||||
|
||||
public PlayerViewModel()
|
||||
{
|
||||
_playerService = PlayerService.Instance;
|
||||
_playerService.PlaybackStateChanged += OnPlaybackStateChanged;
|
||||
_playerService.MediaChanged += OnMediaChanged;
|
||||
|
||||
PlayCommand = new Command(OnPlayExecute, CanPlayExecute);
|
||||
PreviousCommand = new Command(OnPreviousExecute, CanPreviousExecute);
|
||||
NextCommand = new Command(OnNextExecute, CanNextExecute);
|
||||
}
|
||||
|
||||
~PlayerViewModel()
|
||||
{
|
||||
_playerService.PlaybackStateChanged -= OnPlaybackStateChanged;
|
||||
|
||||
}
|
||||
|
||||
#region Public Properties
|
||||
public Command PlayCommand { get; private set; }
|
||||
public Command NextCommand { get; private set; }
|
||||
public Command PreviousCommand { get; private set; }
|
||||
|
||||
public string PlayButtonText
|
||||
{
|
||||
get { return _playerService.PlaybackState == PlaybackState.Buffering ? "Play" : "Pause"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TODO keep player view generic between audio and video.
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public string ArtistName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_metadata == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
AudioMetadata metadata = _metadata as AudioMetadata;
|
||||
return metadata.Artist;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TODO keep player view generic between audio and video.
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public string SongTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_metadata == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
AudioMetadata metadata = _metadata as AudioMetadata;
|
||||
return metadata.Title;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
public bool CanPreviousExecute()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public void OnPreviousExecute()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool CanPlayExecute()
|
||||
{
|
||||
switch (_playerService.PlaybackState)
|
||||
{
|
||||
case PlaybackState.Buffering:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
case PlaybackState.Playing:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
case PlaybackState.Stopped:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnPlayExecute()
|
||||
{
|
||||
switch (_playerService.PlaybackState)
|
||||
{
|
||||
case PlaybackState.Buffering:
|
||||
{
|
||||
_playerService.Play();
|
||||
break;
|
||||
}
|
||||
case PlaybackState.Playing:
|
||||
{
|
||||
_playerService.Pause();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanNextExecute()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnNextExecute()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion public Methods
|
||||
|
||||
#region EventHandlers
|
||||
/// <summary>
|
||||
/// PlayerService playback state changed event handler.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sending object.</param>
|
||||
/// <param name="args">Event arguments.</param>
|
||||
public void OnPlaybackStateChanged(object sender, PlaybackStateChangedEventArgs args)
|
||||
{
|
||||
OnPropertyChanged("PlayButtonText");
|
||||
PlayCommand.ChangeCanExecute();
|
||||
NextCommand.ChangeCanExecute();
|
||||
PreviousCommand.ChangeCanExecute();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PlayerService media changed event handler.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sending object.</param>
|
||||
/// <param name="args">Event arguments.</param>
|
||||
public void OnMediaChanged(object sender, MediaChangedEventArgs args)
|
||||
{
|
||||
_metadata = args.NewMetadata;
|
||||
OnPropertyChanged("ArtistName");
|
||||
OnPropertyChanged("SongTitle");
|
||||
}
|
||||
#endregion EventHandlers
|
||||
}
|
||||
}
|
@ -15,9 +15,8 @@ namespace Aurora.Design.Components.NavigationMenu
|
||||
public int Id { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Group { get; set; }
|
||||
|
||||
public Type TargetType { get; set; }
|
||||
|
||||
public Type TargetViewModelType { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ namespace Aurora.Design.Components.Queue
|
||||
private static void OnDoubleClickPropertyChanged(BindableObject bindable, object newValue, object oldValue)
|
||||
{
|
||||
Queue control = bindable as Queue;
|
||||
var queueDataGrid = control.FindByName("QueueDataGrid") as DataGrid;
|
||||
var queueDataGrid = control.QueueDataGrid;
|
||||
if (queueDataGrid.GestureRecognizers.Count > 0)
|
||||
{
|
||||
var gestureRecognizer = queueDataGrid.GestureRecognizers.First();
|
||||
|
@ -2,6 +2,8 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using Aurora.Models.Media;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Aurora.Design.Views
|
||||
{
|
||||
@ -11,6 +13,38 @@ namespace Aurora.Design.Views
|
||||
{
|
||||
}
|
||||
|
||||
#region Player
|
||||
public virtual void PlayExecute()
|
||||
{
|
||||
|
||||
}
|
||||
public virtual bool PlayCanExecute()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void NextExecute()
|
||||
{
|
||||
|
||||
}
|
||||
public virtual bool NextCanExecute()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void PreviousExecute()
|
||||
{
|
||||
|
||||
}
|
||||
public virtual bool PreviousCanExecute()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public BaseMedia Media { get; set; }
|
||||
|
||||
#endregion Player
|
||||
|
||||
#region Lifecycle
|
||||
public virtual void OnActive() { }
|
||||
|
||||
|
@ -6,6 +6,8 @@ using Aurora.Design.Components.NavigationMenu;
|
||||
using Aurora.Design.Views.MainView;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
using Aurora.Models.Media;
|
||||
using Aurora.Design.Components.MediaPlayer;
|
||||
|
||||
namespace Aurora.Design.Views.Main
|
||||
{
|
||||
@ -20,7 +22,7 @@ namespace Aurora.Design.Views.Main
|
||||
InitializeComponent();
|
||||
BindingContext = new MainViewModel();
|
||||
_viewModels = new Dictionary<int, BaseViewModel>();
|
||||
MasterPage.ListView.ItemSelected += ListView_ItemSelected;
|
||||
MasterPage.ListView.ItemSelected += OnNavItemSelected;
|
||||
|
||||
Appearing += OnAppearing;
|
||||
}
|
||||
@ -29,7 +31,12 @@ namespace Aurora.Design.Views.Main
|
||||
Appearing -= OnAppearing;
|
||||
}
|
||||
|
||||
private void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
|
||||
public Command PlayCommand { get; set; }
|
||||
public Command PreviousCommand { get; set; }
|
||||
public Command NextCommand { get; set; }
|
||||
public BaseMedia Media { get; set; }
|
||||
|
||||
private void OnNavItemSelected(object sender, SelectedItemChangedEventArgs e)
|
||||
{
|
||||
var item = e.SelectedItem as NavigationItem;
|
||||
if (item == null)
|
||||
@ -54,6 +61,14 @@ namespace Aurora.Design.Views.Main
|
||||
vm = (BaseViewModel)Activator.CreateInstance(item.TargetViewModelType);
|
||||
_viewModels.Add(item.Id, vm);
|
||||
}
|
||||
|
||||
//Assign player controls to viewmodel
|
||||
Player player = (Player)ContentPage.FindByName("Player");
|
||||
player.PlayButtonCommand = new Command(vm.PlayExecute, vm.PlayCanExecute);
|
||||
player.NextButtonCommand = new Command(vm.NextExecute, vm.NextCanExecute);
|
||||
player.PreviousButtonCommand = new Command(vm.PreviousExecute, vm.PreviousCanExecute);
|
||||
vm.Media = this.Media;
|
||||
|
||||
//Activate viewmodel
|
||||
vm.OnActive();
|
||||
|
||||
@ -98,6 +113,11 @@ namespace Aurora.Design.Views.Main
|
||||
|
||||
view.BindingContext = vm;
|
||||
_lastViewModel = vm;
|
||||
Player player = (Player)ContentPage.FindByName("Player");
|
||||
player.PlayButtonCommand = new Command(vm.PlayExecute, vm.PlayCanExecute);
|
||||
player.NextButtonCommand = new Command(vm.NextExecute, vm.NextCanExecute);
|
||||
player.PreviousButtonCommand = new Command(vm.PreviousExecute, vm.PreviousCanExecute);
|
||||
vm.Media = this.Media;
|
||||
vm.OnActive();
|
||||
|
||||
ContentPresenter viewContent = (ContentPresenter)ContentPage.Content.FindByName("ViewContent");
|
||||
@ -105,6 +125,7 @@ namespace Aurora.Design.Views.Main
|
||||
|
||||
MasterPage.ListView.SelectedItem = screenList.FirstOrDefault();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
Grid.Row="0"
|
||||
x:Name="ViewContent"/>
|
||||
<mp:Player
|
||||
x:Name="Player"
|
||||
Grid.Row="1"
|
||||
HorizontalOptions="CenterAndExpand"
|
||||
VerticalOptions="End"
|
||||
|
@ -17,6 +17,7 @@ namespace Aurora.Design.Views.Party
|
||||
{
|
||||
SelectingHost,
|
||||
InParty,
|
||||
Hosting,
|
||||
Connecting,
|
||||
}
|
||||
|
||||
@ -51,6 +52,10 @@ namespace Aurora.Design.Views.Party
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Publc property for the members list
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public ObservableCollection<PartyMember> Members
|
||||
{
|
||||
get
|
||||
@ -68,11 +73,19 @@ namespace Aurora.Design.Views.Party
|
||||
get { return _state == PartyState.SelectingHost; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Public property indicating the state.
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public bool IsNotSelectingHost
|
||||
{
|
||||
get { return _state != PartyState.SelectingHost; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Public property for queue item source
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public ObservableCollection<BaseMedia> Queue
|
||||
{
|
||||
get
|
||||
@ -88,26 +101,63 @@ namespace Aurora.Design.Views.Party
|
||||
}
|
||||
}
|
||||
|
||||
public Command JoinCommand { get; set; }
|
||||
public Command HostCommand { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Public property for the hostname bindable field
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public string Hostname
|
||||
{
|
||||
get { return _hostname; }
|
||||
set { SetProperty(ref _hostname, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Public property for the currently selected song.
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public BaseMedia SelectedSong
|
||||
{
|
||||
get { return _selectedSong; }
|
||||
set { SetProperty(ref _selectedSong, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Public property for playing media
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public Command PlayCommand { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Public property for join command
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public Command JoinCommand { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pubic property for host command
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public Command HostCommand { get; set; }
|
||||
|
||||
#endregion Properties
|
||||
|
||||
#region Events
|
||||
public override void OnActive()
|
||||
{
|
||||
//TODO
|
||||
//If in party subscribe to events
|
||||
//If in party get events
|
||||
}
|
||||
|
||||
public override void OnInactive()
|
||||
{
|
||||
//TODO
|
||||
//unsubscribe
|
||||
//stop getting events
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An event handler for the client receiving update events
|
||||
/// </summary>
|
||||
@ -154,10 +204,11 @@ namespace Aurora.Design.Views.Party
|
||||
#region Commands
|
||||
private async void OnJoinExecute()
|
||||
{
|
||||
SetState(PartyState.Connecting);
|
||||
ClientService.Instance.Start(Hostname, SettingsService.Instance.DefaultPort.ToString());
|
||||
await JoinParty();
|
||||
|
||||
SetState(PartyState.Connecting);
|
||||
SetState(PartyState.InParty);
|
||||
}
|
||||
|
||||
private bool CanJoinExecute()
|
||||
@ -167,15 +218,24 @@ namespace Aurora.Design.Views.Party
|
||||
|
||||
private async void OnHostExecute()
|
||||
{
|
||||
//Change state
|
||||
SetState(PartyState.Connecting);
|
||||
ServerService.Instance.Start();
|
||||
string localHost = ServerService.GetLocalIPAddress();
|
||||
ClientService.Instance.Start(localHost, SettingsService.Instance.DefaultPort.ToString());
|
||||
await JoinParty();
|
||||
|
||||
ClientService.Instance.GetEvents();
|
||||
try
|
||||
{
|
||||
//Execute task without waiting
|
||||
await ClientService.Instance.GetEvents().ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Exception occurred while receiviing events: ", ex.Message);
|
||||
}
|
||||
|
||||
//Change state
|
||||
SetState(PartyState.Connecting);
|
||||
SetState(PartyState.Hosting);
|
||||
}
|
||||
|
||||
private bool CanHostExecute()
|
||||
@ -243,6 +303,22 @@ namespace Aurora.Design.Views.Party
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LeaveParty()
|
||||
{
|
||||
//Stop receiving events
|
||||
ClientService.Instance.StopEvents();
|
||||
|
||||
//Unsubscribe
|
||||
UnsubscribeAllRequest unsubscribeReq = new UnsubscribeAllRequest();
|
||||
await ClientService.Instance.RemoteEventClient.UnsubscribeFromAllAsync(unsubscribeReq);
|
||||
|
||||
//Leave party
|
||||
LeavePartyRequest leaveReq = new LeavePartyRequest();
|
||||
await ClientService.Instance.RemotePartyClient.LeavePartyAsync(leaveReq);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh members list.
|
||||
/// </summary>
|
||||
|
@ -11,14 +11,20 @@ namespace Aurora.Design.Views.Songs
|
||||
#region Fields
|
||||
private ObservableCollection<BaseMedia> _songsList;
|
||||
private BaseMedia _selectedSong;
|
||||
private BaseMedia _playingSong;
|
||||
private PlayerService _player;
|
||||
|
||||
#endregion Fields
|
||||
|
||||
#region Constructor
|
||||
public SongsViewModel()
|
||||
{
|
||||
_player = PlayerService.Instance;
|
||||
_songsList = new ObservableCollection<BaseMedia>();
|
||||
PlayCommand = new Command(PlayExecute);
|
||||
PlayCommand = new Command(PlayExecute, PlayCanExecute);
|
||||
|
||||
_player.PlaybackStateChanged += OnPlaybackStateChanged;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
@ -37,6 +43,12 @@ namespace Aurora.Design.Views.Songs
|
||||
set { SetProperty(ref _selectedSong, value); }
|
||||
}
|
||||
|
||||
public BaseMedia PlayingSong
|
||||
{
|
||||
get { return _playingSong; }
|
||||
set { SetProperty(ref _playingSong, value); }
|
||||
}
|
||||
|
||||
public Command PlayCommand { get; private set; }
|
||||
|
||||
#endregion Properties
|
||||
@ -48,13 +60,84 @@ namespace Aurora.Design.Views.Songs
|
||||
SongsList = LibraryService.Instance.GetLibrary();
|
||||
}
|
||||
|
||||
public void PlayExecute()
|
||||
{
|
||||
PlayerService.Instance.LoadMedia(_selectedSong);
|
||||
PlayerService.Instance.Play();
|
||||
}
|
||||
|
||||
#endregion Methods
|
||||
|
||||
#region Commmands
|
||||
public override bool PreviousCanExecute()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public override void PreviousExecute()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override bool PlayCanExecute()
|
||||
{
|
||||
switch (_player.PlaybackState)
|
||||
{
|
||||
case PlaybackState.Buffering:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
case PlaybackState.Playing:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
case PlaybackState.Stopped:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public async override void PlayExecute()
|
||||
{
|
||||
if (!_player.IsMediaLoaded(_selectedSong))
|
||||
{
|
||||
await _player.LoadMedia(_selectedSong).ConfigureAwait(true);
|
||||
}
|
||||
|
||||
_player.Play();
|
||||
switch (_player.PlaybackState)
|
||||
{
|
||||
case PlaybackState.Buffering:
|
||||
{
|
||||
_player.Play();
|
||||
break;
|
||||
}
|
||||
case PlaybackState.Playing:
|
||||
{
|
||||
_player.Pause();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool NextCanExecute()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void NextExecute()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion Commands
|
||||
|
||||
#region Events
|
||||
/// <summary>
|
||||
/// PlayerService playback state changed event handler.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sending object.</param>
|
||||
/// <param name="args">Event arguments.</param>
|
||||
public void OnPlaybackStateChanged(object sender, PlaybackStateChangedEventArgs args)
|
||||
{
|
||||
OnPropertyChanged("PlayButtonText");
|
||||
}
|
||||
|
||||
#endregion Events
|
||||
}
|
||||
}
|
||||
|
@ -93,5 +93,13 @@ namespace Aurora.Services.ClientService
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void StopEvents()
|
||||
{
|
||||
if (!_eventCancellationTokenSource.IsCancellationRequested)
|
||||
{
|
||||
_eventCancellationTokenSource.Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -34,6 +34,19 @@ namespace Aurora.Services.PlayerService
|
||||
get { return _state; }
|
||||
}
|
||||
|
||||
public bool IsLoaded
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._currentMedia == null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsMediaLoaded(BaseMedia media)
|
||||
{
|
||||
return _currentMedia == media;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load media into the media player.
|
||||
/// </summary>
|
||||
@ -51,9 +64,13 @@ namespace Aurora.Services.PlayerService
|
||||
_mediaPlayer.Stopped += OnStopped;
|
||||
md.Dispose();
|
||||
|
||||
if (MediaChanged != null)
|
||||
{
|
||||
MediaChanged.Invoke(this, new MediaChangedEventArgs(_currentMedia.Metadata));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Play currently loaded media.
|
||||
/// </summary>
|
||||
@ -62,8 +79,12 @@ namespace Aurora.Services.PlayerService
|
||||
PlaybackState oldState = _state;
|
||||
_state = PlaybackState.Playing;
|
||||
_mediaPlayer.Play();
|
||||
|
||||
if (PlaybackStateChanged != null)
|
||||
{
|
||||
PlaybackStateChanged.Invoke(this, new PlaybackStateChangedEventArgs(oldState, _state));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pause currently loaded media.
|
||||
@ -73,8 +94,12 @@ namespace Aurora.Services.PlayerService
|
||||
PlaybackState oldState = _state;
|
||||
_state = PlaybackState.Buffering;
|
||||
_mediaPlayer.Pause();
|
||||
|
||||
if (PlaybackStateChanged != null)
|
||||
{
|
||||
PlaybackStateChanged.Invoke(this, new PlaybackStateChangedEventArgs(oldState, _state));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop currently loaded media.
|
||||
@ -84,9 +109,14 @@ namespace Aurora.Services.PlayerService
|
||||
PlaybackState oldState = _state;
|
||||
_state = PlaybackState.Stopped;
|
||||
_mediaPlayer.Stop();
|
||||
|
||||
if (PlaybackStateChanged != null)
|
||||
{
|
||||
PlaybackStateChanged.Invoke(this, new PlaybackStateChangedEventArgs(oldState, _state));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Enqueue(BaseMedia song)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
@ -103,6 +133,7 @@ namespace Aurora.Services.PlayerService
|
||||
private void Unload()
|
||||
{
|
||||
_currentMedia.Unload();
|
||||
_currentMedia = null;
|
||||
_mediaPlayer.Media = null;
|
||||
_mediaPlayer = null;
|
||||
}
|
||||
|
Reference in New Issue
Block a user