# TrayApp **Datei:** `TrayApp.cs` ## Verantwortung - App-Lebenszyklus als `ApplicationContext` (kein Hauptfenster) - Tray-Icon mit Verbindungsstatus und Kontextmenü - Empfang und Routing aller Board-Events (via `SerialManager.PacketReceived`) - sequenzieller Config-/Makro-Dump-Empfang über `ChunkTransferBuffer` - ACK/NACK-Weiterleitung an SerialManager - Öffnen des `ConfigForm` (nur eine Instanz gleichzeitig) ## Tray-Menü ``` [●/○] VersaPad – verbunden / nicht verbunden (disabled, nur Anzeige) ────────────────────────────────────────────── Konfiguration... → OpenConfigForm() ────────────────────────────────────────────── Beenden → Application.Exit() ``` Icon und Tooltip spiegeln den Verbindungsstatus: - Verbunden: `SystemIcons.Information`, Text "VersaPad – verbunden" - Getrennt: `SystemIcons.Application`, Text "VersaPad – nicht verbunden" (TODO: eigenes Icon einbinden) ## Board-Event-Handling (OnPacket) | Event-ID | Aktion | |---|---| | `EvtConfigBegin/Data/End` | Chunkzahl, Indizes und Vollständigkeit prüfen; danach `DeviceConfig.FromBytes()` | | `EvtConfigAck` | `serial.SignalConfigAck()` — gibt SendConfig()-Thread frei | | `EvtConfigNack` | `serial.SignalConfigNack()` — gibt SendConfig()-Thread frei (Fehler) | | `EvtMacroBegin/Data/End` | vollständigen 512-Byte-Dump prüfen; danach `MacroTable.FromBytes()` | | `EvtMacroAck` | `serial.SignalMacroAck()` — gibt SendMacros()-Thread frei | | `EvtMacroNack` | `serial.SignalMacroNack()` — gibt SendMacros()-Thread frei (Fehler) | | `EvtPong` | MessageBox "Ping OK" | | `EvtKeyDown/Up` | Host-Command-ID in Byte 2/3 empfangen | | `EvtEncCw/Ccw` | Host-Command-ID und Encoderrichtung empfangen | Diese vier Host-Events sendet die Firmware nur für Actions vom Typ `HostCommand`. `TrayApp` dekodiert die 16-Bit-ID, führt sie aber noch nicht aus. ACK/NACK-Events zeigen keine eigene MessageBox mehr — das Ergebnis wird nach Abschluss beider Transfers gebündelt in `ConfigForm.OnSave()` angezeigt. ## Verbindungslebenszyklus ``` OnConnected(): Icon + Text + Menü-Item aktualisieren serial.RequestConfig() → Config-Dump vom Board nach gültigem Config-End: serial.RequestMacros() → Makro-Dump vom Board OnDisconnected(): Icon + Text + Menü-Item aktualisieren ``` Ein mit `END` abgeschlossener, aber unvollständiger oder ungültiger Dump wird einmal wiederholt. Schlägt auch der zweite Versuch fehl, zeigt das Tray-Icon eine Warnung. Bleibt `END` vollständig aus, gibt es derzeit keinen Empfangs-Timeout; siehe [`07_known_limitations.md`](07_known_limitations.md). ## Offene Punkte - sichere Zuordnung von Command-IDs zu explizit erlaubten Desktop-Aktionen - Eigenes Tray-Icon statt `SystemIcons.Application`