120 lines
5.0 KiB
Markdown
120 lines
5.0 KiB
Markdown
# 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.
|