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:
@ -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();
|
||||
|
Reference in New Issue
Block a user