Skip to content

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

Mutable list of child LayoutNodes managed by the Compose applier.

clipsToBounds

Whether this node clips its subtree's hit-testing to its own bounds - see ClipToBoundsModifier.

debug

var debug: Boolean

Whether the debug overlay is active. Setting this on a child propagates to the root.

drawModifiers

Ordered list of DrawModifiers extracted from modifier.

extraDebug

Whether the extended modifier info is shown in the debug overlay. Setting this propagates to the root.

height

open override var height: Int

The measured height in pixels.

layer

var layer: Int

layoutChangingModifiers

Ordered list of LayoutChangingModifiers extracted from modifier.

measurePolicy

open override var measurePolicy: MeasurePolicy

Determines how this node measures and places its children.

modifier

open override var modifier: Modifier

The chained Modifier applied to this node.

name

val name: String

This node's human-readable label, as shown in the debug overlay and used by findNode/findAllNodes.

parent

The parent LayoutNode in the scene graph, or null for root nodes.

processedModifier

Processed modifier map keyed by element type for O(1) lookup.

renderer

open override var renderer: 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

The topmost ancestor LayoutNode (the root of this subtree).

size

open val size: IntSize

The measured size as an IntSize value.

width

open override var width: Int

The measured width in pixels.

x

open override var x: Int

This node's placed x position, in pixels, relative to its parent.

y

open override var y: Int

This node's placed y position, in pixels, relative to its parent.

zIndex

val zIndex: Float

The effective z-index for this node, used for draw and input ordering.

Functions

findAllNodes

Recursively searches this subtree for every descendant node whose nodeName equals name, in depth-first order.

findNode

fun findNode(name: String): LayoutNode?

Recursively searches this subtree for a descendant node whose nodeName equals name.

flatten

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

fun getMaxZ(layerOffset: Float): Float

Computes the maximum effective z-depth in this subtree, adding layerOffset.

isAttachedTo

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

fun isBounded(mouseX: Int, mouseY: Int): Boolean

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

open override fun placeAt(x: Int, y: Int)

Places this node at the given screen coordinates.

Parameters

  • x: Absolute x position in screen pixels.

  • y: Absolute y position in screen pixels.

render

open override fun render(
    x: Int, 
    y: Int, 
    guiGraphics: GuiGraphics, 
    mouseX: Int, 
    mouseY: Int, 
    partialTick: Float
)

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.

fun render(
    x: Int, 
    y: Int, 
    guiGraphics: GuiGraphics, 
    mouseX: Int, 
    mouseY: Int, 
    partialTick: Float, 
    zOffset: Float
)

Renders this node and its entire subtree, with z-index translation, draw-modifier wrapping, and the optional debug overlay.

toString

open override fun toString(): String