Skip to content

Commit 8114949

Browse files
authored
Feature: Improve readability in light design (#3191)
* Feature: Improve light theme readability * Feature: Improve light theme * Docs: #3191
1 parent c8b7256 commit 8114949

File tree

7 files changed

+160
-78
lines changed

7 files changed

+160
-78
lines changed

Source/NETworkManager.Localization/Resources/Strings.Designer.cs

Lines changed: 9 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Source/NETworkManager.Localization/Resources/Strings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3993,4 +3993,7 @@ Right-click for more options.</value>
39933993
<data name="CollapseAll" xml:space="preserve">
39943994
<value>Collapse all</value>
39953995
</data>
3996+
<data name="HelpMessage_UseCustomThemes" xml:space="preserve">
3997+
<value>Use custom themes to personalize the appearance of the application. You can edit or add theme in the "Program Folder &gt; Themes" directory. For more details, refer to the documentation.</value>
3998+
</data>
39963999
</root>
Lines changed: 109 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
using System;
1+
using ControlzEx.Theming;
2+
using MahApps.Metro.Controls.Dialogs;
3+
using MahApps.Metro.Theming;
4+
using NETworkManager.Models.Appearance;
5+
using System;
26
using System.Collections.Generic;
37
using System.IO;
48
using System.Linq;
59
using System.Windows;
610
using System.Windows.Media;
7-
using ControlzEx.Theming;
8-
using MahApps.Metro.Controls.Dialogs;
9-
using MahApps.Metro.Theming;
10-
using NETworkManager.Models.Appearance;
1111

1212
namespace NETworkManager.Settings;
1313

@@ -16,6 +16,27 @@ namespace NETworkManager.Settings;
1616
/// </summary>
1717
public static class AppearanceManager
1818
{
19+
#region Variables
20+
/// <summary>
21+
/// Dictionary to override some brushes for the light theme.
22+
/// </summary>
23+
private static readonly ResourceDictionary LightThemeOverrideDictionary = new()
24+
{
25+
//["MahApps.Brushes.ThemeBackground"] = new SolidColorBrush(Color.FromRgb(248, 248, 255)),
26+
//["MahApps.Brushes.Control.Background"] = new SolidColorBrush(Color.FromRgb(248, 248, 255)),
27+
["MahApps.Brushes.Gray3"] = new SolidColorBrush(Color.FromRgb(104, 104, 104)),
28+
["MahApps.Brushes.Gray5"] = new SolidColorBrush(Color.FromRgb(138, 138, 138)),
29+
["MahApps.Brushes.Gray8"] = new SolidColorBrush(Color.FromRgb(190, 190, 190)),
30+
};
31+
32+
/// <summary>
33+
/// Dictionary to override some brushes for the dark theme.
34+
/// </summary>
35+
private static readonly ResourceDictionary DarkThemeOverrideDictionary = new()
36+
{
37+
38+
};
39+
1940
/// <summary>
2041
/// Name of the folder inside the application directory where the custom themes are stored.
2142
/// </summary>
@@ -26,23 +47,40 @@ public static class AppearanceManager
2647
/// </summary>
2748
public static readonly MetroDialogSettings MetroDialog = new();
2849

50+
/// <summary>
51+
/// List who contains all MahApps.Metro themes.
52+
/// </summary>
53+
public static List<ThemeColorInfo> Themes { get; set; }
54+
55+
/// <summary>
56+
/// List who contains all MahApps.Metro custom themes.
57+
/// </summary>
58+
public static List<ThemeInfo> CustomThemes { get; private set; }
59+
60+
/// <summary>
61+
/// List who contains all MahApps.Metro accents.
62+
/// </summary>
63+
public static List<AccentColorInfo> Accents { get; set; }
64+
#endregion
65+
66+
#region Constructor
2967
/// <summary>
3068
/// Load the MahApps.Metro themes and accents when needed.
3169
/// </summary>
3270
static AppearanceManager()
3371
{
34-
Themes = ThemeManager.Current.Themes
72+
Themes = [.. ThemeManager.Current.Themes
3573
.GroupBy(x => x.BaseColorScheme)
3674
.Select(x => x.First())
3775
.Select(x => new ThemeColorInfo
38-
{ Name = x.BaseColorScheme, Color = x.Resources["MahApps.Brushes.ThemeBackground"] as Brush })
39-
.ToList();
76+
{ Name = x.BaseColorScheme, Color = x.Resources["MahApps.Brushes.ThemeBackground"] as Brush })];
4077

41-
Accents = ThemeManager.Current.Themes
78+
Accents = [.. ThemeManager.Current.Themes
4279
.GroupBy(x => x.ColorScheme)
4380
.OrderBy(x => x.Key)
44-
.Select(x => new AccentColorInfo { Name = x.Key, Color = x.First().ShowcaseBrush })
45-
.ToList();
81+
.Select(x => new AccentColorInfo { Name = x.Key, Color = x.First().ShowcaseBrush })];
82+
83+
ThemeManager.Current.ThemeChanged += Current_ThemeChanged;
4684

4785
LoadCustomThemes();
4886

@@ -55,22 +93,9 @@ static AppearanceManager()
5593
MetroDialog.DialogButtonFontSize = 14;
5694
MetroDialog.DialogMessageFontSize = 14;
5795
}
96+
#endregion
5897

59-
/// <summary>
60-
/// List who contains all MahApps.Metro themes.
61-
/// </summary>
62-
public static List<ThemeColorInfo> Themes { get; set; }
63-
64-
/// <summary>
65-
/// List who contains all MahApps.Metro custom themes.
66-
/// </summary>
67-
public static List<ThemeInfo> CustomThemes { get; private set; }
68-
69-
/// <summary>
70-
/// List who contains all MahApps.Metro accents.
71-
/// </summary>
72-
public static List<AccentColorInfo> Accents { get; set; }
73-
98+
#region Methods
7499
/// <summary>
75100
/// Change the appearance based on the user settings. This method should be called once, when starting the application.
76101
/// </summary>
@@ -79,22 +104,21 @@ public static void Load()
79104
if (SettingsManager.Current.Appearance_UseCustomTheme && CustomThemes.Count > 0)
80105
{
81106
ChangeTheme(
82-
CustomThemes.FirstOrDefault(x => x.Name == SettingsManager.Current.Appearance_CustomThemeName) ??
83-
CustomThemes.First());
84-
}
85-
else
86-
{
87-
ChangeTheme(SettingsManager.Current.Appearance_Theme);
88-
ChangeAccent(SettingsManager.Current.Appearance_Accent);
107+
(CustomThemes.FirstOrDefault(x => x.Name == SettingsManager.Current.Appearance_CustomThemeName) ??
108+
CustomThemes.First()).Name);
109+
110+
return;
89111
}
112+
113+
ChangeTheme(SettingsManager.Current.Appearance_Theme, SettingsManager.Current.Appearance_Accent);
90114
}
91115

92116
/// <summary>
93117
/// Method to load the custom themes from a folder into the <see cref="ThemeManager" />.
94118
/// </summary>
95119
private static void LoadCustomThemes()
96120
{
97-
List<ThemeInfo> customThemes = new();
121+
List<ThemeInfo> customThemes = [];
98122

99123
foreach (var file in Directory.GetFiles(Path.Combine(ConfigurationManager.Current.ExecutionPath,
100124
ThemeFolderName)))
@@ -110,29 +134,68 @@ private static void LoadCustomThemes()
110134
}
111135

112136
/// <summary>
113-
/// Method to change the application theme.
137+
/// Method to change the application theme (and accent).
114138
/// </summary>
115-
/// <param name="name">Name of the MahApps theme base color.</param>
139+
/// <param name="name">Theme name as "theme.accent" to apply.</param>
116140
public static void ChangeTheme(string name)
117141
{
118-
ThemeManager.Current.ChangeThemeBaseColor(System.Windows.Application.Current, name);
142+
ThemeManager.Current.ChangeTheme(System.Windows.Application.Current, name);
119143
}
120144

121145
/// <summary>
122-
/// Method to change the application accent.
146+
/// Method to change the application theme (and accent).
123147
/// </summary>
124-
/// <param name="name">Name of the MahApps theme accent color.</param>
125-
public static void ChangeAccent(string name)
148+
/// <param name="theme">Theme name to apply.</param>
149+
/// <param name="accent">Accent name to apply.</param>
150+
public static void ChangeTheme(string theme, string accent)
126151
{
127-
ThemeManager.Current.ChangeThemeColorScheme(System.Windows.Application.Current, name);
152+
ChangeTheme($"{theme}.{accent}");
128153
}
129154

130155
/// <summary>
131-
/// Method to change the application theme based on the name in <see cref="ThemeInfo" />.
156+
///
132157
/// </summary>
133-
/// <param name="themeInfo">Theme as <see cref="ThemeInfo" /> to apply.</param>
134-
public static void ChangeTheme(ThemeInfo themeInfo)
158+
/// <param name="theme"></param>
159+
private static void ApplyCustomThemeFixes(string theme)
160+
{
161+
// Don't apply on custom themes (only built-in light/dark themes)
162+
if (CustomThemes.Any(x => x.Name.Equals(theme, StringComparison.OrdinalIgnoreCase)))
163+
return;
164+
165+
// Get application resources
166+
var appResources = System.Windows.Application.Current.Resources;
167+
168+
// Remove any existing theme overrides
169+
appResources.MergedDictionaries.Remove(LightThemeOverrideDictionary);
170+
appResources.MergedDictionaries.Remove(DarkThemeOverrideDictionary);
171+
172+
173+
// Theme name is in format "theme.accent"
174+
switch (theme.ToLowerInvariant().Split('.')[0])
175+
{
176+
case "light":
177+
appResources.MergedDictionaries.Add(LightThemeOverrideDictionary);
178+
break;
179+
180+
case "dark":
181+
appResources.MergedDictionaries.Add(DarkThemeOverrideDictionary);
182+
break;
183+
}
184+
185+
// Refresh UI
186+
foreach (Window window in System.Windows.Application.Current.Windows)
187+
{
188+
if (window.IsLoaded)
189+
window.InvalidateVisual();
190+
}
191+
}
192+
193+
#endregion
194+
195+
#region Events
196+
private static void Current_ThemeChanged(object sender, ThemeChangedEventArgs e)
135197
{
136-
ThemeManager.Current.ChangeTheme(System.Windows.Application.Current, themeInfo.Name);
198+
ApplyCustomThemeFixes(e.NewTheme.Name);
137199
}
138-
}
200+
#endregion
201+
}

Source/NETworkManager/Resources/Styles/TextBlockStyles.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<Style x:Key="HeaderTextBlock" TargetType="{x:Type TextBlock}" BasedOn="{StaticResource DefaultTextBlock}">
99
<Setter Property="FontFamily" Value="{StaticResource MahApps.Fonts.Family.Header}" />
10-
<Setter Property="Foreground" Value="{StaticResource MahApps.Brushes.Gray5}" />
10+
<Setter Property="Foreground" Value="{DynamicResource MahApps.Brushes.Gray5}" />
1111
<Setter Property="FontSize" Value="18" />
1212
<Setter Property="Margin" Value="0,0,0,10" />
1313
</Style>

Source/NETworkManager/ViewModels/SettingsAppearanceViewModel.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
using System.ComponentModel;
1+
using NETworkManager.Models.Appearance;
2+
using NETworkManager.Settings;
3+
using System.ComponentModel;
24
using System.Linq;
35
using System.Windows.Data;
4-
using NETworkManager.Models.Appearance;
5-
using NETworkManager.Settings;
66

77
namespace NETworkManager.ViewModels;
88

@@ -26,7 +26,7 @@ public ThemeColorInfo SelectedTheme
2626

2727
if (!_isLoading && !UseCustomTheme)
2828
{
29-
AppearanceManager.ChangeTheme(value.Name);
29+
AppearanceManager.ChangeTheme(value.Name, SelectedAccent.Name);
3030
SettingsManager.Current.Appearance_Theme = value.Name;
3131
}
3232

@@ -35,7 +35,6 @@ public ThemeColorInfo SelectedTheme
3535
}
3636
}
3737

38-
3938
public ICollectionView Accents { get; }
4039

4140
private AccentColorInfo _selectedAccent;
@@ -50,7 +49,7 @@ public AccentColorInfo SelectedAccent
5049

5150
if (!_isLoading && !UseCustomTheme)
5251
{
53-
AppearanceManager.ChangeAccent(value.Name);
52+
AppearanceManager.ChangeTheme(SelectedTheme.Name, value.Name);
5453
SettingsManager.Current.Appearance_Accent = value.Name;
5554
}
5655

@@ -95,7 +94,7 @@ public ThemeInfo SelectedCustomTheme
9594

9695
if (!_isLoading && UseCustomTheme)
9796
{
98-
AppearanceManager.ChangeTheme(value);
97+
AppearanceManager.ChangeTheme(value.Name);
9998
SettingsManager.Current.Appearance_CustomThemeName = value.Name;
10099
}
101100

0 commit comments

Comments
 (0)