Files
TerminalBasic/openspec/specs/forms-objektmodell/spec.md

143 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# forms-objektmodell Specification
## Purpose
Das Forms-Objektmodell macht Formulare und Steuerelemente zu benannten
Objekten des laufenden Programms: Eigenschaften lesen und schreiben,
Formulare laden, zeigen, verbergen und entladen — modal wie nicht-modal —,
Steuerelement-Arrays führen und Ereignisse an die Prozeduren
`Name_Ereignis` zustellen. Es ist die Grundlage der Steuerelemente und der
vordefinierten Dialoge.
## Requirements
### Requirement: Formulare und Steuerelemente als benannte Objekte
Ein Formular SHALL unter seinem Namen ansprechbar sein, ein
Steuerelement unter seinem Namen innerhalb seines Formulars. Eigenschaften
SHALL über `objekt.eigenschaft` gelesen und geschrieben werden, mit dem
in der Forms-Referenz festgelegten Typ und Wertebereich. Es SHALL keine
Standardeigenschaft geben: `Text1 = "x"` MUST abgewiesen werden. Das
Schreiben eines Wertes außerhalb des Wertebereichs MUST Laufzeitfehler 5
auslösen; eine zur Laufzeit schreibgeschützte Eigenschaft MUST bei
Zuweisung einen Fehler auslösen.
#### Scenario: Eigenschaft lesen und schreiben
- **WHEN** `Text1.Text = "hallo"` ausgeführt und danach `Text1.Text` gelesen wird
- **THEN** liefert der Zugriff `hallo`
#### Scenario: Keine Standardeigenschaft
- **WHEN** ein Programm `Text1 = "x"` enthält
- **THEN** wird es abgewiesen und die Meldung nennt `Text1`
#### Scenario: Wert außerhalb des Bereichs
- **WHEN** `Check1.Value = 3` ausgeführt wird
- **THEN** tritt Laufzeitfehler 5 auf
#### Scenario: Getrennte Werte gleichnamiger Controls
- **WHEN** Form1!Text1.Text auf a und Form2!Text1.Text auf b gesetzt werden
- **THEN** liefern die beiden Zugriffe unabhängig a und b
### Requirement: Container-Zugriff über den Bang-Operator
`form!steuerelement.eigenschaft` SHALL ein Steuerelement eines benannten
Formulars ansprechen. Die Schreibweise MUST NOT mit dem Typsuffix `!`
für SINGLE verwechselt werden; eine Variable `Form1!` und ein Zugriff
`Form1!Text1` MUST unterscheidbar bleiben.
#### Scenario: Zugriff über den Container
- **WHEN** `Form1!Text1.Text = "a"` ausgeführt wird
- **THEN** trägt die Eigenschaft `Text` des Steuerelements `Text1` in `Form1` den Wert `a`
#### Scenario: Typsuffix bleibt Typsuffix
- **WHEN** ein Programm die Variable `Wert!` verwendet
- **THEN** bleibt sie eine SINGLE-Variable und wird nicht als Containerzugriff gelesen
### Requirement: Lade- und Entladezyklus
`LOAD form` SHALL das Formular anlegen und `Form_Load` ausführen, bevor
es sichtbar wird. `UNLOAD form` SHALL `Form_Unload (Cancel)` ausführen;
ein von der Prozedur gesetzter Wert `Cancel <> 0` MUST das Entladen
verhindern. `HIDE` SHALL nur die Sichtbarkeit zurücknehmen und das
Formular geladen lassen. Der Zugriff auf ein nicht geladenes Formular
SHALL es implizit laden.
#### Scenario: Load läuft vor der Anzeige
- **WHEN** ein Formular gezeigt wird, dessen `Form_Load` eine Eigenschaft setzt
- **THEN** ist der gesetzte Wert bereits in der ersten Anzeige sichtbar
#### Scenario: Entladen abbrechen
- **WHEN** `Form_Unload` den Parameter `Cancel` auf 1 setzt und `UNLOAD Form1` ausgeführt wird
- **THEN** bleibt das Formular geladen und sichtbar
#### Scenario: HIDE entlädt nicht
- **WHEN** `Form1.HIDE` ausgeführt und danach eine Eigenschaft von `Form1` gelesen wird
- **THEN** ist der zuvor gesetzte Wert erhalten und `Form_Load` läuft nicht erneut
### Requirement: Modales und nicht-modales Anzeigen
`form.SHOW [style%]` SHALL das Formular anzeigen; `style%` 0 (Vorgabe)
zeigt es nicht-modal, 1 modal. Bei modaler Anzeige MUST die Anweisung
nach `SHOW` erst ausgeführt werden, wenn das Formular entladen oder
verborgen wurde; die Ereignisschleife MUST währenddessen weiterlaufen.
Verstöße gegen die Stapelregeln des Vorbilds MUST die Fehler 400403
auslösen.
#### Scenario: Modal hält den Ablauf an
- **WHEN** ein Programm `Form1.SHOW 1 : PRINT "danach"` ausführt und ein Ereignis `Form1` entlädt
- **THEN** erscheint `danach` erst nach dem Entladen
#### Scenario: Ereignisse laufen während der Modalität
- **WHEN** ein modales Formular angezeigt wird und ein Ereignis eintrifft
- **THEN** läuft die zugehörige Ereignisprozedur
### Requirement: Steuerelement-Arrays
Steuerelemente mit gleichem Namen und `Index` SHALL als Array
ansprechbar sein. `LOAD ctl(index%)` SHALL ein weiteres Element zur
Laufzeit anlegen, `UNLOAD ctl(index%)` es entfernen. Der Versuch, ein zur
Entwurfszeit angelegtes Element zu entladen, MUST Fehler 362 auslösen.
Bei einem Array MUST `Index AS INTEGER` als erster Parameter der
Ereignisprozedur übergeben werden.
#### Scenario: Element zur Laufzeit anlegen
- **WHEN** `LOAD Command1(3)` ausgeführt wird
- **THEN** existiert `Command1(3)` mit den Eigenschaften des Elements 0 als Vorlage
#### Scenario: Entwurfszeit-Element ist nicht entladbar
- **WHEN** `UNLOAD Command1(0)` für ein zur Entwurfszeit angelegtes Element ausgeführt wird
- **THEN** tritt Fehler 362 auf
#### Scenario: Index als erster Parameter
- **WHEN** ein Klick auf `Command1(3)` zugestellt wird
- **THEN** wird `Command1_Click` mit `Index = 3` aufgerufen
### Requirement: Ereignisdispatch an Name_Ereignis
Ein Ereignis SHALL die Prozedur `Name_Ereignis` des betroffenen Objekts
aufrufen und ihr die Argumente der in der Forms-Referenz festgelegten
Signatur übergeben. Fehlt die Prozedur, MUST das Ereignis wirkungslos
verfallen, ohne Fehler. Die Zustellung SHALL an den Zustellpunkten der
Ereignissteuerung erfolgen; es MUST NOT neue Zustellpunkte geben.
#### Scenario: Ereignisprozedur wird gerufen
- **WHEN** ein Klick auf `Command1` zugestellt wird und `SUB Command1_Click` existiert
- **THEN** läuft die Prozedur genau einmal
#### Scenario: Fehlende Ereignisprozedur
- **WHEN** ein Klick auf ein Steuerelement ohne passende Prozedur zugestellt wird
- **THEN** läuft das Programm unverändert weiter und es entsteht kein Fehler
#### Scenario: Signatur mit Mausargumenten
- **WHEN** `Form_MouseDown` definiert ist und ein Mausereignis in Zeile 5, Spalte 7 zugestellt wird
- **THEN** erhält die Prozedur Taste, Umschaltzustand und die Position in Zellen
### Requirement: SCREEN-Objekt
`SCREEN` SHALL als Objekt ansprechbar sein mit `ActiveControl`,
`ActiveForm`, `Height`, `Width`, `MousePointer` und `ControlPanel` sowie
den Methoden `SHOW` und `HIDE`. `Height` und `Width` SHALL die
**aktuelle** Terminalgröße in Zeichen liefern und schreibgeschützt sein;
die feste Größe des Vorbilds MUST als Abweichung dokumentiert sein.
#### Scenario: Größe folgt dem Terminal
- **WHEN** die Darstellungsfläche 120×40 misst und `SCREEN.Width` gelesen wird
- **THEN** liefert es 120
#### Scenario: Aktives Formular
- **WHEN** zwei Formulare geladen sind und eines den Fokus hat
- **THEN** liefert `SCREEN.ActiveForm` dieses Formular