Skip to content

Composable UI Migration

darkevilmac edited this page Oct 5, 2026 · 3 revisions

Migrating to Compound 2.0

Compound 1.18.0 ports the existing libraries to Minecraft 26.3. Compound 2.0.0 replaces the legacy UI API with the composable framework on that same platform. This is a major-version change; existing UI consumers need migration.

  • Replace CompoundUI with ComposedUI, and CompoundUIContainer with ComposedUIContainer. Describe the screen with composition scopes instead of registering legacy elements and layouts.
  • Replace legacy Element* widgets and Layout* classes with composable controls, containers, and layout properties. Use InventorySlot and the container's slot mapping for inventory screens.
  • Construct observable values with State.of(initialValue). Use the interface factories instead of constructing implementation classes.
  • Use typed tree events and state bindings instead of legacy listener registration. MouseScrollEvent exposes scrollX() and scrollY(); key events distinguish navigation keys from logical editing shortcuts. CharEvent carries a Unicode code point.
  • Carets and highlights compose existing rectangles and text; cursor blinking uses the animation system. Keep retained state and animation ownership tied to the screen's lifecycle.

For consumers of earlier framework prototypes, replace scrollDelta() with scrollY(). TextInput no longer exposes setCanLoseFocus/canLoseFocus: tree focus is authoritative. Maximum layout constraints stay within the parent; use the explicit unbounded operations only when intended.

Frame animation and text controls

  • Use retained IAnimationTimeline.create() and IAnimatedValue.create(...) for visual-only frame animation. Attach the timeline with scope.useAnimationTimeline(timeline) on one owning node. Detach freezes its clock; reattachment preserves elapsed time. Keep AnimatedState with bindLayout for measured-size animation.
  • Replace draw-time pose mutations with elementScope.transform(...). Use beforeGeometry(...) for render-only preparation. Keep draw suppliers read-only so rendering, debug outlines, and hit testing share one geometry snapshot.
  • Mouse callbacks still receive world GUI coordinates. Custom transformed controls should use elementScope.toLocal(...) and handle the empty optional result. Rotated clipping throws; scissors remain axis-aligned, including clips inside text inputs and scroll areas.
  • TextInput.setBordered(false) now hides decoration without changing content insets. Set TextInsets.NONE explicitly for edge-to-edge content. Both editors expose setContentInsets, setTextAlignment, and setBackground; TextArea.setBackgroundVisible controls decoration separately.
  • Explicit TextInput.setTextAlignment takes precedence over the compatibility setCentered setter. Single-line construction, replacement, and insertion remove both CR and LF. Both editors share the Java-only editing core; absolute offsets and limits use UTF-16 code units, with caret movement and truncation respecting code-point boundaries.

Start with the consumer API, then the framework reference. The companion Molecule framework-demo branch provides a widget gallery and a working inventory screen.

For standalone tree composition, use ICompositionScope.root(tree). Use AnimatedState.of(...) or AnimatedState.looping(...) outside composition, and IScreenSpriteWriter.stretch(), tiled(), or nineSlice(...) when explicitly choosing sprite scaling.

Custom composables extend Element, custom containers extend Container, and custom drawing elements extend PrimitiveElement. These replace the prototype base class names. Numeric and boolean drawing suppliers use IntSupplier, DoubleSupplier, and BooleanSupplier; replace boxed supplier declarations and use their getAsInt(), getAsDouble(), or getAsBoolean() methods. Object suppliers such as Supplier<Component> are unchanged. Construct list rows through ListItem.builder(label) and configure selection, hover, and colors before calling build().

Clone this wiki locally