Reloadable configuration, FontService (WIP)
This commit is contained in:
@@ -103,28 +103,13 @@ public class ItemManipulationUserCommandHandlerService : UserCommandHandlerServi
|
||||
{
|
||||
await (command.PasteMode switch
|
||||
{
|
||||
PasteMode.Merge => PasteMerge(),
|
||||
PasteMode.Overwrite => PasteOverwrite(),
|
||||
PasteMode.Skip => PasteSkip(),
|
||||
PasteMode.Merge => Paste(TransportMode.Merge),
|
||||
PasteMode.Overwrite => Paste(TransportMode.Overwrite),
|
||||
PasteMode.Skip => Paste(TransportMode.Skip),
|
||||
_ => throw new ArgumentException($"Unknown {nameof(PasteMode)} value: {command.PasteMode}")
|
||||
});
|
||||
}
|
||||
|
||||
private async Task PasteMerge()
|
||||
{
|
||||
await Paste(TransportMode.Merge);
|
||||
}
|
||||
|
||||
private async Task PasteOverwrite()
|
||||
{
|
||||
await Paste(TransportMode.Overwrite);
|
||||
}
|
||||
|
||||
private async Task PasteSkip()
|
||||
{
|
||||
await Paste(TransportMode.Skip);
|
||||
}
|
||||
|
||||
private async Task Paste(TransportMode mode)
|
||||
{
|
||||
if (_clipboardService.CommandType is null)
|
||||
|
||||
@@ -59,6 +59,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileTime.Core.ContentAccess
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileTime.Core.CommandHandlers", "Core\FileTime.Core.CommandHandlers\FileTime.Core.CommandHandlers.csproj", "{9B161766-A672-4D59-B591-C68907905158}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileTime.GuiApp.Font", "GuiApp\Avalonia\FileTime.GuiApp.Font\FileTime.GuiApp.Font.csproj", "{767F3868-11D0-445D-9B86-F81C7FCEB6FA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileTime.GuiApp.Font.Abstractions", "GuiApp\Avalonia\FileTime.GuiApp.Font.Abstractions\FileTime.GuiApp.Font.Abstractions.csproj", "{2D07F149-106B-4644-9586-D6218F78D868}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -145,6 +149,14 @@ Global
|
||||
{9B161766-A672-4D59-B591-C68907905158}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9B161766-A672-4D59-B591-C68907905158}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9B161766-A672-4D59-B591-C68907905158}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{767F3868-11D0-445D-9B86-F81C7FCEB6FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{767F3868-11D0-445D-9B86-F81C7FCEB6FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{767F3868-11D0-445D-9B86-F81C7FCEB6FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{767F3868-11D0-445D-9B86-F81C7FCEB6FA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2D07F149-106B-4644-9586-D6218F78D868}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2D07F149-106B-4644-9586-D6218F78D868}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2D07F149-106B-4644-9586-D6218F78D868}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2D07F149-106B-4644-9586-D6218F78D868}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -171,6 +183,8 @@ Global
|
||||
{2AC5CAFF-EBDA-4C6E-BCFF-304B651F2906} = {3324D046-1E05-46B5-B1BA-82910D56B332}
|
||||
{88BBB541-7306-44AE-95B1-0F8765AF1D4E} = {3324D046-1E05-46B5-B1BA-82910D56B332}
|
||||
{9B161766-A672-4D59-B591-C68907905158} = {3324D046-1E05-46B5-B1BA-82910D56B332}
|
||||
{767F3868-11D0-445D-9B86-F81C7FCEB6FA} = {01F231DE-4A65-435F-B4BB-77EE5221890C}
|
||||
{2D07F149-106B-4644-9586-D6218F78D868} = {01F231DE-4A65-435F-B4BB-77EE5221890C}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {859FB3DF-C60A-46B1-82E5-90274905D1EF}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="11.0.0-preview4" />
|
||||
<PackageReference Include="Avalonia" Version="11.0.0-preview5" />
|
||||
<PackageReference Include="PropertyChanged.SourceGenerator" Version="1.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
||||
@@ -2,6 +2,7 @@ using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using FileTime.App.DependencyInjection;
|
||||
using FileTime.GuiApp.Font;
|
||||
using FileTime.GuiApp.ViewModels;
|
||||
using FileTime.GuiApp.Views;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -13,9 +14,11 @@ public partial class App : Application
|
||||
{
|
||||
static App()
|
||||
{
|
||||
DI.ServiceProvider ??= DependencyInjection
|
||||
var configuration = Startup.CreateConfiguration();
|
||||
DI.ServiceProvider = DependencyInjection
|
||||
.RegisterDefaultServices()
|
||||
.AddConfiguration()
|
||||
.AddConfiguration(configuration)
|
||||
.ConfigureFont(configuration)
|
||||
.RegisterLogging()
|
||||
.RegisterServices()
|
||||
.AddViewModels()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
@@ -25,11 +25,11 @@
|
||||
<TrimmableAssembly Include="Avalonia.Themes.Default" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="11.0.0-preview4" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.0-preview4" />
|
||||
<PackageReference Include="Avalonia" Version="11.0.0-preview5" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.0-preview5" />
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.0-preview4" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.0-preview4" />
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.0-preview5" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.0-preview5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
|
||||
@@ -42,6 +42,7 @@
|
||||
<ProjectReference Include="..\..\..\AppCommon\FileTime.App.Core\FileTime.App.Core.csproj" />
|
||||
<ProjectReference Include="..\..\..\AppCommon\FileTime.App.DependencyInjection\FileTime.App.DependencyInjection.csproj" />
|
||||
<ProjectReference Include="..\FileTime.GuiApp.CustomImpl\FileTime.GuiApp.CustomImpl.csproj" />
|
||||
<ProjectReference Include="..\FileTime.GuiApp.Font\FileTime.GuiApp.Font.csproj" />
|
||||
<ProjectReference Include="..\FileTime.GuiApp\FileTime.GuiApp.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -20,6 +20,25 @@ namespace FileTime.GuiApp.App;
|
||||
|
||||
public static class Startup
|
||||
{
|
||||
internal static IConfigurationRoot CreateConfiguration()
|
||||
{
|
||||
var configurationBuilder = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(MainConfiguration.Configuration)
|
||||
.AddJsonFile("appsettings.json", optional: true)
|
||||
.AddJsonFile($"appsettings.{Program.EnvironmentName}.json", true);
|
||||
|
||||
var configurationDirectory = new DirectoryInfo(Path.Combine(Program.AppDataRoot, "config"));
|
||||
if (configurationDirectory.Exists)
|
||||
{
|
||||
foreach (var settingsFile in configurationDirectory.GetFiles("*.json"))
|
||||
{
|
||||
configurationBuilder.AddJsonFile(settingsFile.FullName, optional: true, reloadOnChange: true);
|
||||
}
|
||||
}
|
||||
|
||||
return configurationBuilder.Build();
|
||||
}
|
||||
|
||||
internal static IServiceCollection AddViewModels(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.TryAddSingleton<MainWindowViewModel>();
|
||||
@@ -69,14 +88,8 @@ public static class Startup
|
||||
);
|
||||
}
|
||||
|
||||
internal static IServiceCollection AddConfiguration(this IServiceCollection serviceCollection)
|
||||
internal static IServiceCollection AddConfiguration(this IServiceCollection serviceCollection, IConfigurationRoot configuration)
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(MainConfiguration.Configuration)
|
||||
.AddJsonFile("appsettings.json", optional: true)
|
||||
.AddJsonFile($"appsettings.{Program.EnvironmentName}.json", true)
|
||||
.Build();
|
||||
|
||||
return serviceCollection
|
||||
.Configure<ProgramsConfiguration>(configuration.GetSection(SectionNames.ProgramsSectionName))
|
||||
.Configure<KeyBindingConfiguration>(configuration.GetSection(SectionNames.KeybindingSectionName))
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace FileTime.GuiApp.Configuration;
|
||||
|
||||
public class FontConfiguration
|
||||
{
|
||||
public const string SectionName = "Font";
|
||||
|
||||
public List<string> Main { get; set; } = new();
|
||||
public List<string> DateTime { get; set; } = new();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>FileTime.GuiApp</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace FileTime.GuiApp.Services;
|
||||
|
||||
public interface IFontService
|
||||
{
|
||||
IObservable<string?> MainFont { get; }
|
||||
string? GetMainFont();
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>FileTime.GuiApp</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FileTime.GuiApp.Font.Abstractions\FileTime.GuiApp.Font.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="11.0.0-preview5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
|
||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
16
src/GuiApp/Avalonia/FileTime.GuiApp.Font/Font/Startup.cs
Normal file
16
src/GuiApp/Avalonia/FileTime.GuiApp.Font/Font/Startup.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using FileTime.GuiApp.Configuration;
|
||||
using FileTime.GuiApp.Services;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace FileTime.GuiApp.Font;
|
||||
|
||||
public static class Startup
|
||||
{
|
||||
public static IServiceCollection ConfigureFont(this IServiceCollection services, IConfigurationRoot configurationRoot)
|
||||
{
|
||||
services.Configure<FontConfiguration>(configurationRoot.GetSection(FontConfiguration.SectionName));
|
||||
services.AddSingleton<IFontService, FontService>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Subjects;
|
||||
using Avalonia.Media;
|
||||
using FileTime.GuiApp.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace FileTime.GuiApp.Services;
|
||||
|
||||
public class FontService : IFontService
|
||||
{
|
||||
private readonly IOptionsMonitor<FontConfiguration> _fontConfiguration;
|
||||
|
||||
private readonly BehaviorSubject<string?> _mainFont = new(null);
|
||||
public IObservable<string?> MainFont => _mainFont.DistinctUntilChanged();
|
||||
|
||||
public FontService(IOptionsMonitor<FontConfiguration> fontConfiguration)
|
||||
{
|
||||
_fontConfiguration = fontConfiguration;
|
||||
fontConfiguration.OnChange(UpdateFonts);
|
||||
|
||||
UpdateFonts(fontConfiguration.CurrentValue, null);
|
||||
}
|
||||
|
||||
private void UpdateFonts(FontConfiguration newConfiguration, string? arg2)
|
||||
{
|
||||
_mainFont.OnNext(GetMainFont());
|
||||
}
|
||||
|
||||
public string? GetMainFont()
|
||||
{
|
||||
var installedFonts = FontManager.Current.GetInstalledFontFamilyNames().ToList();
|
||||
return _fontConfiguration.CurrentValue.Main.FirstOrDefault(f => installedFonts.Contains(f));
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,14 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="11.0.0-preview4" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.0-preview4" />
|
||||
<PackageReference Include="Avalonia" Version="11.0.0-preview5" />
|
||||
<PackageReference Include="Avalonia.Controls.ItemsRepeater" Version="11.0.0-preview5" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.0-preview5" />
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.0-preview4" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.0-preview4" />
|
||||
<PackageReference Include="Avalonia.Svg.Skia" Version="11.0.0-preview4" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0-preview4" />
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.0-preview5" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.0-preview5" />
|
||||
<PackageReference Include="Avalonia.Svg.Skia" Version="11.0.0-preview5" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0-preview5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
|
||||
<PackageReference Include="MvvmGen" Version="1.1.5" />
|
||||
@@ -40,6 +41,7 @@
|
||||
<ProjectReference Include="..\..\..\AppCommon\FileTime.App.Core.Abstraction\FileTime.App.Core.Abstraction.csproj" />
|
||||
<ProjectReference Include="..\..\..\Providers\FileTime.Providers.Local.Abstractions\FileTime.Providers.Local.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\FileTime.GuiApp.Abstractions\FileTime.GuiApp.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\FileTime.GuiApp.Font.Abstractions\FileTime.GuiApp.Font.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</ResourceDictionary>
|
||||
</Styles.Resources>
|
||||
|
||||
<FluentTheme Mode="Dark" />
|
||||
<FluentTheme />
|
||||
|
||||
<Style Selector="TextBlock">
|
||||
<Setter Property="Foreground" Value="{DynamicResource ForegroundBrush}" />
|
||||
|
||||
@@ -3,4 +3,5 @@ namespace FileTime.GuiApp.ViewModels;
|
||||
public interface IMainWindowViewModelBase
|
||||
{
|
||||
bool Loading { get; }
|
||||
IObservable<string?> MainFont { get; }
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
using System.Reactive.Subjects;
|
||||
|
||||
namespace FileTime.GuiApp.ViewModels;
|
||||
|
||||
public class MainWindowLoadingViewModel : IMainWindowViewModelBase
|
||||
{
|
||||
public bool Loading => true;
|
||||
public IObservable<string?> MainFont { get; } = new BehaviorSubject<string?>("");
|
||||
}
|
||||
@@ -9,6 +9,7 @@ using FileTime.Core.Timeline;
|
||||
using FileTime.GuiApp.Services;
|
||||
using FileTime.Providers.Local;
|
||||
using InitableService;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MvvmGen;
|
||||
@@ -26,9 +27,11 @@ namespace FileTime.GuiApp.ViewModels;
|
||||
[Inject(typeof(IItemPreviewService), PropertyAccessModifier = AccessModifier.Public)]
|
||||
[Inject(typeof(IDialogService), PropertyAccessModifier = AccessModifier.Public)]
|
||||
[Inject(typeof(ITimelessContentProvider), PropertyName = "_timelessContentProvider")]
|
||||
[Inject(typeof(IFontService), "_fontService")]
|
||||
public partial class MainWindowViewModel : IMainWindowViewModelBase
|
||||
{
|
||||
public bool Loading => false;
|
||||
public IObservable<string?> MainFont => _fontService.MainFont;
|
||||
public IGuiAppState AppState => _appState;
|
||||
public string Title { get; private set; }
|
||||
|
||||
|
||||
@@ -20,9 +20,11 @@
|
||||
Background="Transparent"
|
||||
Closed="OnWindowClosed"
|
||||
ExtendClientAreaToDecorationsHint="True"
|
||||
FontFamily="{Binding MainFont^, Mode=OneWay}"
|
||||
Icon="/Assets/filetime.ico"
|
||||
InputElement.KeyDown="OnKeyDown"
|
||||
KeyDown="OnKeyDown"
|
||||
Opened="OnWindowOpened"
|
||||
RequestedThemeVariant="Dark"
|
||||
TransparencyLevelHint="Blur"
|
||||
mc:Ignorable="d">
|
||||
<Window.Resources>
|
||||
|
||||
Reference in New Issue
Block a user