Skip to content

NodeFrame

@Composable



fun NodeFrame(
    modifier: Modifier = Modifier, 
    variant: String = ThemeVariants.DEFAULT, 
    obtained: Boolean = false, 
    contentAlignment: Alignment = Alignment.Center, 
    contentPadding: Int = 8, 
    onClick: (UINode) -> Unit? = null, 
    content: @Composable



 () -> Unit
)

A themed, shaped frame for one NodeTreeView node's own content - the vanilla advancements screen's "normal"/"goal"/"challenge" icon frames (square, rounded, spiky) are exactly this same idea: one differently-bordered box per node kind, chosen by variant rather than by any Kotlin-side shape logic, the same "the theme decides the art, the composable decides the structure" split every other themed container in this package (Panel, Surface) already follows - a theme not declaring a node_frame texture at all just falls back to Surface's own default sprite behavior.

obtained is a separate axis from variant - a TextureStates.OBTAINED/TextureStates.UNOBTAINED state within whichever variant's own texture (matching how a themed button already picks a different sprite per interactive state), not a whole other variant to declare per kind. A theme only needs to declare "goal"/"challenge" as variants at all if it wants their frames to look different in shape from the default ("task") frame - the default's own state map already covers the unshaped default+obtained pair.

Nothing here is NodeTreeView-specific beyond its own default sizing suiting a small icon-sized node - use a plain Panel/Surface (or anything else) instead if a tree's nodes don't want a frame at all.

Parameters

  • variant: The theme variant of the node_frame texture to draw - one per distinct node shape/kind a theme wants to distinguish (e.g. "goal", "challenge"), on top of "task" (an alias for ThemeVariants.DEFAULT) for an ordinary node.

  • obtained: Whether this node's own progress is complete - selects TextureStates.OBTAINED vs. TextureStates.UNOBTAINED within variant's own texture.

  • onClick: When given, the whole frame becomes a Clickable - a NodeTreeView node this wraps can be tapped to open it, request it, etc. without needing its own separate button. null (the default) renders a plain, non-interactive frame with none of Clickable's own focus/hover/cursor machinery attached at all.