Class GridViewElement
Task 2 (05-13, WIRE-03 / D-11): positions ANY widget type by writing parent data at render
time -- applyGridPositions() computes each child's slot from the GridView's
own layout parameters and writes it onto the RenderNode(s) that child's subtree
produced, mirroring Flutter's ParentDataWidget: the child never knows its own
position. This replaces the pre-plan approach of GridView.Builder.items()
special-casing ItemDisplay and hand-copying six fields at build time -- every other
widget type used to receive no slot at all and stacked on the default.
- Since:
- 6.2.0
- Version:
- 1.0.0
- Author:
- UltiTools Team
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final intThe slot valueItemDisplayandTextButton's builders default to when the caller never calls.slot(...).private static final Logger -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate voidWrites each child's GridView-computed slot onto the RenderNode(s) its subtree produced.private static voidcollectRenderNodeLeaves(@NotNull Element element, @NotNull List<RenderNode> out) Gets the list of child Elements.voidMounts this Element into the tree.private voidvoidPerforms a rebuild.voidunmount()Removes this Element from the tree.voidUpdates this Element with a new Widget.Methods inherited from class com.ultikits.ultitools.abstracts.gui.declarative.core.Element
addChild, assignContext, canUpdate, clearDirty, getContext, getParent, getWidget, isDirty, isMounted, markChildNeedsBuild, markNeedsBuild, setRootBuildScheduler, toString, updateChild, updateChildren
-
Field Details
-
LOGGER
-
DEFAULT_UNSET_SLOT
private static final int DEFAULT_UNSET_SLOTThe slot valueItemDisplayandTextButton's builders default to when the caller never calls.slot(...). Neither widget carries a separate "unset" flag -- 0 doubles as both "not specified" and "genuinely slot 0" in this codebase today -- so this is the only signal available here for D-11's conflict rule without changingWidget/ItemDisplay/TextButton's public API (out of this plan's scope;Widgetin particular is required to stay unchanged). A widget legitimately positioned at slot 0 therefore never triggers the conflict warning below -- see 05-13-SUMMARY.md for the full reasoning behind this choice.- See Also:
-
childElements
-
-
Constructor Details
-
GridViewElement
-
-
Method Details
-
mount
Description copied from class:ElementMounts this Element into the tree.Called the first time the Element is inserted into the tree. Subclasses should perform initialization work here and mount their child Elements.
CR-01 (T-05-62 / #371): every
mount(Element)override in this codebase callssuper.mount(parent)before doing its own work (mounting children, running the firstperformRebuild(), etc.) -- this base method is therefore the single choke point through which the ENTIRE mounting recursion passes, one call per Element, regardless of subtype:ContainerElement/GridViewElement.mountChildren()callingchildElement.mount(this)for each child, and themount()->performRebuild()->updateChild()->mount()cascadeStatelessElement/StatefulElementdrive when composing a child Widget for the first time. Checking the depth HERE, rather than separately in every subclass's own mounting method, guards the mount recursion exactly once per node without needing to duplicate the check at each override.update()/unmount()'s own recursions need no separate guard: they only ever walk a subtree whose depth was already validated here when it was first mounted, so they can never exceedRenderDepthGuard.MAX_DEPTHwithout first passing through an unguardedmount()call -- which this check closes. -
update
Description copied from class:ElementUpdates this Element with a new Widget.Called when the Widget rebuilds. Subclasses should update their reference to the Widget and perform any necessary updates.
-
performRebuild
public void performRebuild()Description copied from class:ElementPerforms a rebuild.Subclasses should implement this method to build or rebuild the Widget tree.
- Specified by:
performRebuildin classElement
-
unmount
public void unmount()Description copied from class:ElementRemoves this Element from the tree.Called when the Element is no longer needed. Subclasses should perform cleanup work here and unmount their child Elements.
-
getChildren
Description copied from class:ElementGets the list of child Elements.- Overrides:
getChildrenin classElement- Returns:
- the child Element list, or an empty list if there are none
-
mountChildren
private void mountChildren() -
applyGridPositions
private void applyGridPositions()Writes each child's GridView-computed slot onto the RenderNode(s) its subtree produced.This is parent data, D-11's mechanism: the child never knows its own position, the GridView writes it after the child has (re)built and before
GuiRenderer's collection walk snapshots the tree -- 05-11'scollectRenderNodesRecursivecopies viaRenderNode.copy(), so a write after that point would be invisible in the collected snapshot.A child whose Element is not itself a leaf (a nested
Container, for example) has noRenderNodeof its own;collectRenderNodeLeaves(com.ultikits.ultitools.abstracts.gui.declarative.core.Element, java.util.List<com.ultikits.ultitools.abstracts.gui.declarative.core.RenderNode>)walks its descendants and every leaf found receives the same computed slot. When more than one leaf exists under a single cell this is a genuine, documented collision (seeDEFAULT_UNSET_SLOT's sibling note in 05-13-SUMMARY.md) rather than an arbitrary "last writer wins" -- the traversal order is deterministic post-order, matchingGuiRenderer.collectRenderNodesRecursive's own discipline, so the result is reproducible across rebuilds even though it is not yet a resolved layout. -
collectRenderNodeLeaves
private static void collectRenderNodeLeaves(@NotNull @NotNull Element element, @NotNull @NotNull List<RenderNode> out)
-