5.3 VisGroup

5.3.1 Ausgabe von Grafik

5.3.2 Manuelle Anordnung der Children

5.3.2.1 Größe und Position

5.3.2.2 Wenn sich die Children überlappen

5.3.3 Automatische Anordnung der Children
5.3.3.1 Überblick

5.3.3.2 Festlegen der Größe

5.3.3.3 Ausrichtung und Abstand der Children

5.3.3.4 Children Wrapping



Die VisGroup Class ist die Superclass für die VisContent und VisObj Class. Sie implementiert alle gemeinsamen Fähigkeiten dieser beiden Klassen. Dazu gehören im Wesentlichen die Ausgabe von Grafik und die Verwaltung von Children. Sie können in R-BASIC keine Objekte dieser Klasse anlegen.

Abstammung:

...

Spezielle Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
OnDraw OnDraw = <Handler> nur schreiben
defaultColor defaultColor = fg, bg lesen, schreiben
clipDrawing clipDrawing = TRUE lesen, schreiben
buffered buffered = TRUE lesen, schreiben
bufferedDataSize bufferedDataSize = <Wert> lesen, schreiben
customManageChildren customManageChildren = TRUE | FALSE lesen, schreiben
visPosition visPosition = xPos, yPos lesen, schreiben
visSize visSize = width, height lesen, schreiben
xPosition, yPosition -- nur lesen
xSize, ySize -- nur lesen
visSizeOptions visSizeOptions = <Wert> lesen, schreiben
visSizeFlags visSizeFlags = <Wert> lesen, schreiben
visMinimumSize visMinimumSize = minX, minY lesen, schreiben
visOrientVertically visOrientVertically = TRUE | FALSE lesen, schreiben
visChildJustification visChildJustification = jHor, jVert lesen, schreiben
visChildSpacing visChildSpacing = childSp, wrapSp lesen, schreiben
visSpacingIncludeEnds visSpacingIncludeEnds = TRUE | FALSE lesen, schreiben
visMargins visMargins = left, top, right, bottom lesen, schreiben
allowChildrenToWrap allowChildrenToWrap = TRUE | FALSE lesen, schreiben
visWrapCount visWrapCount = numWert lesen, schreiben


Methoden:

Methode Aufgabe
Dirty Weist das Objekt an, sich neu darzustellen, indem der OnDraw-Handler aufgerufen wird.
Redraw [TRUE] Weist das Objekt an, sich neu darzustellen.
MarkInvalid Berechnet die Geometrie neu und löst ein Neuzeichnen aus


Action-Handler-Typen:

Handler-Typ Parameter
DrawAction (sender as object, width, height as word)


Instance-Variablen und Methoden für SDK-Programmierer:

Variable/Methode Syntax im UI-Code Im BASIC-Code
visClassAttrs visClassAttrs = toSet, toClear lesen, schreiben
visCompGeoAttrs visCompGeoAttrs = toSet, toClear lesen, schreiben
visCompDimensionAttrs visCompDimensionAttrs = toSet, toClear lesen, schreiben
MarkInvalid2 -- (Methode) nur schreiben

^

5.3.1 Ausgabe von Grafik

Die primäre Aufgabe von VisualClass-Objekten ist die Ausgabe von Grafik auf den Bildschirm. VisContent-Objekte und VisObj-Objekte haben dazu einen OnDraw-Handler, der automatisch gerufen wird, wenn sich das Objekt auf dem Bildschirm neu darstellen muss. Alternativ können Sie in einem "gepufferten" Modus arbeiten. Dabei wird der OnDraw-Handler nur einmalig gerufen und die Grafik intern in einem GString gespeichert. Bei Bedarf wird diese dann ausgegeben. Das ist effizienter als der ständige Aufruf des in BASIC geschrieben OnDraw-Handlers, allerdings ist es weniger flexibel.

Eine ausführliche Beschreibung der dahinter stehenden Konzepte finden Sie beim Canvas-Objekt, im Kapitel 4.16 des Objekthandbuchs. Der einzige Unterschied zum Canvas ist, dass man bei VisContent und bei VisObj-Objekte einstellen kann, ob die Grafik an den eigenen Grenzen abgeschnitten wird (Clipping, Instancevariable clipDrawing), beim Canvas-Objekt jedoch nicht. Außerdem steht die Methode Redraw für Canvas-Objekte nicht zur Verfügung.

Beim Aufruf des OnDraw-Handlers wird das Objekt automatisch zum Screen, das heißt alle Grafikausgaben gehen an die Stelle, an der das Objekt dargestellt wird. Der Koordinatenursprung ist dabei immer die linke obere Ecke des Objekts. Die dem OnDraw-Handler übergebenen Parameter width und height enthalten die Breite und die Höhe des Objekts. Da die Koordinaten bei Null anfangen, ist die Maximale Koordinate, die noch innerhalb des Objekts liegt, jeweils um 1 kleiner. Die globalen Variablen MaxX und MaxY enthalten diese Werte.

Verfügbare Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
OnDraw OnDraw = <Handler> nur schreiben
defaultColor defaultColor = fg, bg lesen, schreiben
clipDrawing clipDrawing = TRUE lesen, schreiben
buffered buffered = TRUE lesen, schreiben
bufferedDataSize bufferedDataSize = <Wert> lesen, schreiben


Methoden:

Methode Aufgabe
Dirty Weist das Objekt an, sich neu darzustellen, indem der OnDraw-Handler aufgerufen wird.
Redraw [TRUE] Weist das Objekt an, sich neu darzustellen.


Action-Handler-Typen:

Handler-Typ Parameter
DrawAction (sender as object, width, height as word)


Kurzbeschreibung der Instancevariablen

Eine ausführliche Beschreibung finden Sie beim Canvas-Objekt, im Kapitel 4.16 des Objekthandbuchs.

OnDraw

Die Instance-Variable OnDraw enthält den Namen des Handlers, der die Grafik zeichnen soll. Dieser muss als DrawAction vereinbart sein.
Syntax UI-Code: OnDraw = <Handler> 
     Schreiben: <obj>.OnDraw = <Handler>

Die Parameter width und height enthalten die Breite und die Höhe des Objekts. Die globalen Variablen MaxX und MaxY enthalten die maximale Koordinate, die noch innerhalb des Objekts liegt. Sie ist jeweils um 1 kleiner als width bzw. height.

Weisen Sie zur Laufzeit einen neuen OnDraw-Handler zu, so stellt sich das Objekt automatisch neu dar. Beachten Sie, dass dabei der Hintergrund nicht gelöscht bzw. die bereits vorhandene Grafik nicht vom Schirm genommen wird.

defaultColor

Die Instance-Variable defaultColor enthält die Farben, die beim Aufruf des OnDraw Handlers eingestellt werden.
Syntax UI-Code: defaultColor = fg, bg  
            fg: Vordergrund (foreground)
            bg: Hintergrund (background)
                fg und bg müssen Indexfarben sein.
                RGB-Farben sind nicht zulässig.
         Lesen: <numVar> = <obj>.defaultColor (0)    ' fg
                <numVar> = <obj>.defaultColor (1)    ' bg
     Schreiben: <obj>.defaultColor = fg, bg 

 

buffered

Die Instancevariable buffered legt fest, ob das Objekt die anzuzeigende Grafik zwischenspeichert (buffered = TRUE, "gepufferter" Modus) oder nicht (buffered = FALSE, normaler Modus). FALSE ist der Defaultwert.
Syntax UI-Code: buffered = TRUE
     Schreiben: <obj>.buffered = TRUE | FALSE
         Lesen: <numVar> = <obj>.buffered

 
Achtung! Im gepufferten Modus zeichnet das Objekt seine Grafik sofort, ohne Umweg über den BASIC-Handler. Das geht deutlich schneller, hat aber Konsequenzen, wenn sich Objekte überlappen.

Solange alle Objekte, die sich überlappen, im gleichen Modus arbeiten, gibt es keine Probleme, die Objekte werden in der richtigen Reihenfolge gezeichnet.
Überlappen sich aber Objekte, von denen einige im gepufferten Modus und andere im normalen Modus arbeiten, so werden immer zuerst alle Objekte gezeichnet, die sich im gepufferten Modus befinden. Objekte im normalen Modus werden danach, also über den anderen Objekten gezeichnet, unabhängig davon, in welcher Reihenfolge sie als Children im UI-Code vereinbart sind. Das liegt daran, dass die BASIC-Handler der Objekte im normalen Modus erst ausgeführt werden, wenn die Objekte im gepufferten Modus fertig sind.

VisText-Objekte haben keine BASIC-OnDraw-Handler. Sie arbeiten intern quasi wie im gepufferten Modus. Wenn Sie also ein VisText-Objekt über ein VisObj-Objekt legen wollen, muss das VisObj im gepufferten Modus arbeiten, sonst wird es über dem VisText gezeichnet. Folglich muss auch ein VisContent, wenn es einen OnDraw-Handler hat, im gepufferten Modus arbeiten, falls es VisText-Objekte als Children hat.

bufferedDataSize

Im gepufferten Modus fordert das Objekt Speicher (in einer Datei) an, um die darzustellende Grafik zu speichern. BufferedDataSize enthält die Information, wie groß der benötigte Speicher ungefähr (!) ist. Der Wert ist nicht kritisch, der Defaultwert ist DS_TINY.
Syntax UI-Code: bufferedDataSize = <Wert> 
     Schreiben: <obj>.bufferedDataSize = <Wert> 
         Lesen: <numVar> = <obj>.bufferedDataSize 
        <Wert>: numerische Konstante, siehe aus der Tabelle unten

 
Die folgende Tabelle enthält die zulässigen Werte:

Konstante Wert Zu erwartende Datenmenge
DS_TINY 0 nicht mehr als 10 ... 20 kByte
DS_SMALL 1 nicht mehr als 50 ... 100 kByte
DS_MEDIUM 2 nicht mehr als 500 kByte ... 1 MB
DS_LARGE 3 nicht mehr als 5 MByte
DS_HUGE 4 möglicherweise mehr als 5 MByte


clipDrawing

Die Instance-Variable clipDrawing enthält die Information ob das Objekt über seine eigenen Grenzen (Bounds) hinausschreiben darf, oder nicht. Der Defaultwert ist FALSE, das heißt, das Objekt kann an beliebige Stellen auf den Schirm schreiben.
Syntax UI-Code: clipDrawing = TRUE | FALSE
         Lesen: <numVar> = <obj>.clipDrawing
     Schreiben: <obj>.clipDrawing = TRUE | FALSE

 
Hinweise:

  • Wenn Sie clipDrawing zur Laufzeit ändern, löst das kein Neuzeichnen des Objekts aus. Rufen Sie dazu eine der Methoden Redraw, Dirty oder MarkInvalid für das Objekt oder eines seiner Parents auf.

  • Weisen Sie clipDrawing= TRUE zur Laufzeit zu, so löscht das nicht die Grafiken, die über den Rand hinausgehen.

  • Sollten beim Verschieben des Objekts "Artefakte" zurückbleiben, haben sie über den Rand des Objekts geschrieben. Sie können das vermeiden, indem Sie clipDrawing im UI-Code auf TRUE setzen.


Dirty

Die Methode Dirty (engl: schmutzig) bewirkt, dass sich das Objekt neu darstellt, indem es seinen OnDraw Handler ruft. Die Dirty Methode arbeitet auch im gepufferten Modus. Das Objekt gibt die alte gepufferte Grafik automatisch frei und speichert die neue ab.
Syntax im BASIC Code: <obj>.Dirty

 

Redraw

Die Methode Redraw bewirkt, dass das Objekt sich neu auf den Bildschirm zeichnet. Im gepufferten Modus wird der gespeicherte GString neu ausgegeben, im ungepufferten Modus wird der OnDraw-Handler aufgerufen.
        Syntax: <obj>.Redraw [drawBackground]
drawBackground: TRUE | FALSE (Default: FALSE)

 
Beispiel:
  MyVisObj1.Redraw
  MyVisObj1.Redraw TRUE
DrawBackground = TRUE bewirkt, dass der Redraw-Befehl an das zugehörige View weitergeleitet wird. Damit wird zuerst der Hintergrund gelöscht und dann alle im View dargestellten Objekte neu gezeichnet. Je nach Komplexität der Darstellung und der Anzahl der Objekte kann das einen Moment dauern.

^

5.3.2 Manuelle Anordnung der Children

5.3.2.1 Größe und Position

Per Default verwaltet das GEOS-System die Anordnung und Größe der Objekte in einem visual Tree automatisch. Um die Children manuell zu positionieren, müssen Sie im VisContent-Objekt die Instancevariable customManageChildren auf TRUE setzen. Außerdem müssen Sie die Instancevariablen visPosition und visSize der VisObj-Objekte im visual Tree belegen.
Um die Größe des VisContent-Objekts festzulegen haben Sie neben dem Belegen der Instancevariablen visSize weitere Möglichkeiten, die im Kapitel 5.4.2 (View-Content Konfiguration) beschrieben sind.

Tipp:
Es ist meist komfortabler, zum Lesen der Werte von visPosition und visSize die für alle Objekte verfügbaren read-only Instancevariablen xPosition, yPosition, xSize bzw. ySize zu benutzen.

Im Ordner "Visual Class" finden Sie mehrere Beispiele zur Verwendung von customManageChildren, z.B. "VisObj privData Demo", "VisObj Keyboard Demo" und "Create Custom Managed VisObj".

Zugehörige Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
customManageChildren customManageChildren = TRUE | FALSE lesen, schreiben
visPosition visPosition = xPos, yPos lesen, schreiben
visSize visSize = width, height lesen, schreiben
xPosition, yPosition -- nur lesen
xSize, ySize -- nur lesen


customManageChildren

Die Instance-Variable customManageChildren legt fest, ob der Programmierer oder der Geometriemanager des GEOS-Systems die Anordnung der Children des Objekts steuert. Der Defaultwert für customManageChildren ist FALSE, d.h. der Geometriemanager des GEOS-Systems übernimmt die Anordnung der Children.
Sie müssen customManageChildren auf TRUE setzen, um die Anordnung der Children selbst zu kontrollieren.
Syntax UI-Code: customManageChildren = TRUE | FALSE
         Lesen: <numVar> = <obj>.customManageChildren
     Schreiben: <obj>.customManageChildren = TRUE | FALSE

Es ist möglich und zulässig, den Wert für customManageChildren in einem VisObj des visual Trees auf FALSE zu setzen, wenn im VisContent der Wert auf TRUE gesetzt ist - und umgekehrt. Das GEOS System versucht dann, Ihre Wünsche "so gut wie möglich" zu erfüllen. Ob die Ergebnisse dann Ihren Wünschen entsprechen, müssen Sie ausprobieren.

visPosition

Die Instance-Variable visPosition enthält die aktuelle Position des Objekts, relativ zu seinem VisContent.
Syntax UI-Code: visPosition = xPos, yPos 
          xPos: x-Position
          yPos: y-Position
         Lesen: <numVar> = <obj>.visPosition(0)    ' xPos
                <numVar> = <obj>.visPosition(1)    ' yPos
     Schreiben: <obj>.visPosition = xPos, yPos [, autoRedraw ]
    autoRedraw: FALSE (Default): keine sofortige Neudarstellung
                TRUE: sofortige Neudarstellung (Move-To-Funktion)

 
Per Default führt ein manuelles Verändern der visPosition nicht automatisch zum Neuzeichnen des Objekts an der neuen Position. Dazu müssen Sie die Methode MarkInvalid aufrufen.
Geben Sie als zusätzlichen Parameter TRUE an, so stellt sich das Objekt sofort neu dar, wobei Bereiche, die jetzt nicht mehr vor Objekt überdeckt sind, ebenfalls geupdatet werden. Sie verschieben das Objekt also sofort an seine neue Position.

Hinweise:

  • Im Allgemeinen werden auch andere Objekte neu gezeichnet, wenn Sie autoRedraw = TRUE angeben. Häufig flackert es jedoch weniger, als wenn Sie MarkInvalid für das zugehörige VisContent aufrufen. Im Zweifel hilft hier nur Probieren.

  • Sie sollten die visPosition-Werte für VisContent-Objekte nicht ändern. Das kann zu unerwarteten Ergebnissen, insbesondere einer Verschiebung der Position aller beteiligten Objekte führen.


visSize

Die Instance-Variable visSize enthält die aktuelle Größe des Objekts.
Syntax UI-Code: visSize = width, height 
         width: Breite
        height: Höhe
         Lesen: <numVar> = <obj>.visSize(0)    ' Breite
                <numVar> = <obj>.visSize(1)    ' Höhe
     Schreiben: <obj>.visSize = width, height [, autoRedraw ]
    autoRedraw: FALSE (Default): keine sofortige Neudarstellung
                TRUE: sofortige Neudarstellung

Per Default führt ein manuelles Verändern von visSize nicht automatisch zum Neuzeichnen des Objekts in der neuen Größe. Dazu müssen Sie die Methode MarkInvalid aufrufen.
Geben Sie als zusätzlichen Parameter TRUE an, so stellt sich das Objekt sofort neu dar, wobei Bereiche, die jetzt nicht mehr vor Objekt überdeckt sind, ebenfalls geupdatet werden. Beachten Sie, dass dabei im Allgemeinen auch andere Objekte neu gezeichnet werden.

xPosition, yPosition

Diese Werte liefern die aktuelle Position des Objekts.
Syntax Lesen: <numVar> = <obj>.xPosition 
              <numVar> = <obj>.yPosition

 

xSize, ySize

Diese Werte liefern die aktuelle Größe des Objekts in Pixeln.
Syntax Lesen: <numVar> = <obj>.xSize 
              <numVar> = <obj>.ySize

 

^

5.3.2.2 Wenn sich die Children überlappen

Im customManageChildren-Modus kommt es häufig vor, dass sich Objekte gegenseitig überlappen. Natürlich sollen in diesen Fällen die "oben" liegenden Objekt auch die Maus-Ereignisse erhalten. Deshalb zeichnet R-BASIC die Objekte in der entgegengesetzten Reihenfolge zu der, in der sie im UI-Code definiert wurden. GEOS gibt nämlich die Mausereignisse von Objekt zu Objekt weitergibt, und zwar in der Reihenfolge, in der sie im UI-Code vereinbart sind. Das zuerst vereinbarte Objekt bekommt das Mausereignis zuerst zu sehen. Damit es "oben" liegt, muss es also zuletzt gezeichnet werden.

Achtung! Wenn sich Objekte überlappen, von denen einige im gepufferten Modus und andere im normalen (ungepufferten) Modus arbeiten, ändert sich die Zeichenreihenfolge, nicht aber die Reihenfolge, in der sie Mausereignisse erhalten. Eine genauere Erläuterung dazu finden Sie weiter oben im Kapitel 5.3.1 (Ausgabe von Grafik) bei der Beschreibung der Instancevariablen buffered. Wir setzen daher im Folgenden voraus, dass alle Objekte im gleichen Modus arbeiten. VisText-Objekte zählen dabei als Objekte, die im gepufferten Modus arbeiten!

Nehmen wir an, wir haben ein VisContent mit 3 Children.

VisContent DemoContent
  Children = VisObj1, VisObj2, VisObj3
  customManageChildren = TRUE
  ...
End OBJECT
Größe und Position der Children seien so, dass sie sich überlappen. Da sie von R-BASIC in der "umgekehrten" Reihenfolge gezeichnet werden, kann sich z.B. folgendes Bild ergeben.

...

Damit bekommt jedes Objekt genau dann die Mausklicks zu sehen, wenn der Nutzer in den sichtbaren Bereich des Objekts klickt.

Natürlich können Sie auch hier Objekt-Trees verwenden. Allerdings müssen Sie wissen, dass Mausklicks immer vom den Parents an die Children weitergeleitet werden. Children, die ganz oder teilweise außerhalb ihrer Parents gezeichnet werden, erhalten in den außerhalb liegenden Bereichen keine Mausklicks. Sie müssen selbst dafür sorgen, das jedes Objekt vollständig innerhalb der Grenzen seines Parents dargestellt wird, sonst erhält es möglicherweise Mausklicks nicht oder nur teilweise.

Im folgenden Beispiel ist VisObj3 Child von VisObj 2. Im rot markierten Bereich leitet das Content die Mausklicks nicht an VisObj2 weiter. Deswegen erhält VisObj3 diesem Bereich auch keine Mausklicks.

...   ...

Ein schlechtes Beispiel. VisObj3 erhält als Child von VisObj2 im roten Bereich keine Mausklicks.

^

5.3.3 Automatische Anordnung der Children

5.3.3.1 Überblick

Per Default verwaltet das GEOS-System die Anordnung und Größe der Objekte in einem visual Tree automatisch. Dabei werden die Children nebeneinander (oder untereinander) mit einem vorgegebenen Abstand angeordnet. Sie kennen das von den Dateien im GeoManager oder von den Vorschaubildern im GrafikViewer Gonzo.

Solange der Geometriemanager die Größe und Position der Objekte im visual Tree verwaltet, müssen Sie keine Werte für die im letzten Kapitel besprochenen Instancevariablen visPosition und visSize angeben. Tun Sie es doch, wird der Geometriemanager die Werte überschreiben. Objekte, die keine Children haben, müssen allerdings ihre Größe kennen, so dass Sie hier visSize belegen müssen.

Ansonsten steuern Sie das Verhalten des Geometriemanagers, indem Sie die folgenden Instancevariablen belegen.

Mit Hilfe der Instancevariablen visSizeOptions und visSizeFlags können Sie, getrennt nach x- und y-Richtung, festlegen, ob das Objekt eine feste Größe hat, seine Größe dem Platzbedarf seiner Children anpasst oder sich an der Größe des parent-Objekts orientiert. Mit visMinimumSize können Sie für Objekte variabler Größe festlegen, dass das Objekt nicht beliebig klein werden kann, auch wenn die Children weniger Platz erfordern.

Mit den Instancevariablen visChildJustification und visOrientVertically können Sie die Ausrichtung der Children-Objekte festlegen. Sie können z.B. festlegen ob Sie nebeneinander oder übereinander angeordnet werden sollen, ob sie zentriert, linksbündig oder über die verfügbare Breite verteilt werden sollen, oder ob sie sich den Platz gleichberechtigt aufteilen sollen.

Die Instancevariablen visChildSpacing, visSpacingIncludeEnds und visMargins bestimmen den Platz zwischen benachbarten Objekten.

Schließlich erlauben AllowChildrenToWrap und visWrapCount, dass die Children einer neuen Reihe (oder Spalte) angeordnet werden, wenn der verfügbare Platz in die entsprechende Richtung nicht ausreicht.

Ändern Sie die in diesem Kapitel besprochenen Instancevariablen zur Laufzeit, so werden die Objekte und ihre Children nicht sofort an ihrer neuen Position bzw. in der neuen Größe gezeichnet. Dazu müssen Sie erst die Methode MarkInvalid aufrufen. Der Vorteil dieser Vorgehensweise ist, dass Sie mehrere Änderungen an der Geometrie Ihres visual Trees vornehmen können, ohne dass der Bildschirm mehrfach aktualisiert wird und so unnötig flackert.

Hinweis zur Fehlersuche

Prinzipiell sind die durch die genannten Instancevariablen gebotenen Möglichkeiten beliebig miteinander kombinierbar. Dabei kann es aber schnell passieren, dass Sie Forderungen stellen, die nicht gleichzeitig erfüllbar sind. Typische Probleme sind z.B., dass ein Children-Wrapping erfordert, dass das Objekt seine Größe selbst bestimmen kann oder dass eine horizontale Zentrierung der Children erfordert, dass das Objekt größer ist, als der von den Children selbst eingenommene Platz. Children-Wrapping und gleichzeitige Zentrierung der Objekte ist folglich zunächst auch nicht möglich.

Der Geometriemanager muss in diesen Fällen eine Entscheidung treffen - oftmals wird das Ergebnis nicht Ihren Vorstellungen entsprechen. Es übersteigt die Möglichkeiten dieses Handbuchs bei Weitem, alle denkbaren Fälle zu besprechen. Auf typische Fallen oder Besonderheiten wird an den entsprechenden Stellen eingegangen. Lassen Sie sich dadurch bitte nicht abschrecken, sondern versuchen Sie es einfach.

In vielen Fällen können Sie das Problem lösen, indem Sie ein oder mehrere weitere VisObj-Objekte zum Gruppieren der eigentlichen Objekte einsetzen. Im Kapitel Children Wrapping finden Sie ein Beispiel, wie das oben angesprochene Problem (Children-Wrapping + zentrieren) auf diese Weise gelöst werden kann. Ansonsten hilft nur systematisches Probieren. Und sehen Sie sich die Beispiele an.

Zugehörige Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
visSizeOptions visSizeOptions = <Wert> lesen, schreiben
visSizeFlags visSizeFlags = <Wert> lesen, schreiben
visMinimumSize visMinimumSize = minX, minY lesen, schreiben
visOrientVertically visOrientVertically = TRUE | FALSE lesen, schreiben
visChildJustification visChildJustification = jHor, jVert lesen, schreiben
visChildSpacing visChildSpacing = childSp, wrapSp lesen, schreiben
visSpacingIncludeEnds visSpacingIncludeEnds = TRUE | FALSE lesen, schreiben
visMargins visMargins = left, top, right, bottom lesen, schreiben
allowChildrenToWrap allowChildrenToWrap = TRUE | FALSE lesen, schreiben
visWrapCount visWrapCount = numWert lesen, schreiben


MarkInvalid

Die Methode MarkInvalid bewirkt ein Neuzeichnen des Objekts, wobei - im Gegensatz zu Redraw und Dirty - die Geometrie des visual Trees neu berechnet wird. Dadurch werden unter Umständen auch andere Objekte neu (z.B. an anderer Position) gezeichnet.
Syntax: <obj>.MarkInvalid

Sie müssen MarkInvalid aufrufen, wenn Sie die Geometrie des visual Tree geändert haben, z.B. nach dem Ändern der Instancevariablen visChildJustification oder visMargins. Wenn Sie die Geometrie von mehreren Objekten geändert haben ist es im Allgemeinen ausreichend, MarkInvalid für eins der betroffenen Objekte zu rufen.

Eine Neuberechnung der Geometrie des visual Tree erfolgt auch, wenn der Nutzer das zugehörige View zoomt oder scrollt. Falls Sie vergessen haben, MarkInvalid zu rufen, kann das zu scheinbar seltsamen Effekten führen.

^

5.3.3.2 Festlegen der Größe

Die Bestimmung der Größe eines Objekts ist ein elementares Problem bei der Berechnung des visual Trees. Mittels der Instancevariablen visSizeOptions und visSizeFlags steuern Sie, wie ein Objekt seine Größe berechnen soll. Außerdem können Sie mit visMinimumSize eine Mindestgröße für Objekte mit nicht fest vorgegebener Größe festlegen.

Um die Größe des VisContent-Objekts festzulegen haben Sie weitere Möglichkeiten, die im Kapitel zum VisContent-Objekt beschrieben sind.

Zugehörige Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
visSizeOptions visSizeOptions = <Wert> lesen, schreiben
visSizeFlags visSizeFlags = <Wert> lesen, schreiben
visMinimumSize visMinimumSize = minX, minY lesen, schreiben


visSizeOptions

Die Instancevariable visSizeOptions bestimmt, wie das Objekt seine Größe berechnet. Dieser Wert wird benötigt, wenn sich das Objekt auf dem Schirm darstellt oder wenn das Parent-Objekt seine Größe anhand der Größe seiner Children berechnet.
Syntax UI-Code: visSizeOptions = numWert 
         Lesen: <numVar> = <obj>.visSizeOptions
     Schreiben: <obj>.visSizeOptions = numWert

 
Für visSizeOptions stehen die folgenden Werte zur Verfügung. Der Defaultwert ist VSO_AUTO_SIZE.

Konstante Wert Kurzbeschreibung
VSO_AUTO_SIZE 0 Berechnungsmethode der Größe hängt von den Umständen ab
VSO_VARIABLE_SIZE 1 Objekt passt seine Größe selbständig an
VSO_FIXED_SIZE 2 Objekt hat eine feste Größe
VSO_FIXED_WIDTH 3 Objekt hat eine feste Breite
VSO_FIXED_HEIGHT 4 Objekt hat eine feste Höhe


Im Detail haben die Werte die folgende Wirkung:

VSO_AUTO_SIZE
Das Objekt berechnet seine Größe in Abhängigkeit davon, ob es Children hat, oder nicht. Dieses Verhalten ist für die meisten Situationen sinnvoll und deswegen der Defaultwert.

  1. Fall: Es existieren Children
    Das Objekt berechnet seine Größe so, dass alle Children umfasst werden. Außerdem werden eventuelle Randbedingungen berücksichtigt wie z.B.

    * Ein VisContent soll seine Größe an die Größe des View-Objekts anpassen (siehe Instancevariable contentAttrs)
    * Ein Objekt soll sich den Platz mit seinen Geschwistern gleichmäßig aufteilen oder seine Breite bzw. Höhe maximieren (siehe Instancevariable visSizeFlags)
    * Eventuell gesetzte visMargins
    * ...

    Sie müssen keinen Wert für visSize festlegen, das macht der Geometriemanager.

  2. Fall: Das Objekt hat keine Children
    In diesem Fall wird der in visSize festgelegte Wert benutzt. Sie müssen diesen Wert selbst festlegen.

VSO_VARIABLE_SIZE
Diesen Wert sollten Sie nutzen, wenn ein Objekt keine Children hat, seine Größe aber trotzdem entsprechend den bei VSO_AUTO_SIZE erwähnten Randbedingungen anpassen soll. Ein eventuell in visSize festgelegter Wert wird nicht benutzt.

VSO_FIXED_SIZE
Das Objekt hat eine feste Größe, die durch den in visSize eingestellten Wert bestimmt wird. Dieser Wert kann größer oder kleiner sein, als der von den Children des Objekts benötigte Platz. Die Children werden dann möglicherweise über den Rand des Objekts hinaus gezeichnet. Sie müssen einen Wert für visSize festlegen. Hinweis: Wenn Sie diesen Wert verwenden, funktioniert die automatische Anordnung der Children des Objekts in einigen Fällen nur eingeschränkt, da Sie dem Geometriemanager die Kontrolle entziehen. Versuchen Sie im Problemfall einen anderen Wert für visSizeOptions oder verwenden Sie den Modus mit customManageChildren = TRUE.

VSO_FIXED_WIDTH
Das Objekt hat eine feste Breite. Die Höhe wird entsprechend den bei VSO_AUTO_SIZE beschriebenen Bedingungen berechnet. Sie müssen einen Wert für visSize festlegen.

VSO_FIXED_HEIGHT
Das Objekt hat eine feste Höhe. Die Breite wird entsprechend den bei VSO_AUTO_SIZE beschriebenen Bedingungen berechnet. Sie müssen einen Wert für visSize festlegen.

Hinweis: Ein Ändern des Wertes für visSizeOptions führt nicht automatisch zur Neudarstellung der Objekte. Dazu müssen Sie die Methode MarkInvalid aufrufen.

visSizeFlags

Die Instancevariable visSizeFlags enthält einzelne Bits, welche die Berechnung der Größe des Objekts beeinflussen.
Syntax UI-Code: visSizeFlags = Wert
         Lesen: <numVar> = <Obj>.visSizeFlags
     Schreiben: <Obj>.visSizeFlags = Wert

Für visSizeFlags stehen die folgenden Bits zur Verfügung. Bits, die nicht in der Tabelle aufgeführt sind, werden ignoriert.

Konstante Wert (hex) Dezimalwert
VSF_EXPAND_WIDTH &H20 32
VSF_DIVIDE_WIDTH_EQUALLY &H10 16
VSF_EXPAND_HEIGHT &H02 2
VSF_DIVIDE_HEIGHT_EQUALLY &H01 1

Per Default ist keins dieser Bits gesetzt.
Ein Ändern des Wertes zur Laufzeit löst noch kein Neuzeichnen der Objekte an ihrer neuen Position aus. Dazu müssen Sie die Methode MarkInvalid aufrufen.

Bedeutung der einzelnen Bits:

VSF_EXPAND_WIDTH
Bewirkt, dass sich das Objekt selbst so breit wie möglich macht. Damit kann es breiter werden, als es die Children erfordern, womit z.B. eine horizontale Zentrierung der Children (siehe Instancevariable visChildJustification) möglich wird.

VSF_DIVIDE_WIDTH_EQUALLY
Bewirkt, dass sich die Children des Objekts den verfügbaren Platz in der Breite gleichmäßig untereinander aufteilen. Dazu müssen alle Children dieses Bit ebenfalls gesetzt haben. Das Objekt selbst hat oftmals zusätzlich das Bit VSF_EXPAND_WIDTH gesetzt.

VSF_EXPAND_HEIGHT
Bewirkt, dass sich das Objekt selbst so hoch wie möglich macht. Damit kann es höher werden, als es die Children erfordern, womit z.B. eine vertikale Zentrierung der Children (siehe Instancevariable visChildJustification) möglich wird.

VSF_DIVIDE_HEIGHT_EQUALLY
Bewirkt, dass sich die Children des Objekts den verfügbaren Platz in der Höhe gleichmäßig unterinander aufteilen. Dazu müssen alle Children dieses Bit ebenfalls gesetzt haben. Das Objekt selbst hat oftmals zusätzlich das Bit VSF_EXPAND_HEIGHT gesetzt.
Hinweis: Die visSizeFlags-Bits sind wirkungslos, wenn das Objekt eine feste Größe hat, z.B. wenn das Objekt keine Children hat. Setzen Sie dann visSizeOptions auf VSO_VARIABLE_SIZE, um eine variable Größe zu erzwingen Beispiel

Drei Vis-Objekte sollen sich die Breite in einem View bzw. VisContent gleichmäßig aufteilen. Damit das funktioniert, müssen sowohl das VisContent als auch die VisObj-Objekte die Bits VSF_EXPAND_WIDTH und VSF_DIVIDE_ WIDTH_EQUALLY gesetzt haben.

Die VisObj-Objekte haben keine Children und würden deshalb eine feste Größe haben. Das muss in x-Richtung, aber nicht in y-Richtung geändert werden. Deswegen bekommen Sie einen Wert für visSize und visSizeOptions wird auf den Wert VSO_FIXED_HEIGHT gesetzt, wodurch die Breite variabel wird.

Den kompletten Code finden Sie im Beispiel "ExpandWidth Demo".

VisContent DemoContent
  Children = VisObj1, VisObj2, VisObj3

  visSizeFlags = \
  VSF_EXPAND_WIDTH +VSF_EXPAND_HEIGHT + VSF_DIVIDE_WIDTH_EQUALLY
  ...
End OBJECT

VisObj VisObj1
  visSize = 60, 40
  OnDraw = VisObjDraw
  visSizeFlags = VSF_EXPAND_WIDTH + VSF_DIVIDE_WIDTH_EQUALLY
  visSizeOptions = VSO_FIXED_HEIGHT
End OBJECT


visMinimumSize

Die Instancevariable visMinimumSize enthält die minimale Größe des Objekts, getrennt nach x- und y-Richtung. Objekte, die ihre Größe verändern können, können nicht kleiner werden, als in visMinimumSize angegeben. Für Objekte mit einer festen Größe wird visMinimumSize ignoriert. Die Default-Werte für beide Werte sind 0, d.h. das Objekt hat keine minimale Größe. Beide Werte werden in Pixeln angegeben.
Syntax UI-Code: visMinimumSize = minWidth, minHeight   
     mindWidth: minimale Breite
     minHeight: minimale Höhe
         Lesen: <numVar> = <obj>.visMinimumSize (0)   ' minWidth
                <numVar> = <obj>.visMinimumSize (1)   ' minHeight
     Schreiben: <obj>.visMinimumSize = minWidth, minHeight

 
Ändern Sie visMinimumSize zur Laufzeit, so wird das Objekt und seine Children nicht sofort an ihrer neuen Position bzw. in der neuen Größe gezeichnet. Dazu müssen Sie erst die Methode MarkInvalid aufrufen.

^

5.3.3.3 Ausrichtung und Abstand der Children

Per Default werden die Children eines VisObj oder VisContent-Objekts linksbündig, oben und mit 3 Pixeln Abstand voneinander angeordnet. Mit den in diesem Kapitel besprochenen Instancevariablen können Sie dieses Verhalten in weiten Grenzen ändern.

Zugehörige Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
visOrientVertically visOrientVertically = TRUE | FALSE lesen, schreiben
visChildJustification visChildJustification = jHor, jVert lesen, schreiben
visChildSpacing visChildSpacing = childSp, wrapSp lesen, schreiben
visSpacingIncludeEnds visSpacingIncludeEnds = TRUE | FALSE lesen, schreiben
visMargins visMargins = left, top, right, bottom lesen, schreiben


visOrientVertically

Per Default werden die Children eines VisObj bzw. VisContent nebeneinander angeordnet. Setzen Sie die Instancevariable visOrientVertically auf TRUE, wenn Sie die Children untereinander anordnen möchten.
Syntax UI-Code: visOrientVertically = TRUE | FALSE
         Lesen: <numVar> = <;Obj>.visOrientVertically
     Schreiben: <Obj>.visOrientVertically = TRUE | FALSE

 

visChildJustification

Die Instancevariable visChildJustification enthält die Information, wie die Children des Objekts in horizontaler und vertikaler Richtung ausgerichtet sind.
Syntax UI-Code: visChildJustification = jHor, jVert
         Lesen: <numVar> = <Obj>.visChildJustification (0)  ' jHor
                <numVar> = <Obj>.visChildJustification (1)  ' jVert
     Schreiben: <Obj>.visChildJustification = jHor, jVert
          jHor: horizontale Ausrichtung, siehe Tabelle
         jVert: vertikale Ausrichtung, siehe Tabelle

 
Prinzipiell können Sie die Werte für die horizontale Ausrichtung jHor und die vertikale Ausrichtung jVert beliebig kombinieren. Beachten Sie aber, dass die Randbedingungen für die gewählte Ausrichtung auch stimmen müssen. So muss z.B. für eine horizontale Zentrierung der Children das Objekt selbst breiter sein, als der Platz, den die Children sowieso benötigen. Es ergibt auch keinen Sinn jVert auf J_FULL zu setzen (gleichmäßig über die ganze Höhe verteilt), wenn alle Children nebeneinander angeordnet sind.

Für die horizontale Ausrichtung jHor stehen die folgenden Werte zur Verfügung. Andere Werte führen zu einem Fehler. Der Defaultwert für jHor ist J_LEFT.

Konstante Wert Anordnung der Children
J_LEFT 2 linksbündig
J_RIGHT 4 rechtsbündig
J_CENTER 1 horizontal zentriert
J_FULL 32 horizontal über die ganze Breite verteilt

Für die vertikale Ausrichtung jVert stehen die folgenden Werte zur Verfügung. Andere Werte führen zu einem Fehler. Der Defaultwert für jVert ist J_TOP.

Konstante Wert Anordnung der Children
J_TOP 8 oben bündig
J_BOTTOM 16 unten bündig
J_CENTER 1 vertikal zentriert
J_FULL 32 vertikal über die ganze Höhe verteilt

Beispiele für visChildJustification. Beachten Sie, dass vorausgesetzt ist, dass das grau gezeichnete Parent-Objekt größer ist, als die Children erfordern.

... ...
visChildJustification = J_JEFT, J_TOP (Defaultwert) visChildJustification = J_FULL, J_TOP

...
visChildJustification = J_CENTER, J_CENTER

Hinweise:

  • Um den Abstand zwischen den Children zu verändern, verwenden Sie bitte visChildSpacing.

  • Um Platz zwischen den Children und dem Rand zu lassen, verwenden Sie bitte visMargins.

  • Um die Children untereinander anzuordnen, setzen Sie die Instancevariable visOrientVertically auf den Wert TRUE.

  • Wenn Sie den Wert von visChildJustification zur Laufzeit ändern, führt das nicht zum sofortigen neu Ausrichten der Objekte. Rufen Sie dazu die Methode MarkInvalid auf.


Beispiele mit visOrientVertically = TRUE:

...   ...   ...
Bild 1 Bild 2 Bild 3
 

Bild 1: visChildJustification = J_LEFT, J_BOTTOM
 
Bild 2: visChildJustification = J_RIGHT, J_FULL
visSpacingIncludeEnds = TRUE

 
Bild 3: visChildJustification = J_RIGHT, J_FULL
visMargins = 5, 5, 5, 5

Child 2 hat zusätzlich folgende Instancevariablen gesetzt:
visSizeFlags = VSF_EXPAND_WIDTH + VSF_EXPAND_HEIGHT
visSizeOptions = VSO_VARIABLE_SIZE



visChildSpacing

Die Instancevariable visChildSpacing bestimmt den Abstand zwischen benachbarten Children des Objekts. Der erste Wert (childSpacing) enthält den Abstand zwischen aufeinanderfolgenden (i.a. nebeneinander liegenden) Children, der zweite Wert (wrapSpacing) enthält den vertikalen Abstand zwischen aufeinanderfolgenden "Zeilen" von Children. Dazu muss die automatische Anordnung in mehreren Zeilen (Wrapping, Instancevariable allowChildrenToWrap, Siehe Kapitel 5.3.3.4) aktiv sein.

Die Default-Werte für childSpacing und wrapSpacing sind 3. Beide Werte werden in Pixeln angegeben.


Syntax UI-Code: visChildSpacing = childSpacing, wrapSpacing   
  childSpacing: Abstand "benachbarter" Children
   wrapSpacing: Abstand "umgebrochener" Children
         Lesen: <numVar> = <obj>.visChildSpacing (0) 
                <numVar> = <obj>.visChildSpacing (1) 
     Schreiben: <obj>.visChildSpacing = childSpacing, wrapSpacing

 
Ändern Sie visChildSpacing zur Laufzeit, so werden die Children-Objekte nicht sofort an ihrer neuen Position gezeichnet. Dazu müssen Sie erst die Methode MarkInvalid aufrufen.

Achtung! Sind die Children untereinander angeordnet (siehe Instancevariable visOrientVertically), so enthält childSpacing immer noch den Abstand aufeinander folgender Children, also den vertikalen Abstand. WrapSpacing beschreibt wiederum den Wrapping-Abstand, jetzt also den horizontalen Abstand.

...   ...

Unterschied zwischen childSpacing und wrapSpacing bei horizontaler (Bild 1) und bei vertikaler Anordnung der Children (Bild 2).

visSpacingIncludeEnds

Diese Instancevariable bewirkt, wenn sie auf TRUE gesetzt ist, dass bei der Berechnung der Geometrie zusätzlicher Platz neben (bzw. bei vertikaler Anordnung über oder unter) den Children berücksichtigt wird. Der Defaultwert für visSpacingIncludeEnds ist FALSE.
Syntax UI-Code: visSpacingIncludeEnds = TRUE | FALSE
         Lesen: <numVar> = <obj>.visSpacingIncludeEnds 
     Schreiben: <obj>.visSpacingIncludeEnds = TRUE | FALSE

 
Ändern Sie visSpacingIncludeEnds zur Laufzeit, so werden die Objekte nicht sofort neu angeordnet. Dazu müssen Sie erst die Methode MarkInvalid aufrufen.

Beispiel: Wirkung von visSpacingIncludeEnds bei horizontaler Anordnung  

... ...
visChildJustification = J_FULL, J_TOP
visSpacingIncludeEnds = FALSE
visChildJustification = J_FULL, J_TOP
visSpacingIncludeEnds = TRUE


visMargins

Mit visMargins können Sie einen zusätzlichen Rand um die Children des Objekts reservieren.

...

Die Default-Werte für alle visMargins-Werte sind 0. Alle Werte werden in Pixeln angegeben.


Syntax UI-Code: visMargins = left, top, right, bottom 
          left: linker Rand
           top: oberer Rand
         right: rechter Rand
        bottom: unterer Rand
         Lesen: <numVar> = <obj>.visMargins (0)     ' left
                <numVar> = <obj>.visMargins (1)     ' top
                <numVar> = <obj>.visMargins (2)     ' right
                <numVar> = <obj>.visMargins (3)     ' bottom
     Schreiben: <obj>.visMargins = left, top, right, bottom

 
Ändern Sie visMargins zur Laufzeit, so werden die Children-Objekte nicht sofort an ihrer neuen Position gezeichnet. Dazu müssen Sie erst die Methode MarkInvalid aufrufen.

^

5.3.3.4 Children Wrapping

Unter Wrapping versteht man, dass Objekte automatisch ein einer neuen Zeile oder Spalte angeordnet werden, wenn der Platz nicht mehr ausreicht.
Ist ein Wrapping nicht möglich bzw. nicht erlaubt, so werden die Child-Objekte über die Grenzen ihres Parent-Objekts hinaus angeordnet.

Zugehörige Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
allowChildrenToWrap allowChildrenToWrap = TRUE | FALSE lesen, schreiben
visWrapCount visWrapCount = numWert lesen, schreiben

Im Zusammenhang mit dem Children Wrapping kann es allerdings schnell zu widersprüchlichen Geometrie-Anweisungen kommen. Einige Beispiele:

  • Children-Wrapping erfordert, dass das Parent-Objekt in seiner Größe begrenzt ist. Für VisContent-Objekte ist es deswegen meist erforderlich, die folgenden Instancevariablen zu setzen:
  contentAttrs = \
        CA_SAME_WIDTH_AS_VIEW + CA_SAME_HEIGHT_AS_VIEW, 0
  visSizeFlags = VSF_EXPAND_WIDTH + VSF_EXPAND_HEIGHT
  • Wenn das Wrapping erlaubt ist (allowChildrenToWrap = TRUE) werden horizontal angeordnete Children immer am oberen Rand ausgerichtet - sonst ist unten kein Platz für die nächste Zeile. Anderslautende Einstellungen in der Instancevariablen visChildJustification werden ignoriert. Analog werden vertikal ausgerichtete Children immer links ausgerichtet. Das bedeutet zum Beispiel, dass mit
        visChildJustification = J_CENTER, J_CENTER
    
    die Children nur in eine Richtung zentriert werden.
    Unten finden Sie ein Beispiel, wie man dieses Problem umgehen kann.

  • Hat das Objekt (VisContent oder VisObj) in eine Richtung eine feste Größe (Instancevariable visSizeOptions = VSO_FIXED_WIDTH bzw. ..._HEIGHT), so wird die Größe in die andere Richtung oft nicht korrekt berechnet. Das muss kein Problem sein, da es erlaubt ist, dass sich Children außerhalb der Grenzen ihres Parent-Objekts befinden.

  • Hat das Objekt (VisContent oder VisObj) in beiden Richtungen eine feste Größe (Instancevariable visSizeOptions = VSO_FIXED_SIZE), so wird der Parameter wrapSpacing der Instancevariablen visChildSpacing anders interpretiert. Er beschreibt nicht mehr den Platz zwischen den Objekten sondern bezieht die Größe des darüber bzw. links liegende Objekts mit ein.
Es übersteigt die Möglichkeiten dieses Handbuchs bei Weitem, alle denkbaren Fälle zu besprechen. Für den Fall, dass die Children nicht so angeordnet werden, wie Sie sich das vorstellen, hilft meist nur systematisches Probieren.
Bitte beachten Sie die Beispiele. Dort finden Sie auch Tipps, wie man das Children Wrapping in verschiedenen Fällen konfiguriert.

allowChildrenToWrap

Diese Instancevariable erlaubt, wenn sie auf TRUE gesetzt ist, dass die Children des Objekts "umgebrochen", d.h. in einer neuen Zeile bzw. Spalte dargestellt werden, wenn das Objekt zu klein ist, um alle Children in einer Reihe darzustellen. Wenn die Children horizontal dargestellt werden wird eine neue Zeile eröffnet, werden sie vertikal dargestellt, so wird eine neue Spalte eröffnet.
Der Defaultwert für allowChildrenToWrap ist FALSE.
Syntax UI-Code: allowChildrenToWrap = TRUE | FALSE
         Lesen: <numVar> = <obj>.allowChildrenToWrap 
     Schreiben: <obj>.allowChildrenToWrap = TRUE | FALSE

Ändern Sie allowChildrenToWrap zur Laufzeit, so werden die Objekte nicht sofort neu angeordnet. Dazu müssen Sie erst die Methode MarkInvalid aufrufen.

visWrapCount

Mit der Instancevariablen visWrapCount legen Sie fest, dass der Children-Umbruch (Wrapping) nach einer bestimmten Anzahl von Children erzwungen wird.
Der Defaultwert für visWrapCount ist Null, d.h. es erfolgt kein erzwungenes Wrapping.
Syntax UI-Code: visWrapCount = value
         value: Anzahl Children, nach denen umgebrochen wird
         Lesen: <numVar> = <obj>.visWrapCount 
     Schreiben: <obj>.visWrapCount = value

 
Es gibt zwei Voraussetzungen, dass visWrapCount funktioniert.

  1. Das Wrapping muss erlaubt sein, d.h. die Instancevariable allowChildrenToWrap muss auf TRUE gesetzt sein. Das ist per Default nicht der Fall!

  2. Das Objekt muss in die entsprechende Richtung eine variable Größe haben. Das ist per Default der Fall.
    Setzen Sie jedoch bei horizontal angeordneten Children z.B. visSizeOptions = VSO_FIXED_WIDTH, so hat das Objekt eine vorgegebene Größe und visWrapCount kann nicht funktionieren.
Ändern Sie visWrapCount zur Laufzeit, so werden die Objekte nicht sofort neu angeordnet. Dazu müssen Sie erst die Methode MarkInvalid aufrufen.

Beispiel: Sie möchten 4 Vis-Objekte im Quadrat zentriert in einem View darstellen. VisWrapCount und visChildJustification = J_CENTER funktionieren jedoch nicht gemeinsam, so dass Sie ein weiteres Objekt als Grouping-Objekt für die VisObj-Objekte verwenden müssen. Den kompletten Code finden Sie im Beispiel "Wrap und Center"

VisContent DemoContent
  Children = VisGroupObj
  visChildJustification = J_CENTER, J_CENTER
    ...
End OBJECT

VisObj VisGroupObj
  Children = VisObj1, VisObj2, VisObj3, VisObj4
  allowChildrenToWrap = TRUE
  visWrapCount = 2
  ...
End OBJECT

^

Weiter...