.. _ref-layout: ############################################################################### Layout ############################################################################### Mit der Property ``Layout`` wird die Art beeinflusst, wie ein Widget seine Children layoutet. Diese Property ist auf dem Widget implementiert und steht allen Widget-Typen zur Verfügung. Das Setzen dieser Property auf einem Widget bewirkt, dass auf diesem Widget ein Layoutmanager installiert wird, der alle direkten Child-Widgets in spezifischer Art layoutet; dabei werden u.U. Position und Shape der Child-Widgets verändert. Es gibt verschiedene Arten von Layouts in Maongo. Dies sind * Fill-Layout (die enthaltenen Children werden so positioniert das sie das Widget ausfüllen) * Flow-Layout (die enthaltenen Children werden zeilenweise angeordnet) * Box-Layout (die enthaltenen Children werden neben- bzw. übereinander angeordnet) * Border-Layout (die enthaltenen Children werden auf die angegebenen Layoutpositionen platziert) Syntax:: Allgemeines ================================================================================ Der verfügbare Raum für alle Layouts ist per Default der rechteckige Bereich der ``Bounds`` (das umschließende Rechteck des auf einem Widget gesetzten Shapes) abzüglich eines evtl. ``Padding``. Die Abstände, die mittels des Parameters ``gap`` für die einzelnen Layouts definiert werden, wirken stets nur zwischen den gefüllten Bereichen eines Layouts, nie nach außen. Widgets, deren Property ``Visible`` auf ``false`` steht, werden nicht dargestellt und auch im Layout nicht beachtet. **"PreferredBounds"** Zu jedem Layouttyp ist angegeben, welche ``PreferredBounds`` dieses Layout zurück liefert, wenn es danach gefragt wird. Hintergrund: Neben der Größenangabe, die mit ``Shape`` auf einem Widget gesetzt wird, kann ein Widget auch selbst bestimmen, welchen Platz es gerne hätte. Dies sind die ``PreferredBounds``. Widgets mit Layouts fragen ihre Children nach ``PreferredBounds``, um ein optimales Layout zu erzielen. Dieser Mechanismus funktioniert über mehrere Ebenen im Widget-Tree. ``PreferredBounds`` sind eine Widget-Property und können auch explizit gesetzt werden. Siehe :ref:`ref-possize`. Werden ``PreferredBounds`` vom MAD-Autor gesetzt, so hat dies Vorrang gegenüber dem Widget-eigenen Mechanismus, sie zu bestimmen. Die meisten Widget-Typen bestimmen ihre ``PreferredBounds`` mit der Größenangabe in ``Shape`` (oder dem Default-Shape, falls ``Shape`` nicht gesetzt ist). Ausnahme: Das Text-Widget ist in der Lage, seine ``PreferredBounds`` anhand der Textmenge zu bestimmen. **"LayoutConstraints"** Im Borderlayout müssen die ChildWidgets eines Widgets mit Layout mit der Property ``LayoutConstraints`` versehen werden, die dem Layout die spezifischen Positionen der einzelnen Child-Widgets mitteilt. Auch im Filllayout kann die Property ``LayoutConstraints`` angegeben werden, um für einzelne Children ein spezifisches Layoutverhalten zu erreichen. Bei den anderen Layouts wird eine evtl. vorhandene Property ``LayoutConstraints`` auf den Children ignoriert. FillLayout ================================================================================ :: Enthält ein Widget, dessen Layout-Property auf ``fill`` gesetzt ist, weitere Widgets, so werden die Child-Widgets so positioniert, dass sie das Parent-Widget abzüglich eines eventuellen Paddings ausfüllen. Die Positions- und Shape-Angaben der Child-Widgets werden also ignoriert. Dieses Default-Verhalten kann durch LayoutConstraints auf den Child-Widgets verändert werden (s.u.) **Parameter** keine **PreferredBounds** Die PreferredBounds eines Widgets mit FillLayout werden berechnet, indem die größte Höhe und die größte Breite seiner Children g enutzt werden; gibt es Children mit ``LayoutConstraints=preserve``, so wird auch die Location des betreffenden Childs mit eingerechnet. Children mit ``LayoutConstraints=ignore`` werden ignoriert .. image:: images/mp_layout_bounds1.png **LayoutConstraints** Das Verhalten des FillLayouts kann durch die Angabe von LayoutConstraints auf den Childwidgets modifiziert werden. Bei Child-Widgets ohne LayoutConstraints wird der Default (``padding``) angenommen:: Das FillLayout nutzt je nach eingestellten LayoutConstraints unterschiedliche Modi, um die Größe eines Kindes anzupassen: Bei ``resize`` wird das Child-Shape vergrößert oder verkleinert (ein Kreis bleibt ein Kreis), bei ``reshape`` wird das Child-Shape vom Layout neu gesetzt, vom ursprünglichen Shape des Kindes bleibt nichts erhalten. Mögliche Werte für LayoutConstraints sind: * ``padding``: das Shape des Child-Widgets wird so verändert (resize), dass es die Bounds des Parents-Shapes minus Padding ausfüllt (Default). * ``bounds``: das Shape des Child-Widgets wird so verändert (resize), dass es die Bounds das Parent-Shapes ausfüllt. * ``preserve``: keine Veränderung von Child-Shape und -Location. * ``ignore``: keine Veränderung von Child-Shape und -Location, widget wird bei der Berechnung der PreferredBounds ignoriert. * ``preferred``: keine Veränderung der Location, das Child-Shape wird auf seine PreferredBounds gesetzt (resize). **Beispiel** Ein Beispiel MAD mit verschiedenen LayoutConstraints: :download:`MAD <../reference/layout/fill.mad>`. FlowLayout ================================================================================ :: Enthält ein Widget, dessen Layout-Property auf ``flow`` gesetzt ist, weitere Widgets, so werden diese in horizontaler Richtung zeilenweise angeordnet. Evtl. Positionsangaben im Child-Widget (x, y, Location) werden ignoriert. Das FlowLayout fragt seine Elemente nach ihren ``PreferredBounds`` und nutzt diese. Das hat zur Folge, dass beispielsweise Textwidgets den für die Darstellung des enthaltenen Textes nötigen Platz zurückmelden. **Parameter** :: gap: Abstand zwischen Children: derselbe Wert für horizontal und vertikal gap: , Abstand zwischen Children: zwei Werte für horizontal und vertikal gap: 0.0,0.0 (Default) **PreferredBounds** Die PreferredBounds eines Widgets mit FlowLayout werden zurückgeliefert als Breite der Original-Bounds und Höhe des für das Layout der Children inklusive der Gaps benötigten Bereichs. .. image:: images/mp_layout_bounds2.png **LayoutConstraints** keine **Beispiel** Ein Beispiel :download:`MAD <../reference/layout/flow.mad>`. BoxLayout ================================================================================ :: Enthält ein Widget, dessen Layout-Property auf ``box`` gesetzt ist, weitere Widgets, so werden diese nebeneinander oder übereinander angeordnet. Evtl. Positionsangaben im Child-Widget werden ignoriert. Für die Behandlung der Children-Shapes sind die Einstellungen in ``stackmode`` und ``fillmode`` ausschlaggebend. **Parameter** :: direction: Richtung, in der das Layout gefüllt wird. direction: down (Default) von oben nach unten stackmode: Wie soll das Child-Widget gestapelt werden? Betrifft die Höhe bei direction=up/down und die Breite bei direction=right/left stackmode: preferred (Default) die entsprechende Dimension der PreferredBounds nutzen. stackmode: fill Die Children so skalieren, dass sie den zur Verfügung stehenden Platz in dieser Dimension ausnutzen. stackmode: equal Die Children so skalieren, dass sie in dieser Dimension so groß sind wie das größte Child-Widget. fillmode: Wie soll das Childwidget den zur Verfügung stehenden Platz ausfüllen? Betrifft die Breite bei direction=up/down und die Höhe bei direction=right/left fillmode: fill (Default) Die Children so skalieren, dass sie den zur Verfügung stehenden Platz in dieser Dimension ausnutzen. fillmode: preferred Die entsprechende Dimension der PreferredBounds nutzen. gap: Abstand zwischen Children gap: 0.0 (Default) **PreferredBounds** Die PreferredBounds eines Widgets mit BoxLayout werden zurückgeliefert als (bei direction=up/down) die Breite der Bounds/PreferredBounds des breitesten Elements und die Summe der Höhen der Bounds/PreferredBounds (zzgl. gaps) der Children, (bei direction=right/left) die Höhe der Bounds/PreferredBounds des höchsten Elements und die Summe der Breiten der Bounds/PreferredBounds (zzgl. gaps) der Children. .. image:: images/mp_layout_bounds3.png **LayoutConstraints** keine **Beispiel** Ein Beispiel :download:`MAD <../reference/layout/box.mad>`. BorderLayout ================================================================================ :: Ein Widget, dessen Layout-Property auf ``border`` gesetzt ist, kann bis zu fünf Child-Widgets auf die Layout-Positionen North, West, South, East und Center platzieren. Positions- und Shape-Angaben der Child-Widgets werden dabei u.U. modifiziert:: |north | - - - - - - - - - - - west |center| east - - - - - - - - - - - |south | Die fünf Layout-Positionen konkurrieren um den zur Verfügung stehenden Platz. Das Layout fragt stets die PreferredBounds der Children ab und versucht diesen Platzbedarf zu erfüllen. Ist ``mode: wide`` oder ``mode:portrait``, so erhält die Layoutposition ``center`` den Platz, der nach Platzierung der anderen Laypoutpositionen übrig bleibt. Ist das Attribut ``mode:center``, so erhält die Layoutposition ``center`` den benötigten Platz, und die anderen Layoutpositionen werden entsprechend angepasst. Außerdem bestimmen die ``mode``-Angaben darüber, wie die Bereiche in den "Ecken" des Layouts benutzt werden. wide:: north - - - - - - - - - - - west |center| east - - - - - - - - - - - south portrait:: |north | | - - -| west |center| east | - - -| |south | **Parameter** :: mode: mode: wide (Default) gap: (alle Richtungen) gap: , (senkrechte Achsen, waagrechte Achsen) gap: , , , (obere, rechte, untere, linke Achse) gap: 0 (Default) **PreferredBounds** Die ``PreferredBounds`` eines Widgets mit BorderLayout ist die Addition der Breiten und Höhen (zzgl. ``gap``) aller ``PreferredBounds`` der Child-Widgets, nachdem sie entsprechend ihrer ``LayoutConstraints`` in das Layout platziert wurden. **LayoutConstraints** Innerhalb eines Widgets mit ``Layout=border`` müssen alle Children eine eindeutige Angabe in ihrer Property ``LayoutConstraints`` haben. Layoutpositionen können also nicht mehrfach belegt werden:: Für die Angabe der Himmelsrichtungen ist sowohl die Lang- als auch die Kurzschreibweise (``n, w, s, e, c``) möglich. **Beispiel** Ein Beispiel :download:`MAD <../reference/layout/border_preferred.mad>`.