# Design — Steuerelemente, Menüs, Dialoge

## Context

Siehe proposal.md — Why. Dieser Change setzt auf drei fertigen Stücken
auf: dem Zellenpuffer aus Phase 3, der Ereignisschleife samt Mausquelle
(`phase-4-ereignisschleife`) und dem Objektmodell
(`phase-4-objektmodell`). Er ist der breiteste Change der Phase — 16
Klassen, Menüs, Dialoge —, aber der mit den wenigsten offenen
Architekturfragen.

Die Forms-Referenz lässt drei Detailfragen offen, die hier beantwortet
werden müssen: die Optik je Zustand, die Z-Reihenfolge bei Überlappung
und die Reihenfolge gleichzeitig fälliger Timer.

## Goals / Non-Goals

**Goals:**

- Eine Darstellung, die im Zellenpuffer entsteht und deshalb mit dem
  bestehenden Snapshot-Vergleich prüfbar ist.
- Eingabebehandlung, die je Klasse an einer Stelle steht, statt über
  Sonderfälle in der Schleife verteilt zu sein.

**Non-Goals:**

- Pixelgenaue Nachbildung der Originaloptik; maßgeblich sind Aufbau und
  Zeichen, nicht der Farbton eines Schattens.
- Ein Layoutalgorithmus. Steuerelemente stehen, wo ihre Koordinaten sie
  hinstellen.

## Decisions

### D1 — Zeichnen ist eine Funktion des Zustands, kein Nebeneffekt

Jede Klasse zeichnet sich vollständig aus ihren Eigenschaften in den
Zellenpuffer. Es gibt keinen inkrementellen Zeichenpfad und kein
Merken zuvor gezeichneter Bereiche.

| Alternative | Warum nicht |
|---|---|
| Nur veränderte Bereiche neu zeichnen | Bei 80×25 Zellen ist das Neuzeichnen ohnehin billig; der Zustandsabgleich wäre die zweite Quelle der Wahrheit neben den Eigenschaften |

Neu gezeichnet wird an den Zustellpunkten der Ereignisschleife, wenn
eine Eigenschaft sich geändert hat — dieselbe Bedingung, die der
Bildschirmpuffer heute schon für `present` nutzt.

### D2 — Eingabe geht durch eine Kette, nicht durch eine Fallunterscheidung

Ein Tastenereignis läuft: Menü (wenn offen) → modaler Dialog (wenn
offen) → Access-Key des Formulars → fokussiertes Steuerelement →
`Default`/`Cancel`-Schaltfläche → Formular. Jede Station nimmt das
Ereignis an oder gibt es weiter. Für die Maus entsprechend: Menü →
Dialog → Trefferprüfung über die Z-Reihenfolge → Formular.

Die Kette ist die einzige Stelle, an der Vorrang entschieden wird; die
Klassen selbst wissen nichts über einander.

### D3 — Antworten auf die offenen Detailfragen der Forms-Referenz

- **Optik je Zustand**: aus den Original-Screenshots abgeleitet und je
  Klasse in der Forms-Referenz als Zeichenbild festgehalten, bevor
  gezeichnet wird — sonst legt der erste Implementierungsversuch sie
  stillschweigend fest.
- **Z-Reihenfolge**: Reihenfolge der Erzeugung, später Erzeugtes liegt
  oben; Steuerelement-Arrays nach Index. Das ist die Regel, die aus einer
  `.FRM` reproduzierbar folgt.
- **Gleichzeitig fällige Timer**: in aufsteigender Reihenfolge ihres
  Namens im Formular, damit die Ausgabe eines Korpusprogramms nicht von
  einer Hashreihenfolge abhängt.

Alle drei werden in `docs/forms-referenz.md` als unsere Festlegung
gekennzeichnet, nicht als Referenzverhalten ausgegeben.

### D4 — Dialoge sind Formulare, keine Sonderfälle

`MSGBOX` und `INPUTBOX$` bauen ein Formular mit Label und Schaltflächen
und zeigen es modal über den Weg aus `phase-4-objektmodell` (Frame-Marke,
D4 dort). Damit gelten Fokus, Access-Keys und Esc ohne Sonderbehandlung,
und die Dialoge sind mit demselben Snapshot-Vergleich prüfbar wie jedes
andere Formular.

### D5 — Menü hält die Ereigniszustellung an

Die Forms-Referenz nennt es für das Vorbild: Zeitereignisse und Trapping
ruhen, solange ein Menü den Fokus hat. Umgesetzt wird das über den
`STOP`-Zustand der Ereignissteuerung — kein neuer Mechanismus, sondern
der vorhandene, vom Menü gesetzt und beim Schließen zurückgenommen.

### D6 — Dateisystem-Steuerelemente werden plattformneutral abgebildet

DriveListBox zeigt keine Laufwerksbuchstaben, sondern die Wurzeln bzw.
Einhängepunkte der Plattform; DirListBox und FileListBox arbeiten auf
Pfaden. `Pattern` bleibt das Muster des Vorbilds. Die Abweichung wird in
der Sprachreferenz festgehalten.

### D7 — Korpusbefunde werden im gemeinsamen Ausführungspfad geschlossen

Die VBDOS-Projekte laufen durch denselben CLI-, Frontend-, VM- und
Zellenpufferpfad wie eigene Programme. Projekt- und Include-Auflösung,
VSpin/HSpin, Common-Dialog-Routinen und die tatsächlich verwendete Grafik
werden deshalb dort implementiert und getestet, nicht im Korpus umgangen.

## Risks / Trade-offs

- **Breite statt Tiefe** → 16 Klassen sind viel Fläche für Flüchtigkeit;
  jede Klasse bekommt ihren eigenen Korpusnachweis, nicht nur einen
  gemeinsamen Sammeltest.
- **Vollständiges Neuzeichnen bei großen Terminals** → bei 200×60 sind es
  12 000 Zellen je Anzeige; falls das messbar stört, greift die
  Bedingung „nur bei Änderung" bereits heute, und ein Ausbau bleibt
  möglich, ohne die Klassen anzufassen.
- **Fremdprogramme scheitern aus unerwartetem Grund** → jeder Befund wird
  festgehalten statt umgangen; er ist das eigentliche Ergebnis des
  Kompatibilitätstests.

## Open Questions

Keine.
