diff --git a/src/modules/ShortcutGuide/ShortcutGuide.IndexYmlGenerator/IndexYmlGenerator.cs b/src/modules/ShortcutGuide/ShortcutGuide.IndexYmlGenerator/IndexYmlGenerator.cs
index d8a1179733..1997bc1023 100644
--- a/src/modules/ShortcutGuide/ShortcutGuide.IndexYmlGenerator/IndexYmlGenerator.cs
+++ b/src/modules/ShortcutGuide/ShortcutGuide.IndexYmlGenerator/IndexYmlGenerator.cs
@@ -21,7 +21,7 @@ namespace ShortcutGuide.IndexYmlGenerator
// Todo: Exception handling
public static void CreateIndexYmlFile()
{
- string path = ManifestInterpreter.GetPathOfInterpretations();
+ string path = ManifestInterpreter.PathOfManifestFiles;
if (File.Exists(Path.Combine(path, "index.yml")))
{
File.Delete(Path.Combine(path, "index.yml"));
diff --git a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/DisplayHelper.cs b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/DisplayHelper.cs
index cc968333cb..e638ff1c7e 100644
--- a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/DisplayHelper.cs
+++ b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/DisplayHelper.cs
@@ -9,21 +9,28 @@ namespace ShortcutGuide.Helpers
{
public static class DisplayHelper
{
- private enum MonitorFromWindowDwFlags
- {
- MONITOR_DEFAULTTONEAREST = 2,
- }
-
+ ///
+ /// Returns the display work area for the monitor that contains the specified window.
+ ///
+ /// The window handle
+ /// A element containing the display area
public static Rect GetWorkAreaForDisplayWithWindow(nint hwnd)
{
_foundMonitorIndex = -1;
_monitorIndex = 0;
- var monitor = NativeMethods.MonitorFromWindow(hwnd, (int)MonitorFromWindowDwFlags.MONITOR_DEFAULTTONEAREST);
+ var monitor = NativeMethods.MonitorFromWindow(hwnd, (int)NativeMethods.MonitorFromWindowDwFlags.MONITOR_DEFAULTTONEAREST);
NativeMethods.EnumDisplayMonitors(nint.Zero, nint.Zero, MonitorEnumProc, new NativeMethods.LPARAM(monitor));
return MonitorInfo.GetDisplayMonitors()[_foundMonitorIndex].RectWork;
}
+ ///
+ /// The index of the monitor that contains the specified window. -1 indicates that no monitor was found (yet).
+ ///
private static int _foundMonitorIndex = -1;
+
+ ///
+ /// The index of the monitor in the enumeration. This is used to find the correct monitor in the list of monitors.
+ ///
private static int _monitorIndex;
private static bool MonitorEnumProc(nint hMonitor, nint hdcMonitor, ref NativeMethods.RECT lprcMonitor, nint dwData)
diff --git a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/DpiHelper.cs b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/DpiHelper.cs
index c63f449af1..78f5fa8b12 100644
--- a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/DpiHelper.cs
+++ b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/DpiHelper.cs
@@ -20,13 +20,13 @@ namespace ShortcutGuide.Helpers
return (float)dpi / DEFAULT_DPI;
}
- public static long GetScreenDPIForWindow(int hwnd, ref int dpi)
+ private static long GetScreenDPIForWindow(int hwnd, ref int dpi)
{
var targetMonitor = NativeMethods.MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
return GetScreenDPIForMonitor(targetMonitor.ToInt32(), ref dpi);
}
- public static long GetScreenDPIForMonitor(int targetMonitor, ref int dpi)
+ private static long GetScreenDPIForMonitor(int targetMonitor, ref int dpi)
{
if (targetMonitor != 0)
{
diff --git a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/ManifestInterpreter.cs b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/ManifestInterpreter.cs
index 70497c6b07..e45ccb58d1 100644
--- a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/ManifestInterpreter.cs
+++ b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/ManifestInterpreter.cs
@@ -15,18 +15,34 @@ using YamlDotNet.Serialization;
namespace ShortcutGuide.Helpers
{
+ ///
+ /// Helps to interpret the manifest files for the Shortcut Guide.
+ ///
public class ManifestInterpreter
{
// Todo: Get language from settings or environment variable, default to "en-US"
+
+ ///
+ /// Gets the language used for the manifest files.
+ ///
public static string Language => "en-US";
+ ///
+ /// Returns the shortcuts for a specific application.
+ ///
+ ///
+ /// The method should only be called if the application is known to have a shortcuts file.
+ ///
+ /// The manifest id.
+ /// The deserialized shortcuts file.
+ /// The requested file was not found.
public static ShortcutFile GetShortcutsOfApplication(string applicationName)
{
- string path = GetPathOfInterpretations();
+ string path = PathOfManifestFiles;
IEnumerable files = Directory.EnumerateFiles(path, applicationName + ".*.yml") ??
throw new FileNotFoundException($"The file for the application '{applicationName}' was not found in '{path}'.");
- IEnumerable filesEnumerable = files as string[] ?? files.ToArray();
+ IEnumerable filesEnumerable = files as string[] ?? [.. files];
return filesEnumerable.Any(f => f.EndsWith($".{Language}.yml", StringComparison.InvariantCulture))
? YamlToShortcutList(File.ReadAllText(Path.Combine(path, applicationName + $".{Language}.yml")))
: filesEnumerable.Any(f => f.EndsWith(".en-US.yml", StringComparison.InvariantCulture))
@@ -34,25 +50,38 @@ namespace ShortcutGuide.Helpers
: throw new FileNotFoundException($"The file for the application '{applicationName}' was not found in '{path}' with the language '{Language}' or 'en-US'.");
}
- public static ShortcutFile YamlToShortcutList(string content)
+ ///
+ /// Deserializes the content of a YAML file to a .
+ ///
+ /// The content of the YAML file.
+ /// A deserialized object.
+ private static ShortcutFile YamlToShortcutList(string content)
{
Deserializer deserializer = new();
return deserializer.Deserialize(content);
}
- public static string GetPathOfInterpretations()
- {
- return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft", "WinGet", "KeyboardShortcuts");
- }
+ ///
+ /// Gets the path to the directory where the manifest files are stored.
+ ///
+ public static string PathOfManifestFiles => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft", "WinGet", "KeyboardShortcuts");
+ ///
+ /// Retrieves the index YAML file that contains the list of all applications and their shortcuts.
+ ///
+ /// A deserialized object.
public static IndexFile GetIndexYamlFile()
{
- string path = GetPathOfInterpretations();
+ string path = PathOfManifestFiles;
string content = File.ReadAllText(Path.Combine(path, "index.yml"));
Deserializer deserializer = new();
return deserializer.Deserialize(content);
}
+ ///
+ /// Retrieves all application IDs that should be displayed, based on the foreground window and background processes.
+ ///
+ /// An array of all application IDs.
public static string[] GetAllCurrentApplicationIds()
{
nint handle = NativeMethods.GetForegroundWindow();
diff --git a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/PowerToysShortcutsPopulator.cs b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/PowerToysShortcutsPopulator.cs
index 64c1a0860e..b96bcfa8b9 100644
--- a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/PowerToysShortcutsPopulator.cs
+++ b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/PowerToysShortcutsPopulator.cs
@@ -5,132 +5,147 @@
using System;
using System.Globalization;
using System.IO;
+using System.Text;
using System.Text.RegularExpressions;
using Microsoft.PowerToys.Settings.UI.Library;
using static ShortcutGuide.Helpers.ResourceLoaderInstance;
namespace ShortcutGuide.Helpers
{
+ ///
+ /// Populates the PowerToys shortcuts in the manifest files.
+ ///
internal sealed partial class PowerToysShortcutsPopulator
{
+ ///
+ /// Populates the PowerToys shortcuts in the manifest files.
+ ///
public static void Populate()
{
- string path = Path.Combine(ManifestInterpreter.GetPathOfInterpretations(), $"Microsoft.PowerToys.{ManifestInterpreter.Language}.yml");
+ string path = Path.Combine(ManifestInterpreter.PathOfManifestFiles, $"Microsoft.PowerToys.{ManifestInterpreter.Language}.yml");
- string content = File.ReadAllText(path);
+ StringBuilder content = new(File.ReadAllText(path));
const string populateStartString = "# ";
const string populateEndString = "# ";
- content = PopulateRegex().Replace(content, populateStartString + Environment.NewLine);
+ content = new(PopulateRegex().Replace(content.ToString(), populateStartString + Environment.NewLine));
ISettingsUtils settingsUtils = new SettingsUtils();
EnabledModules enabledModules = SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Enabled;
if (enabledModules.AdvancedPaste)
{
AdvancedPasteProperties advancedPasteProperties = SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties;
- content = HotkeySettingsToYaml(advancedPasteProperties.AdvancedPasteUIShortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), content, SettingsResourceLoader.GetString("AdvancedPasteUI_Shortcut/Header"));
- content = HotkeySettingsToYaml(advancedPasteProperties.PasteAsPlainTextShortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), content, SettingsResourceLoader.GetString("PasteAsPlainText_Shortcut/Header"));
- content = HotkeySettingsToYaml(advancedPasteProperties.PasteAsMarkdownShortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), content, SettingsResourceLoader.GetString("PasteAsMarkdown_Shortcut/Header"));
- content = HotkeySettingsToYaml(advancedPasteProperties.PasteAsJsonShortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), content, SettingsResourceLoader.GetString("PasteAsJson_Shortcut/Header"));
+ content.Append(HotkeySettingsToYaml(advancedPasteProperties.AdvancedPasteUIShortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), SettingsResourceLoader.GetString("AdvancedPasteUI_Shortcut/Header")));
+ content.Append(HotkeySettingsToYaml(advancedPasteProperties.PasteAsPlainTextShortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), SettingsResourceLoader.GetString("PasteAsPlainText_Shortcut/Header")));
+ content.Append(HotkeySettingsToYaml(advancedPasteProperties.PasteAsMarkdownShortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), SettingsResourceLoader.GetString("PasteAsMarkdown_Shortcut/Header")));
+ content.Append(HotkeySettingsToYaml(advancedPasteProperties.PasteAsJsonShortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), SettingsResourceLoader.GetString("PasteAsJson_Shortcut/Header")));
if (advancedPasteProperties.AdditionalActions.ImageToText.IsShown)
{
- content = HotkeySettingsToYaml(advancedPasteProperties.AdditionalActions.ImageToText.Shortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), content, SettingsResourceLoader.GetString("ImageToText/Header"));
+ content.Append(HotkeySettingsToYaml(advancedPasteProperties.AdditionalActions.ImageToText.Shortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), SettingsResourceLoader.GetString("ImageToText/Header")));
}
if (advancedPasteProperties.AdditionalActions.PasteAsFile.IsShown)
{
- content = HotkeySettingsToYaml(advancedPasteProperties.AdditionalActions.PasteAsFile.PasteAsTxtFile.Shortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), content, SettingsResourceLoader.GetString("PasteAsTxtFile/Header"));
- content = HotkeySettingsToYaml(advancedPasteProperties.AdditionalActions.PasteAsFile.PasteAsPngFile.Shortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), content, SettingsResourceLoader.GetString("PasteAsPngFile/Header"));
- content = HotkeySettingsToYaml(advancedPasteProperties.AdditionalActions.PasteAsFile.PasteAsHtmlFile.Shortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), content, SettingsResourceLoader.GetString("PasteAsHtmlFile/Header"));
+ content.Append(HotkeySettingsToYaml(advancedPasteProperties.AdditionalActions.PasteAsFile.PasteAsTxtFile.Shortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), SettingsResourceLoader.GetString("PasteAsTxtFile/Header")));
+ content.Append(HotkeySettingsToYaml(advancedPasteProperties.AdditionalActions.PasteAsFile.PasteAsPngFile.Shortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), SettingsResourceLoader.GetString("PasteAsPngFile/Header")));
+ content.Append(HotkeySettingsToYaml(advancedPasteProperties.AdditionalActions.PasteAsFile.PasteAsHtmlFile.Shortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), SettingsResourceLoader.GetString("PasteAsHtmlFile/Header")));
}
if (advancedPasteProperties.AdditionalActions.Transcode.IsShown)
{
- content = HotkeySettingsToYaml(advancedPasteProperties.AdditionalActions.Transcode.TranscodeToMp3.Shortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), content, SettingsResourceLoader.GetString("TranscodeToMp3/Header"));
- content = HotkeySettingsToYaml(advancedPasteProperties.AdditionalActions.Transcode.TranscodeToMp4.Shortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), content, SettingsResourceLoader.GetString("TranscodeToMp4/Header"));
+ content.Append(HotkeySettingsToYaml(advancedPasteProperties.AdditionalActions.Transcode.TranscodeToMp3.Shortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), SettingsResourceLoader.GetString("TranscodeToMp3/Header")));
+ content.Append(HotkeySettingsToYaml(advancedPasteProperties.AdditionalActions.Transcode.TranscodeToMp4.Shortcut, SettingsResourceLoader.GetString("AdvancedPaste/ModuleTitle"), SettingsResourceLoader.GetString("TranscodeToMp4/Header")));
}
}
if (enabledModules.AlwaysOnTop)
{
- content = HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.Hotkey, SettingsResourceLoader.GetString("AlwaysOnTop/ModuleTitle"), content, SettingsResourceLoader.GetString("AlwaysOnTop_ShortDescription"));
+ content.Append(HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.Hotkey, SettingsResourceLoader.GetString("AlwaysOnTop/ModuleTitle"), SettingsResourceLoader.GetString("AlwaysOnTop_ShortDescription")));
}
if (enabledModules.ColorPicker)
{
- content = HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("ColorPicker/ModuleTitle"), content, SettingsResourceLoader.GetString("ColorPicker_ShortDescription"));
+ content.Append(HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("ColorPicker/ModuleTitle"), SettingsResourceLoader.GetString("ColorPicker_ShortDescription")));
}
if (enabledModules.CmdPal)
{
- content = HotkeySettingsToYaml(new CmdPalProperties().Hotkey, SettingsResourceLoader.GetString("CmdPal/ModuleTitle"), content);
+ content.Append(HotkeySettingsToYaml(new CmdPalProperties().Hotkey, SettingsResourceLoader.GetString("CmdPal/ModuleTitle")));
}
if (enabledModules.CropAndLock)
{
CropAndLockProperties cropAndLockProperties = SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties;
- content = HotkeySettingsToYaml(cropAndLockProperties.ThumbnailHotkey, SettingsResourceLoader.GetString("CropAndLock/ModuleTitle"), content, SettingsResourceLoader.GetString("CropAndLock_Thumbnail"));
- content = HotkeySettingsToYaml(cropAndLockProperties.ReparentHotkey, SettingsResourceLoader.GetString("CropAndLock/ModuleTitle"), content, SettingsResourceLoader.GetString("CropAndLock_Reparent"));
+ content.Append(HotkeySettingsToYaml(cropAndLockProperties.ThumbnailHotkey, SettingsResourceLoader.GetString("CropAndLock/ModuleTitle"), SettingsResourceLoader.GetString("CropAndLock_Thumbnail")));
+ content.Append(HotkeySettingsToYaml(cropAndLockProperties.ReparentHotkey, SettingsResourceLoader.GetString("CropAndLock/ModuleTitle"), SettingsResourceLoader.GetString("CropAndLock_Reparent")));
}
if (enabledModules.FancyZones)
{
- content = HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.FancyzonesEditorHotkey, SettingsResourceLoader.GetString("FancyZones/ModuleTitle"), content, SettingsResourceLoader.GetString("FancyZones_OpenEditor"));
+ content.Append(HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.FancyzonesEditorHotkey, SettingsResourceLoader.GetString("FancyZones/ModuleTitle"), SettingsResourceLoader.GetString("FancyZones_OpenEditor")));
}
if (enabledModules.MouseHighlighter)
{
- content = HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("MouseUtils_MouseHighlighter/Header"), content, SettingsResourceLoader.GetString("MouseHighlighter_ShortDescription"));
+ content.Append(HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("MouseUtils_MouseHighlighter/Header"), SettingsResourceLoader.GetString("MouseHighlighter_ShortDescription")));
}
if (enabledModules.MouseJump)
{
- content = HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("MouseUtils_MouseJump/Header"), content, SettingsResourceLoader.GetString("MouseJump_ShortDescription"));
+ content.Append(HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("MouseUtils_MouseJump/Header"), SettingsResourceLoader.GetString("MouseJump_ShortDescription")));
}
if (enabledModules.MousePointerCrosshairs)
{
- content = HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("MouseUtils_MousePointerCrosshairs/Header"), content, SettingsResourceLoader.GetString("MouseCrosshairs_ShortDescription"));
+ content.Append(HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("MouseUtils_MousePointerCrosshairs/Header"), SettingsResourceLoader.GetString("MouseCrosshairs_ShortDescription")));
}
if (enabledModules.Peek)
{
- content = HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("Peek/ModuleTitle"), content);
+ content.Append(HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("Peek/ModuleTitle")));
}
if (enabledModules.PowerLauncher)
{
- content = HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.OpenPowerLauncher, SettingsResourceLoader.GetString("PowerLauncher/ModuleTitle"), content);
+ content.Append(HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.OpenPowerLauncher, SettingsResourceLoader.GetString("PowerLauncher/ModuleTitle")));
}
if (enabledModules.MeasureTool)
{
- content = HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("MeasureTool/ModuleTitle"), content, SettingsResourceLoader.GetString("ScreenRuler_ShortDescription"));
+ content.Append(HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("MeasureTool/ModuleTitle"), SettingsResourceLoader.GetString("ScreenRuler_ShortDescription")));
}
if (enabledModules.ShortcutGuide)
{
- content = HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.DefaultOpenShortcutGuide, SettingsResourceLoader.GetString("ShortcutGuide/ModuleTitle"), content, SettingsResourceLoader.GetString("ShortcutGuide_ShortDescription"));
+ content.Append(HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.DefaultOpenShortcutGuide, SettingsResourceLoader.GetString("ShortcutGuide/ModuleTitle"), SettingsResourceLoader.GetString("ShortcutGuide_ShortDescription")));
}
if (enabledModules.PowerOcr)
{
- content = HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("TextExtractor/ModuleTitle"), content, SettingsResourceLoader.GetString("PowerOcr_ShortDescription"));
+ content.Append(HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.ActivationShortcut, SettingsResourceLoader.GetString("TextExtractor/ModuleTitle"), SettingsResourceLoader.GetString("PowerOcr_ShortDescription")));
}
if (enabledModules.Workspaces)
{
- content = HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.Hotkey, SettingsResourceLoader.GetString("Workspaces/ModuleTitle"), content, SettingsResourceLoader.GetString("Workspaces_ShortDescription"));
+ content.Append(HotkeySettingsToYaml(SettingsRepository.GetInstance(settingsUtils).SettingsConfig.Properties.Hotkey, SettingsResourceLoader.GetString("Workspaces/ModuleTitle"), SettingsResourceLoader.GetString("Workspaces_ShortDescription")));
}
- content += populateEndString;
+ content.Append(populateEndString);
- File.WriteAllText(path, content);
+ File.WriteAllText(path, content.ToString());
}
- public static string HotkeySettingsToYaml(HotkeySettings hotkeySettings, string moduleName, string content, string? description = null)
+ ///
+ /// Converts the hotkey settings to a YAML format string for the manifest file.
+ ///
+ /// Object containing a hotkey from the settings.
+ /// The name of the PowerToys module.
+ /// Description of the action.
+ /// Yaml code for the manifest file.
+ private static string HotkeySettingsToYaml(HotkeySettings hotkeySettings, string moduleName, string? description = null)
{
+ string content = string.Empty;
content += " - Name: " + moduleName + Environment.NewLine;
content += " Shortcut: " + Environment.NewLine;
content += " - Win: " + hotkeySettings.Win.ToString() + Environment.NewLine;
@@ -147,9 +162,10 @@ namespace ShortcutGuide.Helpers
return content;
}
- public static string HotkeySettingsToYaml(KeyboardKeysProperty keyboardKeys, string moduleName, string content, string? description = null)
+ ///
+ private static string HotkeySettingsToYaml(KeyboardKeysProperty hotkeySettings, string moduleName, string? description = null)
{
- return HotkeySettingsToYaml(keyboardKeys.Value, moduleName, content, description);
+ return HotkeySettingsToYaml(hotkeySettings.Value, moduleName, description);
}
[GeneratedRegex(@"# [\s\S\n\r]*# ")]
diff --git a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/ResourceLoaderInstance.cs b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/ResourceLoaderInstance.cs
index 3441f76ef3..f4e18161e9 100644
--- a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/ResourceLoaderInstance.cs
+++ b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/ResourceLoaderInstance.cs
@@ -8,8 +8,14 @@ namespace ShortcutGuide.Helpers
{
internal static class ResourceLoaderInstance
{
+ ///
+ /// Gets the resource loader for the Shortcut Guide module.
+ ///
internal static ResourceLoader ResourceLoader { get; private set; }
+ ///
+ /// Gets the resource loader for the Settings module.
+ ///
internal static ResourceLoader SettingsResourceLoader { get; private set; }
static ResourceLoaderInstance()
diff --git a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/TasklistPositions.cs b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/TasklistPositions.cs
index 3056a0b28c..efbf444841 100644
--- a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/TasklistPositions.cs
+++ b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Helpers/TasklistPositions.cs
@@ -7,8 +7,15 @@ using TasklistButton = ShortcutGuide.NativeMethods.TasklistButton;
namespace ShortcutGuide.Helpers
{
- internal sealed class TasklistPositions
+ ///
+ /// Provides methods to retrieve the positions of taskbar buttons on the current monitor.
+ ///
+ internal static class TasklistPositions
{
+ ///
+ /// Retrieves the taskbar buttons for the current monitor.
+ ///
+ /// An array of the taskbar buttons.
public static TasklistButton[] GetButtons()
{
var monitor = NativeMethods.MonitorFromWindow(MainWindow.WindowHwnd, 0);
diff --git a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Models/ShortcutEntry.cs b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Models/ShortcutEntry.cs
index 39b72caa75..7f268338e5 100644
--- a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Models/ShortcutEntry.cs
+++ b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Models/ShortcutEntry.cs
@@ -2,9 +2,11 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
using Microsoft.UI.Xaml;
@@ -108,31 +110,11 @@ namespace ShortcutGuide.Models
{
List shortcutStackPanels = [];
- async void AnimateTextBlock(TextBlock animatedTextBlock, string text, int delay = 500)
- {
- try
- {
- int index = 0;
-
- while (!ShortcutView.AnimationCancellationTokenSource.Token.IsCancellationRequested)
- {
- animatedTextBlock.Text = text[index].ToString();
- index = (index + 1) % text.Length;
- await Task.Delay(delay);
- }
- }
- catch
- {
- // ignored
- }
- }
-
for (int i = 0; i < shortcut.Shortcut.Length; i++)
{
ShortcutDescription shortcutEntry = shortcut.Shortcut[i];
- StackPanel shortcutStackPanel = new();
+ StackPanel shortcutStackPanel = new() { Orientation = Orientation.Horizontal };
shortcutStackPanels.Add(shortcutStackPanel);
- shortcutStackPanel.Orientation = Orientation.Horizontal;
// If any entry is blank, we skip the whole shortcut
if (shortcutEntry is { Ctrl: false, Alt: false, Shift: false, Win: false, Keys.Length: 0 })
@@ -184,94 +166,7 @@ namespace ShortcutGuide.Models
foreach (string key in shortcutEntry.Keys)
{
- switch (key)
- {
- case "":
- shortcutStackPanel.Children.Add(new BitmapIcon() { UriSource = new("ms-appx:///Assets/ShortcutGuide/CopilotKey.png") });
- break;
- case "":
- shortcutStackPanel.Children.Add(new BitmapIcon() { UriSource = new("ms-appx:///Assets/ShortcutGuide/OfficeKey.png"), Height = 20, Width = 20 });
- break;
- case "":
- AddNewTextToStackPanel("←");
- break;
- case "":
- AddNewTextToStackPanel("→");
- break;
- case "":
- AddNewTextToStackPanel("↑");
- break;
- case "":
- AddNewTextToStackPanel("↓");
- break;
- case "":
- AddNewTextToStackPanel("...");
- break;
- case "":
- TextBlock animatedTextBlock = new()
- {
- Text = "A",
- Margin = new Thickness(3),
- VerticalAlignment = VerticalAlignment.Center,
-
- // Use monospaced font to ensure the text doesn't move
- FontFamily = new("Courier New"),
- TextDecorations = TextDecorations.Underline,
- };
-
- shortcutStackPanel.Children.Add(animatedTextBlock);
-
- AnimateTextBlock(animatedTextBlock, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
- break;
- case "":
- TextBlock arrowTextBlock = new()
- {
- Text = "→",
- Margin = new Thickness(3),
- VerticalAlignment = VerticalAlignment.Center,
- };
-
- shortcutStackPanel.Children.Add(arrowTextBlock);
-
- AnimateTextBlock(arrowTextBlock, "→↓←↑", 1000);
- break;
- case "":
- TextBlock arrowLRTextBlock = new()
- {
- Text = "→",
- Margin = new Thickness(3),
- FontFamily = new("Courier New"),
- VerticalAlignment = VerticalAlignment.Center,
- };
- shortcutStackPanel.Children.Add(arrowLRTextBlock);
- AnimateTextBlock(arrowLRTextBlock, "→←", 1000);
- break;
- case "":
- TextBlock arrowUDTextBlock = new()
- {
- Text = "↑",
- Margin = new Thickness(3),
- FontFamily = new("Courier New"),
- VerticalAlignment = VerticalAlignment.Center,
- };
- shortcutStackPanel.Children.Add(arrowUDTextBlock);
- AnimateTextBlock(arrowUDTextBlock, "↑↓", 1000);
- break;
- case { } name when name.StartsWith('<') && name.EndsWith('>'):
- AddNewTextToStackPanel(name[1..^1]);
- break;
- case { } num when int.TryParse(num, out int parsedNum):
- if (parsedNum == 0)
- {
- break;
- }
-
- AddNewTextToStackPanel(Helper.GetKeyName((uint)parsedNum));
- break;
- default:
- AddNewTextToStackPanel(key);
- break;
- }
+ AddKeyToStackPanel(key, shortcutStackPanel);
}
continue;
@@ -291,53 +186,190 @@ namespace ShortcutGuide.Models
case <= 1:
return new ShortcutTemplateDataObject(shortcut.Name, shortcut.Description ?? string.Empty, stackPanelToReturn, shortcut);
default:
+ stackPanelToReturn = new StackPanel
{
- {
- stackPanelToReturn = new StackPanel
- {
- Orientation = Orientation.Vertical,
- };
+ Orientation = Orientation.Vertical,
+ };
- foreach (StackPanel panel in shortcutStackPanels)
- {
- panel.Visibility = Visibility.Collapsed;
- stackPanelToReturn.Children.Add(panel);
- }
-
- shortcutStackPanels[0].Visibility = Visibility.Visible;
- for (int i = 1; i < shortcutStackPanels.Count; i++)
- {
- shortcutStackPanels[i].Visibility = Visibility.Collapsed;
- }
-
- async void AnimateStackPanels(StackPanel[] panels, int delay = 2000)
- {
- try
- {
- int index = 0;
- while (!ShortcutView.AnimationCancellationTokenSource.Token.IsCancellationRequested)
- {
- foreach (StackPanel panel in panels)
- {
- panel.Visibility = Visibility.Collapsed;
- }
-
- panels[index].Visibility = Visibility.Visible;
- index = (index + 1) % panels.Length;
- await Task.Delay(delay);
- }
- }
- catch
- {
- // ignored
- }
- }
-
- AnimateStackPanels([.. shortcutStackPanels]);
- }
-
- return new ShortcutTemplateDataObject(shortcut.Name, shortcut.Description ?? string.Empty, stackPanelToReturn, shortcut);
+ foreach (StackPanel panel in shortcutStackPanels)
+ {
+ panel.Visibility = Visibility.Collapsed;
+ stackPanelToReturn.Children.Add(panel);
}
+
+ shortcutStackPanels[0].Visibility = Visibility.Visible;
+ for (int i = 1; i < shortcutStackPanels.Count; i++)
+ {
+ shortcutStackPanels[i].Visibility = Visibility.Collapsed;
+ }
+
+ AnimateStackPanels([.. shortcutStackPanels]);
+
+ return new ShortcutTemplateDataObject(shortcut.Name, shortcut.Description ?? string.Empty, stackPanelToReturn, shortcut);
+ }
+ }
+
+ ///
+ /// Transforms a key string into a visual representation in the stack panel.
+ ///
+ /// The string reprensentation of the key.
+ /// The stackpanel to add the key to.
+ private static void AddKeyToStackPanel(string key, StackPanel shortcutStackPanel)
+ {
+ switch (key)
+ {
+ case "":
+ shortcutStackPanel.Children.Add(new BitmapIcon() { UriSource = new("ms-appx:///Assets/ShortcutGuide/CopilotKey.png") });
+ break;
+ case "":
+ shortcutStackPanel.Children.Add(new BitmapIcon() { UriSource = new("ms-appx:///Assets/ShortcutGuide/OfficeKey.png"), Height = 20, Width = 20 });
+ break;
+ case "":
+ AddNewTextToStackPanel("←");
+ break;
+ case "":
+ AddNewTextToStackPanel("→");
+ break;
+ case "":
+ AddNewTextToStackPanel("↑");
+ break;
+ case "":
+ AddNewTextToStackPanel("↓");
+ break;
+ case "":
+ AddNewTextToStackPanel("...");
+ break;
+ case "":
+ TextBlock animatedTextBlock = new()
+ {
+ Text = "A",
+ Margin = new Thickness(3),
+ VerticalAlignment = VerticalAlignment.Center,
+
+ // Use monospaced font to ensure the text doesn't move
+ FontFamily = new("Courier New"),
+ TextDecorations = TextDecorations.Underline,
+ };
+
+ shortcutStackPanel.Children.Add(animatedTextBlock);
+
+ AnimateTextBlock(animatedTextBlock, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ break;
+ case "":
+ TextBlock arrowTextBlock = new()
+ {
+ Text = "→",
+ Margin = new Thickness(3),
+ VerticalAlignment = VerticalAlignment.Center,
+ };
+
+ shortcutStackPanel.Children.Add(arrowTextBlock);
+
+ AnimateTextBlock(arrowTextBlock, "→↓←↑", 1000);
+ break;
+ case "":
+ TextBlock arrowLRTextBlock = new()
+ {
+ Text = "→",
+ Margin = new Thickness(3),
+ FontFamily = new("Courier New"),
+ VerticalAlignment = VerticalAlignment.Center,
+ };
+ shortcutStackPanel.Children.Add(arrowLRTextBlock);
+ AnimateTextBlock(arrowLRTextBlock, "→←", 1000);
+ break;
+ case "":
+ TextBlock arrowUDTextBlock = new()
+ {
+ Text = "↑",
+ Margin = new Thickness(3),
+ FontFamily = new("Courier New"),
+ VerticalAlignment = VerticalAlignment.Center,
+ };
+ shortcutStackPanel.Children.Add(arrowUDTextBlock);
+ AnimateTextBlock(arrowUDTextBlock, "↑↓", 1000);
+ break;
+ case { } name when name.StartsWith('<') && name.EndsWith('>'):
+ AddNewTextToStackPanel(name[1..^1]);
+ break;
+ case { } num when int.TryParse(num, out int parsedNum):
+ if (parsedNum == 0)
+ {
+ break;
+ }
+
+ AddNewTextToStackPanel(Helper.GetKeyName((uint)parsedNum));
+ break;
+ default:
+ AddNewTextToStackPanel(key);
+ break;
+ }
+
+ void AddNewTextToStackPanel(string text)
+ {
+ shortcutStackPanel.Children.Add(new TextBlock { Text = text, Margin = new Thickness(3), VerticalAlignment = VerticalAlignment.Center });
+ }
+ }
+
+ ///
+ /// Animates the text of a TextBlock by cycling through the characters of a given string.
+ ///
+ ///
+ /// This function runs asynchronously and will not block the UI thread. Exceptions that occur during the animation will be caught and ignored to prevent crashes.
+ ///
+ /// The textblock to animate.
+ /// The characters to cycle through.
+ /// The delay to the next animation frame.
+ private static async void AnimateTextBlock(TextBlock animatedTextBlock, string text, int delay = 500)
+ {
+ try
+ {
+ int index = 0;
+ CancellationToken cancellationToken = ShortcutView.AnimationCancellationTokenSource.Token;
+
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ animatedTextBlock.Text = text[index].ToString();
+ index = (index + 1) % text.Length;
+ await Task.Delay(delay);
+ }
+ }
+ catch
+ {
+ // ignored
+ }
+ }
+
+ ///
+ /// Animates the visibility of the stack panels one after another.
+ ///
+ ///
+ /// This function runs asynchronously and will not block the UI thread. Exceptions that occur during the animation will be caught and ignored to prevent crashes.
+ ///
+ /// The panels to animate.
+ /// The delay to the next animation frame.
+ private static async void AnimateStackPanels(StackPanel[] panels, int delay = 2000)
+ {
+ try
+ {
+ int index = 0;
+ CancellationToken cancellationToken = ShortcutView.AnimationCancellationTokenSource.Token;
+
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ foreach (StackPanel panel in panels)
+ {
+ panel.Visibility = Visibility.Collapsed;
+ }
+
+ panels[index].Visibility = Visibility.Visible;
+ index = (index + 1) % panels.Length;
+ await Task.Delay(delay);
+ }
+ }
+ catch
+ {
+ // ignored
}
}
}
diff --git a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Models/ShortcutPageParameters.cs b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Models/ShortcutPageParameters.cs
index f2faba001a..d88c4cda91 100644
--- a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Models/ShortcutPageParameters.cs
+++ b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Models/ShortcutPageParameters.cs
@@ -7,14 +7,29 @@ using System.Collections.Generic;
namespace ShortcutGuide.Models
{
+ ///
+ /// Represents the parameters for the shortcut page in the Shortcut Guide module.
+ ///
internal struct ShortcutPageParameters
{
+ ///
+ /// Gets or sets the content of the search box.
+ ///
public static SearchFilterObservable SearchFilter = new();
+ ///
+ /// Gets or sets the pinned shortcuts for the Shortcut Guide.
+ ///
public static Dictionary> PinnedShortcuts = [];
+ ///
+ /// Gets or sets the name of the current page being displayed in the Shortcut Guide.
+ ///
public static string CurrentPageName = string.Empty;
+ ///
+ /// The height of the frame that displays the shortcuts.
+ ///
public static FrameHeightObservable FrameHeight = new();
internal sealed class SearchFilterObservable
diff --git a/src/modules/ShortcutGuide/ShortcutGuide.Ui/NativeMethods.cs b/src/modules/ShortcutGuide/ShortcutGuide.Ui/NativeMethods.cs
index 987912c464..e1d830dcc9 100644
--- a/src/modules/ShortcutGuide/ShortcutGuide.Ui/NativeMethods.cs
+++ b/src/modules/ShortcutGuide/ShortcutGuide.Ui/NativeMethods.cs
@@ -119,4 +119,9 @@ internal static partial class NativeMethods
public int Keynum;
}
+
+ public enum MonitorFromWindowDwFlags
+ {
+ MONITOR_DEFAULTTONEAREST = 2,
+ }
}
diff --git a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Program.cs b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Program.cs
index e2602e1f19..a8e4f61b0f 100644
--- a/src/modules/ShortcutGuide/ShortcutGuide.Ui/Program.cs
+++ b/src/modules/ShortcutGuide/ShortcutGuide.Ui/Program.cs
@@ -9,7 +9,6 @@ using System.Threading;
using System.Windows;
using ManagedCommon;
using Microsoft.UI.Dispatching;
-using Microsoft.UI.Xaml;
using Microsoft.Windows.AppLifecycle;
using ShortcutGuide.Helpers;
using Application = Microsoft.UI.Xaml.Application;
@@ -34,9 +33,9 @@ namespace ShortcutGuide
return;
}
- if (!Directory.Exists(ManifestInterpreter.GetPathOfInterpretations()))
+ if (!Directory.Exists(ManifestInterpreter.PathOfManifestFiles))
{
- Directory.CreateDirectory(ManifestInterpreter.GetPathOfInterpretations());
+ Directory.CreateDirectory(ManifestInterpreter.PathOfManifestFiles);
}
if (NativeMethods.IsCurrentWindowExcludedFromShortcutGuide())
@@ -48,7 +47,7 @@ namespace ShortcutGuide
// Todo: Handle error
foreach (var file in InbuiltManifestFiles)
{
- File.Copy(Path.GetDirectoryName(Environment.ProcessPath) + "\\Assets\\ShortcutGuide\\" + file, ManifestInterpreter.GetPathOfInterpretations() + "\\" + file, true);
+ File.Copy(Path.GetDirectoryName(Environment.ProcessPath) + "\\Assets\\ShortcutGuide\\" + file, ManifestInterpreter.PathOfManifestFiles + "\\" + file, true);
}
Process indexGeneration = Process.Start(Path.GetDirectoryName(Environment.ProcessPath) + "\\PowerToys.ShortcutGuide.IndexYmlGenerator.exe");
@@ -56,7 +55,7 @@ namespace ShortcutGuide
if (indexGeneration.ExitCode != 0)
{
Logger.LogError("Index generation failed with exit code: " + indexGeneration.ExitCode);
- MessageBox.Show($"Shortcut Guide encountered an error while generating the index file. There is likely a corrupt shortcuts file in \"{ManifestInterpreter.GetPathOfInterpretations()}\". Try deleting this directory.", "Error displaying shortcuts", MessageBoxButton.OK, MessageBoxImage.Error);
+ MessageBox.Show($"Shortcut Guide encountered an error while generating the index file. There is likely a corrupt shortcuts file in \"{ManifestInterpreter.PathOfManifestFiles}\". Try deleting this directory.", "Error displaying shortcuts", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
diff --git a/src/modules/ShortcutGuide/ShortcutGuide.Ui/ShortcutGuideXAML/MainWindow.xaml b/src/modules/ShortcutGuide/ShortcutGuide.Ui/ShortcutGuideXAML/MainWindow.xaml
index 66323b6f4c..b527eba93f 100644
--- a/src/modules/ShortcutGuide/ShortcutGuide.Ui/ShortcutGuideXAML/MainWindow.xaml
+++ b/src/modules/ShortcutGuide/ShortcutGuide.Ui/ShortcutGuideXAML/MainWindow.xaml
@@ -33,7 +33,7 @@
-
+