Two themes, and one place that decides what colour a station is
Colours came from static brushes scattered over the windows. They now come from a Theme, and everything that paints a station, a spot or a log row asks Themes.Current as it paints, so changing the theme changes every window without reopening it. light is N1MM's own palette, read out of ApplicationStyles: the pale blue behind a window, ivory on a button, white boxes, and the four colours a station is painted in. dark is the same states in colours for a dark screen, which is roughly what the program looked like before. Config > Manage Skins, Colors and Fonts picks one, under N1MM's name for the same dialog, and shows what each theme paints a callsign. The choice is kept in settings.json as Theme, and light is the default. The window chrome follows through resources the Fluent controls read, so a text box and a button take the theme's colours in every state. Fonts and skins are not part of it. Looked at under Xvfb in both themes: the entry window, the theme dialog, and the log window with its rows still coloured by what each contact was worth. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
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;
|
||||
@@ -16,10 +18,62 @@ public partial class App : Application
|
||||
{
|
||||
UserPaths paths = UserPaths.Default();
|
||||
paths.CreateFolders();
|
||||
AppSession session = new(paths, Settings.Load(paths.SettingsFile));
|
||||
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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user