diff --git a/Flow.Launcher.Core/Resource/Theme.cs b/Flow.Launcher.Core/Resource/Theme.cs index 61f0b18e0ef..1c7485a9c24 100644 --- a/Flow.Launcher.Core/Resource/Theme.cs +++ b/Flow.Launcher.Core/Resource/Theme.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Xml; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Controls; @@ -219,17 +220,60 @@ private ResourceDictionary GetCurrentResourceDictionary( ) return GetResourceDictionary(Settings.Theme); } - public List LoadAvailableThemes() + public List LoadAvailableThemes() { - List themes = new List(); + List themes = new List(); foreach (var themeDirectory in _themeDirectories) { - themes.AddRange( - Directory.GetFiles(themeDirectory) - .Where(filePath => filePath.EndsWith(Extension) && !filePath.EndsWith("Base.xaml")) - .ToList()); + var filePaths = Directory + .GetFiles(themeDirectory) + .Where(filePath => filePath.EndsWith(Extension) && !filePath.EndsWith("Base.xaml")) + .Select(GetThemeDataFromPath); + themes.AddRange(filePaths); } - return themes.OrderBy(o => o).ToList(); + + return themes.OrderBy(o => o.Name).ToList(); + } + + private ThemeData GetThemeDataFromPath(string path) + { + using var reader = XmlReader.Create(path); + reader.Read(); + + var extensionlessName = Path.GetFileNameWithoutExtension(path); + + if (reader.NodeType is not XmlNodeType.Comment) + return new ThemeData(extensionlessName, extensionlessName); + + var commentLines = reader.Value.Trim().Split('\n').Select(v => v.Trim()); + var themeData = new ThemeData(extensionlessName, extensionlessName); + foreach (var line in commentLines) + { + if (line.StartsWith("Name:", StringComparison.OrdinalIgnoreCase)) + { + themeData = themeData with { Name = line.Remove(0, "Name:".Length).Trim() }; + } + else if (line.StartsWith("IsDark:", StringComparison.OrdinalIgnoreCase)) + { + themeData = themeData with + { + IsDark = bool.Parse( + line.Remove(0, "IsDark:".Length).Trim() + ) + }; + } + else if (line.StartsWith("BlurAmount:", StringComparison.OrdinalIgnoreCase)) + { + themeData = themeData with + { + BlurAmount = int.Parse( + line.Remove(0, "BlurAmount:".Length).Trim() + ) + }; + } + } + + return themeData; } private string GetThemePath(string themeName) @@ -407,5 +451,7 @@ private void SetWindowAccent(Window w, AccentState state) Marshal.FreeHGlobal(accentPtr); } #endregion + + public record ThemeData(string FileNameWithoutExtension, string Name, bool? IsDark = null, int? BlurAmount = null); } } diff --git a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs index 5046a475481..bac29bfcd8b 100644 --- a/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs +++ b/Flow.Launcher/SettingPages/ViewModels/SettingsPaneThemeViewModel.cs @@ -91,8 +91,7 @@ public double ResultSubItemFontSize get => Settings.ResultSubItemFontSize; set => Settings.ResultSubItemFontSize = value; } - public List Themes => - ThemeManager.Instance.LoadAvailableThemes().Select(Path.GetFileNameWithoutExtension).ToList(); + public List Themes => ThemeManager.Instance.LoadAvailableThemes(); public class ColorScheme diff --git a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml index 08b49e745bb..0c89ea19533 100644 --- a/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml +++ b/Flow.Launcher/SettingPages/Views/SettingsPaneTheme.xaml @@ -409,7 +409,8 @@ ItemsSource="{Binding Themes}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" - SelectedItem="{Binding SelectedTheme}"> + SelectedValue="{Binding SelectedTheme}" + SelectedValuePath="FileNameWithoutExtension">