109 lines
3.8 KiB
C#
109 lines
3.8 KiB
C#
using System.Globalization;
|
|
|
|
using Avalonia;
|
|
using Avalonia.Controls.ApplicationLifetimes;
|
|
using Avalonia.Data.Core.Plugins;
|
|
using Avalonia.Markup.Xaml;
|
|
using Avalonia.Media;
|
|
using Avalonia.Styling;
|
|
|
|
using YKanBan.Services;
|
|
using YKanBan.Storage.AppData;
|
|
using YKanBan.ViewModels;
|
|
using YKanBan.Views;
|
|
|
|
using Resx = YKanBan.Resources;
|
|
|
|
namespace YKanBan;
|
|
|
|
public partial class App : Application {
|
|
/// <summary>
|
|
/// Gets the process-wide composition root, created at startup.
|
|
/// </summary>
|
|
public static AppServices? Services { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Gets the language applied at startup; a live selection differing from it
|
|
/// needs a restart.
|
|
/// </summary>
|
|
public static string StartupLanguage { get; private set; } = AppConfig.DefaultLanguage;
|
|
|
|
/// <summary>
|
|
/// Gets the flow direction of the startup culture. FlowDirection does not
|
|
/// inherit across windows, so the main window and every modal window apply it.
|
|
/// </summary>
|
|
public static FlowDirection UiFlowDirection { get; private set; } = FlowDirection.LeftToRight;
|
|
|
|
public override void Initialize() {
|
|
AvaloniaXamlLoader.Load(this);
|
|
}
|
|
|
|
public override void OnFrameworkInitializationCompleted() {
|
|
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) {
|
|
DisableAvaloniaDataAnnotationValidation();
|
|
|
|
// Startup order: apply the configured culture, its RTL flow direction
|
|
// and the theme BEFORE creating the main window.
|
|
Services = new AppServices();
|
|
CultureInfo culture = ResolveCulture(Services.Config.Language);
|
|
StartupLanguage = Services.Config.Language;
|
|
Resx.Culture = culture;
|
|
|
|
// RTL detection drives the flow direction of every window; the two
|
|
// supported languages are LTR, but the infrastructure stays in
|
|
// place for future languages.
|
|
UiFlowDirection = culture.TextInfo.IsRightToLeft
|
|
? FlowDirection.RightToLeft
|
|
: FlowDirection.LeftToRight;
|
|
ApplyTheme(Services.Config.Theme);
|
|
|
|
var viewModel = new MainWindowViewModel(Services, desktop.Args ?? []);
|
|
desktop.MainWindow = new MainWindow {
|
|
DataContext = viewModel,
|
|
FlowDirection = UiFlowDirection,
|
|
};
|
|
}
|
|
|
|
base.OnFrameworkInitializationCompleted();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resolves a configured language to a culture, falling back to English.
|
|
/// </summary>
|
|
/// <param name="language">The language code from app.json.</param>
|
|
/// <returns>The resolved culture.</returns>
|
|
public static CultureInfo ResolveCulture(string language) {
|
|
try {
|
|
return new CultureInfo(language);
|
|
} catch (CultureNotFoundException) {
|
|
return new CultureInfo(AppConfig.DefaultLanguage);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Applies a theme selection immediately; <see cref="ThemeOption.FollowSystem"/>
|
|
/// inherits the operating system preference.
|
|
/// </summary>
|
|
/// <param name="option">The theme selection.</param>
|
|
public static void ApplyTheme(ThemeOption option) {
|
|
if (Current is null) {
|
|
return;
|
|
}
|
|
|
|
Current.RequestedThemeVariant = option switch {
|
|
ThemeOption.Light => ThemeVariant.Light,
|
|
ThemeOption.Dark => ThemeVariant.Dark,
|
|
_ => ThemeVariant.Default,
|
|
};
|
|
}
|
|
|
|
private static void DisableAvaloniaDataAnnotationValidation() {
|
|
var dataValidationPluginsToRemove =
|
|
BindingPlugins.DataValidators.OfType<DataAnnotationsValidationPlugin>().ToArray();
|
|
|
|
foreach (var plugin in dataValidationPluginsToRemove) {
|
|
BindingPlugins.DataValidators.Remove(plugin);
|
|
}
|
|
}
|
|
}
|