|
2 | 2 | using System.Collections.Generic;
|
3 | 3 | using System.IO;
|
4 | 4 | using System.Linq;
|
| 5 | +using System.Xml; |
5 | 6 | using System.Runtime.InteropServices;
|
6 | 7 | using System.Windows;
|
7 | 8 | using System.Windows.Controls;
|
@@ -219,17 +220,60 @@ private ResourceDictionary GetCurrentResourceDictionary( )
|
219 | 220 | return GetResourceDictionary(Settings.Theme);
|
220 | 221 | }
|
221 | 222 |
|
222 |
| - public List<string> LoadAvailableThemes() |
| 223 | + public List<ThemeData> LoadAvailableThemes() |
223 | 224 | {
|
224 |
| - List<string> themes = new List<string>(); |
| 225 | + List<ThemeData> themes = new List<ThemeData>(); |
225 | 226 | foreach (var themeDirectory in _themeDirectories)
|
226 | 227 | {
|
227 |
| - themes.AddRange( |
228 |
| - Directory.GetFiles(themeDirectory) |
229 |
| - .Where(filePath => filePath.EndsWith(Extension) && !filePath.EndsWith("Base.xaml")) |
230 |
| - .ToList()); |
| 228 | + var filePaths = Directory |
| 229 | + .GetFiles(themeDirectory) |
| 230 | + .Where(filePath => filePath.EndsWith(Extension) && !filePath.EndsWith("Base.xaml")) |
| 231 | + .Select(GetThemeDataFromPath); |
| 232 | + themes.AddRange(filePaths); |
231 | 233 | }
|
232 |
| - return themes.OrderBy(o => o).ToList(); |
| 234 | + |
| 235 | + return themes.OrderBy(o => o.Name).ToList(); |
| 236 | + } |
| 237 | + |
| 238 | + private ThemeData GetThemeDataFromPath(string path) |
| 239 | + { |
| 240 | + using var reader = XmlReader.Create(path); |
| 241 | + reader.Read(); |
| 242 | + |
| 243 | + var extensionlessName = Path.GetFileNameWithoutExtension(path); |
| 244 | + |
| 245 | + if (reader.NodeType is not XmlNodeType.Comment) |
| 246 | + return new ThemeData(extensionlessName, extensionlessName); |
| 247 | + |
| 248 | + var commentLines = reader.Value.Trim().Split('\n').Select(v => v.Trim()); |
| 249 | + var themeData = new ThemeData(extensionlessName, extensionlessName); |
| 250 | + foreach (var line in commentLines) |
| 251 | + { |
| 252 | + if (line.StartsWith("Name:", StringComparison.OrdinalIgnoreCase)) |
| 253 | + { |
| 254 | + themeData = themeData with { Name = line.Remove(0, "Name:".Length).Trim() }; |
| 255 | + } |
| 256 | + else if (line.StartsWith("IsDark:", StringComparison.OrdinalIgnoreCase)) |
| 257 | + { |
| 258 | + themeData = themeData with |
| 259 | + { |
| 260 | + IsDark = bool.Parse( |
| 261 | + line.Remove(0, "IsDark:".Length).Trim() |
| 262 | + ) |
| 263 | + }; |
| 264 | + } |
| 265 | + else if (line.StartsWith("BlurAmount:", StringComparison.OrdinalIgnoreCase)) |
| 266 | + { |
| 267 | + themeData = themeData with |
| 268 | + { |
| 269 | + BlurAmount = int.Parse( |
| 270 | + line.Remove(0, "BlurAmount:".Length).Trim() |
| 271 | + ) |
| 272 | + }; |
| 273 | + } |
| 274 | + } |
| 275 | + |
| 276 | + return themeData; |
233 | 277 | }
|
234 | 278 |
|
235 | 279 | private string GetThemePath(string themeName)
|
@@ -407,5 +451,7 @@ private void SetWindowAccent(Window w, AccentState state)
|
407 | 451 | Marshal.FreeHGlobal(accentPtr);
|
408 | 452 | }
|
409 | 453 | #endregion
|
| 454 | + |
| 455 | + public record ThemeData(string FileNameWithoutExtension, string Name, bool? IsDark = null, int? BlurAmount = null); |
410 | 456 | }
|
411 | 457 | }
|
0 commit comments