more settings work

This commit is contained in:
TheXamlGuy
2024-02-11 22:18:40 +00:00
parent 812556f8b0
commit 6e738becd4
33 changed files with 152 additions and 80 deletions
@@ -1,17 +1,21 @@
using Microsoft.UI.Xaml;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Markup;
namespace Hyperbar.UI.Windows;
public class ViewModelTemplateSelector(IViewModelTemplateProvider descriptors) :
public class ViewModelTemplateSelector :
DataTemplateSelector,
IViewModelTemplateSelector
{
protected override DataTemplate SelectTemplateCore(object item)
{
return descriptors.Get(item.GetType().Name) is Hyperbar.IViewModelTemplate descriptor
? CreateDataTemplate(descriptor)
return item is IObservableViewModel observableViewModel && observableViewModel.ServiceProvider.GetService<IViewModelTemplateProvider>()
is IViewModelTemplateProvider viewModelTemplateProvider
? viewModelTemplateProvider.Get(item.GetType().Name) is IViewModelTemplate viewModelTemplate
? CreateDataTemplate(viewModelTemplate)
: new DataTemplate()
: new DataTemplate();
}
@@ -19,12 +23,12 @@ public class ViewModelTemplateSelector(IViewModelTemplateProvider descriptors) :
DependencyObject container) =>
SelectTemplateCore(item);
private static DataTemplate CreateDataTemplate(Hyperbar.IViewModelTemplate descriptor)
private static DataTemplate CreateDataTemplate(IViewModelTemplate template)
{
string xamlString = @$"
<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:ui=""using:{descriptor.TemplateType.Namespace}"">
<ui:{descriptor.TemplateType.Name} />
xmlns:ui=""using:{template.ViewType.Namespace}"">
<ui:{template.ViewType.Name} />
</DataTemplate>";
return (DataTemplate)XamlReader.Load(xamlString);
@@ -14,7 +14,7 @@ public class MediaControllerViewModel :
ISubscriber subscriber,
IDisposer disposer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
{
viewModelTemplateSelector = viewModelTemplateSelector;
ViewModelTemplateSelector = viewModelTemplateSelector;
Add<MediaInformationViewModel>();
@@ -3,8 +3,9 @@
x:Class="Hyperbar.Widget.MediaController.Windows.MediaControllerWidgetView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<FlipView
<Button>safsfd</Button>
<!--<FlipView
Width="360"
ItemTemplateSelector="{Binding ViewModelTemplateSelector}"
ItemsSource="{Binding}" />
ItemsSource="{Binding}" />-->
</UserControl>
@@ -1,6 +1,4 @@
using Hyperbar.Widget;
namespace Hyperbar.Widget.Primary.Windows;
namespace Hyperbar.Widget.Primary.Windows;
[NotificationHandler(nameof(PrimaryWidgetViewModel))]
public class PrimaryWidgetViewModel(IServiceProvider serviceProvider,
@@ -18,8 +18,8 @@ public static class IServiceCollectionExtensions
services.AddSingleton(provider.GetRequiredService<IList<IXamlMetadataProvider>>());
services.AddSingleton(provider.GetRequiredService<IDispatcher>());
services.AddTransient<IViewModelTemplateSelector, UI.Windows.ViewModelTemplateSelector>();
services.AddTransient<IViewModelTemplateProvider, ViewModelTemplateProvider>();
services.AddTransient<IViewModelTemplateSelector, ViewModelTemplateSelector>();
services.AddScoped<IVirtualKeyboard, VirtualKeyboard>();
services.AddHandler<KeyAcceleratorHandler>();
@@ -1,4 +1,3 @@
using Hyperbar.Widget;
using Microsoft.UI.Xaml.Controls;
namespace Hyperbar.Widget.Windows;
@@ -10,6 +10,8 @@ public static class IServiceCollectionExtensions
services.AddTransient<IInitializer, WidgetExtensionInitializer>();
services.AddTransient<IFactory<Type, IWidget>, WidgetFactory>();
services.AddSingleton<IWidgetHostCollection, WidgetHostCollection>();
services.AddHandler<WidgetExtensionEnumerator>();
services.AddHandler<WidgetExtensionHandler>();
services.AddHandler<WidgetHostHandler>();
@@ -33,7 +35,7 @@ public static class IServiceCollectionExtensions
services.AddKeyedTransient(typeof(IWidgetViewModel), key, contentType);
services.TryAddKeyedTransient(key, (provider, key) => provider.GetService<IWidgetView>()!);
services.AddTransient<IViewModelTemplate>(provider => new ViewModelTemplate { ViewModelType = contentType, TemplateType = templateType, Key = key });
services.AddTransient<IViewModelTemplate>(provider => new ViewModelTemplate { ViewModelType = contentType, ViewType = templateType, Key = key });
return services;
}
@@ -56,7 +58,7 @@ public static class IServiceCollectionExtensions
services.AddTransient<IViewModelTemplate>(provider =>
new ViewModelTemplate { ViewModelType = contentType,
TemplateType = templateType, Key = key });
ViewType = templateType, Key = key });
return services;
}
+7
View File
@@ -0,0 +1,7 @@
namespace Hyperbar.Widget;
public interface IWidgetHostCollection :
IEnumerable<IWidgetHost>
{
void Add(IWidgetHost widgetHost);
}
+3 -3
View File
@@ -26,17 +26,17 @@ public class WidgetBuilder :
.ConfigureServices((context, services) =>
{
services.AddSingleton<IWidgetHost, WidgetHost>();
services.AddScoped<IServiceFactory>(provider =>
new ServiceFactory((type, parameters) =>
ActivatorUtilities.CreateInstance(provider, type, parameters!)));
services.AddSingleton<SubscriptionCollection>();
services.AddSingleton<ISubscriptionManager, SubscriptionManager>();
services.AddScoped<SubscriptionCollection>();
services.AddScoped<ISubscriptionManager, SubscriptionManager>();
services.AddTransient<ISubscriber, Subscriber>();
services.AddTransient<IPublisher, Publisher>();
services.AddScoped<IMediator, Mediator>();
services.AddScoped<IDisposer, Disposer>();
services.AddHandler<WidgetAvailabilityChangedHandler>();
+3 -3
View File
@@ -7,16 +7,16 @@ public class WidgetExtensionHandler(IServiceProvider provider,
IProxyServiceCollection<IWidgetBuilder> typedServices) :
INotificationHandler<Create<WidgetExtension>>
{
public async Task Handle(Create<WidgetExtension> notification,
public async Task Handle(Create<WidgetExtension> args,
CancellationToken cancellationToken)
{
if(notification.Value is WidgetExtension widgetExtension)
if(args.Value is WidgetExtension widgetExtension)
{
IWidgetBuilder builder = widgetExtension.Widget.Create();
builder.ConfigureServices(args =>
{
args.AddSingleton(widgetExtension.Assembly);
args.AddTransient(_ => provider.GetRequiredService<IProxyService<IMediator>>());
args.AddTransient(_ => provider.GetRequiredService<IProxyService<IPublisher>>());
args.AddRange(typedServices.Services);
});
+6 -17
View File
@@ -3,24 +3,13 @@ using Microsoft.Extensions.Hosting;
namespace Hyperbar.Widget;
public sealed class WidgetHost :
public sealed class WidgetHost(IServiceProvider services,
IPublisher publisher,
IProxyService<IPublisher> proxyPublisher,
IEnumerable<IHostedService> hostedServices) :
IWidgetHost
{
private readonly IServiceProvider services;
private readonly IPublisher publisher;
private readonly IProxyService<IMediator> proxyMediator;
private readonly IEnumerable<IHostedService> hostedServices;
public WidgetHost(IServiceProvider services,
IPublisher publisher,
IProxyService<IMediator> proxyMediator,
IEnumerable<IHostedService> hostedServices)
{
this.services = services;
this.publisher = publisher;
this.proxyMediator = proxyMediator;
this.hostedServices = hostedServices;
}
private readonly IPublisher publisher = publisher;
public WidgetConfiguration Configuration =>
Services.GetRequiredService<WidgetConfiguration>();
@@ -39,7 +28,7 @@ public sealed class WidgetHost :
await service.StartAsync(cancellationToken);
}
if (proxyMediator.Proxy is IMediator mediator)
if (proxyPublisher.Proxy is IPublisher publisher)
{
await publisher.PublishAsync(new Started<IWidgetHost>(this),
cancellationToken);
+21
View File
@@ -0,0 +1,21 @@
using System.Collections;
namespace Hyperbar.Widget;
public class WidgetHostCollection :
IWidgetHostCollection
{
private readonly List<IWidgetHost> hosts = [];
public void Add(IWidgetHost host)
{
hosts.Add(host);
}
public IEnumerator<IWidgetHost> GetEnumerator() =>
hosts.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() =>
hosts.GetEnumerator();
}
+5 -3
View File
@@ -2,14 +2,16 @@
namespace Hyperbar.Widget;
public class WidgetHostHandler :
public class WidgetHostHandler(IWidgetHostCollection widgetHosts) :
INotificationHandler<Create<IWidgetHost>>
{
public async Task Handle(Create<IWidgetHost> notification,
public async Task Handle(Create<IWidgetHost> args,
CancellationToken cancellationToken)
{
if (notification.Value is IWidgetHost host)
if (args.Value is IWidgetHost host)
{
widgetHosts.Add(host);
if (host.Services.GetServices<IInitializer>() is
IEnumerable<IInitializer> initializations)
{
+5 -1
View File
@@ -43,8 +43,9 @@ public partial class App :
services.AddTransient<INavigationTargetProvider, NavigationTargetProvider>();
services.AddTransient<IViewModelContentBinder, ViewModelContentBinder>();
services.AddTransient<IViewModelTemplateSelector, ViewModelTemplateSelector>();
services.AddTransient<IViewModelTemplateProvider, ViewModelTemplateProvider>();
services.AddTransient<IViewModelTemplateSelector, ViewModelTemplateSelector>();
services.AddHandler<AppConfigurationChangedHandler>();
services.AddConfiguration((AppConfiguration args) =>
@@ -65,8 +66,11 @@ public partial class App :
services.AddContentTemplate<GeneralSettingsNavigationViewModel, GeneralSettingsNavigationView>();
services.AddContentTemplate<WidgetSettingsNavigationViewModel, WidgetSettingsNavigationView>();
services.AddContentTemplate<WidgetNavigationViewModel, WidgetNavigationView>();
services.AddContentTemplate<WidgetSettingsViewModel, WidgetSettingsView>("WidgetSettings");
services.AddHandler<WidgetNavigationViewModelEnumerator>();
services.AddTransient<IInitializer, AppInitializer>();
})
.Build();
+6
View File
@@ -20,6 +20,7 @@
<None Remove="SecondaryView.xaml" />
<None Remove="SettingsButtonView.xaml" />
<None Remove="SettingsView.xaml" />
<None Remove="WidgetNavigationView.xaml" />
<None Remove="WidgetSettingsNavigationView.xaml" />
<None Remove="WidgetSettingsView.xaml" />
</ItemGroup>
@@ -58,6 +59,11 @@
<ProjectReference Include="..\Hyperbar.Widget\Hyperbar.Widget.csproj" />
<ProjectReference Include="..\Hyperbar\Hyperbar.csproj" />
</ItemGroup>
<ItemGroup>
<Page Update="WidgetNavigationView.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="WidgetSettingsView.xaml">
<Generator>MSBuild:Compile</Generator>
-1
View File
@@ -18,5 +18,4 @@ public partial class PrimaryViewModel(IViewModelTemplateSelector viewModelTempla
private int index = index;
public IViewModelTemplateSelector ViewModelTemplateSelector => viewModelTemplateSelector;
}
+3 -1
View File
@@ -2,7 +2,9 @@
<Window
x:Class="Hyperbar.Windows.SettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:interactions="using:Microsoft.Xaml.Interactions.Core"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity">
<Window.SystemBackdrop>
<MicaBackdrop />
</Window.SystemBackdrop>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<NavigationViewItem
x:Class="Hyperbar.Windows.WidgetNavigationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Content="dsfsdvfsd" />
@@ -0,0 +1,11 @@
using Microsoft.UI.Xaml.Controls;
namespace Hyperbar.Windows;
public sealed partial class WidgetNavigationView :
NavigationViewItem
{
public WidgetNavigationView() =>
InitializeComponent();
}
@@ -1,4 +1,6 @@
namespace Hyperbar.Windows;
using Hyperbar.UI.Windows;
namespace Hyperbar.Windows;
public class WidgetNavigationViewModel(IServiceProvider serviceProvider,
IServiceFactory serviceFactory,
@@ -6,6 +8,4 @@ public class WidgetNavigationViewModel(IServiceProvider serviceProvider,
ISubscriber subscriber,
IDisposer disposer,
string text) :
NavigationViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer, text)
{
}
NavigationViewModel(serviceProvider, serviceFactory, publisher, subscriber, disposer, text);
@@ -0,0 +1,15 @@
using System.Security.Policy;
namespace Hyperbar.Windows;
public class WidgetNavigationViewModelEnumerator(IServiceFactory serviceFactory,
IPublisher publisher) :
INotificationHandler<Enumerate<WidgetNavigationViewModel>>
{
public async Task Handle(Enumerate<WidgetNavigationViewModel> args,
CancellationToken cancellationToken = default)
{
await publisher.PublishAsync(new Create<WidgetNavigationViewModel>(serviceFactory
.Create<WidgetNavigationViewModel>("fo")), nameof(WidgetSettingsNavigationViewModel), cancellationToken);
}
}
@@ -6,10 +6,15 @@
xmlns:interactions="using:Microsoft.Xaml.Interactions.Core"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:ui="using:Hyperbar.UI.Windows"
Content="Widgets">
Content="Widgets"
MenuItemsSource="{Binding}"
SelectsOnInvoked="False">
<interactivity:Interaction.Behaviors>
<interactions:EventTriggerBehavior EventName="Tapped">
<ui:NavigateAction Name="WidgetSettings" TargetName="Settings" />
</interactions:EventTriggerBehavior>
<interactions:EventTriggerBehavior EventName="Loaded">
<interactions:InvokeCommandAction Command="{Binding InitializeCommand}" />
</interactions:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</NavigationViewItem>
@@ -1,4 +1,3 @@
using Hyperbar.Widget;
using Microsoft.UI.Xaml.Controls;
namespace Hyperbar.Windows;
@@ -1,9 +1,16 @@
namespace Hyperbar.Windows;
using Hyperbar.UI.Windows;
public class WidgetSettingsNavigationViewModel(IServiceProvider serviceProvider,
namespace Hyperbar.Windows;
[NotificationHandler(nameof(WidgetSettingsNavigationViewModel))]
public class WidgetSettingsNavigationViewModel(IViewModelTemplateSelector viewModelTemplateSelector,
IServiceProvider serviceProvider,
IServiceFactory serviceFactory,
IPublisher publisher,
ISubscriber subscriber,
IDisposer disposer,
string text) :
NavigationViewModel<WidgetNavigationViewModel>(serviceProvider, serviceFactory, publisher, subscriber, disposer, text);
NavigationViewModel<WidgetNavigationViewModel>(serviceProvider, serviceFactory, publisher, subscriber, disposer, text)
{
public IViewModelTemplateSelector ViewModelTemplateSelector => viewModelTemplateSelector;
}
+5 -10
View File
@@ -2,18 +2,13 @@
namespace Hyperbar.Windows;
public class WidgetSettingsViewModel :
ObservableCollectionViewModel<INavigationViewModel>
{
public WidgetSettingsViewModel(IViewModelTemplateSelector viewModelTemplateSelector,
public class WidgetSettingsViewModel(IViewModelTemplateSelector viewModelTemplateSelector,
IServiceProvider serviceProvider,
IServiceFactory serviceFactory,
IPublisher publisher,
ISubscriber subscriber,
IDisposer disposer) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
{
ViewModelTemplateSelector = viewModelTemplateSelector;
}
public IViewModelTemplateSelector ViewModelTemplateSelector { get; }
IDisposer disposer) :
ObservableCollectionViewModel<IObservableViewModel>(serviceProvider, serviceFactory, publisher, subscriber, disposer)
{
public IViewModelTemplateSelector ViewModelTemplateSelector { get; } = viewModelTemplateSelector;
}
+3 -3
View File
@@ -165,7 +165,7 @@ public static class IServiceCollectionExtensions
services.AddTransient<IViewModelTemplate>(provider => new ViewModelTemplate
{
ViewModelType = contentType,
TemplateType = templateType,
ViewType = templateType,
Key = key
});
@@ -184,8 +184,8 @@ public static class IServiceCollectionExtensions
services.AddSingleton<IMediator, Mediator>();
services.AddSingleton<IProxyService<IMediator>>(provider =>
new ProxyService<IMediator>(provider.GetRequiredService<IMediator>()));
services.AddSingleton<IProxyService<IPublisher>>(provider =>
new ProxyService<IPublisher>(provider.GetRequiredService<IPublisher>()));
services.AddSingleton<IDisposer, Disposer>();
+1 -1
View File
@@ -4,7 +4,7 @@ public interface IViewModelTemplate
{
object Key { get; set; }
Type TemplateType { get; set; }
Type ViewType { get; set; }
Type ViewModelType { get; set; }
}
+1 -2
View File
@@ -12,11 +12,10 @@ public class NavigateHandler(IServiceProvider provider,
public async Task Handle(Navigate args,
CancellationToken cancellationToken)
{
if (viewModelTemplateProvider.Get(args.Name)
is IViewModelTemplate viewModelTemplate)
{
if (provider.GetRequiredKeyedService(viewModelTemplate.TemplateType,
if (provider.GetRequiredKeyedService(viewModelTemplate.ViewType,
viewModelTemplate.Key) is object view &&
provider.GetRequiredKeyedService(viewModelTemplate.ViewModelType,
viewModelTemplate.Key) is object viewModel)
+1 -2
View File
@@ -43,8 +43,7 @@ public class Publisher(ISubscriptionManager subscriptionManager,
List<object?> handlers = provider.GetServices(typeof(INotificationHandler<>)
.MakeGenericType(notificationType)).ToList();
foreach (object? handler in subscriptionManager.GetHandlers(notificationType,
$"{key?.ToString()}:{notificationType}"))
foreach (object? handler in subscriptionManager.GetHandlers(notificationType, key))
{
handlers.Add(handler);
}
+1
View File
@@ -7,6 +7,7 @@ public class SubscriptionManager(SubscriptionCollection subscriptions) :
{
public IEnumerable<object?> GetHandlers(Type notificationType, object key)
{
var d = subscriptions;
if (subscriptions.TryGetValue($"{key?.ToString()}:{notificationType}",
out List<WeakReference>? subscribers))
{
+1 -1
View File
@@ -5,7 +5,7 @@ public record ViewModelTemplate :
{
public required Type ViewModelType { get; set; }
public required Type TemplateType { get; set; }
public required Type ViewType { get; set; }
public required object Key { get; set; }
}
+1
View File
@@ -1,4 +1,5 @@
namespace Hyperbar;
public class ViewModelTemplateProvider(IEnumerable<IViewModelTemplate> viewModelTemplates) :
IViewModelTemplateProvider
{