3.3 Geometriemanagement3.3.1 Überblick ^3.3.1 ÜberblickDie vernünftige Positionierung der UI-Objekte auf dem Schirm ist eine der aufwändigsten Aufgaben in einer grafischen Programmierumgebung. Der Einsteiger wird annehmen, dass es zweckmäßig sei, für jedes Objekt die Position und Größe explizit anzugeben. Auch wenn dies unter GEOS möglich ist, so ist es für generische Objekte jedoch eine sehr schlechte Idee. Neben dem hohen damit verbundenen Aufwand kommt es schnell zu unschönen Resultaten, wenn der User eine andere Bildschirmauflösung, einen anderen Textfont oder Größe für den Standard-Menü-Text in der GEOS.INI eingestellt hat. Die folgenden Bilder zeigen einige schlechte Beispiele.
Im linken Bild haben der Text und der Button rechts oben eine feste Position, das Primary-Objekt wurde jedoch mit der Maus 'zu klein' eingestellt. Das rechte Bild zeigt manuell deutlich fehlplatzierte Objekte.
Diese Bilder demonstrieren die Wirkung einer festen Größe in Pixel für die oberen Buttons. Im rechten Bild wurde eine vergrößerte Systemschrift verwendet. Die Lösung für diese Probleme heißt GEOS-Geometrie-Manager. Der Geometriemanager berechnet automatisch die Größe und Position der Objekte, so dass sie vollständig und vernünftig auf dem Schirm angeordnet werden. Das passiert zur Laufzeit des Programms, so dass unterschiedliche Textfonts und Größen, sowie andere Randbedingungen automatisch berücksichtigt werden. Anstatt festzulegen, wo sich die Objekte befinden sollen und wie groß sie sind, geben Sie dem Geometriemanager nur Hilfen der Form 'Ordne die Objekte nebeneinander an', 'Mache das Objekt so breit wie möglich', 'Zentriere die Objekte horizontal' usw. Dieses Konzept erfordert anfangs etwas Eingewöhnung, aber Sie werden schnell merken, dass es sehr systematisch und intuitiv zu benutzen ist. Sehr hilfreich ist es dabei, die Objekte in Gruppen anzuordnen und die Positionierung der Objekte innerhalb dieser Gruppen auszuführen.
Diese Anwendung beispielsweise besteht aus einer Group (rot, oben) und einer Replybar (unten), die vertikal (untereinander) angeordnet sind. Die rot markierte Gruppe besteht aus einem Text-Objekt und einer weiteren Group, hier blau markiert. Beide Objekte sind horizontal angeordnet. Die rechte (blaue) Group enthält letztlich die Action-Buttons, die untereinander angeordnet sind. Sollte Sie z.B. die Aufschrift des zweiten Buttons verändern, so dass er breiter wird, dann wird der Geometriemanager automatisch alle betroffenen Objekte (beide Group's, das Hauptfenster und die ReplyBar) verbreitern. Eine explizite Größenangabe ist da nur störend. Anweisungen an den Geometriemanager sind als 'Hints' - das heißt 'Hilfen' - für den Geometriemanager organisiert. Das bedeutet, Sie zwingen den Geometriemanager nicht, etwas zu tun, sondern Sie bitten ihn. Der Geometriemanager wird versuchen, Ihre Anweisungen so gut wie möglich umzusetzen. Manchmal kann ihm das jedoch nicht gelingen. Beispielsweise könnten Sie widersprüchliche Forderungen aufgestellt haben. Das ist einer der häufigsten Fehler bei diesem Konzept. Es kann aber auch sein, dass bestimmte Objekte einige Eigenschaften oder Fähigkeiten einfach nicht unterstützen. So ist es bei Buttons nicht möglich, die Aufschrift (Caption$) oberhalb des Buttons anzuordnen, die meisten anderen Objekte unterstützen dies aber. Oder Primary-Objekte (die Hauptfenster eines Programms) ignorieren die Vorgabe einer festen Größe mit 'fixedSize', aber sie akzeptieren 'WindowSizeFromParent'. Gelegentlich kann es daher etwas mit Probieren verbunden sein, den Geometriemanager zu überreden, das zu tun, was man will. Die Organisation der Geometrie-Eigenschaften als 'Hints' hat noch eine andere Konsequenz. Jede Eigenschaft, die Sie vorgeben, kostet einige (wenige) Bytes. Eigenschaften, die nicht explizit angegeben werden, sind auch nicht im Objekt gespeichert. Der Geometriemanager nimmt dann den für das Objekt gültigen Vorgabewert. So ordnen Groups ihre Children untereinander linksbündig an, wenn kein Wert für 'orientChildren' und 'justifyChildren' vorgegeben wird. Intern ist das so organisiert, dass den eigentlichen Objekt-Daten (Instance-Daten) eine Tabelle variabler Länge folgt, in die die Geometrie-Instance-Daten (Geometrie-Hints) abgelegt sind.
Wird z.B. kein Eintrag für 'fixedSize' vorgenommen, so sind die entsprechenden Daten einfach nicht da, das Objekt kommt gar nicht auf die Idee, sich eine feste Größe zu leisten.
Bei vielen der Geometrie-Instance-Daten kann man auch abfragen, ob die Daten präsent sind oder nicht.
3.3.2 Angabe von Größen, Positionen und AbständenGrößen, Positionen oder Abstände werden häufig in Pixeln angegeben. Manchmal ist das aber gar nicht sinnvoll, es ist z.B. oft viel besser zu sagen 'Mache den Text 5 Textzeilen hoch'. Um so etwas zu kennzeichnen wird zum eigentlichen Zahlenwert (hier 5) eine große Konstante addiert, so dass GEOS weiß, das nicht Pixel sondern Textzeilen gemeint sind. Dabei stehen die folgenden Werte zur Verfügung:
ST_PIXELS
ST_AVG_CHAR_WIDTH
ST_MAX_CHAR_WIDTH
ST_LINES_OF_TEXT
ST_PCT_OF_SCREEN_WIDTH
ST_PCT_OF_SCREEN_HEIGHT
Beispiel: feste Größe für ein Textobjekt vorgeben | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Memo MyText
fixedSize = 45 + ST_AVG_CHAR_WIDTH, 8 + ST_LINES_OF_TEXT
<.. weitere Instance-Variablen.. >
END object
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Hinweis: Für Fenster-Objekte (Primary, Dialog, Display) gibt es spezielle Hints zum Festlegen der Größe, die sogenannten Window-Hints. Sie sind im Kapitel 3.3.7 beschrieben.
^3.3.3 Anordnung der ObjekteDie Anweisungen zum Anordnen der Objekte sind die wohl am häufigsten genutzten Anweisungen im Geometriemanagement. Dabei wird dem Parent-Objekt mitgeteilt, wie es seine Children zu organisieren hat. Sie können z.B. festlegen ob die Children neben oder untereinander angeordnet werden und wie sie ausgerichtet werden sollen (linksbündig, rechtsbündig, zentriert usw.). Die folgenden Hints stehen zur Verfügung:
^3.3.3.1 Orientierung und AusrichtungorientChildrenOrientChildren legt fest, ob die Children-Objekte nebeneinander oder untereinander angeordnet werden.
Syntax UI- Code: orientChildren = numWert
Lesen: <numVar> = <obj> . orientChildren
Schreiben: <obj>.orientChildren = numWert
Dabei stehen folgende Konstanten zur Verfügung. Sie können jeweils nur eine Konstante angeben, eine Kombination (mit +) ist nicht zulässig.
justifyChildrenJustifyChildren legt fest, wie die Children-Objekt relativ zueinander angeordnet werden.
Syntax UI-Code: justifyChildren = numWert
Lesen: <numVar> = <obj> . justifyChildren
Schreiben: <obj>.justifyChildren = numWert
Dabei stehen folgende Konstanten zur Verfügung. Sie können mehrere Konstanten kombinieren (mit +), solange dies sinnvoll ist. Ungültige Werte werden ignoriert, bei widersprüchlichen Werten entscheidet der Geometriemanager.
J_FULL_H, J_FULL_V
J_CENTER_ON_CAPTION, J_CENTER_ON_CAPTION_LEFT
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Group TopGroup
Children = Text1, Text2, Text3
orientChildren = ORIENT_VERTICALLY
justifyChildren = J_CENTER_ON_CAPTION
END Object
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Im rechten Bild dagegen ist: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
justifyChildren = J_CENTER_ON_CAPTION_LEFT
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
J_CENTER, J_FULL
Beispiele für ausgerichtete ObjekteWir verwenden folgende Buttons: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Button RomanButton
Caption$ = "Roman"
END Object
Button SansButton
Caption$ = "Sans-Serif"
END Object
Button MonoButton
Caption$ = "Mono"
END Object
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Gruppen zur Ausrichtung der Objekte
3.3.3.2 Child SpacingNormalerweise legt der Geometriemanager die Abstände zwischen benachbarten Objekten fest. Sie können durch das Setzen bestimmter Geometrie-Hints auf diesen Prozess Einfluss nehmen.childSpacingChildSpacing (engl. space: Platz, Abstand) legt einen Wert für den Abstand zwischen benachbarten Children fest. Üblicherweise wird der Wert in Pixeln angegeben, Sie können aber auch die Werte ST_AVG_CHAR_WIDTH, ST_MAX_CHAR_WIDTH bzw. ST_LINES_OF_TEXT verwenden (Details dazu siehe Kapitel 3.3.2). Per Default ist kein childSpacing Wert gesetzt.
Syntax UI-Code: childSpacing = numWert
Lesen: <numVar> = <obj> . childSpacing
Schreiben: <obj>.childSpacing = numWert
Spezialfall: numWert = -1: Löschen eines vorher gesetzten
childSpacing Hints aus den Objekt-Daten
MinimizeChildSpacingMinimizeChildSpacing weist den Geometriemanager an, die Children so eng wie möglich anzuordnen, auch wenn das bedeutet, dass sie sich berühren.Syntax UI-Code: MinimizeChildSpacing Beispiel
Eine Group mit 3 Buttons. Links normal, Rechts mit MinimizeChildSpacing.
IncludeEndsInChildSpacingIncludeEndsInChildSpacing bewirkt, dass der Platz links und rechts der Children bei der Positionsberechnung berücksichtigt wird, das linke Child also nicht ganz an den Rand gesetzt wird.Syntax UI-Code: IncludeEndsInChildSpacing Beispiel Verschiedene Varianten von childSpacing-Werten | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
^3.3.3.3 Automatischer UmbruchwrapAfterChildStandardmäßig ordnen alle Groups, deren Children nebeneinander angeordnet sind (dazu zählen auch Reply Bars), alle Children in einer Reihe an. Der Hint wrapAfterChild erlaubt es, die Children in mehreren Reihen anzuordnen. Damit dies ordentlich funktioniert ist es oft nötig, der Group und ggf. ihren Parents auch den Hint ExpandWidth zu geben.
Syntax UI-Code: wrapAfterChild = numWert
Lesen: <numVar> = <obj>. wrapAfterChild
Schreiben: <obj>.wrapAfterChild = numWert
numWert = - 1: Automatischer Modus
numWert = 0: Hint aus Objektdaten löschen
numWert = 1 .. N : Umbrechen nach N Children
Automatischer Modus: Es werden so viele Children nebeneinander angeordnet, wie Platz ist. Gegebenenfalls werden weitere Reihen eröffnet. Umbrechen nach N Children:
Hinweis: Der Hint ist nicht auf Primaries, DisplayGroups und Displays anwendbar. Verwenden Sie ggf. eine Group als Zwischenobjekt. Beispiel UI- Code: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Group AGroup
Caption$ = "Action:"
justifyCaption = J_TOP
Children = button1, button2, button3
orientChildren = orient_horizontally
wrapAfterChild = -1
ExpandWidth
END Object
Group AReplyBar
MakeReplyBar
Children = button4, button5, button6
wrapAfterChild = 1
END Object
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Nehmen wir an, die Groups befinden sich in einem Primary-Objekt. Zoomt man dieses erhält man die folgenden Bilder:
3.3.3.4 Vorhandenen Platz gleichmäßig verteilenDivideWidthEquallyDieser Hint legt fest, dass sich die Children die vorhandene Breite gleichmäßig untereinander aufteilen sollen. Damit das funktioniert, müssen alle Children den Hint ExpandWidth gesetzt haben. Auch das Objekt selber sollte ExpandWidth gesetzt haben.Syntax UI-Code: DivideWidthEqually DivideHeightEquallyDieser Hint legt fest, dass sich die Children die Höhe gleichmäßig untereinander aufteilen sollen. Damit das funktioniert, müssen alle Children den Hint ExpandHeight gesetzt haben. Auch das Objekt selber sollte ExpandHeight gesetzt haben.Syntax UI-Code: DivideHeightEqually Beispiel:
Die Group befinde sich in einem größenveränderlichen Primary-Objekt. Im rechten Bild wurde nur die Breite des Primary Objekts mit der Maus verändert. Hier ist der UI-Code dazu: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Group BottomGroup
Children = OKButton, ChangeButton, ExitButton
orientChildren = ORIENT_HORIZONTALLY
DivideWidthEqually
ExpandWidth
DrawInBox
END Object
Button OKButton
Caption$ = " OK ", 1
justifyCaption = J_CENTER
ExpandWidth
END Object
Button ChangeButton
Caption$ = " Change ", 1
justifyCaption = J_CENTER
ExpandWidth
END Object
Button ExitButton
Caption$ = " Exit ", 1
justifyCaption = J_CENTER
ExpandWidth
END Object
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
^3.3.4 ObjektgrößeDas Vorschreiben einer bestimmten Objektgröße kann sehr oft hilfreich sein, um das Aussehen Ihres Programms den Erfordernissen anpassen. Gerade bei Listen, Text-Objekten und View's kann eine Größenvorgabe erforderlich sein. Bedenken Sie aber, dass der Nutzer Ihres Programms eine andere Bildschirmauflösung oder eine andere Größe für die Systemtexte eingestellt haben kann. Die Verwendung von Größenangaben, die das berücksichtigen (z.B. ST_LINES_OF_TEXT, ST_AVG_CHAR_WIDTH, siehe Kapitel 3.3.2) ist daher oft eine gute Idee.Beachten Sie, dass es für Fenster-Objekte, wie z.B. Primaries, weitere Geometrie-Hints gibt, die 'Window-Hints' wie z.B. SizeWindowAsDesired. Grundsätzlich gilt, dass Sie die Größe eines generischen Objekts nur dann vorschreiben sollten, wenn es unbedingt erforderlich ist. Dabei stehen Ihnen die folgenden Möglichkeiten zur Verfügung.
ExpandWidth, ExpandHeightDiese Hints bestimmen, dass das Objekt seine Breite (ExpandWidth) bzw. seine Höhe (ExpandHeight) so groß machen soll, dass der gesamte vom Parent zur Verfügung gestellte Platz ausgenutzt wird. Oftmals hat auch das Parent den entsprechenden Hints gesetzt.
Syntax UI-Code: ExpandWidth
ExpandHeight
NoWiderThanChildren, NoHigherThanChildrenDiese Hints bestimmen, dass ein Objekt nicht größer werden soll, als nötig ist um seine Children aufzunehmen.Anmerkung: Primaries ignorieren NoWiderThanChildren.
Syntax UI-Code: NoWiderThanChildren
NoHigherThanChildren
initialSize, minimumSize, maximumSizeDiese Hints legen die anfängliche (initialSize), minimale (minimumSize) bzw. maximale (maximumSize) eines Objekts fest. Das ist häufig nützlich für größenveränderliche Groups, Dialoge, View-Objekte usw., die die Hints ExpandWidth und / oder ExpandHeight gesetzt haben. Primary-Objekte unterstützen die ~Size-Hints jedoch nicht.Syntax: siehe fixedSize fixedSizeDas ist der wohl am häufigsten verwendete Size-Hint. Er gibt dem Objekt eine feste Größe. Achten Sie bei der Auswahl der Größenangabe auf eine zweckmäßige 'Grundeinheit', z.B. ST_LINES_OF_TEXT oder ST_AVG_CHAR_WIDTH. Details dazu finden Sie im Abschnitt 3.3.2.
Syntax UI-Code: fixedSize = width , height [ , count ]
width: Breite des Objekts
height: Höhe des Objekts
count: falls angebracht: "Zähler"
Lesen: <numVar> = <obj>.fixedSize (n)
n = 0: Breite
n = 1: Höhe
n = 2: Count
n = 3: Test ob der Hint gesetzt ist (TRUE) oder nicht (FALSE)
Schreiben: <obj>.fixedSize = width , height [ , count ]
Spezialfall: width oder height = -1: Löschen des Hints.
Beachten Sie, dass es sich um Hints (Hilfen für den Geometriemanager) handelt. Einige Objekte ignorieren diese Werte. Falls das ein Problem darstellt, ist eine häufig geeignete Lösung, das Objekt in eine Group einzuschließen. Groups unterstützen alle diese Hints. Beispiel: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Group InfoGroup
Children = InfoText, MoreInfoButton
orientChildren = ORIENT_VERTICALLY
ExpandWidth
ExpandHeight
DrawInBox
END Object
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Der Parameter 'count' wird bei Objekten verwendet, die eine Anzahl an 'Unterobjekten' darstellen. Der typische Fall sind 'scrollbare' Listen, wie im Beispiel dargestellt. Die Liste ist 15 Zeichen breit, 10 Textzeilen hoch und stellt 10 Einträge gleichzeitig dar.
xSize, ySizeDiese Werte liefern die aktuelle Größe des Objekts in Pixeln. Dabei verwenden sie eine GEOS-internen Struktur, die im PC/GEOS-SDK 'visBounds' heißt. Diese Struktur speichert die Position und Größe des Rechtecks, dass das gesamte Objekt umschließt. Das umfasst auch einen eventuell automatisch um das Objekt gezogenen Rahmen oder die 'Seiten' eines Buttons. Deswegen können die von xSize und ySize gelieferten Werte größer sein, als Sie mit fixedSize festgelegt haben. Außerdem sind die Werte nur gültig, solange das Objekt auch dem Schirm ist. Dabei darf es auch im Hintergrund oder von anderen Objekten verdeckt sein. Aber für Objekte, die auf visible = FALSE gesetzt oder nicht im generic Tree sind, sind die Werte möglicherweise ungültig.
Syntax Lesen: <numVar> = <obj>.xSize
<numVar> = <obj>.ySize
Anmerkung: Die Instancevariablen xSize und ySize sind nicht nur für GenericClass Objekte, sondern auch für VisualClass Objekte (siehe Kapitel 5 des Objekthandbuchs) definiert. ^3.3.5 Positionierung der ObjekteDie Positionierung der generischen Objekte ist eine der elementaren Aufgaben des Geometriemanagers. Sie sollten hier nur eingreifen, wenn es unbedingt sein muss. Folgende Möglichkeiten zur Verfügung:
placeObjectDieser Hint ermöglicht es Ihnen, Objekte an Stellen zu platzieren, auf die Sie sonst keinen Zugriff hätten. Dazu stehen die folgenden Konstanten zur Verfügung. Sie dürfen jeweils nur eine Konstante verwenden, eine Kombination (mit +) ist nicht zulässig.
MENU_BAR Platziert das Objekt in der Menüzeile eines Primary-Objekts. Das Objekt muss dazu direktes Child des Primary-Objekts sein. REPLY_BAR
TITLE_BAR_LEFT, TITLE_BAR_RIGHT
Syntax UI- Code: placeObject = position
position: Wert aus der Tabelle oben
Lesen: <numVar> = <obj>.placeObject
Schreiben: <obj>.placeObject = position
Spezialfall: position = 0: Löschen des Hints.
fixedPositionDieser Hint schreibt die Position eines Objekts relativ zu seinem Parent fest. FixedPosition ist extrem hoch priorisiert. Verwenden Sie diesen Hint für generische Objekte nur im äußersten Notfall, da der Geometriemanager ihn auch dann befolgt, wenn er unsinnige Ergebnisse hervorruft und Teile des automatischen Geometriemanagements außer Kraft gesetzt werden können.
Syntax UI-Code: fixedPosition = xPos, yPos
Lesen: <numVar> = <obj>.fixedPosition (n)
n = 0: xPos
n = 1: yPos
n = 2: Test ob der Hint gesetzt ist (TRUE) oder nicht (FALSE)
Schreiben: <obj>.fixedPosition = xPos, yPos
Spezialfall: xPos oder yPos = -1: Löschen des Hints.
xPosition, yPositionDiese Werte liefern die aktuelle Position des Objekts. Dabei verwenden sie eine GEOS-internen Struktur, die im PC/GEOS-SDK 'visBounds' heißt. Damit gelten die gleichen Einschränkungen, die bei xSize und ySize oben beschrieben wurden. Die mit xPosition und yPosition gelesenen Werte werden für generische Objekte regelmäßig von den eventuell mit fixedPosition gesetzten Werten abweichen, da fixedPosition die Position relativ zum Parent-Objekt setzt, die visBounds sich jedoch üblicherweise auf das zugehörige 'Window' (Primary, Dialog..) beziehen.
Syntax Lesen: <numVar> = <obj>.xPosition
<numVar> = <obj>.yPosition
Anmerkung: Die Instancevariablen xPosition und yPosition sind nicht nur für GenericClass Objekte, sondern auch für VisualClass Objekte (siehe Kapitel 5 des Objekthandbuchs) definiert. ^3.3.6 Spezielle AttributeDie hier beschriebenen Hints sind zwar auf GenericClass Ebene definiert, zeigen jedoch nicht bei allen Objekten eine Wirkung. Die Objekte, für die sie am häufigsten verwendet werden, sind unten jeweils mit angegeben.
DrawInBoxDieser Hint zeichnet einen Rahmen um ein Objekt. Er wird sehr häufig für Group-Objekte und Listen-Objekte verwendet. Syntax UI-Code: DrawInBox MakeToolboxDieser Hint bewirkt, dass das ein Group-Objekt seine Children als 'Werkzeugleiste' (engl. tool box = Werkzeugkasten) darstellt. Viele Objekte stellen sich als 'Tool' anders dar, wobei die Funktionalität aber nicht geändert wird. Syntax UI-Code: MakeToolbox Beispiele: Eine Group mit DrawInBox gesetzt. Rechts ist außerdem MakeToolbox gesetzt.
Der UI-Code dazu: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Group AReplyBar
Children = OKButton, ExitButton
orientChildren = ORIENT_HORIZONTALLY
DrawInBox
ExpandWidth
MakeToolbox
END Object
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Ein Listen-Objekt (RadioButtonGroup), links ohne, rechts mit MakeToolBox:
MakeReplyBarEine ReplyBar ist die Kontroll-Leiste mit den Buttons OK, Abbrechen usw., die sich in vielen Dialogboxen findet. Die Children werden automatisch auf eine spezielle Weise angeordnet.
Syntax UI-Code: MakeReplyBar | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Group AReplyBar
Children = OKButton, ExitButton
MakeReplyBar
END Object
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
tColor, bgColorEinige Objekte, insbesondere Buttons und Listeneinträge von scrollbaren Listen, unterstützen farbigen Caption-Text (tColor) und farbige Hintergründe (bgColor). Es gibt dabei zwei Hintergrundfarben: eine für den 'unselektierten' und eine für den 'selektierten' Zustand.
Syntax UI-Code: tColor = color
color: Text-Farbe. Es muss eine Indexfarbe sein.
RGB-Farben werden nicht unterstützt.
bgColor = col1, col2
col1: Unselektierte Farbe. (ebenfalls nur Indexfarbe)
col2: Selektierte Farbe. (ebenfalls nur Indexfarbe)
Lesen: <numVar> = <obj>.tColor
Liefert -1, wenn Hint nicht gesetzt ist
<numVar> = <obj>.bgColor (n)
n = 0: unselektierte Farbe (col1)
n = 1: selektierte Farbe (col2)
-1, wenn Hint nicht gesetzt ist
Schreiben: <obj>.tColor = color
color = -1 löscht den Hint
<obj>.bgColor = col1, col2
col1 oder col2 = -1 löscht den Hint
NoSeparatorLineDieser Hint beeinflusst nur Groups, die in ein Menü eingebunden sind. Per Default werden sie durch eine Trennlinie abgegrenzt. Damit bekommt das Menü eine bessere Struktur. Dieser Hint entfernt diese Trennlinie.Syntax UI-Code: NoSeparatorLine ^3.3.7 Spezielle Hints für Window-ObjekteDie hier beschriebenen Hints sind zwar auf GenericClass Ebene definiert, zeigen jedoch nur bei Window-Objekten wie Primaries, Displays und Dialogen eine Wirkung. Ob ein bestimmter Hint in einer konkreten Situation die beabsichtigte Wirkung hat müssen Sie ausprobieren. Für Primaries wird z.B. sehr häufig der Hint SizeWindowAsDesired verwendet um die Größe des Programmfensters auf das erforderliche Maß zu beschränken.^3.3.7.1 Aussehen und Verhalten anpassen
NoSysMenuNoSysMenu entfernt das Systemmenu von einem Window-Objekt. Achtung! Mit dem Systemmenü entfernen Sie eventuell den Zugriff auf wichtige Funktionen des Programms!Syntax UI-Code: NoSysMenu NoTitleBarNoTitleBar entfernt die Titelzeile von einem Window-Objekt. Achtung! Mit der Titelzeile entfernen Sie eventuell den Zugriff auf wichtige Funktionen des Programms!Syntax UI-Code: NoTitleBar Beispiel
Ein Primary-Objekt: links normal, rechts mit NoSysMenu gesetzt und unten mit NoTitleBar gesetzt (die Icons im Hintergrund sind jetzt sichtbar). Der UI-Code für das rechte Bild sieht so aus: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Primary APrimary
SizeWindowAsDesired
NoTitleBar
Caption$ = "Title Bar"
' wird ignoriert, weil es keine Title Bar mehr gibt :-)
<.. .. >
END Object
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
WindowNotMovableDieser Hint verhindert, dass ein Fenster, dass normalerweise auf dem Bildschirm verschieblich ist, nicht mehr verschoben werden kann. Sie sollten diesen Hint vorsichtig einsetzten.Syntax UI-Code: WindowNotMovable ^3.3.7.2 Anfängliche Größe festlegenDie hier beschriebenen Hints legen die Größe eines Fenster-Objekts fest, wenn es erstmalig geöffnet wird. Sie sind nur im UI Code zulässig.
SizeWindowAsDesiredDieser Hint verhindert, dass Fenster, oftmals ein Primary-Objekt, am Anfang größer wird, als die Children es benötigen.Syntax UI-Code: SizeWindowAsDesired ExtendWindowToBottomRightBewirkt, dass sich das Fenster beim erstmaligen Öffnen soweit vergrößert, dass es bis an den rechten und den unteren Rand des Parent Windows reicht.Syntax UI-Code: ExtendWindowToBottomRight ExtendWindowNearBottomRightWie ExtendWindowToBottomRight, nur dass unten ein kleiner Bereich freigelassen wird.Syntax UI-Code: ExtendWindowNearBottomRight WindowSizeFromParentDieser Hint bewirkt, dass die Größe eines neu geöffneten Fensters relativ zu seinem Parent-Window festgelegt wird. Beachten Sie, dass das nicht identisch mit dem Parent-Objekt im GenericClass Tree sein muss. Für Dialoge und Primaries ist das Parent Window z.B. der Bildschirm, für Displays ist es die DisplayGroup.
Syntax UI-Code: WindowSizeFromParent = relX, relY
relX, relY: relative Größe in Prozent
Erlaubte Werte: Null bis 100, jeweils einschließlich
WindowSizeFromScreenDieser Hint bewirkt, dass die Größe eines neu geöffneten Fensters relativ zum gesamten Bildschirm festgelegt wird.
Syntax UI-Code: WindowSizeFromScreen = relX, relY
relX, relY: relative Größe in Prozent
Erlaubte Werte: Null bis 100, jeweils einschließlich
^3.3.7.3 Anfängliche Position festlegenDie hier beschriebenen Hints legen die Position eines Fenster-Objekts fest, wenn es erstmalig geöffnet wird. Sie sind nur im UI-Code zulässig.
PositionWindowAtMouseDieser Hint bewirkt, dass die linke obere Ecke eines Fensters, z.B. eines Dialogs oder eines Primary, beim Öffnen an der aktuellen Mausposition steht. Das wir häufig für Kontextmenüs genutzt.Syntax UI-Code: PositionWindowAtMouse WindowPositionFromParentDieser Hint bewirkt, dass die Position eines neu geöffneten Fensters relativ zu seinem Parent-Window festgelegt wird. Beachten Sie, dass das nicht identisch mit dem Parent-Objekt im GenericClass Tree sein muss. Für Dialoge und Primaries ist das Parent Window z.B. der Bildschirm, für Displays ist es die DisplayGroup.
Syntax UI-Code: WindowPositionFromParent = relX, relY
relX, relY: relative Position in Prozent
Erlaubte Werte: Null bis 100, jeweils einschließlich
StaggerWindow, CenterWindow, TileWindowDiese Hints bewirken, dass mehrere Fenster innerhalb eines Parent-Windows (für Displays z.B. die DisplayGroup), die einen dieser Hints gesetzt haben, auf bestimmte Weise angeordnet werden.StaggerWindow: überlappend (engl. staggered: gestaffelt)
Syntax UI-Code: StaggerWindow
CenterWindow
TileWindow
WindowNoConstraintsDieser Hint entfernt alle Einschränkungen (engl.: constraints) bezüglich der Fensterpositionierung. Er sollte nur als letzter Versuch benutzt werden, um ein Fenster zu positionieren.Syntax UI-Code: WindowNoConstraints ^3.3.7.4 Window Management
BringToTopDiese Methode bringt das betroffene Fenster nach vorne. Das Fenster erhält automatisch den Focus.Syntax Basic-Code: <obj>.BringToTop LowerToBottomDiese Methode stellt das betroffene Fenster nach hinten. Es verliert automatisch den Focus, falls es ihn besaß.Syntax Basic-Code: <obj>.LowerToBottom MoveWinDiese Methode verschiebt das Window an eine bestimmte Position. Die Position kann in Pixeln angegeben werden (Parameter mode nicht angegeben oder Null) oder als Prozentwert der Größe des übergeordneten Windows (Parameter mode ungleich Null).Syntax Basic-Code: <obj>.MoveWin xPos, yPos [, mode] ResizeWinDiese Methode ändert die Größe eines Window-Objekts. Die neue Größe kann in Pixeln angegeben werden (Parameter mode nicht angegeben oder Null) oder als Prozentwert der Größe des übergeordneten Windows (Parameter mode ungleich Null).Syntax Basic-Code: <obj>.ResizeWin xPos, yPos [, mode] ResizeWin arbeitet unter Umständen nicht, wenn Sie widersprüchliche Anweisungen geben, z.B. gleichzeitig fixedSize oder SizeWindowAsDesired setzen. ^3.3.8 Hintertürchen für ProgrammiererDie in den letzten Abschnitten besprochenen Hints, wie z.B. ExpandWidth oder NoTitleBar sind nur im UI-Code verfügbar: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Button MyButton
Caption$ = "Drück mich"
ExpandWidth ! Maximale Breite einnehmen
End Object
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Die 'normale' Syntax von R-BASIC erlaubt es nicht, dass sie zur Laufzeit gesetzt oder gelöscht werden. Das ist im Normalfall auch nicht notwendig. Wenn Sie jedoch beispielsweise zur Laufzeit eigene Objekte anlegen (vgl. Kapitel 2.1.5) könnte auch der Bedarf bestehen, solche Hints zu setzen. R-BASIC bietet zur Lösung dieses Problems zwei Befehle an: einen, mit dem ein sonst nur im UI-Code verfügbarer Hint gesetzt werden kann und einen, mit dem er gelöscht wird.
Diesen Befehlen wird nicht etwa der Name des Hints übergeben, sondern sein numerischer Code. Was auf den ersten Blick etwas umständlich wirkt hat einen wesentlichen Vorteil: Sie können auf diese Weise R-BASIC Objekten auch Instance-Variablen bzw. Hints geben, die zwar im PC/GEOS-SDK definiert aber in R-BASIC nicht bekannt sind. Die folgende Tabelle enthält eine paar der häufiger verwendeten Geometrie-Hints, eine vollständige Liste der Codes der in R-BASIC definierten Hints finden Sie im Anhang, Kapitel E. Weitere Codes können Sie mit dem PC/GEOS-SDK bzw. der PC/GEOS-SDK-Dokumentation erhalten. Einige häufiger verwendete UI-Hint Codes. Weitere Codes finden Sie im Anhang.
Wenn sie öfter mit diesen beiden Funktionen arbeiten, können Sie sich für die von Ihnen verwendeten Hints natürlich Konstanten definieren. Beachten Sie, dass sich deren Namen von denen der Instance-Variablen unterscheiden müssen, damit der Compiler sie auseinanderhalten kann. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CONST Draw_In_Box = 24704 CONST C_MakeToolBox = 24976 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Warnung! ObjAddHint und ObjRemoveHint führen keinerlei Fehlerkontrollen aus, die Parameter werden direkt an die entsprechenden PC/GEOS-SDK-Routinen weitergereicht. Insbesondere wird nicht abgeprüft ob:
Hinweis für PC/GEOS-SDK-Programmierer: ObjAddHint und ObjRemoveHint verwenden intern die Messages MSG_META_ADD_VAR_DATA bzw. MSG_META_DELETE_VAR_DATA. Sie können also alles machen, was Sie im PC/GEOS-SDK mit diesen beiden Messages machen können. Das Flag VDF_SAVE_TO_STATE wird jeweils gesetzt. Beide Befehle setzen die Objekte bei Bedarf 'not usable' und nehmen dies, wenn nötig, auch wieder zurück.
ObjAddHint
Syntax BASIC Code: ObjAddHint <ob>, code [, adr, size]
<obj> - Referenz auf ein Objekt
code - numerischer Code des Hints
adr - Adresse, falls der Hint Datenwerte benötige
size - Größe dieser Datenwerte
Der Befehl ObjAddHint fügt einen Hint oder eine Instance-Variable zu einem Objekt hinzu. Verwenden Sie diesen Befehl, wenn die R-BASIC Syntax ansonsten das Setzen des Hints oder der Instance-Variablen zur Laufzeit nicht zulässt oder Sie einen Hint setzen wollen, der von R-BASIC nicht unterstützt wird. Sie können den Befehl auf alle Objekte anwenden. Er arbeitet sowohl mit GenericClass- als auch auf VisClass-Objekten, egal ob sie vom Compiler oder zur Laufzeit angelegt wurden. Beispiel: Hinzufügen der Hints ExpandWidth und ExpandHeight zu einem Objekt und MakeToolBox zu einem anderen. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DIM ob as OBJECT
ObjAddHint MyGroup, 24712
ObjAddHint MyGroup, 24708
ob = MyOtherObject
ObjAddHint ob, 24976
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ein komplexeres Beispiel finden Sie unten.
ObjRemoveHint
Syntax BASIC-Code: ObjRemoveHint <obj>, code
<obj> - Referenz auf ein Objekt
code - numerischer Code des Hints
Der Befehl ObjRemoveHint entfernt einen Hint oder eine Instance-Variable von einem Objekt. Verwenden Sie diesen Befehl, wenn die R-BASIC Syntax ansonsten das Löschen des Hints oder der Instance-Variablen zur Laufzeit nicht zulässt oder Sie einen Hint entfernen wollen, der von R-BASIC nicht unterstützt wird. Sie können den Befehl auf alle Objekte anwenden. Er arbeitet sowohl mit GenericClass- als auch auf VisClass-Objekten, egal ob sie vom Compiler oder zur Laufzeit angelegt wurden. Es ist auch zulässig ObjRemoveHint für eine Hint zu rufen, der gar nicht gesetzt ist. Beispiel: Entfernen der Hints DrawInBox, MakeToolBox und MakeReplyBar von diversen Objekten. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DIM ob as OBJECT
ObjRemoveHint MyGroup, 24704
ObjRemoveHint MyGroup.parent, 24976
ob = MyButton
ObjRemoveHint ob.parent, 24744
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Komplexes BeispielNehmen wir an, Sie wären ein PC/GEOS-SDK-Programmierer. Sie wissen daher, dass die R-BASIC Instance-Variable bgColor über den SDK-Hint HINT_GADGET_BACKGROUND_COLORS realisiert ist. Mit Hilfe des SDK haben Sie erfahren, dass
Sie wollen das nun ändern und alle vier Farben verwenden. Dazu müssen Sie die Datenwerte mit dem Befehl POKE oder einem seiner Verwandten in den R-BASIC Speicher schreiben. Welche Adresse Sie dazu verwenden ist egal, nehmen wir an, Sie entscheiden sich für 100. Die Befehlsfolge sieht dann so aus: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
POKE 100, RED
POKE 101, YELLOW
POKE 102, CYAN
POKE 103, BLUE
ObjAddHint MyButton, 25072, 100, 4
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Sie erhalten einen Button, dessen Hintergrundfarbe im ungedrückten Zustand ein Punktraster aus Rot und Gelb ist, im gedrückten Zustand ist es ein Raster aus Blau und Cyan.
Auf diese Weise können Sie R-BASIC Objekten auch Eigenschaften unterschieben, die von R-BASIC selbst nicht unterstützt werden. |