Skip to content

Commit ee4ee15

Browse files
committed
Support color themes for standalone application
1 parent 553c143 commit ee4ee15

15 files changed

+294
-11
lines changed

src/ResXManager.VSIX/Visuals/MoveToResourceConfigurationViewModel.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44

55
using ResXManager.Infrastructure;
66

7+
using TomsToolbox.Wpf;
78
using TomsToolbox.Wpf.Composition.AttributedModel;
89

910
[LocalizedDisplayName(StringResourceKey.MoveToResource)]
1011
[VisualCompositionExport(RegionId.Configuration)]
1112
[Shared]
12-
internal class MoveToResourceConfigurationViewModel
13+
internal class MoveToResourceConfigurationViewModel : ObservableObject
1314
{
1415
[ImportingConstructor]
1516
public MoveToResourceConfigurationViewModel(DteConfiguration configuration)

src/ResXManager.VSIX/Visuals/VsixShellView.xaml.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Windows.Threading;
88

99
using ResXManager.Infrastructure;
10+
using ResXManager.View;
1011
using ResXManager.View.Themes;
1112

1213
using TomsToolbox.Composition;
@@ -48,17 +49,12 @@ protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
4849
if ((e.Property != ForegroundProperty) && (e.Property != BackgroundProperty))
4950
return;
5051

51-
var foreground = ToGray((Foreground as SolidColorBrush)?.Color);
52-
var background = ToGray((Background as SolidColorBrush)?.Color);
52+
var foreground = ((Foreground as SolidColorBrush)?.Color).ToGray();
53+
var background = ((Background as SolidColorBrush)?.Color).ToGray();
5354

5455
_themeManager.IsDarkTheme = background < foreground;
5556
}
5657

57-
private static double ToGray(Color? color)
58-
{
59-
return color?.R * 0.21 + color?.G * 0.72 + color?.B * 0.07 ?? 0.0;
60-
}
61-
6258
private void Self_Loaded(object? sender, RoutedEventArgs e)
6359
{
6460
this.BeginInvoke(DispatcherPriority.ApplicationIdle, () =>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace ResXManager.View
2+
{
3+
using System.Windows.Media;
4+
5+
public static class ExtensionMethods
6+
{
7+
public static double ToGray(this Color? color)
8+
{
9+
return color?.R * 0.3 + color?.G * 0.6 + color?.B * 0.1 ?? 0.0;
10+
}
11+
}
12+
}

src/ResXManager/App.xaml.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ protected override void OnStartup(StartupEventArgs e)
4848
IExportProvider exportProvider = new ExportProvider(_kernel);
4949
_kernel.Bind<IExportProvider>().ToConstant(exportProvider);
5050

51+
Resources.MergedDictionaries.Add(TomsToolbox.Wpf.Styles.WpfStyles.GetDefaultStyles());
5152
Resources.MergedDictionaries.Add(DataTemplateManager.CreateDynamicDataTemplates(exportProvider));
5253

5354
exportProvider.GetExportedValues<IService>().ForEach(service => service.Start());

src/ResXManager/Configuration.cs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,73 @@
11
namespace ResXManager
22
{
3+
using System.Collections.ObjectModel;
4+
using System.ComponentModel;
35
using System.Composition;
6+
using System.Windows;
7+
using System.Windows.Threading;
8+
9+
using PropertyChanged;
410

511
using ResXManager.Infrastructure;
612
using ResXManager.Model;
13+
using ResXManager.Properties;
14+
15+
using TomsToolbox.Essentials;
16+
using TomsToolbox.Wpf;
17+
18+
public enum ColorTheme
19+
{
20+
[LocalizedDisplayName(StringResourceKey.ColorTheme_System)]
21+
System,
22+
23+
[LocalizedDisplayName(StringResourceKey.ColorTheme_Light)]
24+
Light,
25+
26+
[LocalizedDisplayName(StringResourceKey.ColorTheme_Dark)]
27+
Dark
28+
}
729

830
[Export(typeof(IConfiguration))]
931
[Export(typeof(Configuration))]
1032
[Shared]
1133
public class StandaloneConfiguration : Configuration
1234
{
35+
private readonly Collection<ResourceDictionary> _colorThemeResourceContainer;
36+
1337
[ImportingConstructor]
1438
public StandaloneConfiguration(ITracer tracer)
1539
: base(tracer)
1640
{
41+
var themeDictionary = new ResourceDictionary();
42+
var applicationDictionaries = Application.Current.Resources.MergedDictionaries;
43+
applicationDictionaries.Insert(0, themeDictionary);
44+
_colorThemeResourceContainer = themeDictionary.MergedDictionaries;
45+
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal, OnColorThemeChanged);
1746
}
1847

1948
public override bool IsScopeSupported => false;
2049

2150
public override ConfigurationScope Scope => ConfigurationScope.Global;
51+
52+
[DefaultValue(nameof(ColorTheme.Light))]
53+
[OnChangedMethod(nameof(OnColorThemeChanged))]
54+
public ColorTheme ColorTheme { get; set; }
55+
56+
private void OnColorThemeChanged()
57+
{
58+
_colorThemeResourceContainer.Clear();
59+
60+
switch (ColorTheme)
61+
{
62+
case ColorTheme.System:
63+
break;
64+
case ColorTheme.Light:
65+
_colorThemeResourceContainer.Add(new ResourceDictionary {Source = GetType().Assembly.GeneratePackUri("Themes/LightTheme.xaml")});
66+
break;
67+
case ColorTheme.Dark:
68+
_colorThemeResourceContainer.Add(new ResourceDictionary {Source = GetType().Assembly.GeneratePackUri("Themes/DarkTheme.xaml")});
69+
break;
70+
}
71+
}
2272
}
23-
}
73+
}

src/ResXManager/MainWindow.xaml.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
using System.Windows;
88
using System.Windows.Controls.Primitives;
99
using System.Windows.Documents;
10+
using System.Windows.Media;
1011

1112
using ResXManager.Infrastructure;
1213
using ResXManager.Model;
1314
using ResXManager.Properties;
15+
using ResXManager.View;
16+
using ResXManager.View.Themes;
1417

1518
using TomsToolbox.Composition;
1619
using TomsToolbox.Wpf;
@@ -23,13 +26,15 @@
2326
public partial class MainWindow
2427
{
2528
private readonly ITracer _tracer;
29+
private readonly ThemeManager _themeManager;
2630
private Size _lastKnownSize;
2731
private Vector _lastKnownLocation;
2832

2933
[ImportingConstructor]
30-
public MainWindow(IExportProvider exportProvider, ITracer tracer)
34+
public MainWindow(IExportProvider exportProvider, ITracer tracer, ThemeManager themeManager)
3135
{
3236
_tracer = tracer;
37+
_themeManager = themeManager;
3338

3439
try
3540
{
@@ -152,5 +157,18 @@ private static void Navigate_Click(object? sender, RoutedEventArgs e)
152157

153158
Process.Start(url);
154159
}
160+
161+
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
162+
{
163+
base.OnPropertyChanged(e);
164+
165+
if ((e.Property != ForegroundProperty) && (e.Property != BackgroundProperty))
166+
return;
167+
168+
var foreground =((Foreground as SolidColorBrush)?.Color).ToGray();
169+
var background = ((Background as SolidColorBrush)?.Color).ToGray();
170+
171+
_themeManager.IsDarkTheme = background < foreground;
172+
}
155173
}
156174
}

src/ResXManager/Properties/Resources.Designer.cs

Lines changed: 52 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ResXManager/Properties/Resources.de.resx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,16 @@ Die Datei wird nicht automatisch dem Visual Studio-Projekt hinzugefügt.</value>
143143
<data name="QuerySaveChanges" xml:space="preserve">
144144
<value>Möchten sie die Änderungen speichern?</value>
145145
</data>
146+
<data name="ColorTheme_System" xml:space="preserve">
147+
<value>System</value>
148+
</data>
149+
<data name="ColorTheme_Dark" xml:space="preserve">
150+
<value>Dunkel</value>
151+
</data>
152+
<data name="ColorTheme_Light" xml:space="preserve">
153+
<value>Hell</value>
154+
</data>
155+
<data name="ColorTheme_Title" xml:space="preserve">
156+
<value>Farbschema</value>
157+
</data>
146158
</root>

src/ResXManager/Properties/Resources.resx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,16 @@ In the standalone version the file is not automatically added to the Visual Stud
146146
<data name="QuerySaveChanges" xml:space="preserve">
147147
<value>Do you want to save the changes?</value>
148148
</data>
149+
<data name="ColorTheme_System" xml:space="preserve">
150+
<value>System</value>
151+
</data>
152+
<data name="ColorTheme_Dark" xml:space="preserve">
153+
<value>Dark</value>
154+
</data>
155+
<data name="ColorTheme_Light" xml:space="preserve">
156+
<value>Light</value>
157+
</data>
158+
<data name="ColorTheme_Title" xml:space="preserve">
159+
<value>Color Theme</value>
160+
</data>
149161
</root>

src/ResXManager/ResXManager.csproj

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@
9898
<DependentUpon>OutputView.xaml</DependentUpon>
9999
</Compile>
100100
<Compile Include="OutputViewModel.cs" />
101+
<Compile Include="ThemeConfigurationView.xaml.cs">
102+
<DependentUpon>ThemeConfigurationView.xaml</DependentUpon>
103+
</Compile>
104+
<Compile Include="ThemeConfigurationViewModel.cs" />
101105
<Page Include="MainView.xaml">
102106
<SubType>Designer</SubType>
103107
<Generator>MSBuild:Compile</Generator>
@@ -124,6 +128,18 @@
124128
<SubType>Designer</SubType>
125129
<Generator>MSBuild:Compile</Generator>
126130
</Page>
131+
<Page Include="ThemeConfigurationView.xaml">
132+
<SubType>Designer</SubType>
133+
<Generator>MSBuild:Compile</Generator>
134+
</Page>
135+
<Page Include="Themes\DarkTheme.xaml">
136+
<Generator>MSBuild:Compile</Generator>
137+
<SubType>Designer</SubType>
138+
</Page>
139+
<Page Include="Themes\LightTheme.xaml">
140+
<Generator>MSBuild:Compile</Generator>
141+
<SubType>Designer</SubType>
142+
</Page>
127143
</ItemGroup>
128144
<ItemGroup>
129145
<Compile Include="Properties\AssemblyInfo.cs">
@@ -140,7 +156,9 @@
140156
<DependentUpon>Settings.settings</DependentUpon>
141157
<DesignTimeSharedInput>True</DesignTimeSharedInput>
142158
</Compile>
143-
<EmbeddedResource Include="Properties\Resources.de.resx" />
159+
<EmbeddedResource Include="Properties\Resources.de.resx">
160+
<SubType>Designer</SubType>
161+
</EmbeddedResource>
144162
<EmbeddedResource Include="Properties\Resources.resx">
145163
<SubType>Designer</SubType>
146164
</EmbeddedResource>
@@ -252,6 +270,7 @@
252270
<Version>1.1.1</Version>
253271
</PackageReference>
254272
</ItemGroup>
273+
<ItemGroup />
255274
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
256275
<Target Name="AfterPublish">
257276
<ItemGroup>

0 commit comments

Comments
 (0)