diff --git a/src/ST.Client.Desktop.Avalonia/Application/Converters/ColorStringToBrush.cs b/src/ST.Client.Desktop.Avalonia/Application/Converters/ColorStringToBrush.cs
index 14643e724..7a3b648d9 100644
--- a/src/ST.Client.Desktop.Avalonia/Application/Converters/ColorStringToBrush.cs
+++ b/src/ST.Client.Desktop.Avalonia/Application/Converters/ColorStringToBrush.cs
@@ -19,8 +19,10 @@ namespace System.Application.Converters
}
else
{
- if (value is string c3 && Color2.TryParse(c3, out var cc))
+ if (value is string c3 && Color.TryParse(c3, out var cc))
return cc;
+ if (value is string c4 && Color2.TryParse(c4, out var cc1))
+ return cc1;
}
return value;
}
diff --git a/src/ST.Client.Desktop.Avalonia/Application/UI/App.axaml b/src/ST.Client.Desktop.Avalonia/Application/UI/App.axaml
index 435ecc396..1bf76844d 100644
--- a/src/ST.Client.Desktop.Avalonia/Application/UI/App.axaml
+++ b/src/ST.Client.Desktop.Avalonia/Application/UI/App.axaml
@@ -8,6 +8,11 @@
+
@@ -22,17 +27,17 @@
-
-
-
-
+ PreferSystemTheme="False"/>
+
+
+
+
-
+
diff --git a/src/ST.Client.Desktop.Avalonia/Application/UI/App.axaml.cs b/src/ST.Client.Desktop.Avalonia/Application/UI/App.axaml.cs
index d49ed877f..2f613447d 100644
--- a/src/ST.Client.Desktop.Avalonia/Application/UI/App.axaml.cs
+++ b/src/ST.Client.Desktop.Avalonia/Application/UI/App.axaml.cs
@@ -30,6 +30,7 @@ using AvaloniaApplication = Avalonia.Application;
using ShutdownMode = Avalonia.Controls.ShutdownMode;
using Window = Avalonia.Controls.Window;
using WindowState = Avalonia.Controls.WindowState;
+using Avalonia.Markup.Xaml.MarkupExtensions;
#if WINDOWS
//using WpfApplication = System.Windows.Application;
#endif
@@ -123,20 +124,24 @@ namespace System.Application.UI
}
//var uri_0 = new Uri($"avares://Avalonia.Themes.Fluent/Fluent{themeName}.xaml");
- var uri_1 = new Uri($"avares://System.Application.SteamTools.Client.Avalonia/Application/UI/Styles/Theme{themeName}.xaml");
-
- //Styles[0] = new FluentTheme(uri_0)
- //{
- // Mode = mode,
- //};
- Styles[1] = new StyleInclude(uri_1)
- {
- Source = uri_1,
- };
+ //var uri_1 = new Uri($"avares://System.Application.SteamTools.Client.Avalonia/Application/UI/Styles/Theme{themeName}.xaml");
var faTheme = AvaloniaLocator.Current.GetService();
if (faTheme != null)
faTheme.RequestedTheme = themeName;
+
+ var csTheme = AvaloniaLocator.Current.GetService();
+ if (csTheme != null)
+ csTheme.Mode = themeName;
+
+ //if (Resources.Count > 1)
+ //{
+ // //Styles[0] = new FluentTheme(uri_0)
+ // //{
+ // // Mode = mode,
+ // //};
+ // Resources.MergedDictionaries[0] = (ResourceDictionary)AvaloniaXamlLoader.Load(uri_1);
+ //}
}
public static void SetThemeAccent(string? colorHex)
diff --git a/src/ST.Client.Desktop.Avalonia/Application/UI/CustomTheme.cs b/src/ST.Client.Desktop.Avalonia/Application/UI/CustomTheme.cs
new file mode 100644
index 000000000..98e4adf6a
--- /dev/null
+++ b/src/ST.Client.Desktop.Avalonia/Application/UI/CustomTheme.cs
@@ -0,0 +1,208 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using Avalonia.Markup.Xaml.Styling;
+using Avalonia.Styling;
+using FluentAvalonia.Styling;
+using System;
+using System.Collections.Generic;
+
+namespace System.Application.UI
+{
+ ///
+ /// Includes the fluent theme in an application.
+ ///
+ public class CustomTheme : AvaloniaObject, IStyle, IResourceProvider
+ {
+ private readonly Uri _baseUri;
+ private Styles _sharedStyles = new();
+ private Styles _fluentDark = new();
+ private Styles _fluentLight = new();
+ private bool _isLoading;
+ private IStyle? _loaded;
+ private readonly ResourceDictionary _themeResources = new ResourceDictionary();
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The base URL for the XAML context.
+ public CustomTheme(Uri baseUri)
+ {
+ _baseUri = baseUri;
+ InitStyles(baseUri);
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The XAML service provider.
+ public CustomTheme(IServiceProvider serviceProvider)
+ {
+ _baseUri = ((IUriContext)serviceProvider.GetService(typeof(IUriContext))).BaseUri;
+ InitStyles(_baseUri);
+ }
+
+ public static readonly StyledProperty ModeProperty =
+ AvaloniaProperty.Register(nameof(Mode), "Dark");
+
+ ///
+ /// Gets or sets the mode of the fluent theme (light, dark).
+ ///
+ public string Mode
+ {
+ get => GetValue(ModeProperty);
+ set => SetValue(ModeProperty, value);
+ }
+
+ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
+ {
+ base.OnPropertyChanged(change);
+
+ if (_loaded is null)
+ {
+ // If style wasn't yet loaded, no need to change children styles,
+ // it will be applied later in Loaded getter.
+ return;
+ }
+
+ if (change.Property == ModeProperty)
+ {
+ //if (Mode == FluentAvaloniaTheme.DarkModeString)
+ //{
+ // //(Loaded as Styles)![0] = _fluentDark[0];
+ //}
+ //else
+ //{
+ // //(Loaded as Styles)![0] = _fluentLight[0];
+ //}
+
+ // Remove the old theme of any resources
+
+ _themeResources.MergedDictionaries[0] =
+ (ResourceDictionary)AvaloniaXamlLoader.Load(new Uri($"avares://System.Application.SteamTools.Client.Avalonia/Application/UI/Styles/Theme{Mode}.xaml"), _baseUri);
+
+ Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty);
+ }
+ }
+
+ public IResourceHost? Owner => (Loaded as IResourceProvider)?.Owner;
+
+ ///
+ /// Gets the loaded style.
+ ///
+ public IStyle Loaded
+ {
+ get
+ {
+ if (_loaded == null)
+ {
+ _isLoading = true;
+
+ if (Mode == FluentAvaloniaTheme.LightModeString)
+ {
+ _loaded = new Styles() { _sharedStyles };
+ }
+ else
+ {
+ _loaded = new Styles() { _sharedStyles };
+ }
+
+ _isLoading = false;
+ }
+
+ return _loaded!;
+ }
+ }
+
+ bool IResourceNode.HasResources => (Loaded as IResourceProvider)?.HasResources ?? false;
+
+ IReadOnlyList IStyle.Children => _loaded?.Children ?? Array.Empty();
+
+ public event EventHandler? OwnerChanged
+ {
+ add
+ {
+ if (Loaded is IResourceProvider rp)
+ {
+ rp.OwnerChanged += value;
+ }
+ }
+
+ remove
+ {
+ if (Loaded is IResourceProvider rp)
+ {
+ rp.OwnerChanged -= value;
+ }
+ }
+ }
+
+ public SelectorMatchResult TryAttach(IStyleable target, IStyleHost? host) => Loaded.TryAttach(target, host);
+
+ public bool TryGetResource(object key, out object? value)
+ {
+ // Github build failing with this not being set, even tho it passes locally
+ value = null;
+
+ // We also search the app level resources so resources can be overridden.
+ // Do not search App level styles though as we'll have to iterate over them
+ // to skip the FluentAvaloniaTheme instance or we'll stack overflow
+ if (Avalonia.Application.Current?.Resources.TryGetResource(key, out value) == true)
+ return true;
+
+ // This checks the actual ResourceDictionary where the SystemResources are stored
+ // and checks the merged dictionaries where base resources and theme resources are
+ if (_themeResources.TryGetResource(key, out value))
+ return true;
+
+ if (!_isLoading && Loaded is IResourceProvider p)
+ {
+ return p.TryGetResource(key, out value);
+ }
+
+ value = null;
+ return false;
+ }
+
+ void IResourceProvider.AddOwner(IResourceHost owner) => (Loaded as IResourceProvider)?.AddOwner(owner);
+
+ void IResourceProvider.RemoveOwner(IResourceHost owner) => (Loaded as IResourceProvider)?.RemoveOwner(owner);
+
+ private void InitStyles(Uri baseUri)
+ {
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(this);
+
+ _sharedStyles = new Styles
+ {
+ new StyleInclude(baseUri)
+ {
+ Source = new Uri("avares://System.Application.SteamTools.Client.Avalonia/Application/UI/Styles/ThemeAccent.xaml")
+ },
+ new StyleInclude(baseUri)
+ {
+ Source = new Uri("avares://System.Application.SteamTools.Client.Avalonia/Application/UI/Styles/Controls.xaml")
+ },
+ };
+
+ //_fluentLight = new Styles
+ //{
+ // new StyleInclude(baseUri)
+ // {
+ // Source = new Uri("avares://System.Application.SteamTools.Client.Avalonia/Application/UI/Styles/ThemeLight.xaml")
+ // }
+ //};
+
+ //_fluentDark = new Styles
+ //{
+ // new StyleInclude(baseUri)
+ // {
+ // Source = new Uri("avares://System.Application.SteamTools.Client.Avalonia/Application/UI/Styles/ThemeDark.xaml")
+ // }
+ //};
+
+ // Theme resource colors/brushes
+ _themeResources.MergedDictionaries.Add(
+ (ResourceDictionary)AvaloniaXamlLoader.Load(new Uri($"avares://System.Application.SteamTools.Client.Avalonia/Application/UI/Styles/Theme{Mode}.xaml"), _baseUri));
+ }
+ }
+}
diff --git a/src/ST.Client.Desktop.Avalonia/Application/UI/Styles/Controls/DataGrid.xaml b/src/ST.Client.Desktop.Avalonia/Application/UI/Styles/Controls/DataGrid.xaml
index cbc9a97af..169dd2935 100644
--- a/src/ST.Client.Desktop.Avalonia/Application/UI/Styles/Controls/DataGrid.xaml
+++ b/src/ST.Client.Desktop.Avalonia/Application/UI/Styles/Controls/DataGrid.xaml
@@ -1,10 +1,10 @@
-
+
-
+
@@ -16,9 +16,9 @@
-
+ -->
@@ -79,7 +87,7 @@
+
+
diff --git a/src/ST.Client.Desktop.Avalonia/Application/UI/Styles/ThemeLight.xaml b/src/ST.Client.Desktop.Avalonia/Application/UI/Styles/ThemeLight.xaml
index 704a5a0be..b63d3c2ac 100644
--- a/src/ST.Client.Desktop.Avalonia/Application/UI/Styles/ThemeLight.xaml
+++ b/src/ST.Client.Desktop.Avalonia/Application/UI/Styles/ThemeLight.xaml
@@ -1,135 +1,134 @@
-
-
-
-
-
-
-
-
+
-
- #AAFFFFFF
-
+ #AAFFFFFF
+
- #EEF3F3F3
-
+ #EEF3F3F3
+
- #FFB9B9C0
-
+ #FFB9B9C0
+
- #FF363636
-
+ #FF363636
+
- #FFF5F5F8
-
+ #FFF5F5F8
+
- #FFB9B9C0
-
+ #FFB9B9C0
+
- #FF101010
-
+ #FF101010
+
- #FFFFFFFF
-
+ #FFFFFFFF
+
- #FFB9B9C0
-
+ #FFB9B9C0
+
- #FF000000
-
+ #FF000000
+
- #FFEFEFF2
-
+ #FFEFEFF2
+
- #FFD7D7DE
-
+ #FFD7D7DE
+
- #FF808080
-
+ #FF808080
+
- #FFA5A5AC
-
+ #FFA5A5AC
+
- #FFA5A5AC
-
+ #FFA5A5AC
+
- #FF000000
-
+ #FF000000
+
- #FF696970
-
+ #FF696970
+
- #FF696970
-
+ #FF696970
+
- #FFFFFFFF
-
+ #FFFFFFFF
+
- #FF4B4B52
-
+ #FF4B4B52
+
- #FF4B4B52
-
+ #FF4B4B52
+
- #FFFFFFFF
-
+ #FFFFFFFF
+
- #FF0000C8
-
+ #FF0000C8
+
- #FF007ACC
-
+ #FF007ACC
+
- #FFC80000
-
+ #FFC80000
+
- #33000000
- #C50500
- #FFE6E6E6
- #19000000
- #33000000
- #FFFFFFFF
- #FF000000
- #66000000
- #FFF2F2F2
- #99000000
- #FFF2F2F2
+ #33000000
+ #C50500
+ #FFE6E6E6
+ #19000000
+ #33000000
+ #FFFFFFFF
+ #FF000000
+ #66000000
+ #FFF2F2F2
+ #99000000
+ #FFF2F2F2
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ST.Client.Desktop.Avalonia/Application/UI/Views/Pages/Settings/Settings_UI.axaml b/src/ST.Client.Desktop.Avalonia/Application/UI/Views/Pages/Settings/Settings_UI.axaml
index aadcdaf4c..6e43680ac 100644
--- a/src/ST.Client.Desktop.Avalonia/Application/UI/Views/Pages/Settings/Settings_UI.axaml
+++ b/src/ST.Client.Desktop.Avalonia/Application/UI/Views/Pages/Settings/Settings_UI.axaml
@@ -31,6 +31,13 @@