From 10fe4c773bcdb886dcaf33fb77abfeb80ae9f417 Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Tue, 4 Nov 2025 15:59:48 +0100
Subject: [PATCH 1/4] Add better theme support
---
src/DesktopMagic/Dialogs/ThemeDialog.xaml | 76 ++++++++++
src/DesktopMagic/Dialogs/ThemeDialog.xaml.cs | 143 ++++++++++++++++++
src/DesktopMagic/MainWindow.xaml | 71 +++------
src/DesktopMagic/MainWindow.xaml.cs | 128 +++-------------
src/DesktopMagic/Plugins/PluginData.cs | 2 +-
src/DesktopMagic/Plugins/Theme.cs | 14 +-
.../Resources/Strings/StringResources.de.xaml | 5 +-
.../Resources/Strings/StringResources.en.xaml | 5 +-
.../Settings/DesktopMagicSettings.cs | 15 +-
src/DesktopMagic/Settings/Layout.cs | 29 +++-
src/DesktopMagic/Settings/PluginSettings.cs | 30 +++-
11 files changed, 342 insertions(+), 176 deletions(-)
create mode 100644 src/DesktopMagic/Dialogs/ThemeDialog.xaml
create mode 100644 src/DesktopMagic/Dialogs/ThemeDialog.xaml.cs
diff --git a/src/DesktopMagic/Dialogs/ThemeDialog.xaml b/src/DesktopMagic/Dialogs/ThemeDialog.xaml
new file mode 100644
index 0000000..4611d40
--- /dev/null
+++ b/src/DesktopMagic/Dialogs/ThemeDialog.xaml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/DesktopMagic/Dialogs/ThemeDialog.xaml.cs b/src/DesktopMagic/Dialogs/ThemeDialog.xaml.cs
new file mode 100644
index 0000000..d922c03
--- /dev/null
+++ b/src/DesktopMagic/Dialogs/ThemeDialog.xaml.cs
@@ -0,0 +1,143 @@
+using DesktopMagic.Helpers;
+using DesktopMagic.Plugins;
+
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace DesktopMagic.Dialogs;
+
+///
+/// Interaction logic for ColorDialog.xaml
+///
+public partial class ThemeDialog : Window
+{
+ private readonly Theme theme;
+
+ public ThemeDialog(string content, Theme theme, string title = App.AppName)
+ {
+ this.theme = theme;
+
+ InitializeComponent();
+
+ Resources.MergedDictionaries.Add(App.LanguageDictionary);
+
+ cornerRadiusTextBox.Text = theme.CornerRadius.ToString();
+ marginTextBox.Text = theme.Margin.ToString();
+ primaryColorRechtangle.Fill = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(theme.PrimaryColor));
+ secondaryColorRechtangle.Fill = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(theme.SecondaryColor));
+ backgroundColorRechtangle.Fill = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(theme.BackgroundColor));
+
+ label.Content = content;
+ Title = title;
+ }
+
+ private void OkButton_Click(object sender, RoutedEventArgs e)
+ {
+ DialogResult = true;
+ }
+
+ private void CancelButton_Click(object sender, RoutedEventArgs e)
+ {
+ DialogResult = false;
+ }
+
+ private void TextBlock_Loaded(object sender, RoutedEventArgs e)
+ {
+ int index = 0;
+ foreach (FontFamily ff in Fonts.SystemFontFamilies)
+ {
+ ComboBoxItem comboBoxItem = new()
+ {
+ FontFamily = ff,
+ Content = ff.ToString()
+ };
+ _ = fontComboBox.Items.Add(comboBoxItem);
+
+ if (ff.ToString() == theme.Font)
+ {
+ fontComboBox.SelectedIndex = index;
+ }
+ index++;
+ }
+ if (fontComboBox.SelectedIndex == -1)
+ {
+ fontComboBox.SelectedIndex = 0;
+ }
+ }
+
+ private void FontComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ theme.Font = fontComboBox.SelectedValue.ToString()!.Replace("System.Windows.Controls.ComboBoxItem: ", "");
+ }
+
+ private void ChangePrimaryColorButton_Click(object sender, RoutedEventArgs e)
+ {
+ ColorDialog colorDialog = new ColorDialog("Set Primary Color", theme.PrimaryColor)
+ {
+ Owner = this
+ };
+
+ if (colorDialog.ShowDialog() == true)
+ {
+ theme.PrimaryColor = colorDialog.ResultColor;
+ primaryColorRechtangle.Fill = colorDialog.ResultBrush;
+ }
+ }
+
+ private void ChangeSecondaryColorButton_Click(object sender, RoutedEventArgs e)
+ {
+ ColorDialog colorDialog = new ColorDialog("Set Secondary Color", theme.SecondaryColor)
+ {
+ Owner = this
+ };
+
+ if (colorDialog.ShowDialog() == true)
+ {
+ theme.SecondaryColor = colorDialog.ResultColor;
+ secondaryColorRechtangle.Fill = colorDialog.ResultBrush;
+ }
+ }
+
+ private void ChangeBackgroundColorButton_Click(object sender, RoutedEventArgs e)
+ {
+ ColorDialog colorDialog = new ColorDialog("Set Background Color", theme.BackgroundColor)
+ {
+ Owner = this
+ };
+
+ if (colorDialog.ShowDialog() == true)
+ {
+ theme.BackgroundColor = colorDialog.ResultColor;
+ backgroundColorRechtangle.Fill = colorDialog.ResultBrush;
+ }
+ }
+
+ private void CornerRadiusTextBox_TextChanged(object? sender, TextChangedEventArgs? e)
+ {
+ bool success = int.TryParse(cornerRadiusTextBox.Text, out int cornerRadius);
+ if (success)
+ {
+ cornerRadiusTextBox.Foreground = Brushes.Black;
+ theme.CornerRadius = cornerRadius;
+ }
+ else
+ {
+ cornerRadiusTextBox.Foreground = Brushes.Red;
+ }
+ }
+
+ private void MarginTextBox_TextChanged(object? sender, TextChangedEventArgs? e)
+ {
+ bool success = int.TryParse(marginTextBox.Text, out int margin);
+ if (success)
+ {
+ marginTextBox.Foreground = Brushes.Black;
+ theme.Margin = margin;
+ }
+ else
+ {
+ marginTextBox.Foreground = Brushes.Red;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/DesktopMagic/MainWindow.xaml b/src/DesktopMagic/MainWindow.xaml
index a2aef8b..8ce0e5e 100644
--- a/src/DesktopMagic/MainWindow.xaml
+++ b/src/DesktopMagic/MainWindow.xaml
@@ -24,7 +24,7 @@
-
+
@@ -38,7 +38,7 @@
-
+
@@ -75,53 +75,26 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
diff --git a/src/DesktopMagic/MainWindow.xaml.cs b/src/DesktopMagic/MainWindow.xaml.cs
index fb861ca..f820ded 100644
--- a/src/DesktopMagic/MainWindow.xaml.cs
+++ b/src/DesktopMagic/MainWindow.xaml.cs
@@ -11,10 +11,8 @@
using System.IO;
using System.Linq;
using System.Text.Json;
-using System.Threading;
using System.Windows;
using System.Windows.Controls;
-using System.Windows.Media;
namespace DesktopMagic
{
@@ -301,9 +299,16 @@ private void Window_Closed(object sender, EventArgs e)
#region Options
- private void FontComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ private void ChangeThemeButton_Click(object sender, RoutedEventArgs e)
{
- Settings.CurrentLayout.Theme.Font = fontComboBox.SelectedValue.ToString()!.Replace("System.Windows.Controls.ComboBoxItem: ", "");
+ Theme theme = themesListBox.SelectedItem as Theme ?? Settings.CurrentLayout.Theme;
+
+ ThemeDialog themeDialog = new(theme.Name, theme, App.AppName)
+ {
+ Owner = this
+ };
+
+ themeDialog.ShowDialog();
}
private void OptionsComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
@@ -381,100 +386,6 @@ private void ScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.
e.Handled = true;
}
- private void TextBlock_Loaded(object sender, RoutedEventArgs e)
- {
- int index = 0;
- foreach (FontFamily ff in Fonts.SystemFontFamilies)
- {
- ComboBoxItem comboBoxItem = new()
- {
- FontFamily = ff,
- Content = ff.ToString()
- };
- _ = fontComboBox.Items.Add(comboBoxItem);
-
- if (ff.ToString() == Settings.CurrentLayout.Theme.Font)
- {
- fontComboBox.SelectedIndex = index;
- }
- index++;
- }
- if (fontComboBox.SelectedIndex == -1)
- {
- fontComboBox.SelectedIndex = 0;
- }
- }
-
- private void ChangePrimaryColorButton_Click(object sender, RoutedEventArgs e)
- {
- ColorDialog colorDialog = new ColorDialog("Set Primary Color", Settings.CurrentLayout.Theme.PrimaryColor)
- {
- Owner = this
- };
-
- if (colorDialog.ShowDialog() == true)
- {
- Settings.CurrentLayout.Theme.PrimaryColor = colorDialog.ResultColor;
- primaryColorRechtangle.Fill = colorDialog.ResultBrush;
- }
- }
-
- private void ChangeSecondaryColorButton_Click(object sender, RoutedEventArgs e)
- {
- ColorDialog colorDialog = new ColorDialog("Set Secondary Color", Settings.CurrentLayout.Theme.SecondaryColor)
- {
- Owner = this
- };
-
- if (colorDialog.ShowDialog() == true)
- {
- Settings.CurrentLayout.Theme.SecondaryColor = colorDialog.ResultColor;
- secondaryColorRechtangle.Fill = colorDialog.ResultBrush;
- }
- }
-
- private void ChangeBackgroundColorButton_Click(object sender, RoutedEventArgs e)
- {
- ColorDialog colorDialog = new ColorDialog("Set Background Color", Settings.CurrentLayout.Theme.BackgroundColor)
- {
- Owner = this
- };
-
- if (colorDialog.ShowDialog() == true)
- {
- Settings.CurrentLayout.Theme.BackgroundColor = colorDialog.ResultColor;
- backgroundColorRechtangle.Fill = colorDialog.ResultBrush;
- }
- }
-
- private void CornerRadiusTextBox_TextChanged(object? sender, TextChangedEventArgs? e)
- {
- bool success = int.TryParse(cornerRadiusTextBox.Text, out int cornerRadius);
- if (success)
- {
- cornerRadiusTextBox.Foreground = Brushes.Black;
- Settings.CurrentLayout.Theme.CornerRadius = cornerRadius;
- }
- else
- {
- cornerRadiusTextBox.Foreground = Brushes.Red;
- }
- }
-
- private void MarginTextBox_TextChanged(object? sender, TextChangedEventArgs? e)
- {
- bool success = int.TryParse(marginTextBox.Text, out int margin);
- if (success)
- {
- marginTextBox.Foreground = Brushes.Black;
- Settings.CurrentLayout.Theme.Margin = margin;
- }
- else
- {
- marginTextBox.Foreground = Brushes.Red;
- }
- }
-
#region Layout
private readonly JsonSerializerOptions jsonSettingsOptions = new()
@@ -538,9 +449,11 @@ private void LoadSettings()
{
Settings = new DesktopMagicSettings()
{
- Layouts =
- [
+ Layouts = [
new Layout((string)FindResource("default"))
+ ],
+ Themes = [
+ new Theme((string)FindResource("default"))
]
};
@@ -551,9 +464,11 @@ private void LoadSettings()
Settings = JsonSerializer.Deserialize(json, jsonSettingsOptions) ?? new DesktopMagicSettings()
{
- Layouts =
- [
+ Layouts = [
new Layout((string)FindResource("default"))
+ ],
+ Themes = [
+ new Theme((string)FindResource("default"))
]
};
}
@@ -561,17 +476,8 @@ private void LoadSettings()
private void LoadLayout(bool minimize = true)
{
mainWindowDataContext.IsLoading = true;
- cornerRadiusTextBox.Text = Settings.CurrentLayout.Theme.CornerRadius.ToString();
- marginTextBox.Text = Settings.CurrentLayout.Theme.Margin.ToString();
blockWindowsClosing = false;
- primaryColorRechtangle.Fill = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(Settings.CurrentLayout.Theme.PrimaryColor));
- secondaryColorRechtangle.Fill = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(Settings.CurrentLayout.Theme.SecondaryColor));
- backgroundColorRechtangle.Fill = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(Settings.CurrentLayout.Theme.BackgroundColor));
-
- CornerRadiusTextBox_TextChanged(null, null);
- MarginTextBox_TextChanged(null, null);
-
foreach (Window window in Windows)
{
window.Close();
diff --git a/src/DesktopMagic/Plugins/PluginData.cs b/src/DesktopMagic/Plugins/PluginData.cs
index 19162d3..6a39238 100644
--- a/src/DesktopMagic/Plugins/PluginData.cs
+++ b/src/DesktopMagic/Plugins/PluginData.cs
@@ -9,7 +9,7 @@ internal class PluginData(PluginWindow window, PluginSettings pluginSettings) :
{
private readonly PluginWindow window = window;
- public ITheme Theme { get; } = pluginSettings.Theme;
+ public ITheme Theme => pluginSettings.Theme;
public Size WindowSize => new Size((int)window.ActualWidth, (int)window.ActualHeight);
diff --git a/src/DesktopMagic/Plugins/Theme.cs b/src/DesktopMagic/Plugins/Theme.cs
index 2ed05d5..9f96709 100644
--- a/src/DesktopMagic/Plugins/Theme.cs
+++ b/src/DesktopMagic/Plugins/Theme.cs
@@ -11,17 +11,27 @@
namespace DesktopMagic.Plugins;
-public class Theme : ITheme, INotifyPropertyChanged
+public class Theme(string name) : ITheme, INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
private Color primaryColor = Color.White;
- private Color secondaryColor = Color.White;
+ private Color secondaryColor = Color.LightGray;
private Color backgroundColor = Color.Transparent;
private string font = "Segoe UI";
private int cornerRadius;
private int margin;
+ public string Name
+ {
+ get => name;
+ set
+ {
+ name = value;
+ OnPropertyChanged();
+ }
+ }
+
public Color PrimaryColor
{
get => primaryColor;
diff --git a/src/DesktopMagic/Resources/Strings/StringResources.de.xaml b/src/DesktopMagic/Resources/Strings/StringResources.de.xaml
index e3180a4..49aa23d 100644
--- a/src/DesktopMagic/Resources/Strings/StringResources.de.xaml
+++ b/src/DesktopMagic/Resources/Strings/StringResources.de.xaml
@@ -26,7 +26,7 @@
Standard
Wollen sie das Programm wirklich schließen?
Keine Optionen!
- Bearbeiten
+ Layout Bearbeiten
Uhrzeit
Datum
CPU Auslastung
@@ -34,6 +34,9 @@
Signalverstärkung:
Neues Layout
Layout Löschen
+ Neues Theme
+ Theme Löschen
+ Theme Ändern
Ok
Abbrechen
Layoutnamen eingeben:
diff --git a/src/DesktopMagic/Resources/Strings/StringResources.en.xaml b/src/DesktopMagic/Resources/Strings/StringResources.en.xaml
index e4e5d3c..d173ff9 100644
--- a/src/DesktopMagic/Resources/Strings/StringResources.en.xaml
+++ b/src/DesktopMagic/Resources/Strings/StringResources.en.xaml
@@ -26,7 +26,7 @@
Default
Do you really want to close the program?
No Options!
- Edit
+ Edit Layout
Time
Date
CPU Usage
@@ -34,6 +34,9 @@
Signal Amplification:
New Layout
Delete Layout
+ New Theme
+ Delete Theme
+ Change Theme
Ok
Cancel
Enter layout name
diff --git a/src/DesktopMagic/Settings/DesktopMagicSettings.cs b/src/DesktopMagic/Settings/DesktopMagicSettings.cs
index 035699a..3e14dea 100644
--- a/src/DesktopMagic/Settings/DesktopMagicSettings.cs
+++ b/src/DesktopMagic/Settings/DesktopMagicSettings.cs
@@ -1,4 +1,6 @@
-using System.Collections.ObjectModel;
+using DesktopMagic.Plugins;
+
+using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
@@ -11,8 +13,19 @@ internal class DesktopMagicSettings : INotifyPropertyChanged
public event PropertyChangedEventHandler? PropertyChanged;
private ObservableCollection layouts = [];
+ private ObservableCollection themes = [];
private string? currentLayoutName;
+ public ObservableCollection Themes
+ {
+ get => themes;
+ set
+ {
+ themes = value;
+ OnPropertyChanged();
+ }
+ }
+
public ObservableCollection Layouts
{
get => layouts;
diff --git a/src/DesktopMagic/Settings/Layout.cs b/src/DesktopMagic/Settings/Layout.cs
index 03a42d9..8015c83 100644
--- a/src/DesktopMagic/Settings/Layout.cs
+++ b/src/DesktopMagic/Settings/Layout.cs
@@ -1,9 +1,11 @@
-using DesktopMagic.Plugins;
+using DesktopMagic.DataContexts;
+using DesktopMagic.Plugins;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
+using System.Text.Json.Serialization;
namespace DesktopMagic.Settings;
@@ -12,16 +14,30 @@ internal class Layout(string name) : INotifyPropertyChanged
public event PropertyChangedEventHandler? PropertyChanged;
private string name = name;
- private Theme theme = new Theme();
+ private string? currentThemeName = null;
private Dictionary plugins = [];
+ [JsonIgnore]
public Theme Theme
{
- get => theme;
+ get
+ {
+ DesktopMagicSettings settings = MainWindowDataContext.GetSettings();
+ return settings.Themes.FirstOrDefault(theme => theme.Name == currentThemeName) ?? settings.Themes.FirstOrDefault() ?? new Theme("ERROR");
+ }
+ }
+
+ public string? CurrentThemeName
+ {
+ get => currentThemeName;
set
{
- theme = value;
- OnPropertyChanged();
+ if (currentThemeName != value)
+ {
+ currentThemeName = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(Theme));
+ }
}
}
@@ -47,7 +63,8 @@ public string Name
public void UpdatePlugins()
{
- Plugins = Plugins.ToDictionary();
+ plugins = plugins.ToDictionary();
+ OnPropertyChanged(nameof(Plugins));
}
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
diff --git a/src/DesktopMagic/Settings/PluginSettings.cs b/src/DesktopMagic/Settings/PluginSettings.cs
index b9ae278..df6a30e 100644
--- a/src/DesktopMagic/Settings/PluginSettings.cs
+++ b/src/DesktopMagic/Settings/PluginSettings.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.ComponentModel;
+using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json.Serialization;
using System.Windows;
@@ -13,19 +14,40 @@ public class PluginSettings : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
- private readonly Theme? theme;
+ private string? currentThemeName;
private List settings = [];
private bool enabled = false;
private Point position = new Point(100, 100);
private Point size = new Point(300, 300);
- [JsonIgnore]
- public Theme Theme => theme is null ? MainWindowDataContext.GetSettings().CurrentLayout.Theme : theme;
-
// Only for internal use to show the name of the plugin in the main window
[JsonIgnore]
public string Name { get; set; } = string.Empty;
+ [JsonIgnore]
+ public Theme Theme
+ {
+ get
+ {
+ DesktopMagicSettings settings = MainWindowDataContext.GetSettings();
+ return settings.Themes.FirstOrDefault(t => t.Name == currentThemeName) ?? settings.CurrentLayout.Theme;
+ }
+ }
+
+ public string? CurrentThemeName
+ {
+ get => currentThemeName;
+ set
+ {
+ if (currentThemeName != value)
+ {
+ currentThemeName = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(Theme));
+ }
+ }
+ }
+
public List Settings
{
get => settings;
From 0bc7033196809781970f71185dd7e16cc20f4407 Mon Sep 17 00:00:00 2001
From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com>
Date: Mon, 8 Dec 2025 20:11:12 +0100
Subject: [PATCH 2/4] Fix some issues with the new theme support
---
src/DesktopMagic/MainWindow.xaml | 4 +-
src/DesktopMagic/MainWindow.xaml.cs | 70 ++++++++++++++-----
src/DesktopMagic/Plugins/PluginWindow.xaml.cs | 12 +++-
.../Resources/Strings/StringResources.de.xaml | 2 +
.../Resources/Strings/StringResources.en.xaml | 4 ++
.../Settings/DesktopMagicSettings.cs | 13 +++-
src/DesktopMagic/Settings/Layout.cs | 16 ++++-
src/DesktopMagic/Settings/PluginSettings.cs | 6 ++
8 files changed, 103 insertions(+), 24 deletions(-)
diff --git a/src/DesktopMagic/MainWindow.xaml b/src/DesktopMagic/MainWindow.xaml
index 8ce0e5e..1c1b7be 100644
--- a/src/DesktopMagic/MainWindow.xaml
+++ b/src/DesktopMagic/MainWindow.xaml
@@ -77,13 +77,13 @@
-