4.8 Listen-Objekte

4.8.1 Überblick

4.8.2 Option und OptionGroup

4.8.3 RadioButton und RadioButtonGroup

Tab-styled RadioButtonGroup - Neues Objekt in R-BASIC 1.02

4.8.4 DynamicList

4.8.5 Listen-Objekte im Delayed Mode



4.8.1 Überblick

In R-BASIC gibt es 3 Typen von Listen-Objekten:
    ...
  • Die OptionGroup verwaltet eine Liste von Option-Objekten, das jedes für sich und abhängig voneinander den Zustand "ein" oder "aus" haben kann.

    ...

  • Die RadioButtonGroup verwaltet eine Liste von RadioButton-Objekten.

    Diese können einzeln oder in Gruppen ausgewählt (selektiert) werden. Die RadioButtonGroup ist ein sehr vielseitiges Objekt das insbesondere dann zum Einsatz kommt, wenn die Anzahl der Listeneinträge von vorneherein bekannt und unveränderlich ist.

    ...

  • Die DynamicList stammt von der RadioButtonGroup ab und ist daher genauso vielseitig wie diese. Sie wird eingesetzt, wenn die Anzahl der Listeneinträge nicht von vorneherein bekannt ist und / oder sich während des Programmablaufs verändert.
Alle Listen können einen ActionHandler aufrufen, wenn vom Nutzer ein Eintrag selektiert bzw. geändert wird. Über die Instance-Variable look kann das Aussehen der Listen weitgehend verändert werden. So können alle Listen-Objekte - nicht nur die DynamicList - als scrollbare Listen auftreten. Die Größe eines als scrollbare Liste erscheinenden List-Objekts wird häufig über den Geometrie-Hint fixedSize eingestellt. Beispiele dazu finden Sie bei der Beschreibung der Instance-Variablen look der OptionGroup.

Die folgenden Ausführungen gehen zunächst grundsätzlich davon aus, dass die Listen-Objekte im normalen Modus (nicht im sogenannten "Delayed Mode") arbeiten. Das ist der Normalfall, wenn man nicht spezielle Hints setzt, um in den Delayed Mode zu kommen. Dieser "Delayed Mode" ist ausführlich im Kapitel 3.4.2 (Delayed Mode und Status-Message) dieses Handbuchs beschrieben.

Action-Handler-Typen:

Handler-Typ Parameter
ListAction (sender as object, selection as word, modified as word, numSelections as word)

Alle ActionHandler der List-Objekte müssen als ListAction deklariert sein. Die Bedeutung der Parameter "selection", "modified" und "numSelections" variiert je nach Listen-Objekt und ActionHandler. Gelegentlich sind einige der Parameter auch bedeutungslos für den speziellen Fall.

^

4.8.2 Option und OptionGroup

Option

Abstammung:

...

Spezielle Instance-Variablen

Instance-Variable Syntax im UI-Code Im BASIC-Code
identifier identifier = numWert lesen, schreiben


identifier

Die Instance-Variable identifier identifiziert das einzelne Option-Objekt. Sie ist vom Typ WORD. Der Wert muss eine 2er-Potenz sein (nur genau 1 Bit gesetzt, d.h. einer der Werte 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 81912, 16384, 32768). Option-Objekte müssen Children einer OptionGroup sein. Innerhalb einer OptionGroup darf jeder Identifier-Wert nur genau einmal vorkommen.
Syntax UI-Code: identifier = numWert 
         Lesen: <numVar> = <obj>.identifier 
     Schreiben: <obj>.identifier = numWert

 

OptionGroup

Abstammung:

...

Eine OptionGroup managed eine Liste von Option-Objekten (bis zu 16). OptionGroup-Objekte können nur Option-Objekte als Children haben.

...

Beispiel UI-Code:

OptionGroup ListOfOptions
  Caption$= "Select Options"
  justifyCaption = J_TOP
  Children = bool1, bool2, bool3
  OrientChildren = ORIENT_VERTICALLY
  ApplyHandler = BoolApply  
  selection = 4
  END Object

Option bool1: caption$="Option 1":identifier = 1: End Object
Option bool2: caption$="Option 2":identifier = 2: End Object
Option bool3 
  Caption$="Option 3" : identifier = 4: 
  End Object
Zur Demonstration wurde in an einigen Stellen im Code oben die Syntax mit mehreren, durch Doppelpunkt getrennten Anweisungen verwendet, die auch im UI-Code zulässig ist.

Spezielle Instance-Variablen

Instance-Variable Syntax im UI-Code Im BASIC-Code
selection identifier = numWert lesen, schreiben
isSelected -- nur lesen
look look = numWert lesen, schreiben
modified modified = numWert lesen, schreiben
isModified -- nur lesen
ApplyHandler ApplyHandler = <Handler> nur schreiben
StatusHandler StatusHandler = <Handler> nur schreiben
Methoden:

Methode Aufgabe
MakeVisible n Einen bestimmten Eintrag sichtbar machen
SendStatus Status-Handler aufrufen


selection

Options können den Zustand "ein" oder "aus" haben. Die Instance-Variable selection der OptionGroup enthält die Summe der identifier derjenigen Options, die auf "ein" sind. Genauer gesagt ist es die logische Oder-Verknüpfung der identifier. Wenn man sich an die Regel hält, dass Option-Identifier nur 2er-Potenzen sein dürfen (was man unbedingt sollte), sind beide Aussagen gleichwertig.
Syntax UI-Code: selection = numWert 
         Lesen: <numVar> = <obj>.selection 
     Schreiben: <obj>.selection = numWert

 

isSelected

IsSelected prüft, ob ein bestimmtes Option-Objekt, gegeben durch seinen Identifier, selektiert ist oder nicht.
Syntax Lesen: <numVar> = <obj>.isSelected (n)
              <obj>  OptionGroup Objekt
           n: Identifier eines Option-Objekts

 

look

Instance-Variable look bestimmt das Aussehen der OptionGroup und ihrer Option-Objekte (engl. look : Aussehen, äußere Erscheinung). Funktionell sind alle Looks identisch.
Syntax UI-Code: look = numWert 
         Lesen: <numVar> = <obj>.look 
     Schreiben: <obj>.look = numWert

 
Für alle Listen-Objekte stehen folgende Looks zur Verfügung:

Konstante Wert Aussehen
LOOK_NORMAL 0 Klassisches Aussehen
LOOK_SCROLLABLE 1 Scrollbare Liste
LOOK_MINIMIZE_SIZE 2 Minimaler Platzverbrauch
LOOK_TOOLBOX 4 ToolBox-Style

Die Look-Werte können kombiniert werden (mit +), was insbesondere bei LOOK_MINIMIZE_SIZE + LOOK_TOOLBOX gelegentlich Sinn macht. Ungültige bzw. widersprüchliche Kombinationen können jedoch zu seltsamen Effekten führen.

...     ...     ...

...

Das Bild zeigt die Liste mit dem UI-Code von oben, jedoch jeweils mit verschiedenen Werten für look gesetzt.

Insbesondere bei scrollbaren Listen besteht häufig der Bedarf die Größe und die Anzahl der gleichzeitig sichtbaren Listeneinträge festzulegen. Dazu eignet sich der Geometrie-Hint fixedSize. Die in den folgenden Bildern dargestellten Listen haben die Instance-Variable look auf LOOK_SCROLLABLE und folgenden fixedSize-Hint gesetzt:

 fixedSize = 15 + ST_AVG_CHAR_WIDTH, 4 + ST_LINES_OF_TEXT, 4

...     ...

Die Listen-Objekte im Bild sind 15 Zeichen breit und das Listen-Fenster ist 4 Zeilen hoch (4 + ST_LINES_OF_TEXT). Der letzte Parameter (4) bestimmt, dass 4 Einträge im Fenster gleichzeitig dargestellt werden sollen. Sinnvollerweise ist er identisch mit der Höhe, gemessen in Textzeilen. Die Liste rechts im Bild hat - zur Demonstration - zusätzlich den Hint DrawInBox gesetzt.

modified

Die Instance-Variable modified der OptionGroup enthält die logische OR-Verknüpfung der Identifier derjenigen Options, die seit der letzten Apply-Aktion modifiziert wurden.

Beachten Sie, dass ein Verändern des Objekts vom BASIC-Code aus (z.B. Belegen der Instance-Variable selection), das Objekt nicht als "modified" markiert, d.h. der Wert der Instance-Variablen modified wird nicht verändert. Sie können dies bei Bedarf selbst machen, indem Sie die Anweisung "<obj>.modified = numWert" verwenden, wobei "numWert" ein einzelner Identifier oder die OR-Verknüpfung mehrerer Identifier der Option Objekte aus der OptionGroup sein soll.


Syntax UI-Code: modified = numWert 
         Lesen: <numVar> = <obj>.modified 
     Schreiben: <obj>.modified = numWert

Wenn Sie die Instance Variable modified lesen, werden Sie feststellen, dass sie Null enthält, es sei denn, Sie haben sie explizit auf einen anderen Wert gesetzt. Ändert der Nutzer nämlich des Zustand eines Option-Objekts, so passiert intern folgendes:

  • Die Instance-Variable modified wird mit dem Identifier des betroffenen Option-Objekts belegt.

  • Es wird geprüft ob ein ApplyHandler vorhanden ist und dieser wird ggf. aufgerufen. Der Wert von modified wird dem Handler übergeben.

  • Die Instance-Variable modified wird zurückgesetzt (mit Null belegt).
Hinweis: Im sogenannten Delayed Mode (siehe entsprechendes Kapitel weiter unten) werden die letzten beiden Schritte nicht ausgeführt, so dass die Instance-Variable modified eine eigene Bedeutung erhält. isModified IsModified liest den "modified"-Zustand eines bestimmten Option-Objekts, gegeben durch seinen Identifier, aus.
Syntax Lesen: <numVar> = <obj>.isModified (n)
              <obj> OptionGroup Objekt
           n: Identifier eines Option-Objekts

 

ApplyHandler

Der ApplyHandler der OptionGroup wird aufgerufen, wenn eines der Option-Objekte in der Group geändert wird. Er muss als ListAction deklariert sein.
Syntax UI-Code: ApplyHandler = <Handler> 
     Schreiben: <obj>.ApplyHandler = <Handler>

Beispiel, passend zum UI-Code oben:
ListAction BoolApply
  Print selection; modified
  IF modified AND 1 THEN Print "Option 1 geklickt"
  IF modified AND 4 THEN Print "Option 3 geklickt"
  END Action
Der Parameter selection enthält die selektierten Options (OR-Verknüpfung, d.h. die Summe der Identifier).

Der Parameter modified enthält den Identifier, der geändert wurde und so den Apply-Handler auslöste.

Die Abfrage erfolgt mit dem logischen Operator AND, siehe Beispiel.

Achtung! Der Parameter numSelections ist hier bedeutungslos.

Hinweis: Es ist möglich den ApplyHandler der OptionGroup manuell (vom BASIC-Code aus) zu aktivieren. Dazu wird die von der GenericClass geerbte Methode Apply verwendet. Da ApplyHandler nur ausgelöst werden, wenn das Objekt "modified" ist, muss es vorher als "modified" markiert werden. Alternativ könnte man dem Objekt auch den Hint ApplyEvenIfNotModified geben.

Beispiel:

  ListOfOptions.modified = TRUE
  ListOfOptions.Apply
Eine ausführliche Beschreibung dazu finden Sie im Kapitel 3.4 (Die "Apply"-Message) dieses Handbuchs.

MakeVisible

MakeVisible sorgt dafür, dass ein bestimmtes Option-Objekt für den Nutzer sichtbar wird. Diese Methode ist für scrollbare Listen ( look = LOOK_SCROLLABLE) sinnvoll.
Syntax im Basic-Code: <obj>.MakeVisible n 
               <obj>: OptionGroup-Objekt
                   n: Identifier des gewünschten Option-Objekts

 

StatusHandler, SendStatus

OptionGroups unterstützen den sogenannten Delayed Mode. Er ist weiter unten, im Kapitel 4.8.5 beschrieben.

^

4.8.3 RadioButton und RadioButtonGroup

RadioButton

Abstammung:

...

Spezielle Instance-Variablen

Instance-Variable Syntax im UI-Code Im BASIC-Code
identifier identifier = numWert lesen, schreiben


identifier

RadioButtons haben einen identifier, der sie identifiziert. Es ist vom Typ WORD und muss innerhalb einer RadioButtonGroup eindeutig sein. 65535 (alle Bits im WORD gesetzt) ist nicht zulässig, auch wenn es keine sofortige Fehlermeldung gibt. Dieser Wert wird verwendet wenn kein RadioButton-Objekt selektiert ist / werden soll. Für ihn gibt es die Konstante NONE_SELECTED.

RadioButton-Objekte müssen Children einer RadioButtonGroup sein.

RadioButtonGroup

Abstammung:

...

Eine RadioButtonGroup managed eine Liste von RadioButton-Objekten (theoretisch bis über 65000). RadioButtonGroup-Objekte können nur RadioButton-Objekte als Children haben.

...

Beispiel:

RadioButtonGroup Itemgroup
  Caption$= "Select an Item"
  justifyCaption = J_TOP
  Children = item1, item2, item3
  OrientChildren = ORIENT_VERTICALLY
  ApplyHandler = ItemApply      
  selection = 2
  End Object       
 
RadioButton item1: Caption$="Item 1":identifier = 1: End Object
RadioButton item2: Caption$="Item 2":identifier = 2: End Object
RadioButton item3
  Caption$="Item 3"
  identifier = 3
  End Object
Die UI-Anweisungen für die Objekte item1 und item2 wurden zur Demonstration in einer Zeile untergebracht. Dazu wird - wie im BASIC-Code auch - ein Doppelpunkt zur Trennung verwendet.

Spezielle Instance-Variablen

Instance-Variable Syntax im UI-Code Im BASIC-Code
behavior behavior = numWert lesen, schreiben
look look = numWert lesen, schreiben
selection selection = numWert lesen, schreiben
isSelected -- nur lesen
numSelections -- nur lesen
DisplayCurrentSelection DisplayCurrentSelection --
modified modified = numWert lesen, schreiben
ModifiedOnRedundantSelection ModifiedOnRedundantSelection --
ApplyHandler ApplyHandler = <Handler> nur schreiben
DoublePressHandler DoublePressHandler = <Handler> nur schreiben
StatusHandler StatusHandler = <Handler> nur schreiben

Methoden:

Methode Aufgabe
MakeVisible n Einen bestimmten Eintrag sichtbar machen
SelectItem n [,FALSE] Selektiert-Status eines Eintrags ändern
SendStatus Status-Handler aufrufen


behavior

Die Instance-Variable behavior bestimmt, wie sich die Group bezüglich Selektionsmöglichkeiten der Einträge verhält.

Konstante Wert Bedeutung
LB_EXCLUSIVE 0 Das ist der Default-Wert. Nur genau ein Element kann selektiert sein.
LB_EXCLUSIVE_NONE 1 Ein oder kein Element kann selektiert sein. Ist kein Element selektiert, wird als "selection" 65535 (NONE_SELECTED) geliefert.
LB_EXTENDED_SELECTION 2 Wie LB_EXCLUSIVE_NONE, aber der Nutzer kann die Selektion durch Ziehen mit der Maus oder durch Shift-Klick oder Strg-Klick "erweitern". Es können also mehrere Elemente selektiert sein.
LB_NON_EXCLUSIVE 3 Jedes Element kann unabhängig von den anderen einzeln selektiert werden.


look

Instance-Variable look bestimmt das Aussehen der RadioButtonGroup und ihrer RadioButton-Objekte (engl. look : Aussehen, äußere Erscheinung). Funktionell sind alle Looks identisch.
Syntax UI- Code: look = numWert 
          Lesen: <numVar> = <obj>.look 
      Schreiben: <obj>.look = numWert

Für alle Listen-Objekte stehen die bei der OptionGroup beschriebenen Looks (LOOK_NORMAL, LOOK_SCROLLABLE, LOOK_MINIMIZE_SIZE und LOOK_TOOLBOX) zur Verfügung. Dort finden Sie auch Bilder und weitergehende Informationen dazu.

selection

Die Instance-Variable selection enthält den Identifier des aktuell selektierten RadioButton-Objekts. Ist kein Objekt selektiert, enthält sie den Wert 65535 (NONE_SELECTED). Falls mehrere Objekte selektiert sind, enthält selection den Identifier eines der selektierten Objekte.
Syntax UI-Code: selection = numWert 
         Lesen: <numVar> = <obj>.selection 
     Schreiben: <obj>.selection = numWert

Konstante Wert Bedeutung
NONE_SELECTED 65535 Spezialwert für die Instance-Variable "selection" wenn kein Eintrag selektiert ist oder kein Eintrag selektiert werden soll. Behavior sollte den Wert LB_EXTENDED_SELECTION oder LB_EXCLUSIVE_NONE haben.

isSelected

IsSelected prüft, ob ein bestimmtes RadioButton-Objekt bzw. Listeneintrag, gegeben durch seinen Identifier, selektiert ist oder nicht.

Siehe auch: SelectItem


Syntax Lesen: <numVar> = <obj>.isSelected (n)
              <obj> RadioButtonGroup Objekt
           n: Identifier eines RadioButton-Objekts bzw. Listeneintrags

 

numSelections

Die Instance-Variable numSelections enthält die Anzahl der aktuell selektierten Listeneinträge.
Syntax Lesen: <numVar> = <obj>.numSelections

 

DisplayCurrentSelection

Der Hint DisplayCurrentSelection beeinflusst RadioButtonGroups mit look = LOOK_MINIMIZE_SIZE und bewirkt, dass im minimierten Zustand statt des Caption-Textes der RadioButtonGroup der Text des aktuell selektierten RadioButtons angezeigt wird.
Syntax UI- Code: DisplayCurrentSelection

RadioButtonGroup Itemgroup
  Caption$= "Select an Item"
  Children = item1, item2, item3
  look = LOOK_MINIMIZE_SIZE
  DisplayCurrentSelection
  fixedSize = 15 + ST_AVG_CHAR_WIDTH, 1 + ST_LINES_OF_TEXT
  ApplyHandler = ItemApply 
  selection = 2
  End Object

...   ...

Das Bild zeigt die RadioButtonGroup entsprechend dem obigen Code, links ohne und rechts mit dem Hint DisplayCurrentSelection.

modified

Die Instance-Variable modified der RadioButtonGroup enthält die Information, ob die Selektion der RadioButtonGroup seit der letzten Apply-Aktion geändert wurde.

Beachten Sie, dass ein Verändern des Objekts vom BASIC-Code aus (z.B. Belegen der Instance-Variable selection), das Objekt nicht als "modified" markiert, d.h. der Wert der Instance-Variablen modified wird nicht verändert. Sie können dies bei Bedarf selbst machen, indem Sie die Anweisung "<obj>.modified = TRUE" verwenden.


Syntax UI-Code: modified = TRUE | FALSE
         Lesen: <numVar> = <obj>.modified 
     Schreiben: <obj>.modified = TRUE | FALSE

Wenn Sie die Instance Variable modified lesen, werden Sie feststellen, dass sie Null enthält, es sei denn, Sie haben sie explizit auf einen anderen Wert gesetzt. Ändert der Nutzer nämlich Auswahl innerhalb der Liste, so passiert intern folgendes:

  • Die Instance-Variable modified wird mit TRUE belegt.

  • Es wird geprüft ob ein ApplyHandler vorhanden ist und dieser wird ggf. aufgerufen. Der Wert von modified wird dem Handler übergeben.

  • Die Instance-Variable modified wird zurückgesetzt (mit FALSE belegt).
Hinweis: Im sogenannten Delayed Mode (siehe entsprechendes Kapitel weiter unten) werden die letzten beiden Schritte nicht ausgeführt, so dass die Instance-Variable modified eine eigene Bedeutung erhält.

ModifiedOnRedundantSelection

Der Hint ModifiedOnRedundantSelection bewirkt, das eine RadioButtonGroup sich selbst als modified markiert, wenn der Nutzer den bereits selektierten Eintrag erneut auswählt. Im Wesentlichen bedeutet dass, dass die RadioButtonGroup ihre Apply Message aussendet wenn der Nutzer einen bereits selektierten Eintrag erneut selektiert.
Syntax UI-Code: ModifiedOnRedundantSelection

 

ApplyHandler

Der ApplyHandler der RadioButtonGroup wird aufgerufen, wenn der User ein Element selektiert / die Selektion ändert. Er muss als ListAction deklariert sein. Beispiel, passend zum UI-Code oben:
ListAction ItemApply
  Print selection; numSelections
  END Action
Der Parameter selection enthält den Identifier, der geändert wurde und so den Apply-Handler auslöste.

Der Parameter numSelections enthält die Anzahl der der selektierten Elemente.

Der Parameter modified ist immer 65535, d.h. alle Bits des WORD sind gesetzt. Das ist das Analogon zur Integer-Konstanten TRUE (= -1).


Syntax UI- Code: ApplyHandler = <Handler> 
      Schreiben: <obj>.ApplyHandler = <Handler>

Hinweis: Es ist möglich den ApplyHandler der RadioButtonGroup manuell (vom BASIC-Code aus) zu aktivieren. Dazu wird die von der GenericClass geerbte Methode Apply verwendet. Da ApplyHandler nur ausgelöst werden, wenn das Objekt "modified" ist, muss es vorher als "modified" markiert werden. Alternativ könnte man dem Objekt auch den Hint ApplyEvenIfNotModified geben.

Beispiel:

 Itemgroup.modified = TRUE
 Itemgroup.Apply
Eine ausführliche Beschreibung dazu finden Sie im Kapitel 3.4 (Die "Apply"-Message) dieses Handbuchs.

DoublePressHandler

Der DoublePressHandler wird aufgerufen, wenn der User ein Element mit der Maus doppelklickt. War der Eintrag bis dahin noch nicht selektiert wird vorher der ApplyHandler aufgerufen. Die Parameter entsprechen denen des ApplyHandlers.
Syntax UI- Code: ApplyHandler = <Handler> 
      Schreiben: <obj>.ApplyHandler = <Handler>

Hinweis: GEOS unterstützt einen DoublePressHandler nur, wenn die Instance-Variable behavior auf LB_EXCLUSIVE oder LB_EXTENDED_SELECTION gesetzt ist. R-BASIC kann nichts dafür - sorry.

MakeVisible

MakeVisible sorgt dafür, dass ein bestimmtes RadioButton-Objekt bzw. ein bestimmter Listeneintrag einer DynamicList für den Nutzer sichtbar wird. Diese Methode ist für scrollbare Listen ( look = LOOK_SCROLLABLE, z.B. DynamicList Objekte) sinnvoll.
Syntax im Basic-Code: <obj>.MakeVisible n 
               <obj>: RadioButtonGroup-Objekt
                   n: Identifier des gewünschten RadioButton-Objekts bzw.
                      Listeneintrags

 

SelectItem

Mit SelectItem können Sie den Status "Selektiert" oder "nicht selektiert" für ein bestimmtes RadioButton-Objekt bzw. einen bestimmten Listeneintrag einer DynamicList ändern. Diese Methode ist für Listen, die eine Mehrfachauswahl erlauben, sinnvoll (behavior = LB_EXCLUSIVE_NONE, LB_EXTENDED _SELECTION oder LB_NON_EXCLUSIVE). Für Standard-Listen (behavior = LB_EXCLUSIVE) sollten Sie die Instancevariable selection benutzen.
Syntax im Basic-Code: <obj>.SelectItem n [, state]
               <obj>: RadioButtonGroup-Objekt
                   n: Identifier des gewünschten RadioButton-Objekts bzw.
                      Listeneintrags
               state: TRUE (Default): Eintrag selektieren
                      FALSE: Eintrag auf "nicht selektiert" setzen

 

StatusHandler, SendStatus

RadioButtonGroups unterstützen den sogenannten Delayed Mode. Er ist weiter unten, im Kapitel 4.8.5 beschrieben.

^

4.8.4 DynamicList

Abstammung:

...

Eine DynamicList ist eine erweiterte RadioButtonGroup. Daher erbt sie alle Instance-Variablen und Fähigkeiten dieser Klasse (behavior, look, selection, modified, ApplyHandler, DoublePressHandler, SelectItem, Arbeit im Delayed Mode usw.). Zusätzlich hat sie folgende Besonderheiten:

  • Die Instance-Variable look steht per Default auf LOOK_SCROLLABLE. Sie können das natürlich im UI-Code ändern.

  • Eine DynamicList hat im UI-Code keine Children. Sie erzeugt und verwaltet ihren Children (Listeneinträge) selbst.

  • Sie müssen der Instance-Variable numItems auf eine Wert ungleich Null setzen und einen QueryHandler für eine DynamicList schreiben, sonst werden keine Listeneinträge angezeigt.
Spezielle Instance-Variablen

Instance-Variable Syntax im UI-Code Im BASIC-Code
numItems numItems = numWert lesen, schreiben
QueryHandler QueryHandler = <Handler> nur schreiben

Methoden:

Methode Aufgabe
ItemText$ Listeneintrag einen Text zuweisen
ItemGString Listeneintrag eine Grafik zuweisen
InsertItems Eine bestimmte Anzahl von Einträgen hinzufügen
RemoveItems Eine bestimmte Anzahl von Einträgen entfernen

So arbeitet eine DynamicList

...

Nehmen wir an, wie haben eine DynamicList mit 5 Einträgen, die hier als Items bezeichnet werden, so wie im Code-Beispiel dargestellt.

DynamicList DynList
  Caption$ = "List Example"
  justifyCaption = J_TOP
  numItems = 5
  fixedSize = 15 + ST_AVG_CHAR_WIDTH, \
               3 + ST_LINES_OF_TEXT, 3
  selection = 3
  ApplyHandler = MyApplyHandler
  QueryHandler = MyListQuery
  END Object 
Die Instance-Variable numItems bestimmt, wie viele Items eine DynamicList hat. Die Items sind selbst Objekte, sie werden aber im UI-Code nicht aufgeführt, sondern die DynamicList erzeugt sie bei Bedarf selbst. Die von der RadioButtonGroup-Klasse geerbte Instance-Variable selection legt fest, welcher Eintrag am Anfang selektiert ist. Ebenfalls von der RadioButtonGroup Klasse geerbt ist die Instance-Variable ApplyHandler. FixedSize hingegen ist von der GenericClass geerbt und legt im Beispiel fest, dass die Liste 15 Zeichen breit und 3 Zeilen hoch ist, wobei 3 Items gleichzeitig angezeigt werden sollen. Will eine DynamicList eines ihrer Items darstellen, so benötigt sie eine Information, welchen Text das Item darzustellen hat. Dazu ruft sie den QueryHandler auf (engl. to query: anfordern). Diesem wird die Nummer des Items, das dargestellt werden soll, übergeben. Die Zählung beginnt dabei immer mit Null. Der Handler muss den anzuzeigenden Text (bzw. die Grafik) ermitteln und ihn an die DynamicList übergeben, wie im Beispielcode dargestellt.
LISTACTION MyListQuery
DIM name$   AS String

  ON selection SWITCH
  CASE 0: name$ = "Ralph"  : END CASE
  CASE 1: name$ = "Fred"   : END CASE
  CASE 2: name$ = "Joshua" : END CASE
  CASE 3: name$ = "Mary"   : END CASE
  CASE 4: name$ = "Antoinette": END CASE
  DEFAULT:  name$ = "no name"          'Nur zur Sicherheit!
  END SWITCH 

  sender.ItemText$(selection) = name$

  END Action
 

numItems

Die Instance-Variable numItems bestimmt, wie viele Listeneinträge die DynamicList hat. Sie kann im sowohl UI-Code als auch im BASIC-Code gesetzt werden.
Syntax UI- Code: numItems = numWert 
          Lesen: <numVar> = <obj>.numItems 
      Schreiben: <obj>.numItems = numWert

Es ist explizit zulässig, numItems im UI-Code nicht oder mit Null zu belegen, was die gleiche Wirkung hat. Die Liste bleibt dann zunächst leer und sendet keine Query-Message aus. Es ist daher eine gute Idee, numItems am Programmende auf Null zu setzen.

Tipp: Der Ändern Sie den Wert von numItems im BASIC-Code, so stellt sich die Liste neu dar. Wenn Sie also die Anzahl der Einträge oder deren Inhalt in der Liste zur Laufzeit ändern wollen, so müssen Sie nur numItems einen Wert zuweisen. Die Liste fordert dann über ihren Queryhandler alle Einträge neu an. Alternativ können Sie die Methoden InsertItems bzw. RemoveItems verwenden.

ItemText$

Die Methode ItemText$(index) kann nur im BASIC-Code aufgerufen werden. Das passiert üblicherweise im QueryHandler der DynamicList. Über ItemText$(index) wird der Liste mitgeteilt, welchen Text das entsprechende Item darzustellen hat. "Index" bestimmt, welchem Item der Text zugeordnet wird.
Syntax Schreiben: <obj>.ItemText$(index) = "Text"

 

ItemGString

Die Methode ItemGString(index) kann nur im BASIC-Code aufgerufen werden. Das passiert üblicherweise im QueryHandler der DynamicList. Über ItemGString(index) wird der Liste mitgeteilt eine Grafik oder einen formatierten Text für das entsprechende Item darzustellen. "Index" bestimmt, welchem Item die Grafik zugeordnet wird.
Syntax Schreiben: <obj>.ItemGString (index) = <gsHan>
         <gsHan>: Handle eines GStrings

Wenn Sie Grafiken in DynamicList-Objekten darstellen wollen sollten Sie Breite und Höhe der Listen mit Hilfe des Hints fixedSize festlegen. Die ersten beiden Parameter dieses Hints bestimmen Breite und Höhe der gesamten Liste, der dritte Parameter bestimmt die Anzahl der gleichzeitig dargestellten Items. Folglich ist die Höhe eines einzelnen Listeneintrags der Quotient aus Höhe der Liste und Anzahl der Einträge.
DynamicList MyList
  QueryHandler = QueryGraphic
  selection = 0

   ' Die Liste soll 4 Grafiken mit 
 ' je 50x50 Pixel gleichzeitig darstellen
  ' Weil sie selbst etwas Platz braucht machen
  ' wir sie etwas größer
  ' fixedSize = sizeX, sizeY, numElements
  fixedSize = 60, 205, 4

  ' Insgesamt sollen es 5 Elemente sein.
  numItems = 5

End Object

...

Der QueryHandler erzeugt verschieden grafische Symbole, die als Listeneintrag dargestellt werden.

LISTACTION QueryGraphic
dim gsHan as HANDLE

  ' Wir starten die Aufzeichnung eines GString
  ' Alle Grafik- und Textausgaben gehen 
  ' jetzt in den GString

  gsHan = StartRecordGS() 
  on selection SWITCH
  case 0:
    FillEllipse 2, 2, 48, 48, blue
    end case
  case 1:
    FillRect  2, 2, 48, 48, yellow
    Rectangle 2, 2, 48, 48, black
    end case
  case 2:
    FillEllipse 2, 2, 48, 48, red
    FillEllipse 10, 10, 40, 40, cyan
  end case
  case 3:
    FillRect 2, 20, 48, 30, light_green
    FillRect 20, 2, 30, 48, light_green
    PRINT atxy 0,0;"A"
    PRINT atxy 35,0;"B"
    PRINT atxy 0,35;"C"
    PRINT atxy 35,35;"D"
    end case
  case 4:
    printfont.style = ts_bold
    PRINT atxy 0,0;ink red;"Hello"
    PRINT atxy 0, 20;ink blue;"World"
    end case
  end switch 
 
  ' EndRecordGS beendet den Aufzeichnusmodus.
  EndRecordGS gsHan

  ' Wir übergeben die Grafik an den Listeneintrag 
  sender.ItemGString(selection) = gsHan 

  ' Ganz wichtig: 
  ' Das Handle wieder freigeben, sonst frisst
  ' das Programm Systemhandles!
  FreeGS gsHan

  END Action
Tipp: Möchten Sie die grafischen Einträge nebeneinander darstellen, so verwenden Sie orientChildren = ORIENT_HORIZONTALLY. Die Liste muss dann natürlich 4 Einträge breit und nur einen Eintrag hoch sein. Den kompletten Code dazu finden Sie bei den Beispielen zu den Listenobjekten.
DynamicList MyList
  QueryHandler = QueryGraphic
  selection = 0
  orientChildren = ORIENT_HORIZONTALLY
  fixedSize = 205, 60, 4
  numItems = 5
End Object
Achtung! DynamicList Objekte verwalten ihre Einträge als Children selbst. Auch die Captions der Listeneinträge werden in dem Objektblock gespeichert, in dem die Liste ist. Im Normalfall befinden sich auch noch andere Objekt in diesem Block, so dass er anfangs bereits ca. 4 kByte groß ist. Damit ist ein gewisser Platzbedarf für die Listeneinträge bereits berücksichtigt. Da man mit ItemGString aber auch relativ große Grafiken zuweisen kann (z.B. wenn der GString eine Bitmap enthält), kann der Objektblock zur Laufzeit trotzdem sehr groß werden und der Speichermanager bekommt ein Problem ("Hauptspeicher voll"). Um dieses Problem zu vermeiden sollte man Listen, die viele oder große grafische Elemente darstellen sollen, in einem eigenen Objektblock ablegen. Dazu verwendet man die UI-Anweisung ForceNewObjBlock (siehe Kapitel 2.1.4). Diese weist den Compiler an unverzüglich mit einem neuen Objektblock zu beginnen, auch wenn im aktuell aufgebauten Block noch Platz zu sein scheint.

Weitere Informationen zu GStrings und auch zum Speicherbedarf vom GStrings finden Sie im R-BASIC Programmierhandbuch, Kapitel 2.8.5 (Arbeit mit Graphic Strings).

ForceNewObjBlock

DynamicList MyBigList
  ...
  END Object

ForceNewObjBlock

QueryHandler

Der QueryHandler wird automatisch aufgerufen, wenn die DynamicList eines seiner Items darstellen will. QueryHandler müssen als ListAction deklariert sein. Der Parameter selection enthält die Nummer des Items, für das ein Text angefordert wird. Die anderen Parameter sind bedeutungslos.

Die korrekte Reaktion des QueryHandlers ist, wie in den Code-Beispielen oben, die Methoden ItemText$(selection) oder ItemGString(index) der DynamicList aufzurufen.


Syntax UI-Code: QueryHandler = <Handler> 
     Schreiben: <obj>.QueryHandler = <Handler>

Das Zusammenspiel zwischen DynamicList und QueryHandler funktioniert automatisch, so dass Sie sich nicht weiter darum kümmern müssen. Sie müssen nur sicherstellen, dass der QueryHandler zu jedem selection-Wert, der von der Liste kommen kann (Null ... numItems-1), einen passenden Text oder eine Grafik bereitstellt. Dabei ist es, wie im Beispiel-Code zu ItemText$ oben, sinnvoll auch "unerwartete" Fälle zu berücksichtigen, falls sie später etwas ändern oder ein Programmierfehler auftritt.

InsertItems

InsertItems fügt eine bestimmte Anzahl von Listeneinträgen ab einer wählbaren Position in die Liste ein. Die aktuell selektierten Einträge bleiben selektiert.
    Syntax im BASIC-Code: <obj>.InsertItems pos, anz
                     pos: Position, aber der eingefügt werden soll
                    Null: Einfügen am Anfang
                    pos > aktuelle Anzahl: Anhängen
                     anz: Anzahl der neuen Einträge

 

RemoveItems

RemoveItems löscht eine bestimmte Anzahl von Listeneinträgen ab einer wählbaren Position. Die aktuell selektierten Einträge bleiben selektiert, falls sie nicht gelöscht wurden.
Syntax im BASIC-Code: <obj>.InsertItems pos, anz
                 pos: Position, aber der gelöscht werden soll
                 anz: Anzahl der zu löschenden Einträge


^

4.8.5 Listen-Objekte im Delayed Mode

Alle Listen-Objekte können im "Delayed Mode" (engl.: verzögerter Modus) arbeiten. Dazu muss man dem Objekt selbst bzw. einem seiner Parents im UI-Code den Hint MakeDelayedApply geben oder man bindet das Objekt als Child in einem Dialog ein, dessen dialogType Instance Variable auf DT_DELAYED_APPLY gesetzt ist. Dieser "Delayed Mode" ist ausführlich im Kapitel 3.4.2 (Delayed Mode und Status-Message) dieses Handbuchs beschrieben, eine Beschreibung des Dialog-Objekts im Delayed Mode finden Sie im Kapitel 4.6.6.5.

Instance Variable Syntax im UI-Code Im BASIC-Code
StatusHandler StatusHandler = <Handler> nur schreiben


Syntax UI-Code: StatusHandler = <Handler> 
     Schreiben: <obj>.StatusHandler = <Handler>

Der StatusHandler wird im Delayed Mode statt des ApplyHandlers gerufen, wenn der Nutzer die Auswahl innerhalb der Liste ändert. Der ApplyHandler hingegen wird erst auf Anforderung gerufen (siehe Kapitel 3.4.2).

Die Instance-Variable modified kann einen Wert ungleich Null enthalten, nämlich dann, wenn das Objekt vom User modifiziert wurde, der ApplyHandler aber noch nicht gerufen wurde. Der Aufruf des ApplyHandlers setzt auch im Delayed Mode den modified-Status zurück. Falls kein ApplyHandler gesetzt ist wird der modified-Status wird immer dann zurückgesetzt, wenn der ApplyHandler gerufen werden müsste.

Bei einer OptionGroup gilt außerdem:

  • Ändert der Nutzer den Zustand eines Option-Objekts der OptionGroup, so wird die Instance-Variable modified mit dessen identifier logisch OR verknüpft.

  • Der Parameter "modified" enthält folglich sowohl beim StatusHandler als auch beim ApplyHandler die logische OR-Verknüpfung der Identifier der seit dem letzten Aufruf des ApplyHandler veränderten Option-Objekte.

Methode Aufgabe
SendStatus Status-Handler aufrufen


Syntax BASIC-Code: <obj>.SendStatus

Die Methode SendStatus fordert das Objekt auf, seinen StatusHandler aufzurufen (d.h. seine Status-Message zu senden).

^

Weiter...