Forge
csharp4405de34
1namespace CascadeIDE.Services.ChordNotation;
2
3/// <summary>Подписи внутри «кнопок-клавиш»: слова как в Windows или глифы как в macOS.</summary>
4public enum ChordKeycapLabelFlavor
5{
6 /// <summary>Ctrl, Alt, Shift, Win.</summary>
7 WindowsWords,
8
9 /// <summary>⌃ ⌥ ⇧ ⌘.</summary>
10 MacGlyphs
11}
12
13/// <summary>Один визуальный кэп (подпись внутри Border).</summary>
14public sealed record ChordKeycapSegment(string Label);
15
16/// <summary>Один шаг последовательности (например один аккорд или одна plain-клавиша) — горизонтальный ряд кэпов.</summary>
17public sealed record ChordKeycapStep(IReadOnlyList<ChordKeycapSegment> Segments);
18
19/// <summary>Последовательность шагов для <see cref="Views.ChordKeycapStrip"/> (между шагами — отступ в разметке).</summary>
20public sealed record ChordKeycapSequence(IReadOnlyList<ChordKeycapStep> Steps)
21{
22 public static ChordKeycapSequence Empty { get; } = new(Array.Empty<ChordKeycapStep>());
23}
24
25/// <summary>Семантика → плоская раскладка для UI «как на клавиатуре».</summary>
26public static class ChordKeycapLayoutBuilder
27{
28 public static ChordKeycapSequence Build(NormalizedKeySequence? sequence, ChordKeycapLabelFlavor flavor = ChordKeycapLabelFlavor.WindowsWords)
29 {
30 if (sequence is null || sequence.Steps.Count == 0)
31 return ChordKeycapSequence.Empty;
32
33 var steps = new List<ChordKeycapStep>(sequence.Steps.Count);
34 foreach (var st in sequence.Steps)
35 steps.Add(BuildStep(st, flavor));
36
37 return new ChordKeycapSequence(steps);
38 }
39
40 private static ChordKeycapStep BuildStep(NormalizedSequenceStep step, ChordKeycapLabelFlavor flavor) =>
41 step switch
42 {
43 NormalizedChordStep ch => new ChordKeycapStep(BuildChordSegments(ch.Modifiers, ch.KeySymbol, flavor)),
44 NormalizedPlainKeyStep pl => new ChordKeycapStep([new ChordKeycapSegment(PlainLabel(pl.KeySymbol, flavor))]),
45 _ => throw new InvalidOperationException($"Неизвестный шаг: {step.GetType().Name}")
46 };
47
48 private static IReadOnlyList<ChordKeycapSegment> BuildChordSegments(ChordModifierKeys modifiers, string keySymbol, ChordKeycapLabelFlavor flavor)
49 {
50 var list = new List<ChordKeycapSegment>(5);
51 if (modifiers.HasFlag(ChordModifierKeys.Control))
52 list.Add(new ChordKeycapSegment(ModifierLabel(ChordModifierKeys.Control, flavor)));
53 if (modifiers.HasFlag(ChordModifierKeys.Alt))
54 list.Add(new ChordKeycapSegment(ModifierLabel(ChordModifierKeys.Alt, flavor)));
55 if (modifiers.HasFlag(ChordModifierKeys.Shift))
56 list.Add(new ChordKeycapSegment(ModifierLabel(ChordModifierKeys.Shift, flavor)));
57 if (modifiers.HasFlag(ChordModifierKeys.Meta))
58 list.Add(new ChordKeycapSegment(ModifierLabel(ChordModifierKeys.Meta, flavor)));
59 list.Add(new ChordKeycapSegment(keySymbol));
60 return list;
61 }
62
63 private static string ModifierLabel(ChordModifierKeys single, ChordKeycapLabelFlavor flavor)
64 {
65 if (flavor == ChordKeycapLabelFlavor.MacGlyphs)
66 {
67 return single switch
68 {
69 ChordModifierKeys.Control => "\u2303",
70 ChordModifierKeys.Alt => "\u2325",
71 ChordModifierKeys.Shift => "\u21E7",
72 ChordModifierKeys.Meta => "\u2318",
73 _ => "?"
74 };
75 }
76
77 return single switch
78 {
79 ChordModifierKeys.Control => "Ctrl",
80 ChordModifierKeys.Alt => "Alt",
81 ChordModifierKeys.Shift => "Shift",
82 ChordModifierKeys.Meta => "Win",
83 _ => "?"
84 };
85 }
86
87 private static string PlainLabel(string keySymbol, ChordKeycapLabelFlavor flavor)
88 {
89 _ = flavor;
90 return keySymbol;
91 }
92}
93
View only · write via MCP/CIDE