Files
2026-05-20 02:06:16 +02:00

73 lines
2.1 KiB
C#

namespace MeetingAssistant.Hotkeys;
[Flags]
public enum HotkeyModifiers : uint
{
None = 0,
Alt = 0x0001,
Control = 0x0002,
Shift = 0x0004,
Windows = 0x0008
}
public sealed record HotkeyDefinition(HotkeyModifiers Modifiers, uint VirtualKey)
{
public static HotkeyDefinition Parse(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("Hotkey cannot be empty.", nameof(value));
}
var modifiers = HotkeyModifiers.None;
uint? virtualKey = null;
foreach (var rawPart in value.Split('+', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
{
var part = rawPart.ToUpperInvariant();
modifiers |= part switch
{
"CTRL" or "CONTROL" => HotkeyModifiers.Control,
"ALT" => HotkeyModifiers.Alt,
"SHIFT" => HotkeyModifiers.Shift,
"WIN" or "WINDOWS" => HotkeyModifiers.Windows,
_ => HotkeyModifiers.None
};
if (modifiers.HasFlagForToken(part))
{
continue;
}
virtualKey = ParseVirtualKey(part);
}
return virtualKey is null
? throw new FormatException($"Hotkey '{value}' does not contain a key.")
: new HotkeyDefinition(modifiers, virtualKey.Value);
}
private static uint ParseVirtualKey(string part)
{
if (part.Length == 1 && char.IsLetterOrDigit(part[0]))
{
return part[0];
}
if (part.Length is 2 or 3 && part[0] == 'F' && int.TryParse(part[1..], out var functionKey) && functionKey is >= 1 and <= 24)
{
return (uint)(0x70 + functionKey - 1);
}
throw new FormatException($"Unsupported hotkey key '{part}'.");
}
}
file static class HotkeyModifierExtensions
{
public static bool HasFlagForToken(this HotkeyModifiers _, string token)
{
return token is "CTRL" or "CONTROL" or "ALT" or "SHIFT" or "WIN" or "WINDOWS";
}
}