More work on MC visuals

This commit is contained in:
TheXamlGuy
2024-02-03 21:47:32 +00:00
parent dfa12cf9f1
commit 0191080e14
15 changed files with 111 additions and 33 deletions
@@ -7,7 +7,8 @@ public interface IMediaButtonViewModel :
{
IRelayCommand? InvokeCommand { get; set; }
bool IsEnabled { get; set; }
string? Button { get; set; }
string? State { get; set; }
}
@@ -1,3 +1,3 @@
namespace Hyperbar.Widget.MediaController.Windows;
public record MediaButton(bool IsEnabled);
public record MediaButton<TMediaButton>(MediaButtonState State);
@@ -0,0 +1,7 @@
namespace Hyperbar.Widget.MediaController.Windows;
public record MediaButtonDisabled :
MediaButtonState
{
public override string ToString() => "Disabled";
}
@@ -0,0 +1,7 @@
namespace Hyperbar.Widget.MediaController.Windows;
public record MediaButtonEnabled :
MediaButtonState
{
public override string ToString() => "Enabled";
}
@@ -0,0 +1,7 @@
namespace Hyperbar.Widget.MediaController.Windows;
public record MediaButtonPaused :
MediaButtonState
{
public override string ToString() => "Paused";
}
@@ -0,0 +1,7 @@
namespace Hyperbar.Widget.MediaController.Windows;
public record MediaButtonPlaying :
MediaButtonState
{
public override string ToString() => "Playing";
}
@@ -0,0 +1,3 @@
namespace Hyperbar.Widget.MediaController.Windows;
public record MediaButtonState;
@@ -0,0 +1,7 @@
namespace Hyperbar.Widget.MediaController.Windows;
public record MediaButtonStopped :
MediaButtonState
{
public override string ToString() => "Stopped";
}
@@ -23,7 +23,6 @@
Height="{StaticResource ButtonHeight}"
Padding="{StaticResource ButtonPadding}"
Command="{x:Bind ViewModel.InvokeCommand}"
Content="{x:Bind ViewModel.State}"
FontFamily="{StaticResource SymbolThemeFontFamily}"
FontSize="16"
IsEnabled="False">
@@ -36,7 +35,7 @@
<VisualStateGroup>
<VisualState x:Name="MediaPreviousButtonState">
<VisualState.StateTriggers>
<triggers:IsEqualStateTrigger Value="{Binding State}" To="MediaPreviousButton" />
<triggers:IsEqualStateTrigger Value="{Binding Button}" To="MediaPreviousButton" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Button.Content" Value="&#xE892;" />
@@ -44,7 +43,7 @@
</VisualState>
<VisualState x:Name="MediaNextButtonState">
<VisualState.StateTriggers>
<triggers:IsEqualStateTrigger Value="{Binding State}" To="MediaNextButton" />
<triggers:IsEqualStateTrigger Value="{Binding Button}" To="MediaNextButton" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Button.Content" Value="&#xE893;" />
@@ -52,14 +51,32 @@
</VisualState>
</VisualStateGroup>
<VisualStateGroup>
<VisualState x:Name="IsEnabledState">
<VisualState x:Name="EnabledState">
<VisualState.StateTriggers>
<triggers:IsEqualStateTrigger Value="{Binding IsEnabled}" To="True" />
<triggers:IsEqualStateTrigger Value="{Binding State}" To="Enabled" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Button.IsEnabled" Value="True" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PlayingState">
<VisualState.StateTriggers>
<triggers:IsEqualStateTrigger Value="{Binding State}" To="Playing" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Button.Content" Value="&#xE769;" />
<Setter Target="Button.IsEnabled" Value="True" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PausedState">
<VisualState.StateTriggers>
<triggers:IsEqualStateTrigger Value="{Binding State}" To="Paused" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Button.Content" Value="&#xE768;" />
<Setter Target="Button.IsEnabled" Value="True" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Button>
@@ -9,24 +9,22 @@ public partial class MediaButtonViewModel<TMediaButton>(IServiceFactory serviceF
ITemplateFactory templateFactory,
IRelayCommand invokeCommand) :
WidgetComponentViewModel(serviceFactory, mediator, disposer, templateFactory),
INotificationHandler<Changed<TMediaButton>>,
INotificationHandler<Changed<MediaButton<TMediaButton>>>,
IMediaButtonViewModel
where TMediaButton :
MediaButton
{
[ObservableProperty]
private IRelayCommand? invokeCommand = invokeCommand;
[ObservableProperty]
private bool isEnabled;
private string? state;
[ObservableProperty]
private string? state = $"{typeof(TMediaButton).Name}";
private string? button = $"{typeof(TMediaButton).Name}";
public Task Handle(Changed<TMediaButton> args,
public Task Handle(Changed<MediaButton<TMediaButton>> args,
CancellationToken cancellationToken)
{
IsEnabled = args.Value is not null && args.Value.IsEnabled;
State = $"{args.Value?.State}";
return Task.CompletedTask;
}
@@ -1,23 +1,24 @@
using System.Collections.Concurrent;
using System.Diagnostics;
using Windows.Media.Control;
using Windows.Media.Control;
using Windows.Storage.Streams;
namespace Hyperbar.Widget.MediaController.Windows;
public class MediaController :
INotificationHandler<Request<MediaPrevious>>,
INotificationHandler<Request<MediaPlayPause>>,
INotificationHandler<Request<MediaNext>>,
INotificationHandler<Request<MediaInformation>>,
INotificationHandler<Request<MediaPreviousButton>>,
INotificationHandler<Request<MediaPlayPauseButton>>,
INotificationHandler<Request<MediaNextButton>>,
IDisposable
{
private readonly AsyncLock asyncLock = new();
private readonly IDisposer disposer;
private readonly IMediator mediator;
private readonly GlobalSystemMediaTransportControlsSession session;
private bool isNextEnabled;
private bool isPreviousEnabled;
private GlobalSystemMediaTransportControlsSessionPlaybackStatus playbackStatus;
public MediaController(IMediator mediator,
@@ -63,6 +64,28 @@ public class MediaController :
public async Task Handle(Request<MediaNextButton> args,
CancellationToken cancellationToken) => await UpdateMediaStateAsync();
public async Task Handle(Request<MediaPlayPause> args,
CancellationToken cancellationToken)
{
GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo =
session.GetPlaybackInfo();
if (playbackInfo.PlaybackStatus is GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing)
{
await session.TryPauseAsync();
}
if (playbackInfo.PlaybackStatus is GlobalSystemMediaTransportControlsSessionPlaybackStatus.Paused)
{
await session.TryPlayAsync();
}
await UpdateMediaStateAsync();
}
public async Task Handle(Request<MediaPlayPauseButton> args,
CancellationToken cancellationToken) => await UpdateMediaStateAsync();
private async void OnMediaPropertiesChanged(GlobalSystemMediaTransportControlsSession sender,
MediaPropertiesChangedEventArgs args)
{
@@ -103,9 +126,6 @@ public class MediaController :
}
}
private bool isPreviousEnabled;
private bool isNextEnabled;
private async Task UpdateMediaStateAsync()
{
try
@@ -113,11 +133,18 @@ public class MediaController :
GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo =
session.GetPlaybackInfo();
await mediator.PublishAsync(new Changed<MediaButton<MediaPlayPauseButton>>(new
MediaButton<MediaPlayPauseButton>(playbackInfo.PlaybackStatus is
GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing ?
new MediaButtonPlaying() :
new MediaButtonPaused())));
bool isPreviousEnabled = playbackInfo.Controls.IsPreviousEnabled;
if (this.isPreviousEnabled != isPreviousEnabled)
{
await mediator.PublishAsync(new Changed<MediaPreviousButton>(new
MediaPreviousButton(isPreviousEnabled)));
await mediator.PublishAsync(new Changed<MediaButton<MediaPreviousButton>>(new
MediaButton<MediaPreviousButton>(isPreviousEnabled ? new MediaButtonEnabled() :
new MediaButtonDisabled())));
this.isPreviousEnabled = isPreviousEnabled;
}
@@ -125,8 +152,9 @@ public class MediaController :
bool isNextEnabled = playbackInfo.Controls.IsNextEnabled;
if (this.isNextEnabled != isNextEnabled)
{
await mediator.PublishAsync(new Changed<MediaNextButton>(new
MediaNextButton(isNextEnabled)));
await mediator.PublishAsync(new Changed<MediaButton<MediaNextButton>>(new
MediaButton<MediaNextButton>(isNextEnabled ? new MediaButtonEnabled() :
new MediaButtonDisabled())));
this.isNextEnabled = isNextEnabled;
}
@@ -22,7 +22,7 @@ public class MediaControllerViewModel :
await mediator.PublishAsync<Request<MediaPrevious>>()));
Add<MediaButtonViewModel<MediaPlayPauseButton>>(new RelayCommand(async () =>
await mediator.PublishAsync<Request<MediaPlayPauseButton>>()));
await mediator.PublishAsync<Request<MediaPlayPause>>()));
Add<MediaButtonViewModel<MediaNextButton>>(new RelayCommand(async () =>
await mediator.PublishAsync<Request<MediaNext>>()));
@@ -1,4 +1,3 @@
namespace Hyperbar.Widget.MediaController.Windows;
public record MediaNextButton(bool IsEnabled) :
MediaButton(IsEnabled);
public record MediaNextButton;
@@ -1,4 +1,3 @@
namespace Hyperbar.Widget.MediaController.Windows;
public record MediaPlayPauseButton(bool IsEnabled) :
MediaButton(IsEnabled);
public record MediaPlayPauseButton;
@@ -1,5 +1,3 @@
namespace Hyperbar.Widget.MediaController.Windows;
public record MediaPreviousButton(bool IsEnabled) :
MediaButton(IsEnabled);
public record MediaPreviousButton;