A widget should have only one IWidgetViewModel by default... wondering whether if we should go for the first served, or throw if multiple detected, or ignore the widget
This commit is contained in:
@@ -4,11 +4,14 @@ public class ContextualWidget :
|
|||||||
IWidget
|
IWidget
|
||||||
{
|
{
|
||||||
public IWidgetBuilder Create() =>
|
public IWidgetBuilder Create() =>
|
||||||
WidgetBuilder<ContextualWidgetConfiguration>.Configure(args =>
|
WidgetBuilder.Create()
|
||||||
|
.Configuration<ContextualWidgetConfiguration>(args =>
|
||||||
{
|
{
|
||||||
args.Name = "Contextual commands";
|
args.Name = "Contextual commands";
|
||||||
|
|
||||||
}).ConfigureServices(args =>
|
})
|
||||||
|
.UseViewModel<ContextualWidgetViewModel>()
|
||||||
|
.ConfigureServices(args =>
|
||||||
{
|
{
|
||||||
args.AddWidgetTemplate<ContextualWidgetViewModel>();
|
args.AddWidgetTemplate<ContextualWidgetViewModel>();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,13 +7,15 @@ public class MediaControllerWidget :
|
|||||||
IWidget
|
IWidget
|
||||||
{
|
{
|
||||||
public IWidgetBuilder Create() =>
|
public IWidgetBuilder Create() =>
|
||||||
WidgetBuilder<MediaControllerWidgetConfiguration>.Configure(args =>
|
WidgetBuilder.Create()
|
||||||
|
.Configuration<MediaControllerWidgetConfiguration>(args =>
|
||||||
{
|
{
|
||||||
args.Name = "Media controller";
|
args.Name = "Media controller";
|
||||||
}).ConfigureServices(args =>
|
})
|
||||||
|
.UseViewModelTemplate<MediaControllerWidgetViewModel, MediaControllerWidgetView>()
|
||||||
|
.ConfigureServices(args =>
|
||||||
{
|
{
|
||||||
args.AddWidgetTemplate<MediaControllerWidgetViewModel, MediaControllerWidgetView>()
|
args.AddSingleton<IInitializer, MediaControllerManager>()
|
||||||
.AddSingleton<IInitializer, MediaControllerManager>()
|
|
||||||
.AddTransient<IServiceScopeFactory<MediaController>, ServiceScopeFactory<MediaController>>()
|
.AddTransient<IServiceScopeFactory<MediaController>, ServiceScopeFactory<MediaController>>()
|
||||||
.AddTransient<IServiceScopeProvider<MediaController>, ServiceScopeProvider<MediaController>>()
|
.AddTransient<IServiceScopeProvider<MediaController>, ServiceScopeProvider<MediaController>>()
|
||||||
.AddCache<MediaController, IServiceScope>()
|
.AddCache<MediaController, IServiceScope>()
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ public class PrimaryWidget :
|
|||||||
IWidget
|
IWidget
|
||||||
{
|
{
|
||||||
public IWidgetBuilder Create() =>
|
public IWidgetBuilder Create() =>
|
||||||
WidgetBuilder<PrimaryWidgetConfiguration>.Configure(args =>
|
WidgetBuilder.Create()
|
||||||
|
.Configuration<PrimaryWidgetConfiguration>(args =>
|
||||||
{
|
{
|
||||||
args.Name = "Primary commands";
|
args.Name = "Primary commands";
|
||||||
args.Commands =
|
args.Commands =
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public static class IServiceCollectionExtensions
|
|||||||
{
|
{
|
||||||
public static IServiceCollection AddWidgetWindows(this IServiceCollection services)
|
public static IServiceCollection AddWidgetWindows(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddContentTemplate<WidgetBarViewModel, WidgetBarView>();
|
services.AddContentTemplate<WidgetViewModel, WidgetBarView>();
|
||||||
|
|
||||||
// We need to feed information to the Widgets about our Windows host,
|
// We need to feed information to the Widgets about our Windows host,
|
||||||
// so the Windows host can make discussions how to display and interact with the widgets.
|
// so the Windows host can make discussions how to display and interact with the widgets.
|
||||||
@@ -20,8 +20,6 @@ public static class IServiceCollectionExtensions
|
|||||||
{
|
{
|
||||||
services.AddSingleton(provider.GetRequiredService<IList<IXamlMetadataProvider>>());
|
services.AddSingleton(provider.GetRequiredService<IList<IXamlMetadataProvider>>());
|
||||||
services.AddSingleton(provider.GetRequiredService<IDispatcher>());
|
services.AddSingleton(provider.GetRequiredService<IDispatcher>());
|
||||||
services.AddTransient<IFactory<IWidgetHost, WidgetContainerViewModel?>,
|
|
||||||
WidgetContainerFactory>();
|
|
||||||
|
|
||||||
services.AddTransient<ITemplateFactory, TemplateFactory>();
|
services.AddTransient<ITemplateFactory, TemplateFactory>();
|
||||||
|
|
||||||
@@ -35,7 +33,6 @@ public static class IServiceCollectionExtensions
|
|||||||
services.AddTransient<IInitializer, WidgetResourceInitializer>();
|
services.AddTransient<IInitializer, WidgetResourceInitializer>();
|
||||||
services.AddTransient<IInitializer, WidgetXamlMetadataInitializer>();
|
services.AddTransient<IInitializer, WidgetXamlMetadataInitializer>();
|
||||||
|
|
||||||
services.AddContentTemplate<WidgetContainerViewModel, WidgetContainerView>();
|
|
||||||
services.AddContentTemplate<WidgetButtonViewModel, WidgetButtonView>();
|
services.AddContentTemplate<WidgetButtonViewModel, WidgetButtonView>();
|
||||||
services.AddContentTemplate<WidgetSplitButtonViewModel, WidgetSplitButtonView>();
|
services.AddContentTemplate<WidgetSplitButtonViewModel, WidgetSplitButtonView>();
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<UserControl
|
|
||||||
x:Class="Hyperbar.Widget.Windows.WidgetContainerView"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:interactions="using:Microsoft.Xaml.Interactions.Core"
|
|
||||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
|
||||||
xmlns:ui="using:Hyperbar.UI.Windows">
|
|
||||||
<Grid>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto" />
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<Rectangle
|
|
||||||
Width="1"
|
|
||||||
Height="40"
|
|
||||||
Margin="6,2,6,2"
|
|
||||||
Fill="Red" />
|
|
||||||
<ItemsControl
|
|
||||||
Grid.Column="1"
|
|
||||||
ItemTemplateSelector="{Binding Converter={ui:DataTemplateConverter}}"
|
|
||||||
ItemsSource="{Binding}">
|
|
||||||
<ItemsControl.ItemsPanel>
|
|
||||||
<ItemsPanelTemplate>
|
|
||||||
<StackPanel Orientation="Horizontal" />
|
|
||||||
</ItemsPanelTemplate>
|
|
||||||
</ItemsControl.ItemsPanel>
|
|
||||||
<interactivity:Interaction.Behaviors>
|
|
||||||
<interactions:EventTriggerBehavior EventName="Loaded">
|
|
||||||
<interactions:InvokeCommandAction Command="{Binding Initialize}" />
|
|
||||||
</interactions:EventTriggerBehavior>
|
|
||||||
</interactivity:Interaction.Behaviors>
|
|
||||||
</ItemsControl>
|
|
||||||
</Grid>
|
|
||||||
</UserControl>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml.Controls;
|
|
||||||
|
|
||||||
namespace Hyperbar.Widget.Windows;
|
|
||||||
|
|
||||||
public sealed partial class WidgetContainerView :
|
|
||||||
UserControl
|
|
||||||
{
|
|
||||||
public WidgetContainerView() => InitializeComponent();
|
|
||||||
}
|
|
||||||
@@ -6,14 +6,18 @@ public interface IWidgetBuilder
|
|||||||
{
|
{
|
||||||
IWidgetHost Build();
|
IWidgetHost Build();
|
||||||
|
|
||||||
IWidgetBuilder ConfigureServices(Action<IServiceCollection> configureDelegate);
|
IWidgetBuilder Configuration<TConfiguration>(Action<TConfiguration> configurationDelegate)
|
||||||
}
|
|
||||||
|
|
||||||
public interface IWidgetBuilder<TConfiguration> :
|
|
||||||
IWidgetBuilder
|
|
||||||
where TConfiguration :
|
where TConfiguration :
|
||||||
WidgetConfiguration,
|
WidgetConfiguration,
|
||||||
new()
|
new();
|
||||||
{
|
|
||||||
|
|
||||||
|
IWidgetBuilder ConfigureServices(Action<IServiceCollection> configureDelegate);
|
||||||
|
|
||||||
|
IWidgetBuilder UseViewModel<TViewModel>()
|
||||||
|
where TViewModel :
|
||||||
|
IWidgetViewModel;
|
||||||
|
|
||||||
|
IWidgetBuilder UseViewModelTemplate<TViewModel, TTemplate>()
|
||||||
|
where TViewModel :
|
||||||
|
IWidgetViewModel;
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
namespace Hyperbar.Widget;
|
namespace Hyperbar.Widget;
|
||||||
|
|
||||||
[NotificationHandler(nameof(WidgetBarViewModel))]
|
[NotificationHandler(nameof(WidgetViewModel))]
|
||||||
public partial class WidgetBarViewModel(ITemplateFactory templateFactory,
|
public partial class WidgetViewModel(ITemplateFactory templateFactory,
|
||||||
IServiceFactory serviceFactory,
|
IServiceFactory serviceFactory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IDisposer disposer) :
|
IDisposer disposer) :
|
||||||
ObservableCollectionViewModel<WidgetContainerViewModel>(serviceFactory, mediator, disposer),
|
ObservableCollectionViewModel<IWidgetViewModel>(serviceFactory, mediator, disposer),
|
||||||
ITemplatedViewModel
|
ITemplatedViewModel
|
||||||
{
|
{
|
||||||
public ITemplateFactory TemplateFactory => templateFactory;
|
public ITemplateFactory TemplateFactory => templateFactory;
|
||||||
|
|||||||
@@ -5,13 +5,14 @@ using System.Reflection;
|
|||||||
|
|
||||||
namespace Hyperbar.Widget;
|
namespace Hyperbar.Widget;
|
||||||
|
|
||||||
public class WidgetBuilder<TConfiguration>(TConfiguration configuration) :
|
public class WidgetBuilder :
|
||||||
IWidgetBuilder<TConfiguration>
|
IWidgetBuilder
|
||||||
where TConfiguration :
|
|
||||||
WidgetConfiguration,
|
|
||||||
new()
|
|
||||||
{
|
{
|
||||||
private readonly IHostBuilder hostBuilder = new HostBuilder()
|
private readonly IHostBuilder hostBuilder;
|
||||||
|
|
||||||
|
private WidgetBuilder()
|
||||||
|
{
|
||||||
|
hostBuilder = new HostBuilder()
|
||||||
.UseContentRoot(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
.UseContentRoot(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||||
Assembly.GetEntryAssembly()?.GetName().Name!), true)
|
Assembly.GetEntryAssembly()?.GetName().Name!), true)
|
||||||
.ConfigureAppConfiguration(config =>
|
.ConfigureAppConfiguration(config =>
|
||||||
@@ -21,31 +22,46 @@ public class WidgetBuilder<TConfiguration>(TConfiguration configuration) :
|
|||||||
.ConfigureServices((context, services) =>
|
.ConfigureServices((context, services) =>
|
||||||
{
|
{
|
||||||
services.AddSingleton<IWidgetHost, WidgetHost>();
|
services.AddSingleton<IWidgetHost, WidgetHost>();
|
||||||
|
|
||||||
services.AddScoped<IServiceFactory>(provider =>
|
services.AddScoped<IServiceFactory>(provider =>
|
||||||
new ServiceFactory((type, parameters) =>
|
new ServiceFactory((type, parameters) =>
|
||||||
ActivatorUtilities.CreateInstance(provider, type, parameters!)));
|
ActivatorUtilities.CreateInstance(provider, type, parameters!)));
|
||||||
services.AddScoped<IMediator, Mediator>();
|
services.AddScoped<IMediator, Mediator>();
|
||||||
services.AddScoped<IDisposer, Disposer>();
|
services.AddScoped<IDisposer, Disposer>();
|
||||||
|
services.AddSingleton<IValue<WidgetAvailability>, Value<WidgetAvailability>>();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
services.AddSingleton<IValue<WidgetAvailability>,
|
public static IWidgetBuilder Create() => new WidgetBuilder();
|
||||||
Value<WidgetAvailability>>();
|
|
||||||
|
|
||||||
|
public IWidgetBuilder Configuration<TConfiguration>(Action<TConfiguration> configurationDelegate)
|
||||||
|
where TConfiguration :
|
||||||
|
WidgetConfiguration,
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
TConfiguration configuration = new TConfiguration();
|
||||||
|
configurationDelegate(configuration);
|
||||||
|
|
||||||
|
hostBuilder.ConfigureServices(services =>
|
||||||
|
{
|
||||||
services.AddHandler<WidgetConfigurationHandler>();
|
services.AddHandler<WidgetConfigurationHandler>();
|
||||||
|
services.AddConfiguration<WidgetConfiguration>(section: configuration.GetType().Name, configuration: configuration);
|
||||||
services.AddConfiguration<WidgetConfiguration>(section: configuration.GetType().Name,
|
|
||||||
configuration: configuration);
|
|
||||||
services.AddConfiguration(configuration);
|
services.AddConfiguration(configuration);
|
||||||
});
|
});
|
||||||
|
|
||||||
public static IWidgetBuilder Configure(Action<TConfiguration> configurationDelegate)
|
return this;
|
||||||
{
|
|
||||||
TConfiguration configuration = new();
|
|
||||||
configurationDelegate(configuration);
|
|
||||||
|
|
||||||
return new WidgetBuilder<TConfiguration>(configuration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IWidgetBuilder UseViewModelTemplate<TWidgetContent, TWidgetTemplate>()
|
||||||
|
where TWidgetContent :
|
||||||
|
IWidgetViewModel
|
||||||
|
{
|
||||||
|
hostBuilder.ConfigureServices(services =>
|
||||||
|
{
|
||||||
|
services.AddWidgetTemplate<TWidgetContent, TWidgetTemplate>();
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
public IWidgetHost Build()
|
public IWidgetHost Build()
|
||||||
{
|
{
|
||||||
IHost host = hostBuilder.Build();
|
IHost host = hostBuilder.Build();
|
||||||
@@ -54,7 +70,19 @@ public class WidgetBuilder<TConfiguration>(TConfiguration configuration) :
|
|||||||
|
|
||||||
public IWidgetBuilder ConfigureServices(Action<IServiceCollection> configureDelegate)
|
public IWidgetBuilder ConfigureServices(Action<IServiceCollection> configureDelegate)
|
||||||
{
|
{
|
||||||
hostBuilder.ConfigureServices(configureDelegate.Invoke);
|
hostBuilder.ConfigureServices(configureDelegate);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IWidgetBuilder UseViewModel<TViewModel>()
|
||||||
|
where TViewModel :
|
||||||
|
IWidgetViewModel
|
||||||
|
{
|
||||||
|
hostBuilder.ConfigureServices(services =>
|
||||||
|
{
|
||||||
|
services.AddWidgetTemplate<TViewModel>();
|
||||||
|
});
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
namespace Hyperbar.Widget;
|
|
||||||
|
|
||||||
public class WidgetContainerFactory(IServiceFactory factory) :
|
|
||||||
IFactory<IWidgetHost, WidgetContainerViewModel?>
|
|
||||||
{
|
|
||||||
public WidgetContainerViewModel? Create(IWidgetHost value)
|
|
||||||
{
|
|
||||||
return factory.Create<WidgetContainerViewModel>(value.Configuration.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
|
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
|
|
||||||
namespace Hyperbar.Widget;
|
|
||||||
|
|
||||||
[NotificationHandler(nameof(WidgetContainerViewModel))]
|
|
||||||
public partial class WidgetContainerViewModel(ITemplateFactory templateFactory,
|
|
||||||
IServiceFactory serviceFactory,
|
|
||||||
IMediator mediator,
|
|
||||||
IDisposer disposer,
|
|
||||||
Guid id) :
|
|
||||||
ObservableCollectionViewModel<IWidgetViewModel>(serviceFactory, mediator, disposer),
|
|
||||||
ITemplatedViewModel
|
|
||||||
{
|
|
||||||
[ObservableProperty]
|
|
||||||
private Guid id = id;
|
|
||||||
|
|
||||||
public ITemplateFactory TemplateFactory => templateFactory;
|
|
||||||
}
|
|
||||||
@@ -11,13 +11,10 @@ public class WidgetHostHandler(IMediator mediator) :
|
|||||||
{
|
{
|
||||||
if (notification.Value is IWidgetHost host)
|
if (notification.Value is IWidgetHost host)
|
||||||
{
|
{
|
||||||
if (host.Services.GetRequiredService<IFactory<IWidgetHost, WidgetContainerViewModel?>>() is { } factory)
|
if (host.Services.GetService<IWidgetViewModel>() is IWidgetViewModel viewModel)
|
||||||
{
|
{
|
||||||
if (factory.Create(host) is WidgetContainerViewModel containerViewModel)
|
await mediator.PublishAsync(new Created<IWidgetViewModel>(viewModel),
|
||||||
{
|
nameof(WidgetViewModel), cancellationToken);
|
||||||
await mediator.PublishAsync(new Created<WidgetContainerViewModel>(containerViewModel),
|
|
||||||
nameof(WidgetBarViewModel), cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class WidgetViewModelEnumerator(IWidgetHost host,
|
|||||||
foreach (IWidgetViewModel viewModel in viewModels)
|
foreach (IWidgetViewModel viewModel in viewModels)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Created<IWidgetViewModel>(viewModel),
|
await mediator.PublishAsync(new Created<IWidgetViewModel>(viewModel),
|
||||||
nameof(WidgetContainerViewModel), cancellationToken);
|
nameof(WidgetViewModel), cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
|
|
||||||
namespace Hyperbar.Windows;
|
namespace Hyperbar.Windows;
|
||||||
|
|
||||||
public class AppInitializer([FromKeyedServices(nameof(WidgetBarViewModel))] WidgetBarView view,
|
public class AppInitializer([FromKeyedServices(nameof(WidgetViewModel))] WidgetBarView view,
|
||||||
[FromKeyedServices(nameof(WidgetBarViewModel))] WidgetBarViewModel viewModel,
|
[FromKeyedServices(nameof(WidgetViewModel))] WidgetViewModel viewModel,
|
||||||
DesktopBar desktopFlyout,
|
DesktopBar desktopFlyout,
|
||||||
AppConfiguration configuration) :
|
AppConfiguration configuration) :
|
||||||
IInitializer
|
IInitializer
|
||||||
|
|||||||
Reference in New Issue
Block a user