Merge pull request #528 from irihitech/sync

Add RegisterFollowSystemTheme extension to Application
This commit is contained in:
Dong Bin
2025-01-07 15:08:11 +08:00
committed by GitHub
3 changed files with 81 additions and 39 deletions

View File

@@ -1,10 +1,7 @@
using System.Runtime.InteropServices;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Avalonia.Platform;
using Semi.Avalonia.Demo.Views;
namespace Semi.Avalonia.Demo;
@@ -31,30 +28,7 @@ public partial class App : Application
break;
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var setting = PlatformSettings?.GetColorValues();
if (setting?.ContrastPreference is ColorContrastPreference.High)
{
if (setting.AccentColor1 == Color.Parse("#8EE3F0"))
{
RequestedThemeVariant = SemiTheme.Aquatic;
}
else if (setting.AccentColor1 == Color.Parse("#903909"))
{
RequestedThemeVariant = SemiTheme.Desert;
}
else if (setting.AccentColor1 == Color.Parse("#A1BFDE"))
{
RequestedThemeVariant = SemiTheme.Dusk;
}
else if (setting.AccentColor1 == Color.Parse("#D6B4FD"))
{
RequestedThemeVariant = SemiTheme.NightSky;
}
}
}
this.RegisterFollowSystemTheme();
base.OnFrameworkInitializationCompleted();
}
}

View File

@@ -33,9 +33,14 @@ public partial class MainViewModel : ObservableObject
[
new MenuItemViewModel
{
Header = "High Contrast Theme",
Header = "Theme",
Items =
[
new MenuItemViewModel
{
Header = "Auto",
Command = FollowSystemThemeCommand
},
new MenuItemViewModel
{
Header = "Aquatic",
@@ -62,10 +67,10 @@ public partial class MainViewModel : ObservableObject
},
]
},
new MenuItemViewModel()
new MenuItemViewModel
{
Header = "Locale",
Items=
Items =
[
new MenuItemViewModel
{
@@ -114,6 +119,12 @@ public partial class MainViewModel : ObservableObject
];
}
[RelayCommand]
private void FollowSystemTheme()
{
Application.Current?.RegisterFollowSystemTheme();
}
[RelayCommand]
private void ToggleTheme()
{
@@ -121,26 +132,24 @@ public partial class MainViewModel : ObservableObject
if (app is null) return;
var theme = app.ActualThemeVariant;
app.RequestedThemeVariant = theme == ThemeVariant.Dark ? ThemeVariant.Light : ThemeVariant.Dark;
app.UnregisterFollowSystemTheme();
}
[RelayCommand]
private void SelectTheme(object? obj)
{
var app = Application.Current;
if (app is not null)
{
app.RequestedThemeVariant = obj as ThemeVariant;
}
if (app is null) return;
app.RequestedThemeVariant = obj as ThemeVariant;
app.UnregisterFollowSystemTheme();
}
[RelayCommand]
private void SelectLocale(object? obj)
{
var app = Application.Current;
if (app is not null)
{
SemiTheme.OverrideLocaleResources(app, obj as System.Globalization.CultureInfo);
}
if (app is null) return;
SemiTheme.OverrideLocaleResources(app, obj as CultureInfo);
}
[RelayCommand]

View File

@@ -0,0 +1,59 @@
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Avalonia;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Styling;
namespace Semi.Avalonia;
public static class ApplicationExtension
{
private static Application _app = null!;
private static readonly Dictionary<Color, ThemeVariant> ColorThemeMap = new()
{
[Color.Parse("#8EE3F0")] = SemiTheme.Aquatic,
[Color.Parse("#903909")] = SemiTheme.Desert,
[Color.Parse("#A1BFDE")] = SemiTheme.Dusk,
[Color.Parse("#D6B4FD")] = SemiTheme.NightSky
};
public static void RegisterFollowSystemTheme(this Application app)
{
_app = app;
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return;
if (app.PlatformSettings is null) return;
app.PlatformSettings.ColorValuesChanged -= OnColorValuesChanged;
app.PlatformSettings.ColorValuesChanged += OnColorValuesChanged;
OnColorValuesChanged(null, app.PlatformSettings?.GetColorValues());
}
public static void UnregisterFollowSystemTheme(this Application app)
{
_app = app;
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return;
if (app.PlatformSettings is null) return;
app.PlatformSettings.ColorValuesChanged -= OnColorValuesChanged;
}
private static void OnColorValuesChanged(object? _, PlatformColorValues? args)
{
ThemeVariant result;
if (args?.ContrastPreference is ColorContrastPreference.High)
{
result = ColorThemeMap.TryGetValue(args.AccentColor1, out var theme) ? theme : ThemeVariant.Default;
}
else
{
result = args?.ThemeVariant switch
{
PlatformThemeVariant.Light => ThemeVariant.Light,
PlatformThemeVariant.Dark => ThemeVariant.Dark,
_ => ThemeVariant.Default
};
}
_app.RequestedThemeVariant = result;
}
}