From 4e0e7c1900cbb0e05de1d65114b5e2d90c2bc8f2 Mon Sep 17 00:00:00 2001 From: Caeden Statia Date: Fri, 7 Feb 2020 17:09:25 -0800 Subject: [PATCH] Themes refactoring and commenting --- ModAssistant/Classes/Themes.cs | 100 ++++++++++++++++++----------- ModAssistant/MainWindow.xaml.cs | 4 +- ModAssistant/Pages/Options.xaml.cs | 4 +- 3 files changed, 67 insertions(+), 41 deletions(-) diff --git a/ModAssistant/Classes/Themes.cs b/ModAssistant/Classes/Themes.cs index 4ac5a27..81bc457 100644 --- a/ModAssistant/Classes/Themes.cs +++ b/ModAssistant/Classes/Themes.cs @@ -19,27 +19,30 @@ namespace ModAssistant private static Dictionary loadedThemes = new Dictionary(); private static List preInstalledThemes = new List { "Light", "Dark" }; + /// + /// Load all themes from local Themes subfolder and from embedded resources. + /// This also refreshes the Themes dropdown in the Options screen. + /// public static void LoadThemes() { loadedThemes.Clear(); - foreach (string localTheme in preInstalledThemes) + foreach (string localTheme in preInstalledThemes) //Load local themes (Light and Dark) { ResourceDictionary theme = LoadTheme(localTheme, true); loadedThemes.Add(localTheme, theme); } - if (Directory.Exists(ThemeDirectory)) + if (Directory.Exists(ThemeDirectory)) //Load themes from Themes subfolder if it exists. { foreach (string file in Directory.EnumerateFiles(ThemeDirectory)) { FileInfo info = new FileInfo(file); + //FileInfo includes the extension in its Name field, so we have to split the string and select only the actual name. + string name = info.Name.Split('.').First(); //Ignore Themes without the xaml extension and ignore themes with the same names as others. //If requests are made I can instead make a Theme class that splits the pre-installed themes from //user-made ones so that one more user-made Light/Dark theme can be added. - MessageBox.Show(info.Extension); - if (info.Extension.ToLower().Contains("xaml")) + if (info.Extension.ToLower().Contains("xaml") && !loadedThemes.ContainsKey(name)) { - string name = info.Name.Split('.').First(); - MessageBox.Show(name); ResourceDictionary theme = LoadTheme(name); if (theme != null) { @@ -47,27 +50,20 @@ namespace ModAssistant } } } - //MessageBox.Show($"(DEBUG) Loaded {loadedThemes.Count - 2} themes from Themes folder."); } - if (Options.Instance != null && Options.Instance.ApplicationThemeComboBox != null) + if (Options.Instance != null && Options.Instance.ApplicationThemeComboBox != null) //Refresh Themes dropdown in Options screen. { Options.Instance.ApplicationThemeComboBox.ItemsSource = LoadedThemes; Options.Instance.ApplicationThemeComboBox.SelectedIndex = LoadedThemes.IndexOf(LoadedTheme); } } - private static ResourceDictionary LoadTheme(string name, bool localUri = false) - { - string location = $"{Environment.CurrentDirectory}/Themes/{name}.xaml"; - if (!File.Exists(location) && !localUri) return null; - if (localUri) location = $"Themes/{name}.xaml"; - Uri uri = new Uri(location, localUri ? UriKind.Relative : UriKind.Absolute); - ResourceDictionary dictionary = new ResourceDictionary(); - dictionary.Source = uri; - return dictionary; - } - - public static void ApplyTheme(string theme, FrameworkElement element) + /// + /// Applies a loaded theme to ModAssistant. + /// + /// Name of the theme. + /// Page that this is called on (Used for refreshing button icon colors). + public static void ApplyTheme(string theme) { ResourceDictionary newTheme = loadedThemes[theme]; if (newTheme != null) @@ -75,27 +71,15 @@ namespace ModAssistant Application.Current.Resources.MergedDictionaries.RemoveAt(0); LoadedTheme = theme; Application.Current.Resources.MergedDictionaries.Insert(0, newTheme); - ReloadIcons(element); + ReloadIcons(); } else throw new ArgumentException($"{theme} does not exist."); } - private static void ReloadIcons(FrameworkElement element) - { - ResourceDictionary icons = Application.Current.Resources.MergedDictionaries.First(x => x.Source.ToString() == "Resources/Icons.xaml"); - - ChangeColor(element, icons, "AboutIconColor", "heartDrawingGroup"); - ChangeColor(element, icons, "InfoIconColor", "info_circleDrawingGroup"); - ChangeColor(element, icons, "OptionsIconColor", "cogDrawingGroup"); - ChangeColor(element, icons, "ModsIconColor", "microchipDrawingGroup"); - } - - private static void ChangeColor(FrameworkElement element, ResourceDictionary icons, string ResourceColorName, string DrawingGroupName) - { - element.Resources[ResourceColorName] = loadedThemes[LoadedTheme][ResourceColorName]; - ((GeometryDrawing)((DrawingGroup)icons[DrawingGroupName]).Children[0]).Brush = (Brush)element.Resources[ResourceColorName]; - } - + /// + /// Writes a local theme to disk. You cannot write a theme loaded from the Themes subfolder to disk. + /// + /// Name of local theme. public static void WriteThemeToDisk(string themeName) { if (!Directory.Exists(ThemeDirectory)) @@ -118,5 +102,47 @@ namespace ModAssistant } else MessageBox.Show("Template theme already exists!"); } + + /// + /// Loads a ResourceDictionary from either Embedded Resources or from a file location. + /// + /// ResourceDictionary file name. + /// Specifies whether or not to search in Embedded Resources or in the Themes subfolder. + /// + private static ResourceDictionary LoadTheme(string name, bool localUri = false) + { + string location = $"{Environment.CurrentDirectory}/Themes/{name}.xaml"; + if (!File.Exists(location) && !localUri) return null; + if (localUri) location = $"Themes/{name}.xaml"; + Uri uri = new Uri(location, localUri ? UriKind.Relative : UriKind.Absolute); + ResourceDictionary dictionary = new ResourceDictionary(); + dictionary.Source = uri; + return dictionary; + } + + /// + /// Reload the icon colors for the About, Info, Options, and Mods buttons from the currently loaded theme. + /// + private static void ReloadIcons() + { + ResourceDictionary icons = Application.Current.Resources.MergedDictionaries.First(x => x.Source.ToString() == "Resources/Icons.xaml"); + + ChangeColor(icons, "AboutIconColor", "heartDrawingGroup"); + ChangeColor(icons, "InfoIconColor", "info_circleDrawingGroup"); + ChangeColor(icons, "OptionsIconColor", "cogDrawingGroup"); + ChangeColor(icons, "ModsIconColor", "microchipDrawingGroup"); + } + + /// + /// Change the color of an image from the loaded theme. + /// + /// ResourceDictionary that contains the image. + /// Resource name of the color to change. + /// DrawingGroup name for the image. + private static void ChangeColor(ResourceDictionary icons, string ResourceColorName, string DrawingGroupName) + { + Application.Current.Resources[ResourceColorName] = loadedThemes[LoadedTheme][ResourceColorName]; + ((GeometryDrawing)((DrawingGroup)icons[DrawingGroupName]).Children[0]).Brush = (Brush)Application.Current.Resources[ResourceColorName]; + } } } diff --git a/ModAssistant/MainWindow.xaml.cs b/ModAssistant/MainWindow.xaml.cs index 9bdbe94..e60811f 100644 --- a/ModAssistant/MainWindow.xaml.cs +++ b/ModAssistant/MainWindow.xaml.cs @@ -63,11 +63,11 @@ namespace ModAssistant Themes.LoadThemes(); try { - Themes.ApplyTheme("Light", this); + Themes.ApplyTheme("Light"); } catch (ArgumentException) { - Themes.ApplyTheme("Light", this); + Themes.ApplyTheme("Light"); MainText = "Theme not found, reverting to Light theme..."; } diff --git a/ModAssistant/Pages/Options.xaml.cs b/ModAssistant/Pages/Options.xaml.cs index ed4ab3a..b7e4dd5 100644 --- a/ModAssistant/Pages/Options.xaml.cs +++ b/ModAssistant/Pages/Options.xaml.cs @@ -251,9 +251,9 @@ namespace ModAssistant.Pages { if ((sender as ComboBox).SelectedItem == null) { - Themes.ApplyTheme("Light", this); + Themes.ApplyTheme("Light"); MainWindow.Instance.MainText = "Current theme has been removed, reverting to Light..."; - }else Themes.ApplyTheme((sender as ComboBox).SelectedItem.ToString(), this); + }else Themes.ApplyTheme((sender as ComboBox).SelectedItem.ToString()); } private void ApplicationThemeExportTemplate_Click(object sender, RoutedEventArgs e)