155 lines
7.1 KiB
Markdown
155 lines
7.1 KiB
Markdown
# forms-steuerelemente Specification
|
||
|
||
## Purpose
|
||
|
||
Die Steuerelemente machen ein Formular bedienbar: sie stellen sich im
|
||
Textbildschirm dar, nehmen Tastatur und Maus entgegen, führen Fokus und
|
||
Tabreihenfolge, tragen die Menüleiste und stellen die vordefinierten
|
||
Dialoge bereit.
|
||
|
||
## Requirements
|
||
|
||
### Requirement: Darstellung im Zellenpuffer
|
||
Steuerelemente SHALL sich im vorhandenen Textbildschirm darstellen; es
|
||
MUST NOT eine zweite Zeichenschicht neben ihm entstehen. Jede Klasse
|
||
SHALL die in der Forms-Referenz festgelegte Optik für die Zustände
|
||
normal, fokussiert und deaktiviert zeigen. Der CommandButton SHALL seine
|
||
Darstellung nach der Höhe wählen: eine Zeile als `<Text>`, zwei Zeilen
|
||
mit einzeiligem Rahmen, ab drei Zeilen als Kasten. Überlappen
|
||
Steuerelemente, SHALL die festgelegte Z-Reihenfolge entscheiden, welches
|
||
sichtbar ist.
|
||
|
||
#### Scenario: Schaltfläche nach Höhe
|
||
- **WHEN** ein CommandButton mit `Height = 1` und `Caption = "OK"` gezeichnet wird
|
||
- **THEN** erscheint im Zellenpuffer `<OK>`
|
||
|
||
#### Scenario: Deaktivierter Zustand
|
||
- **WHEN** ein Steuerelement `Enabled = 0` trägt
|
||
- **THEN** unterscheidet sich seine Darstellung sichtbar vom aktiven Zustand und es nimmt keinen Fokus an
|
||
|
||
### Requirement: Fokus, Tabreihenfolge und Access-Keys
|
||
Der Fokus SHALL mit Tab in aufsteigender `TabIndex`-Folge und mit
|
||
Umschalt-Tab rückwärts wechseln; Elemente mit `TabStop = 0` oder
|
||
`Enabled = 0` MUST übersprungen werden. Ein `&` im Text SHALL den
|
||
folgenden Buchstaben zum Access-Key machen, der mit Alt das Element
|
||
auslöst oder ihm den Fokus gibt. Enter SHALL die `Default`-Schaltfläche
|
||
auslösen, Esc die `Cancel`-Schaltfläche. Fokuswechsel MUST `LostFocus`
|
||
am alten und `GotFocus` am neuen Element auslösen, in dieser Reihenfolge.
|
||
|
||
Die über das Terminal gelieferte Rückwärtstab-Taste SHALL denselben Fokuswechsel wie Tab mit Umschalt auslösen. Die Reihenfolge LostFocus vor GotFocus SHALL auch an den Wirkungen der BASIC-Handler sichtbar bleiben.
|
||
|
||
#### Scenario: Tab überspringt
|
||
- **WHEN** das mittlere von drei Elementen `TabStop = 0` trägt und Tab gedrückt wird
|
||
- **THEN** erhält das dritte Element den Fokus
|
||
|
||
#### Scenario: Access-Key
|
||
- **WHEN** eine Schaltfläche `Caption = "&OK"` trägt und Alt+O gedrückt wird
|
||
- **THEN** wird ihr `Click`-Ereignis ausgelöst
|
||
|
||
#### Scenario: Reihenfolge der Fokusereignisse
|
||
- **WHEN** der Fokus von `Text1` auf `Text2` wechselt
|
||
- **THEN** läuft erst `Text1_LostFocus`, danach `Text2_GotFocus`
|
||
|
||
#### Scenario: Handlerwirkungen in Fokusreihenfolge
|
||
- **WHEN** LostFocus den Text L und GotFocus den Text G an dieselbe Variable anhängen
|
||
- **THEN** lautet das Ergebnis LG
|
||
|
||
#### Scenario: Rückwärtstab vom Terminal
|
||
- **WHEN** das Terminal eine Rückwärtstab-Taste liefert
|
||
- **THEN** wechselt der Fokus zum vorherigen zulässigen TabIndex
|
||
|
||
### Requirement: Maussteuerung mit Trefferprüfung
|
||
Ein Mausereignis SHALL dem obersten Steuerelement an seiner Position
|
||
zugestellt werden; liegt dort keines, dem Formular. Klick, Doppelklick
|
||
sowie `MouseDown`, `MouseMove` und `MouseUp` SHALL mit Taste,
|
||
Umschaltzustand und Position in Zellen zugestellt werden. Bei
|
||
`DragMode = 1` SHALL das Ziehen automatisch beginnen; `DRAG action%`
|
||
SHALL es manuell beginnen, ablegen oder abbrechen, mit `DragOver` und
|
||
`DragDrop` am Ziel.
|
||
|
||
#### Scenario: Treffer nach Z-Reihenfolge
|
||
- **WHEN** zwei Steuerelemente überlappen und in den gemeinsamen Bereich geklickt wird
|
||
- **THEN** erhält das obere das Ereignis
|
||
|
||
#### Scenario: Klick ohne Steuerelement
|
||
- **WHEN** auf eine freie Stelle des Formulars geklickt wird
|
||
- **THEN** erhält das Formular das Ereignis
|
||
|
||
#### Scenario: Ziehen und Ablegen
|
||
- **WHEN** ein Element mit `DragMode = 1` auf ein anderes gezogen und dort losgelassen wird
|
||
- **THEN** läuft am Ziel `DragOver` mit dem Zustand Over und danach `DragDrop` mit der Quelle als Argument
|
||
|
||
### Requirement: Steuerelemente mit Listeninhalt
|
||
ListBox und ComboBox SHALL `ADDITEM` und `REMOVEITEM` unterstützen und
|
||
`List`, `ListCount`, `ListIndex` und `Text` konsistent führen; bei
|
||
`Sorted = -1` SHALL die Einfügereihenfolge der Sortierung folgen.
|
||
`ListIndex = -1` SHALL „keine Auswahl" bedeuten. Die ComboBox SHALL die
|
||
drei Stilarten (Dropdown, Simple, Dropdown List) darstellen.
|
||
|
||
#### Scenario: Element hinzufügen
|
||
- **WHEN** `List1.ADDITEM "b"` und `List1.ADDITEM "a"` bei `Sorted = -1` ausgeführt werden
|
||
- **THEN** liefert `List1.List(0)` den Wert `a` und `List1.ListCount` den Wert 2
|
||
|
||
#### Scenario: Keine Auswahl
|
||
- **WHEN** eine ListBox ohne Auswahl gelesen wird
|
||
- **THEN** liefert `ListIndex` den Wert −1
|
||
|
||
### Requirement: Timer-Steuerelement
|
||
Ein Timer SHALL bei `Enabled = -1` und `Interval > 0` sein
|
||
`Timer`-Ereignis im eingestellten Abstand auslösen, gestützt auf die
|
||
Zeitquelle der Ereignissteuerung. `Interval = 0` SHALL ihn abschalten.
|
||
Sind mehrere Timer gleichzeitig fällig, SHALL die Reihenfolge festgelegt
|
||
und dokumentiert sein.
|
||
|
||
#### Scenario: Timer feuert im Abstand
|
||
- **WHEN** ein Timer mit `Interval = 100` läuft und die Zeit um 250 ms vorrückt
|
||
- **THEN** ist sein Ereignis zweimal gelaufen
|
||
|
||
#### Scenario: Interval 0 schaltet ab
|
||
- **WHEN** `Timer1.Interval = 0` gesetzt wird
|
||
- **THEN** läuft kein weiteres Ereignis
|
||
|
||
### Requirement: Menüsystem
|
||
Ein Formular SHALL eine Menüleiste mit bis zu sechs Ebenen tragen.
|
||
Menüeinträge SHALL Access-Keys (`&`), Shortcuts, `Checked`, `Enabled`,
|
||
`Visible` und Separatoren (`-`) unterstützen; ein Separator MUST NOT
|
||
`Checked`, deaktiviert oder mit Shortcut versehen sein, ein Menütitel
|
||
MUST NOT einen Shortcut tragen. Solange ein Menü geöffnet ist, MUST die
|
||
Zustellung von Zeitereignissen und klassischen Traps ruhen und danach
|
||
fortgesetzt werden.
|
||
|
||
#### Scenario: Menüauswahl löst Click aus
|
||
- **WHEN** ein Menüeintrag über seinen Access-Key gewählt wird
|
||
- **THEN** läuft seine `Click`-Prozedur
|
||
|
||
#### Scenario: Traps ruhen im geöffneten Menü
|
||
- **WHEN** ein Menü geöffnet ist und ein Zeit-Trap fällig wird
|
||
- **THEN** läuft sein Handler erst, nachdem das Menü geschlossen wurde
|
||
|
||
#### Scenario: UEVENT an gewöhnlicher Anweisungsgrenze
|
||
- **WHEN** ein Menü offen ist und UEVENT vor einer Zuweisung ansteht
|
||
- **THEN** läuft dessen Handler erst nach dem Schließen des Menüs
|
||
|
||
### Requirement: Vordefinierte Dialoge
|
||
`MSGBOX text$ [, typ% [, titel$]]` SHALL als Anweisung und als Funktion
|
||
verfügbar sein; die Funktion SHALL die gedrückte Schaltfläche als
|
||
INTEGER liefern (1 OK, 2 Cancel/Esc, 3 Abort, 4 Retry, 5 Ignore, 6 Yes,
|
||
7 No). `typ%` SHALL die Schaltflächengruppe (0–5) und die
|
||
Vorgabeschaltfläche (0/256/512) tragen. `INPUTBOX$(text$ [, titel$
|
||
[, vorgabe$ [, x%, y%]]])` SHALL eine Zeichenkette liefern und bei
|
||
Abbruch den leeren String. Beide Dialoge SHALL modal sein; `INPUTBOX$`
|
||
SHALL 46×16 Zeichen messen und ohne Positionsangabe zentriert
|
||
erscheinen.
|
||
|
||
#### Scenario: MSGBOX als Funktion
|
||
- **WHEN** `a% = MSGBOX("Weiter?", 4, "Frage")` ausgeführt und `Yes` gewählt wird
|
||
- **THEN** liefert der Aufruf 6
|
||
|
||
#### Scenario: INPUTBOX$ abgebrochen
|
||
- **WHEN** ein `INPUTBOX$`-Dialog mit Esc geschlossen wird
|
||
- **THEN** liefert er den leeren String
|
||
|
||
#### Scenario: Dialog ist modal
|
||
- **WHEN** ein Dialog offen ist
|
||
- **THEN** wird die Anweisung nach dem Aufruf erst nach dem Schließen ausgeführt
|