.. index:: pair: page; Native UI Layout Reference .. _doxid-ui_layout_reference: Native UI Layout Reference ========================== This document is the authoritative reference for eepp's **native application UI layout system**. It describes the behavior of the layout primitives used by normal eepp applications such as ecode, eterm, eproc, dialogs, settings panels, forms, workspaces, toolbars, and application-specific tools. For the recommended high-level authoring model and conventions, read ```ui_authoring.md``` first. This document intentionally describes **current eepp behavior**, not Android, browser, Qt, or other framework behavior that may look similar. HTML formatting contexts such as block, inline, Flexbox, CSS Grid, table layout, floats, and positioned HTML are a separate system primarily used by ``UIWebView``, ``UIMarkdownView``, and the HTML compatibility layer. They are not covered here except where a distinction is important. .. _doxid-ui_layout_reference_1autotoc_md949: 1. Native layout model ~~~~~~~~~~~~~~~~~~~~~~ The normal eepp layout model consists of: .. ref-code-block:: cpp UIWidget size policy margins padding layout gravity min/max constraints optional layout weight optional relative-position relationship UILayout owns or participates in positioning/sizing children specific layouts UILinearLayout UIRelativeLayout UIGridLayout UIFlowLayout UISplitter The most important idea is: **The parent layout controls the final allocation and position of its children.** A child supplies a sizing/placement contract through properties such as: .. ref-code-block:: cpp layout_width layout_height layout_weight layout_gravity margin min-width max-width min-height max-height The exact meaning of those properties depends on the parent layout. .. _doxid-ui_layout_reference_1autotoc_md951: 2. XML and CSS spelling ~~~~~~~~~~~~~~~~~~~~~~~ eepp accepts aliases, but normal project style distinguishes XML attributes from CSS properties. Preferred XML spelling: .. ref-code-block:: cpp Preferred CSS spelling: .. ref-code-block:: cpp .form-input { layout-width: 0dp; layout-height: wrap_content; layout-weight: 1; layout-gravity: center_vertical; } Common compact aliases: .. ref-code-block:: cpp layout_width -> lw layout_height -> lh layout_weight -> lw8 layout_gravity -> lg match_parent -> mp wrap_content -> wc Both full and compact forms are common in production eepp code. .. _doxid-ui_layout_reference_1autotoc_md953: 3. Default widget layout state ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A newly constructed ``UIWidget`` starts with: .. ref-code-block:: cpp layout weight = 0 layout gravity = unset / 0 width policy = WrapContent height policy = WrapContent position policy = None Specific widgets may override their own defaults. Do not assume every widget behaves identically under ``wrap_content``; intrinsic sizing is widget-specific. .. _doxid-ui_layout_reference_1autotoc_md955: 4. Size policies ~~~~~~~~~~~~~~~~ The native size-policy enum is: .. ref-code-block:: cpp enum class :ref:`SizePolicy ` { :ref:`Fixed `, :ref:`MatchParent `, :ref:`WrapContent ` }; These policies are applied independently to width and height. .. _doxid-ui_layout_reference_1autotoc_md956: 4.1 wrap_content ------------------------- XML: .. ref-code-block:: cpp layout_width="wrap_content" layout_height="wrap_content" Compact: .. ref-code-block:: cpp lw="wc" lh="wc" A ``WrapContent`` axis asks the widget to derive its size from its intrinsic/content size. The exact intrinsic size is widget-specific. Examples: * text widgets derive size from their text and font metrics; * image widgets derive size from the drawable; * buttons derive size from their internal content/theme; * native layouts may derive their wrapped axis from their visible children. Padding contributes to normal content sizing where the widget implementation defines it. ``wrap_content`` is the default native size policy for a plain ``UIWidget``. .. _doxid-ui_layout_reference_1autotoc_md957: 4.2 match_parent ------------------------- XML: .. ref-code-block:: cpp layout_width="match_parent" layout_height="match_parent" Compact: .. ref-code-block:: cpp lw="mp" lh="mp" ``MatchParent`` requests the available parent content size on that axis. The generic match-parent calculation is: .. ref-code-block:: cpp parent size - parent content offsets - non-auto child margins Parent content offsets include padding and, where applicable, borders. ``max-width`` / ``max-height`` can cap the resulting match-parent size. Conceptually: .. ref-code-block:: cpp child match-parent width = parent width - parent left/right content offsets - child left/right margins The exact layout can perform additional sizing rules around this value. Do not treat ``match_parent`` as a synonym for CSS ``width: 100%``. They may often produce similar geometry, but they belong to different layout systems. .. _doxid-ui_layout_reference_1autotoc_md958: 4.3 Fixed size -------------- Any explicit dimension normally selects ``Fixed`` sizing on that axis: .. ref-code-block:: cpp layout_width="240dp" layout_height="32dp" The value is resolved and stored as the widget size. The literal value: .. ref-code-block:: cpp fixed can also select the fixed policy without supplying a new dimension. Use explicit sizes where the dimension itself is meaningful. Do not use arbitrary fixed dimensions to compensate for a parent-layout mistake. .. _doxid-ui_layout_reference_1autotoc_md959: 4.4 Zero size and weighted LinearLayout children ------------------------------------------------ There is one important special case. Inside a ``UILinearLayout``, the canonical weighted-child pattern intentionally uses zero on the weighted axis: Horizontal parent: .. ref-code-block:: cpp Vertical parent: .. ref-code-block:: cpp When eepp parses a zero layout dimension for a weighted child whose parent is a ``UILinearLayout``, it does not immediately force the stored size in the normal fixed-size path. The linear layout assigns the weighted size during packing. .. _doxid-ui_layout_reference_1autotoc_md961: 5. Minimum and maximum constraints ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Widgets support: .. ref-code-block:: cpp min-width max-width min-height max-height These can constrain native layout results. For example, generic ``match_parent`` width calculation applies a ``max-width`` cap when one exists. Some native layout algorithms also explicitly fit wrapped container sizes against min/max constraints. Do not assume min/max handling is identical to browser intrinsic-sizing rules. This document describes the native layout system; HTML layout has additional rules. .. _doxid-ui_layout_reference_1autotoc_md963: 6. Margin and padding ~~~~~~~~~~~~~~~~~~~~~ .. _doxid-ui_layout_reference_1autotoc_md964: Margin ------ Margins belong to the child and participate in parent layout allocation/positioning. Example: .. ref-code-block:: cpp Margins affect: * linear packing; * match-parent available size; * relative positioning; * flow wrapping; * grid placement; * splitter/container alignment where relevant. .. _doxid-ui_layout_reference_1autotoc_md965: Padding ------- Padding belongs to the container/widget. Example: .. ref-code-block:: cpp ... Native layouts generally place children inside the padded content area. Conceptually: .. ref-code-block:: cpp container border box padding child layout area .. _doxid-ui_layout_reference_1autotoc_md967: 7. gravity and layout_gravity ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These are different properties. .. _doxid-ui_layout_reference_1autotoc_md968: gravity ---------------- ``gravity`` controls the widget's own content or, for layouts that explicitly use it, the layout's internal arrangement. Examples include: .. ref-code-block:: cpp left right center_horizontal top bottom center_vertical center Widget behavior varies because different widget types own different content. .. _doxid-ui_layout_reference_1autotoc_md969: layout_gravity ----------------------- ``layout_gravity`` describes how the widget should be placed by its parent layout when that layout supports gravity. XML: .. ref-code-block:: cpp layout_gravity="right|center_vertical" CSS: .. ref-code-block:: cpp layout-gravity: right|center_vertical; The distinction is: .. ref-code-block:: cpp gravity content/layout behavior inside this widget layout_gravity placement of this widget by its parent This distinction is especially important in ``UILinearLayout``. .. _doxid-ui_layout_reference_1autotoc_md971: 8. gravity-owner ~~~~~~~~~~~~~~~~~~~~~~~~~ Layouts normally respect the positioning policy of their parent. Some parent widgets advertise that they own child positioning with ``UI_OWNS_CHILDREN_POSITION``. A layout can set: .. ref-code-block:: cpp gravity-owner: true to force its own ``layout_gravity`` alignment against the parent even when the parent normally owns child positions. This is an advanced escape hatch and should not be a default solution to layout problems. .. _doxid-ui_layout_reference_1autotoc_md973: 9. Layout invalidation and update behavior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Native layouts are invalidated when relevant state changes, including: * child count changes; * layout-affecting child attributes; * layout size changes; * padding changes; * parent-size changes. A dirty layout is normally scheduled through the owning ``UISceneNode``. During an active layout pass, some updates can occur synchronously to avoid waiting for another frame. Calling ``UILayout::getSize()`` on a dirty layout forces that layout to update before returning its size. Nested layouts are tracked by their parent ``UILayout`` and participate in layout-tree updates. This matters mainly when implementing custom layout widgets. Ordinary application code should set properties and allow the scene to perform layout. .. _doxid-ui_layout_reference_1autotoc_md975: 10. Visibility and native layouts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Native layouts generally operate on **visible widget children**. Examples: * ``UILinearLayout`` ignores invisible children while packing; * ``UIFlowLayout`` ignores invisible children while creating rows; * ``UIGridLayout`` ignores invisible children; * invisible native layouts may collapse their own layout size to zero during their update path. Do not use invisible children as spacers. .. _doxid-ui_layout_reference_1autotoc_md977: 11. UILinearLayout ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``UILinearLayout`` is the primary sequential application layout. XML aliases: .. ref-code-block:: cpp C++: .. ref-code-block:: cpp UILinearLayout::NewVertical(); UILinearLayout::NewHorizontal(); Default orientation: .. ref-code-block:: cpp vertical .. _doxid-ui_layout_reference_1autotoc_md978: 11.1 Vertical linear layout --------------------------- A vertical layout packs visible children from top to bottom. Each child's vertical margins contribute to the consumed main-axis space. The child's ``layout_gravity`` controls **horizontal** placement inside the layout: .. ref-code-block:: cpp left center_horizontal right Example: .. ref-code-block:: cpp .. _doxid-ui_layout_reference_1autotoc_md979: 11.2 Horizontal linear layout ----------------------------- A horizontal layout packs visible children from left to right. Each child's horizontal margins contribute to consumed main-axis space. The child's ``layout_gravity`` controls **vertical** placement: .. ref-code-block:: cpp top center_vertical bottom Example: .. ref-code-block:: cpp .. _doxid-ui_layout_reference_1autotoc_md981: 12. LinearLayout size-policy behavior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Before packing, the layout applies child policies on the cross axis. .. _doxid-ui_layout_reference_1autotoc_md982: Vertical layout --------------- For child width: * ``WrapContent`` : child auto-sizing is enabled; * ``MatchParent`` : width becomes the layout's content width minus child horizontal margins; * ``Fixed`` : existing width remains. A child with ``layout_height="match_parent"`` and zero weight can also be resized to the parent's available height. .. _doxid-ui_layout_reference_1autotoc_md983: Horizontal layout ----------------- For child height: * ``WrapContent`` : child auto-sizing is enabled; * ``MatchParent`` : height becomes the layout's content height minus child vertical margins; * ``Fixed`` : existing height remains. A child with ``layout_width="match_parent"`` and zero weight can also be resized to the parent's available width. .. _doxid-ui_layout_reference_1autotoc_md985: 13. LinearLayout weights ~~~~~~~~~~~~~~~~~~~~~~~~ ``layout_weight`` distributes remaining space along the layout orientation. Canonical horizontal use: .. ref-code-block:: cpp Canonical vertical use: .. ref-code-block:: cpp .. _doxid-ui_layout_reference_1autotoc_md986: 13.1 Weight calculation ----------------------- The implementation treats positive weights as **relative weights**. For all visible children: .. ref-code-block:: cpp totalWeight = sum(max(childWeight, 0)) The layout first calculates the main-axis space already consumed by: * visible non-weighted fixed/wrapped children; * visible child margins. Then each positively weighted child gets: .. ref-code-block:: cpp remainingSpace * childWeight / totalWeight Therefore these are equivalent ratios: .. ref-code-block:: cpp 1, 1 0.5, 0.5 50, 50 and: .. ref-code-block:: cpp 1, 3 25, 75 produce equivalent proportions. Current implementation does **not** require weights to be normalized to ``0..1`` or sum to ``1``. Older documentation that describes weights as normalized should be considered overly restrictive. .. _doxid-ui_layout_reference_1autotoc_md987: 13.2 Example calculation ------------------------ Container: .. ref-code-block:: cpp horizontal content width = 600dp Children: .. ref-code-block:: cpp A = fixed 100dp B = weight 1 C = weight 3 Ignoring margins: .. ref-code-block:: cpp remaining = 600 - 100 = 500 totalWeight = 4 B = 125 C = 375 .. _doxid-ui_layout_reference_1autotoc_md989: 14. LinearLayout wrap-content behavior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A vertical ``UILinearLayout`` with ``layout_height="wrap_content"`` grows to the visible child heights, vertical margins, and padding. A horizontal ``UILinearLayout`` with ``layout_width="wrap_content"`` similarly grows from visible child widths, margins, and padding. The cross-axis wrapped size is based on the maximum visible non-match-parent child extent plus container padding, with min/max constraints considered. A wrapped linear layout can repack after its cross-axis size changes because that size may affect child alignment or nested layout. .. _doxid-ui_layout_reference_1autotoc_md991: 15. LinearLayout properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Layout-specific: .. ref-code-block:: cpp orientation gravity-owner ``orientation`` values: .. ref-code-block:: cpp vertical horizontal Default: .. ref-code-block:: cpp vertical Child properties commonly used with a linear layout: .. ref-code-block:: cpp layout_width layout_height layout_weight layout_gravity margin min-width max-width min-height max-height .. _doxid-ui_layout_reference_1autotoc_md993: 16. UIRelativeLayout ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``UIRelativeLayout`` is a native layout for: * alignment against the parent; * positioning one child relative to a sibling. It owns child positioning. Use it when sibling relationships are more natural than a nested ``vbox`` / ``hbox`` hierarchy. Do not choose it merely because it permits more arbitrary positioning. .. _doxid-ui_layout_reference_1autotoc_md995: 17. RelativeLayout child sizing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For each widget child: Width: .. ref-code-block:: cpp WrapContent -> enable auto-sizing MatchParent -> layout width - child horizontal margins - layout horizontal padding Fixed -> keep existing width Height: .. ref-code-block:: cpp WrapContent -> enable auto-sizing MatchParent -> layout height - child vertical margins - layout vertical padding Fixed -> keep existing height .. _doxid-ui_layout_reference_1autotoc_md997: 18. RelativeLayout parent alignment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When a child has no sibling-relative position policy, ``layout_gravity`` positions it against the ``UIRelativeLayout``. Horizontal: .. ref-code-block:: cpp left center_horizontal right Vertical: .. ref-code-block:: cpp top center_vertical bottom Example: .. ref-code-block:: cpp .. _doxid-ui_layout_reference_1autotoc_md999: 19. RelativeLayout sibling relationships ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Supported relationships are: .. ref-code-block:: cpp layout_to_left_of layout_to_right_of layout_to_top_of layout_to_bottom_of The value is the target sibling ID. Example: .. ref-code-block:: cpp The relationship is resolved by finding the referenced node and storing the target widget. It is used only when target and positioned widget share the same parent. Only one stored ``PositionPolicy`` is active at a time. This is not a general constraint solver. .. _doxid-ui_layout_reference_1autotoc_md1001: 20. RelativeLayout wrap-content caveat ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``UIRelativeLayout::updateLayout()`` applies its own size policy and lays out children, but it does **not** compute a new bounding rectangle from all positioned children. For application containers, prefer a defined or ``match_parent`` size when using ``UIRelativeLayout``. Do not assume ``wrap_content`` behaves like a general constraint-layout "measure descendants and fit" pass. .. _doxid-ui_layout_reference_1autotoc_md1003: 21. UIGridLayout ~~~~~~~~~~~~~~~~~~~~~~~~~ ``UIGridLayout`` is eepp's **native repeated-cell grid**. It is not CSS Grid. Use it for normal application UI when children should occupy repeated cells with a common row/column size policy. Do not infer CSS track sizing behavior from this class. .. _doxid-ui_layout_reference_1autotoc_md1005: 22. GridLayout sizing model ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Grid cells use one column mode and one row mode. .. ref-code-block:: cpp column-mode: size weight row-mode: size weight Defaults: .. ref-code-block:: cpp column-mode = weight row-mode = weight column-weight = 0.25 row-weight = 0.25 column-width = 0 row-height = 0 column-margin = 0 row-margin = 0 When ``column-mode=size``, cell width is ``column-width``. When ``column-mode=weight``, cell width is approximately: .. ref-code-block:: cpp available grid width * column-weight When ``row-mode=size``, cell height is ``row-height``. When ``row-mode=weight``, cell height is approximately: .. ref-code-block:: cpp available grid height * row-weight .. _doxid-ui_layout_reference_1autotoc_md1007: 23. GridLayout placement ~~~~~~~~~~~~~~~~~~~~~~~~ Visible widget children are processed sequentially. For each child: #. determine target cell size; #. set child size policy to ``Fixed, Fixed``; #. resize child to target size; #. place child at current grid position; #. advance by cell width plus column margin; #. wrap to the next row when the next cell no longer fits. This is a repeated-cell wrapping grid, not a named-track CSS grid. .. _doxid-ui_layout_reference_1autotoc_md1009: 24. GridLayout child weight override ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``UIGridLayout`` has a special behavior: If a child has non-zero ``layout_weight``, that child's target **width** becomes: .. ref-code-block:: cpp child layout weight * grid content width This is not ``UILinearLayout`` 's remaining-space distribution algorithm. Do not assume ``layout_weight`` means the same algorithm in every layout type. For straightforward grids, prefer the layout-level row/column sizing properties unless this per-child width override is intentionally needed. .. _doxid-ui_layout_reference_1autotoc_md1011: 25. GridLayout alignment ~~~~~~~~~~~~~~~~~~~~~~~~ The grid's own horizontal ``gravity`` affects row placement: .. ref-code-block:: cpp left center right This is container ``gravity``, not child ``layout_gravity``. .. _doxid-ui_layout_reference_1autotoc_md1013: 26. GridLayout wrap-content behavior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ With: .. ref-code-block:: cpp layout_height="wrap_content" the layout derives its height from generated rows plus vertical padding. A match-parent grid width/height is resolved from the parent before cell placement. Children are converted to fixed cell sizes during grid layout. .. _doxid-ui_layout_reference_1autotoc_md1015: 27. GridLayout properties ~~~~~~~~~~~~~~~~~~~~~~~~~ .. ref-code-block:: cpp column-mode column-weight column-width column-margin row-mode row-weight row-height row-margin Container ``gravity`` also affects horizontal grid alignment. .. _doxid-ui_layout_reference_1autotoc_md1017: 28. UIFlowLayout ~~~~~~~~~~~~~~~~~~~~~~~~~ ``UIFlowLayout`` is eepp's native horizontal wrapping flow layout. Conceptually: .. ref-code-block:: cpp A B C D E F G H I Children are consumed in order from left to right. When the next visible child no longer fits the current row, a new row is created. .. _doxid-ui_layout_reference_1autotoc_md1019: 29. FlowLayout width behavior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A notable design choice: When the flow layout itself uses: .. ref-code-block:: cpp layout_width="wrap_content" it initially uses the available match-parent width as its wrapping width. After layout, if all visible children effectively fit on one row and use less than the available width, the layout can shrink its wrapped width to the used width. So ``wrap_content`` for ``UIFlowLayout`` is not simply "sum all child widths without a constraint." Available parent width participates in wrapping first. .. _doxid-ui_layout_reference_1autotoc_md1021: 30. FlowLayout row creation ~~~~~~~~~~~~~~~~~~~~~~~~~~~ For each visible child: #. apply the child's size policy; #. test whether the child would exceed the current row; #. if necessary, create a new row; #. place the child; #. include child margins in row consumption; #. track the row's maximum height. The implementation can also create a new row after placement when the resulting cursor exceeds the layout width. .. _doxid-ui_layout_reference_1autotoc_md1023: 31. FlowLayout child size policies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Before rows are built: .. ref-code-block:: cpp WrapContent width/height enable child auto-sizing MatchParent width available match-parent width MatchParent height available match-parent height Fixed retain explicit size After row heights are known, a child with: .. ref-code-block:: cpp layout_height="match_parent" is resized to that row's maximum height. .. _doxid-ui_layout_reference_1autotoc_md1025: 32. FlowLayout alignment ~~~~~~~~~~~~~~~~~~~~~~~~ The flow layout's own ``gravity`` controls row-group placement. Horizontal gravity: .. ref-code-block:: cpp left center right controls each row's horizontal displacement. Vertical gravity: .. ref-code-block:: cpp top center_vertical bottom can shift the complete row group inside a container taller than the total flow content. Within each row, ``row-valign`` controls child vertical alignment. .. _doxid-ui_layout_reference_1autotoc_md1027: 33. row-valign ~~~~~~~~~~~~~~~~~~~~~~~ Values: .. ref-code-block:: cpp top center bottom Default: .. ref-code-block:: cpp bottom Meaning: .. ref-code-block:: cpp top child aligns near row top, respecting top margin center child is centered in row maximum height bottom child aligns near row bottom, respecting bottom margin This is separate from the container's vertical ``gravity``. .. _doxid-ui_layout_reference_1autotoc_md1029: 34. FlowLayout wrap-content height ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ With: .. ref-code-block:: cpp layout_height="wrap_content" height becomes: .. ref-code-block:: cpp top padding + sum(row maximum heights) + bottom padding with child vertical margins contributing to row heights. .. _doxid-ui_layout_reference_1autotoc_md1031: 35. FlowLayout properties ~~~~~~~~~~~~~~~~~~~~~~~~~ Layout-specific: .. ref-code-block:: cpp row-valign gravity-owner Important general properties: .. ref-code-block:: cpp gravity layout_width layout_height padding margin ``UIFlowLayout`` does not use child ``layout_weight`` as a remaining-space distribution mechanism. .. _doxid-ui_layout_reference_1autotoc_md1033: 36. UISplitter ~~~~~~~~~~~~~~~~~~~~~~~ ``UISplitter`` is a two-pane resizable layout. Default orientation: .. ref-code-block:: cpp horizontal Horizontal: .. ref-code-block:: cpp [first pane] | [second pane] Vertical: .. ref-code-block:: cpp [first pane] ------------- [second pane] The separator is an internal draggable widget. .. _doxid-ui_layout_reference_1autotoc_md1035: 37. Splitter child model ~~~~~~~~~~~~~~~~~~~~~~~~ ``UISplitter`` supports at most two external widget children. Internally it also owns its separator widget. The first external child becomes the first pane; the second becomes the last pane. Additional external children are rejected/closed. Children placed into the splitter are forced to: .. ref-code-block:: cpp Fixed, Fixed because the splitter owns their exact geometry. .. _doxid-ui_layout_reference_1autotoc_md1037: 38. Splitter with one child ~~~~~~~~~~~~~~~~~~~~~~~~~~~ If only one pane exists: * the separator is hidden and disabled; * the first child fills the splitter's padded content area. .. _doxid-ui_layout_reference_1autotoc_md1039: 39. Split partition ~~~~~~~~~~~~~~~~~~~ Property: .. ref-code-block:: cpp splitter-partition Default: .. ref-code-block:: cpp 50% Meaning: Desired space occupied by the first pane along the splitter axis. The separator's own size is removed from available split space when visible. Conceptually: .. ref-code-block:: cpp totalSpace = splitter content axis size - visible separator size first = resolve(splitter-partition, totalSpace) second = totalSpace - first .. _doxid-ui_layout_reference_1autotoc_md1041: 40. Splitter minimum sizes ~~~~~~~~~~~~~~~~~~~~~~~~~~ The first pane's minimum size constrains the initial partition. During dragging, both pane minimum sizes constrain separator movement. A requested partition may therefore not be achievable when it violates minimum sizes. Do not assume ``0%`` always produces a physically zero-sized first pane if its minimum size is non-zero. .. _doxid-ui_layout_reference_1autotoc_md1043: 41. Splitter visibility properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. ref-code-block:: cpp splitter-always-show Default: .. ref-code-block:: cpp true When true, the divider remains visible whenever two panes exist. .. ref-code-block:: cpp splitter-hide-on-edge Default: .. ref-code-block:: cpp false When enabled and ``splitter-always-show`` is false, percentage partitions exactly at ``0%`` or ``100%`` can hide the divider so one pane consumes the full splitter. .. _doxid-ui_layout_reference_1autotoc_md1045: 42. Splitter dragging ~~~~~~~~~~~~~~~~~~~~~ Horizontal orientation: .. ref-code-block:: cpp separator drags along x cursor = horizontal resize Vertical orientation: .. ref-code-block:: cpp separator drags along y cursor = vertical resize Dragging immediately resizes both children. After a drag, the stored split partition is recalculated as a percentage of available split space. .. _doxid-ui_layout_reference_1autotoc_md1047: 43. Splitter properties ~~~~~~~~~~~~~~~~~~~~~~~ .. ref-code-block:: cpp orientation splitter-partition splitter-always-show splitter-hide-on-edge Orientation values: .. ref-code-block:: cpp horizontal vertical .. _doxid-ui_layout_reference_1autotoc_md1049: 44. Choosing the correct native layout ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ======================================== ========================= Need Native layout ======================================== ========================= Vertical sequence Horizontal sequence Flexible remaining space in a row/column Child positioned relative to a sibling Repeated equal/weighted cells Horizontal items that wrap into rows Two user-resizable panes Tabs Split/tab editor workspace Web/document formatting HTML compatibility layout ======================================== ========================= ``UITabWidget`` and ``UITabWidgetSplitter`` are higher-level containers rather than low-level generic layout algorithms and belong in the widget/application references. .. _doxid-ui_layout_reference_1autotoc_md1051: 45. Production patterns ~~~~~~~~~~~~~~~~~~~~~~~ .. _doxid-ui_layout_reference_1autotoc_md1052: Flexible form row ----------------- .. ref-code-block:: cpp .. _doxid-ui_layout_reference_1autotoc_md1053: Header + flexible content + footer ---------------------------------- .. ref-code-block:: cpp .. _doxid-ui_layout_reference_1autotoc_md1054: Wrapping option group --------------------- .. ref-code-block:: cpp .. _doxid-ui_layout_reference_1autotoc_md1055: Two-pane workspace ------------------ .. ref-code-block:: cpp .. _doxid-ui_layout_reference_1autotoc_md1057: 46. Important differences from browser layout ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Do not import these as semantic equivalences: .. ref-code-block:: cpp match_parent == width:100% layout_weight == flex-grow UIGridLayout == CSS Grid UIFlowLayout == display:flex + flex-wrap layout_gravity == justify-content / align-items They can be useful analogies, but native eepp layouts are separate algorithms. .. _doxid-ui_layout_reference_1autotoc_md1059: 47. Important differences from Android intuition ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eepp deliberately borrows several Android-style concepts, especially: .. ref-code-block:: cpp LinearLayout layout_width layout_height match_parent wrap_content layout_weight layout_gravity RelativeLayout-style sibling relations dp Android documentation is not authoritative for eepp. Notable example: Current eepp ``UILinearLayout`` weights are arbitrary relative positive values; they do not need to be normalized or sum to ``1``. Always prefer eepp behavior over external analogy. .. _doxid-ui_layout_reference_1autotoc_md1061: 48. Inspecting native layout at runtime ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Use the **Runtime UI Inspector & Automation Protocol** rather than guessing geometry. Typical process: .. ref-code-block:: cpp ui.contexts ↓ ui.query target ↓ ui.inspect target geometry/layout properties ↓ inspect parent ↓ inspect relevant siblings ↓ screenshot if useful Stable debugging questions: .. ref-code-block:: cpp What parent layout owns this child? What are its width/height policies? What are its actual bounds? Does it have weight? What are its margins? What is the parent's padding? What gravity is active? What min/max constraints exist? For weighted linear layouts, inspect all siblings participating in the same axis. .. _doxid-ui_layout_reference_1autotoc_md1063: 49. Layout debugging checklist ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When size is wrong: .. ref-code-block:: cpp 1. identify parent layout type 2. inspect layout_width / layout_height 3. determine Fixed / MatchParent / WrapContent 4. check layout_weight 5. check margins 6. check parent padding/content offsets 7. check min/max constraints 8. check sibling sizes/weights 9. check visibility 10. only then consider an explicit fixed size When position is wrong: .. ref-code-block:: cpp 1. identify parent layout 2. check layout_gravity 3. distinguish layout_gravity from gravity 4. check margins 5. check RelativeLayout position relationship 6. check parent gravity where Grid/Flow uses it 7. check gravity-owner only if parent positioning ownership matters .. _doxid-ui_layout_reference_1autotoc_md1065: 50. Implementation-oriented notes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These details matter mainly when implementing custom layouts. .. _doxid-ui_layout_reference_1autotoc_md1066: Layout dirtiness ---------------- ``UILayout`` maintains dirty state and participates in the scene's layout invalidation queue. .. _doxid-ui_layout_reference_1autotoc_md1067: Reentrancy guard ---------------- Layouts use ``mPacking`` to prevent recursive packing. .. _doxid-ui_layout_reference_1autotoc_md1068: Nested layouts -------------- A ``UILayout`` tracks direct child layouts and updates the layout tree recursively. .. _doxid-ui_layout_reference_1autotoc_md1069: Auto-size children ------------------ A layout can request ``onAutoSize()`` for ordinary children or temporarily update a child layout as wrapping content. .. _doxid-ui_layout_reference_1autotoc_md1070: Parent notifications -------------------- When a layout's wrapped size changes, implementations notify the parent so enclosing layouts can repack. Custom layout implementations should preserve these lifecycle expectations. .. _doxid-ui_layout_reference_1autotoc_md1072: 51. Scope boundaries ~~~~~~~~~~~~~~~~~~~~ This document intentionally does not specify: * HTML Flexbox; * HTML CSS Grid; * block/inline formatting; * HTML table layout; * floats; * sticky/fixed/absolute HTML positioning; * HTML intrinsic min-content/max-content behavior. See ```ui_html_compatibility.md``` for HTML/web layout semantics. For related topics: * ```ui_introduction.md``` — introduction to eepp's UI system. * ```ui_authoring.md``` — recommended application UI mental model and authoring conventions. * ```ui_css_for_applications.md``` — CSS behavior and conventions for normal application widgets. * ```ui_inspector.md``` — runtime UI inspection and automation protocol. * ```ui_databinding.md``` — UI data binding. * ```ui_charts.md``` — charting widgets and chart-specific behavior. .. _doxid-ui_layout_reference_1autotoc_md1074: 52. Source of truth ~~~~~~~~~~~~~~~~~~~ When uncertain about native layout behavior, use this order: #. current eepp implementation #. current eepp unit/integration tests #. production eepp/ecode/eterm/eproc usage #. this reference #. ```css_specification.md``` and other general docs #. Android/browser/other-framework analogy If a documented rule and the current implementation disagree, treat the implementation as authoritative and update the documentation.