Skip to content

Screen layout DSL

ScreenLayout is the authoring layer one rung above ScreenContent. You declare an ordered list of typed widgets — title bars, panels, labels, action buttons, dividers, text inputs, swatches — and ScreenLayoutCompiler walks them in order to emit a ScreenContent you hand to ServerScreenManager. The wire format is unchanged; this is just sugar over hand-positioning rects and text.

  • You’re building any non-trivial in-world UI and want named widgets instead of raw rectangles.
  • You want a single switch-statement to consult for “how do I add a new widget kind”.
  • You’re composing layouts from constants (regions defined as named fields) rather than UV math.
package me.zlex.conduit.screen.ui.layout;
public record ScreenLayout(
Theme theme,
int backgroundColor,
List<ScreenWidget> widgets) {
public static ScreenLayout of(Theme theme, ScreenWidget... widgets);
public static ScreenLayout of(Theme theme, int backgroundColor, ScreenWidget... widgets);
public ScreenContent compile();
}
public final class ScreenLayoutCompiler {
public static ScreenContent compile(ScreenLayout layout);
}

Widgets render in declared order — later widgets paint on top.

import me.zlex.conduit.screen.ScreenContent;
import me.zlex.conduit.screen.ui.Region;
import me.zlex.conduit.screen.ui.Theme;
import me.zlex.conduit.screen.ui.layout.ScreenLayout;
import me.zlex.conduit.screen.ui.layout.ScreenWidget;
public final class RosterScreen {
public static ScreenContent build(List<String> playerNames) {
Theme theme = Theme.darkBlue();
var widgets = new java.util.ArrayList<ScreenWidget>();
widgets.add(new ScreenWidget.PanelWidget(new Region(0f, 0f, 1f, 1f)));
widgets.add(new ScreenWidget.TitleBarWidget(
new Region(0f, 0f, 1f, 0.12f), "Roster", "close"));
widgets.add(new ScreenWidget.LabelWidget(
new Region(0.06f, 0.16f, 0.9f, 0.04f),
"Players (" + playerNames.size() + ")",
ScreenWidget.LabelWidget.Kind.SECTION_HEADER));
float y = 0.22f;
for (String name : playerNames) {
widgets.add(new ScreenWidget.LabelWidget(
new Region(0.08f, y, 0.84f, 0.04f), name,
ScreenWidget.LabelWidget.Kind.BODY));
y += 0.05f;
}
widgets.add(new ScreenWidget.ActionWidget(
new Region(0.32f, 0.86f, 0.36f, 0.10f),
"ready", "READY UP", ScreenWidget.ActionWidget.Style.PRIMARY));
return new ScreenLayout(theme, 0x00000000, widgets).compile();
}
}
  • Adding a new widget kind means a new record in ScreenWidget and a new branch in ScreenLayoutCompiler.compile.
  • The default background colour is 0x00000000 (fully transparent) — useful when the layout sits over a PanelWidget you control.
  • ScreenLayout.region(x, y, w, h) is a static helper for constructing UV regions inline.