5.3 VisGroup5.3.1 Ausgabe von Grafik 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:
Methoden:
Action-Handler-Typen:
Instance-Variablen und Methoden für SDK-Programmierer:
^5.3.1 Ausgabe von GrafikDie 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.
Methoden:
Action-Handler-Typen:
Kurzbeschreibung der InstancevariablenEine ausführliche Beschreibung finden Sie beim Canvas-Objekt, im Kapitel 4.16 des Objekthandbuchs.OnDrawDie 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.
defaultColorDie 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
bufferedDie 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.
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.
bufferedDataSizeIm 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:
clipDrawingDie 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:
DirtyDie 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 RedrawDie 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 Children5.3.2.1 Größe und PositionPer 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:
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:
customManageChildrenDie 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. visPositionDie 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:
visSizeDie 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, yPositionDiese Werte liefern die aktuelle Position des Objekts.
Syntax Lesen: <numVar> = <obj>.xPosition
<numVar> = <obj>.yPosition
xSize, ySizeDiese 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 überlappenIm 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 Children5.3.3.1 ÜberblickPer 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 FehlersuchePrinzipiell 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:
MarkInvalidDie 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ößeDie 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:
visSizeOptionsDie 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.
Im Detail haben die Werte die folgende Wirkung:
Hinweis: Ein Ändern des Wertes für visSizeOptions führt nicht automatisch zur Neudarstellung der Objekte. Dazu müssen Sie die Methode MarkInvalid aufrufen.
visSizeFlagsDie 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.
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:
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
visMinimumSizeDie 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 ChildrenPer 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:
visOrientVerticallyPer 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
visChildJustificationDie 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.
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.
Beispiele für visChildJustification. Beachten Sie, dass vorausgesetzt ist, dass das grau gezeichnete Parent-Objekt größer ist, als die Children erfordern.
Hinweise:
Beispiele mit visOrientVertically = TRUE:
visChildSpacingDie 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).
visSpacingIncludeEndsDiese 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
visMarginsMit 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 WrappingUnter 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:
Im Zusammenhang mit dem Children Wrapping kann es allerdings schnell zu widersprüchlichen Geometrie-Anweisungen kommen. Einige Beispiele:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
contentAttrs = \
CA_SAME_WIDTH_AS_VIEW + CA_SAME_HEIGHT_AS_VIEW, 0
visSizeFlags = VSF_EXPAND_WIDTH + VSF_EXPAND_HEIGHT
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Bitte beachten Sie die Beispiele. Dort finden Sie auch Tipps, wie man das Children Wrapping in verschiedenen Fällen konfiguriert. allowChildrenToWrapDiese 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. visWrapCountMit 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.
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
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
^ |