Rename projects to better structure it. The aim is to try and keep it not dependant on the type of UI framework it uses thus allowing us to switch to another UI framework if we need later...
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Application
|
||||
x:Class="Hyperbar.Windows.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:desktop="using:Hyperbar.Windows">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<DataTemplate x:Key="DefaultDataTemplate">
|
||||
<desktop:TemplateGeneratorControl />
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -0,0 +1,67 @@
|
||||
using Hyperbar.Windows.Contextual;
|
||||
using Hyperbar.Windows.Controls;
|
||||
using Hyperbar.Windows.Primary;
|
||||
using Hyperbar.Lifecycles;
|
||||
using Hyperbar.Templates;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.UI.Xaml;
|
||||
|
||||
namespace Hyperbar.Windows;
|
||||
|
||||
public partial class App :
|
||||
Application
|
||||
{
|
||||
public App() => InitializeComponent();
|
||||
|
||||
protected override async void OnLaunched(LaunchActivatedEventArgs args)
|
||||
{
|
||||
base.OnLaunched(args);
|
||||
|
||||
IHost? host = Host.CreateDefaultBuilder()
|
||||
.UseContentRoot(AppContext.BaseDirectory)
|
||||
.ConfigureAppConfiguration(config =>
|
||||
{
|
||||
config.SetBasePath(AppContext.BaseDirectory);
|
||||
config.AddJsonFile("Settings.json", true);
|
||||
|
||||
config.Build();
|
||||
})
|
||||
.ConfigureServices((context, services) =>
|
||||
{
|
||||
services.AddHostedService<AppService>();
|
||||
|
||||
services.AddTransient<IInitializer, AppInitializer>();
|
||||
services.AddTransient<DesktopFlyout>();
|
||||
|
||||
services.AddTransient<ITemplateFactory, TemplateFactory>();
|
||||
services.AddTransient<ITemplateGeneratorFactory, TemplateGeneratorFactory>();
|
||||
|
||||
services.AddDataTemplate<CommandViewModel, CommandView>();
|
||||
|
||||
services.AddCommand<ContextualCommandWidgetBuilder>("");
|
||||
services.AddCommand<PrimaryCommandWidgetBuilder>("");
|
||||
|
||||
services.AddTransient(provider =>
|
||||
{
|
||||
static IEnumerable<ICommandWidgetViewModel> Resolve(IServiceProvider services)
|
||||
{
|
||||
foreach (ICommandWidgetContext commandContext in services.GetServices<ICommandWidgetContext>())
|
||||
{
|
||||
if (commandContext.ServiceProvider.GetService<ICommandWidgetViewModel>() is
|
||||
ICommandWidgetViewModel commandViewModel)
|
||||
{
|
||||
yield return commandViewModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Resolve(provider);
|
||||
});
|
||||
})
|
||||
.Build();
|
||||
|
||||
await host.RunAsync();
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 432 B |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 637 B |
|
After Width: | Height: | Size: 283 B |
|
After Width: | Height: | Size: 456 B |
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,48 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<RootNamespace>Hyperbar.Windows</RootNamespace>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<Platforms>x86;x64;ARM64</Platforms>
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
|
||||
<PublishProfile>win-$(Platform).pubxml</PublishProfile>
|
||||
<UseRidGraph>true</UseRidGraph>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<EnableMsixTooling>true</EnableMsixTooling>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="ContextualCommandView.xaml" />
|
||||
<None Remove="Views\CommandView.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Content Include="Assets\StoreLogo.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.231202003-experimental1" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.25936-preview" />
|
||||
<Manifest Include="$(ApplicationManifest)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||
<ProjectCapability Include="Msix" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Hyperbar.Windows.Contextual\Hyperbar.Windows.Contextual.csproj" />
|
||||
<ProjectReference Include="..\Hyperbar.Windows.Controls\Hyperbar.Windows.Controls.csproj" />
|
||||
<ProjectReference Include="..\Hyperbar.Windows.Primary\Hyperbar.Windows.Primary.csproj" />
|
||||
<ProjectReference Include="..\Hyperbar\Hyperbar.csproj" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||
<HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,22 @@
|
||||
using Hyperbar.Windows.Controls;
|
||||
using Hyperbar.Lifecycles;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hyperbar.Windows;
|
||||
|
||||
public class AppInitializer([FromKeyedServices(nameof(CommandViewModel))] CommandView view,
|
||||
[FromKeyedServices(nameof(CommandViewModel))] CommandViewModel viewModel,
|
||||
DesktopFlyout desktopFlyout) :
|
||||
IInitializer
|
||||
{
|
||||
public Task InitializeAsync()
|
||||
{
|
||||
view.DataContext = viewModel;
|
||||
|
||||
desktopFlyout.Placement = DesktopFlyoutPlacement.Top;
|
||||
desktopFlyout.Content = view;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Hyperbar.Lifecycles;
|
||||
using Hyperbar.Templates;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace Hyperbar.Windows
|
||||
{
|
||||
public static class IServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddCommand<TCommandBuilder>(this IServiceCollection services,
|
||||
string key)
|
||||
where TCommandBuilder :
|
||||
ICommandWidgetBuilder, new()
|
||||
{
|
||||
TCommandBuilder builder = new();
|
||||
IHost? host = new HostBuilder()
|
||||
.ConfigureServices(isolatedServices =>
|
||||
{
|
||||
isolatedServices.AddTransient<ITemplateFactory, TemplateFactory>();
|
||||
isolatedServices.AddTransient<ITemplateGeneratorFactory, TemplateGeneratorFactory>();
|
||||
|
||||
builder.Create(isolatedServices);
|
||||
}).Build();
|
||||
|
||||
services.AddTransient<ICommandWidgetContext>(provider => new CommandWidgetContext(host.Services));
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
IgnorableNamespaces="uap rescap">
|
||||
|
||||
<Identity
|
||||
Name="24ccddba-447f-4d37-891d-523e8d820f45"
|
||||
Publisher="CN=dan_c"
|
||||
Version="1.0.0.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="24ccddba-447f-4d37-891d-523e8d820f45" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>Hyperbar.Windows</DisplayName>
|
||||
<PublisherDisplayName>dan_c</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate"/>
|
||||
</Resources>
|
||||
|
||||
<Applications>
|
||||
<Application Id="App"
|
||||
Executable="$targetnametoken$.exe"
|
||||
EntryPoint="$targetentrypoint$">
|
||||
<uap:VisualElements
|
||||
DisplayName="Hyperbar.Windows"
|
||||
Description="Hyperbar.Windows"
|
||||
BackgroundColor="transparent"
|
||||
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||
Square44x44Logo="Assets\Square44x44Logo.png">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
</Capabilities>
|
||||
</Package>
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Hyperbar.Windows (Package)": {
|
||||
"commandName": "MsixPackage"
|
||||
},
|
||||
"Hyperbar.Windows (Unpackaged)": {
|
||||
"commandName": "Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
|
||||
namespace Hyperbar.Windows
|
||||
{
|
||||
|
||||
public interface ITemplateGeneratorFactory
|
||||
{
|
||||
DataTemplate Create();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using Hyperbar.Templates;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Hyperbar.Windows;
|
||||
|
||||
public class TemplateFactory(ITemplateGeneratorFactory factory,
|
||||
IEnumerable<IDataTemplateDescriptor> descriptors,
|
||||
IServiceProvider provider) :
|
||||
DataTemplateSelector,
|
||||
ITemplateFactory
|
||||
{
|
||||
protected override DataTemplate SelectTemplateCore(object item) => factory.Create();
|
||||
|
||||
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) => factory.Create();
|
||||
|
||||
public object? Create(object key)
|
||||
{
|
||||
if (descriptors.FirstOrDefault(x => x.Key == key) is IDataTemplateDescriptor descriptor)
|
||||
{
|
||||
if (provider.GetRequiredKeyedService(descriptor.TemplateType, descriptor.Key) is { } template)
|
||||
{
|
||||
return template;
|
||||
}
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Hyperbar.Templates;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Hyperbar.Windows;
|
||||
|
||||
public class TemplateGeneratorControl :
|
||||
ContentControl
|
||||
{
|
||||
public TemplateGeneratorControl()
|
||||
{
|
||||
DataContextChanged += OnDataContextChanged;
|
||||
}
|
||||
|
||||
private void OnDataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
|
||||
{
|
||||
if (DataContext is ITemplatedViewModel templatedViewModel)
|
||||
{
|
||||
Content = templatedViewModel.TemplateFactory.Create(DataContext.GetType().Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Markup;
|
||||
|
||||
namespace Hyperbar.Windows;
|
||||
|
||||
public class TemplateGeneratorFactory :
|
||||
ITemplateGeneratorFactory
|
||||
{
|
||||
public DataTemplate Create()
|
||||
{
|
||||
string xamlString = @"
|
||||
<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
|
||||
xmlns:desktop='using:Hyperbar.Windows'>
|
||||
<desktop:TemplateGeneratorControl />
|
||||
</DataTemplate>";
|
||||
|
||||
return (DataTemplate)XamlReader.Load(xamlString);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Page
|
||||
x:Class="Hyperbar.Windows.CommandView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<ItemsControl ItemTemplateSelector="{Binding TemplateFactory}" ItemsSource="{Binding}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</Page>
|
||||
@@ -0,0 +1,14 @@
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
|
||||
namespace Hyperbar.Windows;
|
||||
|
||||
public sealed partial class CommandView : Page
|
||||
{
|
||||
public CommandView() => InitializeComponent();
|
||||
|
||||
protected override void OnKeyDown(KeyRoutedEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Hyperbar.Lifecycles;
|
||||
using Hyperbar.Templates;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Hyperbar.Windows;
|
||||
|
||||
public partial class CommandViewModel :
|
||||
ObservableCollectionViewModel,
|
||||
ITemplatedViewModel
|
||||
{
|
||||
public CommandViewModel(ITemplateFactory templateFactory,
|
||||
IEnumerable<ICommandWidgetViewModel> commands)
|
||||
{
|
||||
TemplateFactory = templateFactory;
|
||||
AddRange(commands);
|
||||
}
|
||||
|
||||
public ITemplateFactory TemplateFactory { get; }
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="Hyperbar.Windows.app"/>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- The ID below informs the system that this application is compatible with OS features first introduced in Windows 10.
|
||||
It is necessary to support features in unpackaged applications, for example the custom titlebar implementation.
|
||||
For more info see https://docs.microsoft.com/windows/apps/windows-app-sdk/use-windows-app-sdk-run-time#declare-os-compatibility-in-your-application-manifest -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
||||