LayoutNode¶
class LayoutNode(nodeName: String = "LayoutNode") : Measurable, Placeable, UINode, MeasureScope
The concrete node type that forms Archie's UI scene graph.
Every composable in the Archie GUI framework ultimately creates one LayoutNode. It handles measurement, draw-chain rendering (including DrawModifier wrapping), z-index sorting, input hit-testing, and the Ctrl+Shift debug overlay.
Do not instantiate directly — use Layout and higher-level composables instead.
Parameters¶
- nodeName: A human-readable label shown in the debug overlay for this node.
Constructors¶
LayoutNode¶
constructor(nodeName: String = "LayoutNode")
Parameters
- nodeName: A human-readable label shown in the debug overlay for this node.
Properties¶
absoluteCoords¶
Absolute on-screen coordinates, accumulating parent offsets up the scene graph.
children¶
val children: MutableList<LayoutNode>
Mutable list of child LayoutNodes managed by the Compose applier.
clipsToBounds¶
val clipsToBounds: Boolean
Whether this node clips its subtree's hit-testing to its own bounds - see ClipToBoundsModifier.
debug¶
Whether the debug overlay is active. Setting this on a child propagates to the root.
drawModifiers¶
var drawModifiers: List<DrawModifier>
Ordered list of DrawModifiers extracted from modifier.
extraDebug¶
var extraDebug: Boolean
Whether the extended modifier info is shown in the debug overlay. Setting this propagates to the root.
height¶
The measured height in pixels.
layer¶
layoutChangingModifiers¶
Ordered list of LayoutChangingModifiers extracted from modifier.
measurePolicy¶
open override var measurePolicy: MeasurePolicy
Determines how this node measures and places its children.
modifier¶
The chained Modifier applied to this node.
name¶
This node's human-readable label, as shown in the debug overlay and used by findNode/findAllNodes.
parent¶
var parent: LayoutNode?
The parent LayoutNode in the scene graph, or null for root nodes.
processedModifier¶
var processedModifier: Map<KClass<out Modifier.Element<*>>, Modifier.Element<*>>
Processed modifier map keyed by element type for O(1) lookup.
renderer¶
Draws this node's own content (not its children) each frame.
renderState¶
open override var renderState: String?
The net.kernelpanicsoft.archie.gui.composables.theme.TextureStates key a stateful Renderer most recently selected to draw (e.g. "focused", "clicked_and_focused"), or null for nodes that don't render theme-state-driven visuals.
Set by the Renderer itself, purely as a test hook - lets a client GameTest assert which visual state a component resolved to without pixel comparison. Not read by the framework.
rootNode¶
val rootNode: LayoutNode
The topmost ancestor LayoutNode (the root of this subtree).
size¶
The measured size as an IntSize value.
width¶
The measured width in pixels.
x¶
This node's placed x position, in pixels, relative to its parent.
y¶
This node's placed y position, in pixels, relative to its parent.
zIndex¶
The effective z-index for this node, used for draw and input ordering.
Functions¶
findAllNodes¶
fun findAllNodes(name: String): List<LayoutNode>
Recursively searches this subtree for every descendant node whose nodeName equals name, in depth-first order.
findNode¶
fun findNode(name: String): LayoutNode?
flatten¶
fun flatten(): List<LayoutNode>
This subtree (this node plus every descendant), in depth-first pre-order.
get¶
inline fun <T : Modifier.Element<T>> get(): T?
Retrieves the merged Modifier.Element of type T from processedModifier, or null.
getMaxZ¶
Computes the maximum effective z-depth in this subtree, adding layerOffset.
isAttachedTo¶
fun isAttachedTo(root: LayoutNode): Boolean
Whether this node is still attached to the tree rooted at root.
Compose's applier clears parent when it removes a node (see net.kernelpanicsoft.archie.gui.nodes.LayoutNodeApplier.remove), so a detached node's rootNode walk terminates at itself instead of reaching the real root. Anything holding a node across recompositions has to check this before trusting its geometry: a detached node is never measured or placed again, so its width/height/position are frozen at whatever they were when it was dropped.
isBounded¶
Returns true if (mouseX, mouseY) falls within this node's absolute screen bounds and within those of every clipping ancestor - see ClipToBoundsModifier.
The ancestor walk is what keeps hit-testing honest inside a scroller: a scissor hides a scrolled-off child's pixels but leaves it at real coordinates, typically over whatever sits below the viewport, so testing self bounds alone would let an invisible node take a click (and a press consumes the event, so the visible target never sees it).
measure¶
open override fun measure(constraints: Constraints): Placeable
Measures this node within constraints and returns a Placeable for placement.
Parameters
- constraints: The size constraints imposed by the parent.
placeAt¶
Places this node at the given screen coordinates.
Parameters
-
x: Absolute x position in screen pixels.
-
y: Absolute y position in screen pixels.
render¶
Renders this node and its subtree at the given absolute screen position.
Parameters
-
x: Absolute screen x position to render at.
-
y: Absolute screen y position to render at.
-
guiGraphics: The graphics context to draw with.
-
mouseX: Current mouse x position, in screen space.
-
mouseY: Current mouse y position, in screen space.
-
partialTick: Fractional tick time for this frame, for smooth animation.
Renders this node and its entire subtree, with z-index translation, draw-modifier wrapping, and the optional debug overlay.