4.18 Display und zugehörige Objekte

4.18.1 Überblick

4.18.2 Display

4.18.3 DisplayGroup

4.18.4 DisplayControl



4.18.1 Überblick

Jede große Applikation (z.B. Write, R-BASIC) zeigt ihre Dokumente in eigenen Fenstern an. Diese Fenster gehören der Objektklasse Display an. Displayobjekte enthalten ähnlich wie Dialoge weitere UI-Objekte, z.B. Views, Memos, Buttons oder Listen. Der Bereich, in dem die Displays dargestellt werden, ist ein Objekt der Klasse DisplayGroup. Die DisplayGroup managet die Displays, organisiert z.B. dass sie überlappend dargestellt werden oder sich den Platz aufteilen. Dabei hat die DisplayGroup selbst keine UI, mit der der Nutzer interagieren kann. Das übernimmt ein Objekt der Klasse DisplayControl, das sich üblicher Weise im "Fenster" Menü befindet. Der Vorteil von dieser Trennung ist, dass man mehrere DisplayGroups haben kann, die alle über das Fenster-Menü gesteuert werden.

...

Eine typische Konfiguration: Eine DisplayGroup mit zwei Displays. Das DisplayControl befindet sich im "Fenster" Menü.

Displays, DisplayGroup und DisplayControl arbeiten im Hintergrund eng zusammen. Im Kern ist es so, dass die DisplayGroup weiß, welche Displays (Fenster) es gibt, da sie die Children der DisplayGroup sind. Sie sendet eine Message an das DisplayControl, das daraufhin eine Liste der vorhandenen Fenster aufbaut. Wählt der Nutzer aus dieser Liste ein Display aus so sendet das DisplayControl eine Message an die DisplayGroup. Diese wiederum wählt das geforderte Display aus. Genauso verhält es sich, wenn der Nutzer den Eintrag "Überlappend", "Bildschirmfüllend" oder "Aufteilen" auswählt. Die DisplayGroup bekommt den Befehl vom DisplayControl und organisiert die Anzeige entsprechend. Im Gegenzug bekommt das DisplayControl eine Message, wenn der Nutzer z.B. auf ein bestimmtes Display klickt und es so zum aktiven Fenster macht. All das passiert ohne weiteres Zutun des Programmierers.

...

Prinzipielle Organisation von Display, DisplayGroup und DisplayControl

Das System organisiert diese Zusammenarbeit intern über die Target-Hierarchie. Das stellt auch sicher, dass die Zusammenarbeit mit mehreren DisplayGroups funktioniert. Hintergrundinformationen zur Target-Hierarchie finden Sie im Handbuch Spezielle Themen, Vol. 2, Kapitel 12. Für die Verwendung von Display, DisplayGroup und DisplayControl müssen Sie in diesem Zusammenhang folgendes wissen:

  • Sie müssen der DisplayGroup (falls Sie mehrere haben: genau einer) den Hint defaultTarget geben. Andernfalls weiß das DisplayControl nicht, mit wem es zusammenarbeiten soll und baut die Fenster-Liste nicht automatisch auf.

  • Falls Sie verhindern wollen, dass eine DisplayGroup auf die Messages des DisplayControl reagiert, so müssen Sie ihre Instancevariable targetable auf FALSE setzen.

^

4.18.2 Display

... Objekte der Klasse Display sind die "Fenster" in denen alle großen Applikationen ihre Daten anzeigen. Displays müssen Children eines DisplayGroup Objekts sein. Die Displays selbst enthalten weitere UI-Objekte, die die eigentlichen Informationen darstellen. Im Bild links ist das ein Memo-Objekt.

Abstammung:

...

Das Displayobjekt erbt alle Eigenschaften und Fähigkeiten der GenericClass. Von besonderer Bedeutung sind dabei die Fähigkeiten zum Geometriemanagement, insbesondere die Window-bezogenen Hints (Kapitel 3.3.7: Spezielle Hints für Window-Objekte) sind hier von Bedeutung. Beachten Sie, dass insbesondere die Größe eines Displayobjekts im Zusammenspiel mit der DisplayGroup geändert werden kann. Es ist deshalb leicht möglich, dass Sie widersprüchliche Hints setzen. So verhindert z.B. der Hint "NotMaximizable", dass sich das Display bildschirmfüllend darstellt.

Displays können in drei Modi dargestellt werden:

  • Bildschirmfüllend (maximiert): Das Displayobjekt nimmt den gesamten verfügbaren Platz in der DisplayGroup ein. Wenn ein Displayobjekt bildschirmfüllend dargestellt wird so sind auch alle anderen Displays bildschirmfüllend.

  • Überlappend: Jedes Displayobjekt hat seine eigene Größe. Der Nutzer kann die Größe ändern, Displayobjekte können sich gegenseitig überlappen. Der Zustand "aufgeteilt" ist ein Spezialfall von "überlappend", bei dem Größe und Anordnung der Displays automatisch so gewählt wird, dass sie alle möglichst gut zu sehen sind.

  • Minimiert: Das Displayobjekt ist nicht mehr sichtbar, aber noch in der Liste des DisplayControl Objekts verfügbar. Von dort aus kann es wieder sichtbar gemacht werden.

    Der Zustand "minimiert" ist nicht identisch mit "unsichtbar" (visible = FALSE). Wird die Instancevariable "visible" auf FALSE gesetzt verschwindet das Displayobjekt auch aus der Liste des DisplayControl Objekts.

Die Instancevariablen minimizedState und maximizedState bestimmen gemeinsam mit den Hints MinimizedOnStartup und MaximizedOnStartup in welchem der drei Modi sich das Displayobjekt befindet. Mit den Hints NotMinimizable, NotMaximizable, NotResizable und NotRestorable kann man bei Bedarf die Fähigkeiten des Displayobjekts einschränken. Die Instancevariable userDismissable und die Methode Close wird nur benötigt, wenn man den Mechanismus "Schließen von Displays" (siehe unten) implementieren will.

Spezielle Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
minimizedState minimizedState = TRUE | FALSE lesen, schreiben
MinimizedOnStartup MinimizedOnStartup --
NotMinimizable NotMinimizable --
maximizedState maximizedState = TRUE | FALSE lesen, schreiben
MaximizedOnStartup MaximizedOnStartup --
NotMaximizable NotMaximizable --
NotResizable NotResizable --
NotRestorable NotRestorable --
userDismissable userDismissable = TRUE | FALSE lesen, schreiben
OnClose OnClose = <Handler> lesen, schreiben

Methoden:

Methode Aufgabe
Close Ruft den OnClose Handler des Objekts auf

Action-Handler-Typen:

Handler-Typ Parameter
DialogAction (sender as object, command as integer)

Ein einfaches Displayobjekt, dass ein Memo als Child enthält, sieht so aus:

Display Disp1  
  Caption$ = "Erlkönig"' , 0
  Children = Memo1
End OBJECT

Memo Memo1
  text$ = "Wer reitet so spät durch Nacht und Wind?"
  ExpandWidth:ExpandHeight
  backColor = WHITE
End Object


Minimized und Maximized State

Die folgenden Instancevariablen bestimmen ob das Displayobjekt minimiert (versteckt), maximiert (bildschirmfüllend) oder überlappend dargestellt wird.

Hinweis: Da Primary-Objekte von Displays abstammen erben Sie die im Folgenden aufgelisteten Fähigkeiten.

minimizedState

MinimizedState enthält die Information ob das Displayobjekt "minimiert" ist oder nicht.

  • Am Programmstart bestimmt das DisplayGroup-Objekt, wie die Displays dargestellt werden. Das Setzen des Wertes im UI-Code ist möglicherweise wirkungslos. Verwenden Sie in diesem Fall MinimizedOnStartup.

Syntax UI-Code: minimizedState = TRUE
                Der Defaultwert ist FALSE.
     Schreiben: <obj>.minimizedState = <Wert> 
         Lesen: <numVar> = <obj>.minimizedState

 

MinimizedOnStartup

MinimizedOnStartup bewirkt, dass das Displayobjekt am Programmstart minimiert ist.
Syntax UI-Code: MinimizedOnStartup

 

NotMinimizable

NotMinimizable bewirkt, dass das Displayobjekt nicht minimiert werden kann. Der entsprechende Button in der Titelbar des Displayobjekts wird entfernt und das Setzen der Instancevariablen minimizedState bleibt wirkungslos.
Syntax UI-Code: NotMinimizable

 

maximizedState

MaximizedState enthält die Information, ob das Displayobjekt "bildschirmfüllend" (maximizedState = TRUE) dargestellt wird oder nicht.

  • Am Programmstart bestimmt das DisplayGroup-Objekt, wie die Displays dargestellt werden. Das Setzen des Wertes im UI-Code ist möglicherweise wirkungslos.

  • Wenn Sie den Wert für ein Displayobjekt zur Laufzeit ändern, hat das Auswirkungen auf alle anderen Displays in der DisplayGroup.

Syntax UI-Code: maximizedState  = TRUE
                Der Defaultwert ist FALSE.
     Schreiben: <obj>.maximizedState = <Wert> 
         Lesen: <numVar> = <obj>.maximizedState

 

MaximizedOnStartup

MaximizedOnStartup bewirkt, dass das Displayobjekt am Programstart maximiert dargestellt wird.

  • Am Programmstart bestimmt das DisplayGroup-Objekt, wie die Displays dargestellt werden. Das Setzen des Wertes ist möglicherweise wirkungslos.

Syntax UI-Code: MaximizedOnStartup

 

NotMaximizable

NotMaximizable bewirkt, dass der Nutzer das Displayobjekt nicht maximieren kann. Das Display bleibt im "überlappenden" Modus, auch wenn die anderen Displays bildschirmfüllend sind.
Syntax UI-Code: NotMaximizable

 

Weitere Hints

NotResizable

NotResizable bewirkt, dass der Nutzer die Größe des Displayobjekts nicht ändern kann, wenn es im Modus "überlappend" dargestellt wird.
Syntax UI-Code: NotResizable

 

NotRestorable

NotRestorable bewirkt, dass ein Wechsel in den "minimiert" Modus nicht zurückgenommen werden kann. Verwenden Sie diesen Hint mit Vorsicht.
Syntax UI-Code: NotRestorable

 

Schließen von Displays

Große Applikationen wie GeoWrite oder R-BASIC stellen Ihre Dokumente in Fenstern dar, die Display-Objekte sind. Wird ein Dokument geschlossen so muss auch das zugehörige Display-Objekt vom Schirm genommen werden. Falls das Display beim Öffnen des Dokuments, also zur Laufzeit, mit der Routine CreateObject erzeugt wurde muss es dann auch wieder mit der Routine DestroyObject wieder vernichtet werden. Bitte lesen Sie die Dokumentation dieser Routinen sorgfältig.

Werden die Fenster (Display-Objekte) überlappend dargestellt so findet sich im Systemmenü des Displays der Eintrag "Schließen". Er ist per Default inaktiv. Um ihn zu aktivieren müssen Sie die Instancevariable userDismissable des Display-Objekts auf TRUE setzen. Klickt der Nutzer jetzt auf diesen Eintrag wird der OnClose Handler des Displayobjekts aufgerufen. Dieser Handler muss alle notwendigen Schritte auslösen um das Dokument zu schließen und das Display-Objekt vom Schirm zu nehmen. Ist kein OnClose Handler gesetzt so passiert nichts.

Hinweis: Primary-Objekte stammen von Displays ab. Sie implementieren jedoch ihr eigenes Handling zum Schließen eines Programms. Die folgenden Instancevariablen sind für Primaries daher nicht verfügbar.

userDismissable

UserDismissable = TRUE aktiviert den Eintrag "Schließen" im Systemmenü des Displayobjekts. Der Defaultwert ist FALSE. Das Systemmenü ist nur sichtbar, wenn die Displays überlappend dargestellt sind.

Wenn der Nutzer auf "Schließen" im Systemmenü des Displayobjekts klickt wird der OnClose Handler des Objekts aufgerufen.


Syntax UI-Code: userDismissable = TRUE
                Der Defaultwert ist FALSE.
     Schreiben: <obj>.userDismissable = <Wert> 
         Lesen: <numVar> = <obj>.userDismissable

 

OnClose

Der OnClose Handler wird gerufen, wenn der Nutzer auf den Eintrag "Schließen" im Systemmenü des Displayobjekts klickt. Das Systemmenü ist nur sichtbar, wenn die Displays überlappend dargestellt sind. Um den Eintrag "Schließen" im Systemmenü des Displayobjekts zu aktivieren müssen Sie die Instancevariable userDismissable des Displayobjekts auf TRUE setzen.

Der OnClose Handler muss als DialogAction deklariert sein.


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

 

Close

Die Methode Close ruft den OnClose Handler des Objekts auf. Dieser Handler muss dann alle weiteren Schritte auslösen. Ist kein OnClose Handler definiert so passiert auch nichts.
Syntax BASIC Code: <obj>.Close


^

4.18.3 DisplayGroup

... Eine DisplayGroup stellt den Bereich bereit, in dem die Displayobjekte dargestellt werden. Im Bild sind drei Displays in einer DisplayGroup zu sehen.

Das DisplayGroup Objekt interagiert mit den Displays um sie anzuordnen, ihre Größe festzulegen usw.

Außerdem arbeitet das DisplayGroup Objekt automatisch mit dem DisplayControl Objekt zusammen. Damit dies alles funktioniert müssen Sie Folgendes tun:

  • Die Displays müssen Children des DisplayGroup Objekts sein.

  • Das DisplayGroup Objekt muss den Hint defaultTarget gesetzt haben.
Abstammung:

...

Per Default ist eine DisplayGroup so eingestellt, dass die Displays am Programmstart im bildschirmfüllenden Modus angezeigt werden. Wenn Sie das nicht möchten setzen Sie im UI-Code die Instancevariable fullSizeState auf FALSE. Um die Displays am Programmstart "aufgeteilt" darzustellen müssen Sie in Ihrem OnStartup Handler die Methode "TileDisplays" für das DisplayGroup Objekt aufrufen.

Spezielle Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
fullSizeState fullSizeState = TRUE | FALSE lesen, schreiben
activeDisplay -- nur lesen
NoFullSizeMode NoFullSizeMode --
NoOverlappingMode NoOverlappingMode --
TileHorizontally TileHorizontally --
TileVertically TileVertically --
SizeIndependentlyOfDisplays SizeIndependentlyOfDisplays --

Methoden:

Methode Aufgabe
TileDisplays Ordnet die Displays "aufgeteilt" an
SelectDisplay (n) Wählt ein Display als aktives Display aus

Eine typische Konfiguration einer DisplayGroup sieht so aus:

DisplayGroup DGroup
  children = Disp1, Disp2, Disp3
  initialSize = 800, 400
  defaultTarget
  fullSizeState = FALSE
  ExpandWidth
  ExpandHeight 
  SizeIndependentlyOfDisplays
End OBJECT


FullSizeState

Die Instancevariable fullSizeState enthält die Information, ob die Displays in der DisplayGroup überlappend (fullSizeState = FALSE) oder bildschirmfüllend (fullSizeState = TRUE) dargestellt werden. Sie können den Wert zur Laufzeit ändern um den entsprechenden Zustand einzustellen.

Um die Displays gleichmäßig in der DisplayGroup aufzuteilen verwenden Sie die Methode "TileDisplays" (siehe unten).


Syntax UI- Code: fullSizeState = FALSE 
                 Der Defaultwert ist TRUE
      Schreiben: <obj>.fullSizeState = TRUE | FALSE 
          Lesen: <numVar> = <obj>.fullSizeState

 

activeDisplay

Die Instancevariable activeDisplay enthält das aktuell aktive Displayobjekt. Ist kein Displayobjekt "aktiv" enthält activeDisplay das zuletzt aktive Displayobjekt. Sollte die DisplayGroup keine Displays enthalten so liefert activeDisplay ein Null-Objekt.
Syntax Lesen: <objVar> = <obj>.activeDisplay

 

NoFullSizeMode

NoFullSizeMode verhindert, dass die Displays in der DisplayGroup bildschirmfüllend angezeigt werden. Am Programmstart werden die Displays per Default trotzdem immer bildschirmfüllend angezeigt. Setzen Sie daher im UI-Code zusätzlich die Instancevariable fullSizeState auf FALSE.
Syntax UI-Code: NoFullSizeMode

 

NoOverlappingMode

NoOverlappingMode verhindert, dass die Displays in der DisplayGroup überlappend angezeigt werden.
Syntax UI-Code: NoOverlappingMode

 

TileDisplays

Die Methode TileDisplays ordnet die Displays "aufgeteilt" an. Der Aufruf dieser Methode hat die gleiche Wirkung als ob der Nutzer im DisplayControl den Eintrag "Aufteilen" anklickt.
Syntax BASIC Code: <obj>.TileDisplays

 

TileHorizontally

TileHorizontally bewirkt, dass die Displays in der DisplayGroup nebeneinander angeordnet werden, wenn sie "aufgeteilt" werden. Um die Displays aufzuteilen kann der Nutzer im DisplayControl den entsprechenden Eintrag anklicken oder man ruft die Methode "TileDisplays" auf.
Syntax UI-Code: TileHorizontally

 

TileVertically

TileVertically bewirkt, dass die Displays in der DisplayGroup übereinander angeordnet werden, wenn sie "aufgeteilt" werden. Um die Displays aufzuteilen kann der Nutzer im DisplayControl den entsprechenden Eintrag anklicken oder man ruft die Methode "TileDisplays" auf.
Syntax UI-Code: TileVertically

 

SizeIndependentlyOfDisplays

Sowohl die Anordnung der Displays als auch die Größe der DisplayGroup werden zwischen Displays und DisplayGroup automatisch ausgehandelt. In einigen Situationen kann das dazu führen, dass die DisplayGroup nicht so aussieht, wie Sie sich das wünschen, z.B. dass sie zu klein ist, oder dass die Geometrie der Displays nicht stimmt. Verwenden Sie in diesen Fällen den Hint SizeIndependentlyOfDisplays um die Geometrie der DisplayGroup und die Geometrie der Displays voneinander zu entkoppeln.

Tipp: Setzen Sie diesen Hint immer. Nur wenn Sie den Eindruck haben, dass die Geometrie nicht stimmt versuchen Sie es ohne ihn.


Syntax UI-Code: SizeIndependentlyOfDisplays

 

SelectDisplay

SelectDisplay(n) wählt ein Display als aktives Display aus. Die Zählung beginnt dabei bei Null.

Tipp: Um herauszubekommen wie viele Displays zu einem DisplayGroup Objekt gehören fragen Sie die Instancevariable numChildren der DisplayGroup ab.


Syntax BASIC Code: <obj>.SelectDisplay (<Wert>)
            <Wert> Nummer des auszuwählenden Displays
                   Die Zählung beginnt bei Null.


^

4.18.4 DisplayControl

... Das DisplayControl stellt die UI bereit, mit der der Nutzer die Displays in der DisplayGroup anordnen kann. Außerdem enthält es eine Liste mit den Namen (Caption$) der Displays in der DisplayGroup. Wie im Bild zu sehen ist das DisplayControl üblicher Weise ein Child des "Fenster" Menüs.

Das DisplayControl arbeitet automatisch mit den Displays und der DisplayGroup zusammen. Das funktioniert sogar, wenn Sie mehrere DisplayGroup Objekte haben. Der Programmierer muss dazu nichts weiter tun als die Objekte in seinen Tree einbinden. Außerdem muss das DisplayGroup Objekt (falls Sie mehrere haben: genau eines) den Hint defaultTarget gesetzt haben. Abstammung:

...

Spezielle Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
dcFeatures dcFeatures = <Wert> lesen, schreiben
nameOnPrimaryIfMaximized nameOnPrimaryIfMaximized = TRUE lesen, schreiben


dcFeatures

DcFeatures bestimmt, welche Elemente der Controller-UI angezeigt werden. Per Default werden alle Elemente angezeigt.
Syntax UI-Code: dcFeatures = <Wert>
     Schreiben: <obj>.dcFeatures = <Wert> 
         Lesen: <numVar> = <obj>.dcFeatures

Folgende Werte sind für dcFeatures verfügbar:

Konstante Wert Bedeutung
DCF_OVERLAPP_FULL 4 Auswahl "Überlappend" / "Bildschirmfüllend" anzeigen
DCF_TILE 2 Schalter "Aufteilen" anzeigen
DCF_DISPLAY_LIST 1 Liste aller Displays anzeigen


NameOnPrimaryIfMaximized

Diese Instancevariable bestimmt, ob der Name des aktuell aktiven Displays in der Titelzeile des Primary-Objekts angezeigt werden soll.

  • Üblicher Weise wird die Instancevariable im UI-Code belegt.

  • Ändern Sie den Wert zur Laufzeit von TRUE auf FALSE während die Displays maximiert sind, so updated das DisplayControl die Titelzeile im Primary nicht mehr. Die Anzeige ist dann möglicherweise fehlerhaft oder veraltet.

  • Intern wird die Instancevariable Caption2$ des Primaryobjekts verwendet, um diese Funktion zu realisieren.

Syntax UI-Code: nameOnPrimaryIfMaximized = TRUE
                Der Defaultwert ist FALSE.
     Schreiben: <obj>.nameOnPrimaryIfMaximized = <Wert> 
         Lesen: <numVar> = <obj>.nameOnPrimaryIfMaximized

Beispiel. Beachten Sie, dass das DisplayControl keinen Verweis auf die Display-Group enthält. Das wird intern über die Target Hierarchie geregelt.
Menu WindowMenu
  Caption$ = "Fenster" , 0
  Children = DControl
End OBJECT

DisplayControl DControl
  nameOnPrimaryIfMaximized = TRUE
End OBJECT

^

Weiter...