40 splitbox

Das Objekt splitbox ist ein Hilfsobjekt (ähnlich einer groupbox), um einen Bildschirmausschnitt in Bereiche zu unterteilen. Alle Bereiche werden durch Splitbars voneinander getrennt, die interaktiv vom Benutzer mit der Maus verschoben werden können, um so eine neue Aufteilung der Bereiche zu erzielen. Jedem sichtbaren Kind einer splitbox wird ein Bereich zugewiesen, in dem sich nur dieses Kind befinden kann, und dessen Größe und/oder Sichtbarkeit sich nach der Größe des ihm zugewiesenen Splitbereichs richtet. Möchte man in einem Splitbereich mehrere Kinder platzieren, so muss dort eine groupbox oder layoutbox als Kind benutzt werden, die dann die gewünschte Anzahl von Kindern aufnimmt. Mit einer groupbox als Kind können Splitbereiche auch mit virtuellen Größen ausgestattet werden.

Definition

{ export | reexport } { model } splitbox { <Bezeichner> }
{
  <Standardattribute>
  <Allgemeine Attribute>
  <Geometrieattribute>
  <Rasterattribute>
  <Hierarchieattribute>
  <Hierarchieattribut>
  <Objektspezifische Attribute>
}

Für jeden Splitbereich kann der Anwender seine gewünschte Größe festlegen. Außerdem können Minimal- und Maximalwerte pro Splitbereich angegeben werden, die interaktiv (verschieben einer Splitbar mit der Maus) nicht unter- bzw. überschritten werden können.

Die Ausrichtung der Splitbars kann entweder horizontal oder vertikal erfolgen.

Ereignisse

cut

extevent

help

key

paste

resize

select

Kinder

canvas

checkbox

control

document

edittext

groupbox

image

layoutbox

listbox

notebook

poptext

pushbutton

radiobutton

rectangle

record

scrollbar

spinbox

splitbox

statictext

tablefield

transformer

treeview

Vater

dialog

groupbox

layoutbox

module

notepage

splitbox

toolbar

window

Menü

Popup-Menü

40.1 Attribute

.acc_label

.acc_text

.accelerator

.active

.barwidth

.bgc

.bordercolor

.borderraster

.borderstyle

.borderwidth

.childcount

.control

.cursor

.cut_pending

.cut_pending_changed

.dialog

direction

.external

.external[integer]

.fgc

.firstchild

.firstrecord

.focus

.focus_on_click

.font

.function

.groupbox

.height

.help

.label

.lastchild

.lastrecord

.layoutbox

.mapped

.maxsize[integer]

.minsize[integer]

.model

.module

.navigable

.notepage

options[enum]

.parent

.posraster

.real_height

.real_sensitive

.real_size[integer]

.real_visible

.real_width

.record[integer]

.recordcount

.reffont

.scope

.self

.sensitive

.size[integer]

.sizeraster

.source

.statushelp

.target

tile

.tilestyle

.toolhelp

.userdata

.visible

.width

.window

.xauto

.xleft

.xraster

.xright

.yauto

.ybottom

.yraster

.ytop

40.2 Spezifische Attribute

Attribut Beschreibung

.barwidth

Breite der Splitbars.

.borderraster

Legt die Art der Geometrieberechnung bei aktivem Raster fest. Die detaillierte Beschreibung finden sie in der Attribut-Beschreibung in der „Attributreferenz“.

Nur aktiv, wenn .borderwidth > 0.

.borderstyle

Definiert den Stil, also Darstellung und Ausprägung, des Rahmens (ab IDM-Version A.06.01.a).

direction

Ausrichtung der Splitbars.

1 – vertikal.

2 – horizontal.

.maxsize[integer]

Maximale Größe des Splitbereichs I.

Siehe auch Kapitel „Größenbestimmung der Splitbereiche“ und „Besonderheiten“.

.minsize[integer]

Minimale Größe des Splitbereichs I.

Siehe auch Kapitel „Größenbestimmung der Splitbereiche“ und „Besonderheiten“.

options[enum]

Optionen des Objekts.

Indizes:

opt_center_toolhelp (nur MS Windows).

.real_size[integer]

Momentan wirklich vorhandene Größe des Splitbereichs I.

Siehe auch Kapitel „Größenbestimmung der Splitbereiche“ und „Besonderheiten“.

.size[integer]

Größe der einzelnen Splitbereiche I.

Siehe auch Kapitel „Größenbestimmung der Splitbereiche“ und „Besonderheiten“.

tile

Definiert das Hintergrundbild des Objekts

.tilestyle

Gibt die Art und Weise an, wie das in tile definierte Hintergrundbild dargestellt wird.

40.2.1 Größenbestimmung der Splitbereiche

Die Größe der einzelnen Splitbereiche wird über das Attribut .size[integer] angegeben.

Soll ein Splitbereich durch den Anwender durch Verschieben der Splitbar eine minimale bzw. maximale Größe nicht unter-/überschreiten können, ist dies in den Attributen .minsize[integer] bzw. .maxsize[integer] anzugeben. Dabei wird I = 0 als Defaultwert für alle Splitbereiche, die Werte I = 1 bis .childcount für den jeweiligen Splitbereich benutzt. Zum genauen Zusammenspiel dieser Attribute, insbesondere bei Größenänderungen durch den Anwender, siehe die folgenden Kapitel.

Die momentan vorhandene Größe eines Splitbereichs kann über .real_size[integer] abgefragt werden.

40.3 Besonderheiten

Das besondere Augenmerk im Zusammenhang mit der Splitbox ist in erster Linie auf das Layout und Geometriemanagement und der Verwendung von Randbedingungen wie eingeschaltetem Sizerastering oder der Benutzung der Minimal-/Maximalwerte zu legen.

40.3.1 Sizerastering

Im Gegensatz zu anderen Objekten, die die Benutzung von Attributen wie .xraster, .yraster und .reffont erlauben, wird bei der Splitbox das Rastergitter nicht auf das gesamte Objekt angewandt, sondern jeweils auf die einzelnen Splitbereiche. Damit sollen Rundungsprobleme vermieden werden, die unvermeidlich wären, wenn man einzelne Splitbereiche am globalen Rastergitter ausrichten müsste, und daneben noch Splitbars (deren Breite ja in Pixelwerten angegeben wird) in diesem Muster unterbringen müsste. Die Breiten der Splitbars ebenfalls in Rastergrößen anzupassen, erscheint als wenig attraktiv (es sieht einfach hässlich aus). Die Verwendung des Rastergitters nur lokal für das jeweilige Splitbereich löst dieses Problem. Darüber hinaus kann die bisher übliche Berechnungsvorschrift zur Pixelwertbestimmung vereinfacht werden. Üblich ist: Pixelwert = (Rasterwert – 1)*Raster. Für die Größenberechnung der Splitbereiche gilt Pixelwert = Rasterwert*Raster.

40.3.2 Größenberechung der Splitbereiche

Zur Berechnung der tatsächlichen Größen der Splitbereiche wird folgender Algorithmus verwendet.

  1. Zunächst wird versucht, jedem einzelnen Bereich die Größe zuzuweisen, die im Attribut .size[I] angegeben ist.
  2. Wird nach Schritt 1 festgestellt, dass dabei mehr Platz (Breiten der Splitbereiche plus Breiten der Splitbars) verbraucht wurde, als das Objekt durch die Definition der Geometrieattribute wie .width, .height, .xauto, .yauto, usw. zur Verfügung stellt, werden Splitbereiche unter Berücksichtigung der Minimalwerte anfangend von rechts bzw. unten in den Größen beschnitten, bis die Platzeinschränkung erfüllt wird. Wird dieses nicht erreicht, weil z.B. die Summe aller Minimalwerte (minsize[I]) bereits jeglichen Rahmen sprengt, werden Splitbereiche nochmals von rechts bzw. unten durchgegangen. Diesmal werden diese gekürzt ohne Rücksicht auf Minimalwerte. Auf der rechten bzw. unteren Seite können dabei eine Reihe von Splitbereichen mit der Größe 0 entstehen. Man sieht also nur noch übrig gebliebene Splitbars. Am Ende dieses Prozesses kann es passieren, dass obwohl alle Splitbereiche auf Null reduziert wurden, es immer nicht genug Platz zur Verfügung gibt (Summe der Breiten der Splitbars ist größer als die Ausdehnung der Splitbox). In diesem Fall werden die Splitbereiche samt deren Splitbars, für die der Platz nicht ausreicht, nach rechts bzw. unten außerhalb des sichtbaren Bereichs verschoben.
  3. Wird nach Schritt 1 festgestellt, dass dabei zu wenig Platz verbraucht wurde, als das was von der Splitbox durch die Definition der Geometrieattribute zur Verfügung gestellt wurde, werden Splitbereiche unter Berücksichtigung der Maximalwerte von rechts bzw. unten soweit vergrößert, bis die gesamte Fläche der Splitbox ausgefüllt ist. Wird dieses Ziel auf Anhieb nicht erreicht, weil z.B. die Summe aller Maximalwerte und der Breiten der Splitbars bereits kleiner ist als die Ausdehnung der Splitbox, wird der letzte Splitbereich unter Missachtung des ihm zugewiesenen Maximalwertes, soweit notwendig, vergrößert.

Man beachte, dass während dieses Prozesses die Attribute .size[I], .minsize[I], maxsize[I] nicht verändert werden. Sprich, dort stehen immer noch die Wunschwerte des IDM-Programmierers, die lediglich aufgrund der widrigen Bedingungen nur ansatzweise berücksichtigt werden konnten. Diese Eigenschaft ermöglicht eine Neuberechnung der tatsächlichen Splitbereichbreiten nach jedem Verändern der äußeren Maße der Splitbox. Wird z.B. die Splitbox mit .xauto=0 und .yauto=0 an einem Fenster angebunden, so kann beim interaktiven Verkleinern des Fensters und damit auch der Splitbox beobachtet werden, wie die Splitbereiche nacheinander mit und dann auch ohne Berücksichtigung der Minimalwerte verkleinert werden. Wird das Fenster wieder vergrößert, so kehren die Splitbars wieder in ihre Ausgangspositionen zurück.

Die Werte im .size[I] werden lediglich verändert, wenn diese im Widerspruch zu den Minimal-/Maximalwerten in minsize[I]/maxsize[I] stehen, wobei die Werte in minsize[I] für den IDM höhere Priorität haben als die Werte in maxsize[I].

Sollte es zu den in Schritten 2 und 3 beschriebenen Übertretungen der Minimal-/Maximalwerte kommen, können die betroffenen Splitbars interaktiv nicht mehr verschoben werden, da diese ohnehin schon an eigentlich nicht erlaubten Positionen stehen. Durch das Anfassen und dann Loslassen der Splitbars wird jedoch die Größe, und zwar die in .size[I]-Vektor, der betroffenen Splitbereiche auf neue Werte gesetzt. Dadurch werden auch EM_resize-Events ausgelöst, obwohl rein optisch sich nichts verändert hat; aber eben die Attributwerte in .size[I]. In jedem Fall wird der IDM-Programmierer dadurch informiert, dass seine Wunschwerte im size[I]-Vektor durch den Endanwender verändert worden sind. Wird versucht, dieselbe Splitbar nochmals zu verschieben, wird rein optisch sich wieder nichts ändern, da die von den Minimal-/Maximalwerten herrührenden Einschränkungen immer noch gelten. Diesmal werden jedoch keine weiteren EM_resize-Events verschickt, da die Werte in size[I] nach dem ersten Versuch bereits passend gesetzt wurden.

Eine Besonderheit ist beim Sizerastering zu beachten. Da es in der Praxis so gut wie unmöglich ist, dass alle Splitbereiche bei dem oben beschriebenen Anpassungsprozeß genau auf die Rastergröße gebracht werden können, existiert in der Regel (höchstens) ein Splitbereich, dessen Größe nicht auf das Vielfache von Rasterwerten passt. Es handelt sich dabei um den Splitbereich, der als letzter von dem oben beschriebenen Algorithmus angepasst wird.

Als Beispiel betrachten wir folgende Situation:

Es sei eine Splitbox mit .direction=1, .size[0]=10, minsize[0]=2 gegeben. Sizerastering ist eingeschaltet und am Vaterobjekt ist .xraster=10 gesetzt. Die Splitbox ist mit .xauto=0 und .yauto=0 an dem Vaterfenster angebunden. In der folgenden Abbildung ist diese Splitbox dargestellt. Man sieht, dass durch die äußeren Einflüsse nicht alle Werte aus dem .size[I]-Vektor erfüllt werden können. Die Zwei letzten Splitbereiche haben bereits ihre Minimalgrößen erreicht und zwar 20 Pixel. Der erste Splitbereich hat seine gewünschte Größe von 100 Pixeln. Der Splitbereich mit der Nummer 2 ist derjenige, der von dem Algorithmus als letzter verändert wurde, und nun nicht mehr in das Rastergitter passt.

40.3.3 Größenänderung (resize) durch den Benutzer

Ein typischer Anwendungsfall einer Splitbox besteht darin, die Größe der Splitbereiche interaktiv zu verändern. Hierzu muss der Mauszeiger über einer der Splitbars positioniert werden. Wie in der nachfolgenden Abbildung zu sehen ist ändert sich dabei das Aussehen des Mauszeigers.

Nun wird die linke Maustaste gedrückt und die Splitbar (in diesem Beispiel) nach rechts/links verschoben. Wie in der nachfolgenden Abbildung gezeigt, wird dabei als optisches Feedback ein teils durchsichtiger Balken zusammen mit dem Mauszeiger mit bewegt. Wird beim Verschieben irgendeine der Minimal-/Maximalbedingungen verletzt (etwa die Maximalgröße des zweiten Splitbereichs überschritten oder die Minimalgröße des dritten Splitbereichs unterschritten) bleibt der gezogene Balken an der zuletzt gültigen Position stehen.

Unter Microsoft Windows kann die Verschiebeaktion durch das Betätigen der Escape-Taste abgebrochen werden.

Wenn die gewünschte Position erreicht wurde, kann die linke Maustaste losgelassen werden, wodurch die Splitbox dazu veranlasst wird, die betroffenen Splitbereiche auf neue Größen zu bringen. Die folgende Abbildung dokumentiert das Endergebnis der Aktion.

Nun werden auch maximal zwei resize-Events verschickt. Eins, um anzuzeigen, dass sich die Größe des zweiten Splitbereichs verändert hat (dabei ist in erster Linie die Änderung des Wertes im size[I]-Vektor relevant; ist dieser Wert unverändert geblieben, wird kein Event ausgelöst). Im thisevent.index ist der Index (einsbasiert) des Kindes aus dem betroffenen Splitbereich eingetragen. Der zweite resize-Event ist den Änderungen im dritten Bereich gewidmet. Entsprechend ist im thisevent.index der Index des dritten Kindes eingetragen.

Hinweis

Wenn an dem Objekt .sizeraster auf true gesetzt ist, so wirkt sich dieses während der Verschiebeaktion zunächst gar nicht aus. Die Splitbar wird kontinuierlich mit dem Mauszeiger mit bewegt. Erst wenn die Splitbar losgelassen wird, schnappt sie auf die links/oben naheliegende Rasterposition ein, so dass die betroffenen Nachbarbereiche wieder auf die Rastergrößen gebracht werden.

40.4 Beispiel

Eine einfache Verwendung des splitbox-Objektes kann wie folgt aussehen:

dialog Dialog

window W
{
  .title  "splitbox-Demo";
  .width  400;
  .height 400;

  child splitbox Splbox
  {
    .xauto   0;
    .yauto   0;
    .xleft   5;
    .xright  5;
    .ytop    5;
    .ybottom 50;
    .size[0] 50;
    .minsize[0] 20;
    .maxsize[0] 100;

    child pushbutton Pb1
    {
      .text "in Bereich 1";
    }

    child statictext St1
    {
      .text  "in Bereich 2";
      .yauto -1;
      .xauto -1;
    }

    child groupbox Gb1
    {
      .xauto   0;
      .yauto   0;
      .xleft   4;
      .xright  4;
      .ytop    4;
      .ybottom 4;
    }

    child treeview Tv
    {
      .xauto   0;
      .yauto   0;
      .xleft   4;
      .xright  4;
      .ytop    4;
      .ybottom 4;
      .content[1]  "Eins";
      .content[2]  "a";
      .content[3]  "b";
      .content[4]  "c";
      .content[5]  "Zwei";
      .content[6]  "d";
      .content[7]  "Drei";
      .content[8]  "Vier";
      .content[9]  "e";
      .content[10] "f";
      .content[11] "g";
      .level[2]  2;
      .level[3]  2;
      .level[4]  2;
      .level[6]  2;
      .level[9]  2;
      .level[10] 2;
      .level[11] 2;
      .firstchar 1;
      .editable  true;
      .style[style_lines]   true;
      .style[style_buttons] true;
      .style[style_root]    true;
      .selstyle  multiple;
    }
  }

  on close { exit(); }
}