# ActionDialog **Datei:** `ActionDialog.cs` ## Verantwortung Modaler Dialog zum Bearbeiten einer einzelnen Aktion (MX-Button oder Encoder-Slot) inkl. optionaler LED-Einstellungen. ## Ergebnis-Properties ```csharp public DeviceAction ResultAction { get; } // Typ + Keycode/Usage/etc. public Color ResultColor { get; } // LED-Basisfarbe public LedAnimType ResultAnim { get; } // Animation public ushort ResultPeriod { get; } // Periode in ms ``` ## Panels (je nach Typ ein Panel sichtbar) | Typ | Panel | Inhalt | |---|---|---| | HID Tastatur | `_hidKeyPanel` | Capture-Button + Strg/Shift/Alt/Win-Checkboxen | | HID Consumer | `_consumerPanel` | Dropdown mit 12 Medien-Aktionen | | Host Command | `_cmdPanel` | TextBox für numerische Command-ID | | Makro | `_macroPanel` | 8 Step-Buttons + je Strg/Shift/Alt-Checkboxen | | Profil wechseln | `_profilePanel` | Dropdown: "Nächstes Profil (Zyklus)" / "Profil 1" / "Profil 2" / "Profil 3" | | Keine | — | Alle Panels ausgeblendet | LED-Panels (`_colorPanel`, `_animPanel`) erscheinen zusätzlich wenn `showColor=true` (nur MX-Buttons, nicht Encoder). `UpdateLayout()` repositioniert LED-Panels und passt `ClientSize` dynamisch an wenn der Typ gewechselt wird. ## Profil-Panel ```csharp // Items in _profileCombo: // Index 0: "Nächstes Profil (Zyklus)" → Data = 0xFFFF // Index 1: "Profil 1" → Data = 0 // Index 2: "Profil 2" → Data = 1 // Index 3: "Profil 3" → Data = 2 // Initialbelegung: _profileCombo.SelectedIndex = action.Data == 0xFFFF ? 0 : action.Data + 1; // In OnOk(): data = _profileCombo.SelectedIndex == 0 ? (ushort)0xFFFF : (ushort)(_profileCombo.SelectedIndex - 1); ``` Im Board wird `0xFFFF` als `(uint8_t)0xFF` gespeichert und in der Firmware als "nächstes Profil" interpretiert. ## Tasten-Capture (HID-Modus) 1. Benutzer klickt "Taste drücken..." 2. `_capturing = true` 3. Nächste Taste in `ProcessCmdKey()` → `VkToHid()` → `_hidKeycode` setzen 4. Capture-Button zeigt Tastenname (`HidKeyName()`) **Warum `ProcessCmdKey` statt `OnKeyDown`?** WinForms behandelt Pfeil- und Enter-Tasten als "Dialog Keys" in `ProcessDialogKey()` — sie erreichen `OnKeyDown` nie. `ProcessCmdKey` wird vor `ProcessDialogKey` aufgerufen und kann diese Tasten abfangen. ## Makro-Capture Jeder der 8 Steps hat einen eigenen Capture-Button. `_captureStep` (0–7, -1 = inaktiv) zeigt welcher Step gerade aufnimmt. Capture-Logik identisch mit HID-Modus, schreibt in `_stepKeycodes[captureStep]`. ## Schlüssellookup (layout-unabhängig) **Problem**: Windows VK-Codes sind tastaturlayout-abhängig. `Keys.OemQuotes` auf QWERTZ → Ö, auf US → `'`. Würde falsche HID-Codes liefern. **Lösung**: PS/2 Scan-Codes sind layout-unabhängig (physische Tastenposition). ``` VK → Scan-Code via MapVirtualKey(vk, MAPVK_VK_TO_VSC) Scan-Code → HID Usage via s_scanToHid[sc] ``` `s_scanToHid`: vollständige PS/2-Set-1 → HID-Tabelle (~60 Einträge). **Ausnahme**: Erweiterte Navigationstasten (Pfeiltasten, Pos1, Ende, …) geben via `MapVirtualKey` den Numpad-Scan-Code zurück. Für diese gibt es eine direkte `Keys → HID`-Tabelle (`s_extVkToHid`). **Anzeige**: `HidKeyName(hid)` gibt den lokalisierten Tastennamen zurück: - Sondertasten: fest eingetragene deutsche Namen ("Esc", "→", "F5", …) - Zeichentasten: `GetKeyNameText(scanCode << 16, ...)` → Windows gibt den Namen laut aktivem Layout zurück ("Ö" auf QWERTZ, ";" auf US) ## Consumer-Aktionen 12 HID Consumer Usage IDs als feste Liste: | Usage | Name | |---|---| | 0x00CD | Play / Pause | | 0x00B5 | Nächster Titel | | 0x00B6 | Vorheriger Titel | | 0x00B7 | Stop | | 0x00E9 | Lauter | | 0x00EA | Leiser | | 0x00E2 | Stummschalten | | 0x0192 | Taschenrechner | | 0x0223 | Browser – Startseite | | 0x0224 | Browser – Zurück | | 0x0225 | Browser – Vor | | 0x00B0 | Aufnahme | ## LED-Einstellungen Nur wenn `showColor=true` (MX-Buttons). Enthält: - **Farbpicker**: `ColorDialog` → `_colorBtn.BackColor` - **Animations-Dropdown**: Statisch / Blinken / Pulsieren / Regenbogen - **Periode-Dropdown**: Presets von "Sehr langsam (8 s)" bis "Sehr schnell (250 ms)" Bei "Regenbogen" wird der Farbpicker ausgeblendet (Farbe irrelevant).