using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Avalonia.Media; using Nonemm.App.Configuration; using Nonemm.App.Theming; using Nonemm.App.Windows; namespace Nonemm.App; public partial class App : Application { public override void Initialize() => AvaloniaXamlLoader.Load(this); public override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { UserPaths paths = UserPaths.Default(); if (paths.CreateFolders() is { } problem) { desktop.MainWindow = new StartupProblemWindow(problem, paths.Root); base.OnFrameworkInitializationCompleted(); return; } Settings settings = Settings.Load(paths.SettingsFile); Themes.Use(settings.Theme); Themes.Changed += (_, _) => ApplyTheme(); ApplyTheme(); AppSession session = new(paths, settings); desktop.MainWindow = new EntryWindow(session); desktop.ShutdownRequested += (_, _) => session.Dispose(); } base.OnFrameworkInitializationCompleted(); } /// The window chrome follows the theme through these resources; everything /// that draws a station or a spot asks `Themes.Current` as it paints. private void ApplyTheme() { Theme theme = Themes.Current; RequestedThemeVariant = theme.Variant; Set("FormBackground", theme.FormBackground); Set("FormForeground", theme.FormForeground); Set("FieldBackground", theme.FieldBackground); Set("FieldForeground", theme.FieldForeground); // the keys the Fluent controls read, so a text box and a button take // the theme's colours in every state rather than only where a style of // ours reaches them foreach (string key in new[] { "TextControlBackground", "TextControlBackgroundPointerOver", "TextControlBackgroundFocused", "TextControlBackgroundDisabled", "ComboBoxBackground", "ComboBoxBackgroundPointerOver", "ComboBoxBackgroundPressed", "DataGridRowBackgroundBrush", }) { Set(key, theme.FieldBackground); } foreach (string key in new[] { "TextControlForeground", "TextControlForegroundPointerOver", "TextControlForegroundFocused", "ComboBoxForeground", "ButtonForeground", "ButtonForegroundPointerOver", "ButtonForegroundPressed", }) { Set(key, theme.FieldForeground); } Set("ButtonBackground", theme.ButtonBackground); Set("ButtonBackgroundPointerOver", Lighter(theme.ButtonBackground)); Set("ButtonBackgroundPressed", Darker(theme.ButtonBackground)); } private void Set(string key, Color colour) => Resources[key] = new SolidColorBrush(colour); private static Color Lighter(Color colour) => Shifted(colour, 12); private static Color Darker(Color colour) => Shifted(colour, -18); private static Color Shifted(Color colour, int by) => Color.FromRgb( (byte)Math.Clamp(colour.R + by, 0, 255), (byte)Math.Clamp(colour.G + by, 0, 255), (byte)Math.Clamp(colour.B + by, 0, 255)); }