Working player contained within main page and control delegated to viewmodels

This commit is contained in:
watsonb8 2019-11-08 19:54:51 -05:00
parent 794b4739b1
commit 63efcdad69
7 changed files with 134 additions and 75 deletions

View File

@ -14,11 +14,9 @@
<StackLayout
Grid.Column="0">
<Label
x:Name="SongTitleLabel"
Text="{Binding SongTitle}"/>
x:Name="SongTitleLabel"/>
<Label
x:Name="ArtistNameLabel"
Text="{Binding ArtistName}"/>
x:Name="ArtistNameLabel"/>
</StackLayout>
<StackLayout
Grid.Column="1"
@ -26,19 +24,16 @@
<Button
Text="Previous"
x:Name="PreviousButton"
Command="{Binding PreviousCommand}"
WidthRequest="100"
HeightRequest="50"/>
<Button
x:Name="PlayButton"
Text="{Binding PlayButtonText}"
Command="{Binding PlayCommand}"
Text="Play/Pause"
WidthRequest="100"
HeightRequest="50"/>
<Button
Text="Next"
x:Name="NextButton"
Command="{Binding NextCommand}"
WidthRequest="100"
HeightRequest="50"/>
</StackLayout>

View File

@ -7,9 +7,6 @@ namespace Aurora.Design.Components.MediaPlayer
{
public Player()
{
// this.PreviousButton.Clicked += OnPreviousButtonClicked;
// this.PlayButton.Clicked += OnPlayButtonClicked;
// this.NextButton.Clicked += OnNextButtonClicked;
InitializeComponent();
}
@ -33,7 +30,7 @@ namespace Aurora.Design.Components.MediaPlayer
}
}
private static void OnSongTitlePropertyChanged(BindableObject bindable, object newValue, object oldValue)
private static void OnSongTitlePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
Player component = bindable as Player;
component.SongTitleLabel.Text = (string)newValue;
@ -60,7 +57,7 @@ namespace Aurora.Design.Components.MediaPlayer
}
}
private static void OnArtistNamePropertyChanged(BindableObject bindable, object newValue, object oldValue)
private static void OnArtistNamePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
Player component = bindable as Player;
component.ArtistNameLabel.Text = (string)newValue;

View File

@ -4,44 +4,71 @@ using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Aurora.Models.Media;
using Xamarin.Forms;
using Aurora.Design.Views.Main;
namespace Aurora.Design.Views
{
public class BaseViewModel : INotifyPropertyChanged
{
private BaseMedia _baseMedia;
public BaseViewModel()
{
}
#region Player
public virtual void PlayExecute()
{
}
public virtual bool PlayCanExecute()
/// <summary>
/// Command event handler for player play button
/// </summary>
public virtual void OnPlayExecute() { }
public virtual bool CanPlayExecute()
{
return true;
}
public virtual void NextExecute()
{
}
public virtual bool NextCanExecute()
/// <summary>
/// Command event handler for player next button
/// </summary>
public virtual void OnNextExecute() { }
public virtual bool CanNextExecute()
{
return true;
}
public virtual void PreviousExecute()
{
}
public virtual bool PreviousCanExecute()
/// <summary>
/// Command event handler for player previous button
/// </summary>
public virtual void OnPreviousExecute() { }
public virtual bool CanPreviousExecute()
{
return true;
}
public BaseMedia Media { get; set; }
/// <summary>
/// Model for the currently playing music.
/// </summary>
/// <value></value>
public BaseMedia Media
{
get
{
return this._baseMedia;
}
set
{
if (value != _baseMedia)
{
_baseMedia = value;
if (this.SetPlayerMetadata != null)
{
SetPlayerMetadata.Invoke(value);
}
}
}
}
public SetPlayerMetadataDelegate SetPlayerMetadata { get; set; }
#endregion Player

View File

@ -11,8 +11,14 @@ using Aurora.Design.Components.MediaPlayer;
namespace Aurora.Design.Views.Main
{
/// <summary>
/// Delegate for updating player metadata
/// </summary>
/// <param name="media"></param>
public delegate void SetPlayerMetadataDelegate(BaseMedia media);
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MainView : MasterDetailPage
public partial class MainView : MasterDetailPage, IDisposable
{
private Dictionary<int, BaseViewModel> _viewModels;
private BaseViewModel _lastViewModel;
@ -26,16 +32,17 @@ namespace Aurora.Design.Views.Main
Appearing += OnAppearing;
}
~MainView()
public void Dispose()
{
Appearing -= OnAppearing;
}
public Command PlayCommand { get; set; }
public Command PreviousCommand { get; set; }
public Command NextCommand { get; set; }
public BaseMedia Media { get; set; }
/// <summary>
/// Event handler for side bar items being selected
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnNavItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = e.SelectedItem as NavigationItem;
@ -60,24 +67,22 @@ namespace Aurora.Design.Views.Main
//Instantiate new view model
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();
//Deactivate last viewModel
_lastViewModel.OnInactive();
//Unasign deactivating vm
UnassignPlayerControls(_lastViewModel);
//Assign viewModel
_lastViewModel = vm;
view.BindingContext = vm;
//Assign player controls to viewmodel
AssignPlayerControls(vm);
ContentPresenter viewContent = (ContentPresenter)ContentPage.Content.FindByName("ViewContent");
viewContent.Content = view;
@ -113,19 +118,50 @@ 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;
AssignPlayerControls(vm);
vm.OnActive();
ContentPresenter viewContent = (ContentPresenter)ContentPage.Content.FindByName("ViewContent");
viewContent.Content = view;
MasterPage.ListView.SelectedItem = screenList.FirstOrDefault();
}
/// <summary>
/// Unassign setplayer delegate to prevent vms from changing player info when inactive
/// </summary>
/// <param name="vm"></param>
private void UnassignPlayerControls(BaseViewModel vm)
{
vm.SetPlayerMetadata = null;
}
/// <summary>
/// Assign main views music player controls to a view model
/// </summary>
/// <param name="vm">BaseViewModel to assign controls to</param>
private void AssignPlayerControls(BaseViewModel vm)
{
Player player = (Player)ContentPage.FindByName("Player");
player.PlayButtonCommand = new Command(vm.OnPlayExecute, vm.CanPlayExecute);
player.NextButtonCommand = new Command(vm.OnNextExecute, vm.CanNextExecute);
player.PreviousButtonCommand = new Command(vm.OnPreviousExecute, vm.CanPreviousExecute);
//Assign SetPlayer delegate
vm.SetPlayerMetadata = SetPlayerDelegate;
}
private void SetPlayerDelegate(BaseMedia media)
{
Player player = (Player)ContentPage.FindByName("Player");
if (media.Metadata is AudioMetadata)
{
AudioMetadata meta = (AudioMetadata)media.Metadata;
player.ArtistName = meta.Artist;
player.SongTitle = meta.Title;
}
}
}
}

View File

@ -6,7 +6,8 @@
xmlns:mp="clr-namespace:Aurora.Design.Components.MediaPlayer"
x:Class="Aurora.Design.Views.MainView.PageContainer">
<ContentPage.Content>
<Grid>
<Grid
x:Name="Grid">
<Grid.RowDefinitions>
<RowDefinition
Height="*"/>

View File

@ -39,7 +39,7 @@ namespace Aurora.Design.Views.Party
SetState(PartyState.SelectingHost);
PlayCommand = new Command(PlayExecute);
PlayCommand = new Command(OnPlayExecute);
//Hook up event handler
ClientService.Instance.EventReceived += this.OnEventReceived;
@ -182,7 +182,7 @@ namespace Aurora.Design.Views.Party
Port = derivedEvent.Member.Port
};
AddMember(member);
Members.Add(member);
break;
}
@ -315,8 +315,6 @@ namespace Aurora.Design.Views.Party
//Leave party
LeavePartyRequest leaveReq = new LeavePartyRequest();
await ClientService.Instance.RemotePartyClient.LeavePartyAsync(leaveReq);
}
/// <summary>
@ -339,16 +337,27 @@ namespace Aurora.Design.Views.Party
OnPropertyChanged("IsNotSelectingHost");
}
private void AddMember(PartyMember member)
public override async void OnPlayExecute()
{
Members.Add(member);
}
public async void PlayExecute()
{
await PlayerService.Instance.LoadMedia(_selectedSong);
await PlayerService.Instance.LoadMedia(_selectedSong).ConfigureAwait(true);
PlayerService.Instance.Play();
}
public override bool CanPlayExecute()
{
return this._state == PartyState.Hosting;
}
public override bool CanNextExecute()
{
return this._state == PartyState.Hosting;
}
public override bool CanPreviousExecute()
{
return this._state == PartyState.Hosting;
}
#endregion Private Methods
}
}

View File

@ -11,7 +11,6 @@ namespace Aurora.Design.Views.Songs
#region Fields
private ObservableCollection<BaseMedia> _songsList;
private BaseMedia _selectedSong;
private BaseMedia _playingSong;
private PlayerService _player;
#endregion Fields
@ -21,7 +20,7 @@ namespace Aurora.Design.Views.Songs
{
_player = PlayerService.Instance;
_songsList = new ObservableCollection<BaseMedia>();
PlayCommand = new Command(PlayExecute, PlayCanExecute);
PlayCommand = new Command(OnPlayExecute, CanPlayExecute);
_player.PlaybackStateChanged += OnPlaybackStateChanged;
@ -43,12 +42,6 @@ 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
@ -63,16 +56,16 @@ namespace Aurora.Design.Views.Songs
#endregion Methods
#region Commmands
public override bool PreviousCanExecute()
public override bool CanPreviousExecute()
{
return true;
}
public override void PreviousExecute()
public override void OnPreviousExecute()
{
}
public override bool PlayCanExecute()
public override bool CanPlayExecute()
{
switch (_player.PlaybackState)
{
@ -92,11 +85,12 @@ namespace Aurora.Design.Views.Songs
return false;
}
public async override void PlayExecute()
public async override void OnPlayExecute()
{
if (!_player.IsMediaLoaded(_selectedSong))
base.Media = _selectedSong;
if (!_player.IsMediaLoaded(base.Media))
{
await _player.LoadMedia(_selectedSong).ConfigureAwait(true);
await _player.LoadMedia(base.Media).ConfigureAwait(true);
}
_player.Play();
@ -115,12 +109,12 @@ namespace Aurora.Design.Views.Songs
}
}
public override bool NextCanExecute()
public override bool CanNextExecute()
{
return true;
}
public override void NextExecute()
public override void OnNextExecute()
{
}