using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using OwlCore.Extensions; using StrixMusic.Sdk.AppModels; using StrixMusic.Sdk.ViewModels; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace StrixMusic.Sdk.WinUI.Controls.Shells { /// /// A Templated for the NowPlaying bar in a Shell. /// public partial class NowPlayingBar : Control { /// /// Initializes a new instance of the class. /// public NowPlayingBar() { this.DefaultStyleKey = typeof(NowPlayingBar); this.DataContext = this; AttachEvents(); } private void AttachEvents() { Unloaded += NowPlayingBar_Unloaded; foreach (var device in Devices) AttachEvents(device); } private void DetachEvents() { Unloaded -= NowPlayingBar_Unloaded; foreach (var device in Devices) DetachEvents(device); } /// /// Attaches events to the provided devices. /// protected virtual void AttachEvents(IDevice device) { device.IsActiveChanged += Device_IsActiveChanged; } /// /// Detaches events from the provided devices. /// protected virtual void DetachEvents(IDevice device) { device.IsActiveChanged -= Device_IsActiveChanged; } private void Device_IsActiveChanged(object sender, bool e) { if (e) { var device = (IDevice)sender; if (device is not DeviceViewModel dvm) dvm = new DeviceViewModel(device); ActiveDevice = dvm; } } private void NowPlayingBar_Unloaded(object sender, RoutedEventArgs e) { DetachEvents(); } /// /// Holds active devices and track playback information. /// public DeviceViewModel? ActiveDevice { get => (DeviceViewModel?)GetValue(ActiveDeviceProperty); set => SetValue(ActiveDeviceProperty, value); } /// /// A list of devices that can be selected from for displaying playback status. /// public IReadOnlyList Devices { get => (IReadOnlyList)GetValue(DevicesProperty); set => SetValue(DevicesProperty, value); } /// /// The backing dependency property for . /// public static readonly DependencyProperty DevicesProperty = DependencyProperty.Register(nameof(Devices), typeof(IReadOnlyList), typeof(NowPlayingBar), new PropertyMetadata(new List(), (s, e) => s.Cast().OnDevicesChanged(e.OldValue.Cast>(), e.NewValue.Cast>()))); /// /// Backing dependency property for . /// public static readonly DependencyProperty ActiveDeviceProperty = DependencyProperty.Register(nameof(ActiveDevice), typeof(DeviceViewModel), typeof(NowPlayingBar), new PropertyMetadata(null, (s, e) => s.Cast().OnActiveDeviceChanged(e.OldValue.Cast(), e.NewValue.Cast()))); /// /// Callback for when the property is changed. /// protected virtual void OnActiveDeviceChanged(DeviceViewModel? oldValue, DeviceViewModel? newValue) { } /// /// Callback for when the property is changed. /// protected virtual void OnDevicesChanged(IReadOnlyList oldValue, IReadOnlyList newValue) { foreach (var item in oldValue) DetachEvents(item); foreach (var item in newValue) AttachEvents(item); var targetDevice = newValue.FirstOrDefault(x => x.IsActive); if (targetDevice is null) return; if (targetDevice is not DeviceViewModel dvm) dvm = new DeviceViewModel(targetDevice); ActiveDevice = dvm; } } }