====== Creating Custom UI Elements ====== Remixed Dungeon has a sophisticated UI system that allows modders to create custom interfaces for their mods. Understanding this system is essential for creating professional-looking UI elements that integrate well with the game. ===== UI System Overview ===== The UI system in Remixed Dungeon follows a hierarchical structure: * **Gizmo** - Base class for all interactive elements * **Visual** - Visual elements with position, scale, transform * **Group** - Container for other Gizmos * **Scene** - Top-level container representing a screen * **Component** - UI components with layout capabilities ===== Creating a Simple Custom UI Element ===== Here's how to create a basic custom UI element: package com.yourmod.ui; import com.watabou.noosa.ui.Component; public class CustomUIElement extends Component { // Your UI components private Text title; private RedButton actionButton; @Override protected void createChildren() { // Create all child elements here title = PixelScene.createText("Custom Element", GuiProperties.titleFontSize()); add(title); actionButton = new RedButton("Action"); add(actionButton); // Set up event handlers actionButton.setClickListener(() -> { // Handle button click onClickAction(); }); } @Override protected void layout() { // Position all child elements here title.x = x + (width - title.width()) / 2; title.y = y + 2; actionButton.setRect(x + 2, y + title.height() + 4, width - 4, 16); } private void onClickAction() { // Your click handling logic } } ===== Layout Containers ===== Remixed Dungeon provides specialized layout containers to simplify UI arrangement: ==== VBox (Vertical Box) ==== VBox arranges its children vertically: VBox vbox = new VBox(); vbox.setGap(2); // Set spacing between elements vbox.setAlign(VBox.Align.Top); // Alignment options: Top, Bottom, Center // Add UI elements vbox.add(new RedButton("Button 1")); vbox.add(new RedButton("Button 2")); vbox.add(new RedButton("Button 3")); // Position the container vbox.setPos(10, 10); add(vbox); ==== HBox (Horizontal Box) ==== HBox arranges its children horizontally: HBox hbox = new HBox(200); // Maximum width hbox.setGap(2); // Set spacing between elements hbox.setAlign(HBox.Align.Left); // Alignment options: Left, Right, Center, Width // Add UI elements hbox.add(new RedButton("Button 1")); hbox.add(new RedButton("Button 2")); hbox.add(new RedButton("Button 3")); // Position the container hbox.setPos(10, 10); add(hbox); ===== Button Types ===== The game provides several button types for different purposes: * **Button** - Basic interactive component * **TextButton** - Button with text label * **RedButton** - Styled button with specific visual theme * **IconButton** - Button with icon and text * **ImageButton** - Button with only an image * **ImageTextButton** - Button with image and text * **CheckBox** - Checkable button with icon ===== Working with Windows ===== For modal dialogs, use the Window system: public class CustomWindow extends Window { private static final int WIDTH = 120; private static final int MARGIN = 2; public CustomWindow(String message) { super(); // Create content Text text = PixelScene.createText(message, GuiProperties.regularFontSize()); text.maxWidth(WIDTH - MARGIN * 2); text.measure(); add(text); // Layout window resize(WIDTH, (int)(text.height() + 2 * MARGIN)); // Add close button IconButton closeBtn = new IconButton(Icons.get(Icons.CLOSE)); closeBtn.setPos(width() - closeBtn.width() - 2, 2); add(closeBtn); closeBtn.setClickListener(this::hide); } } ===== UI Styling and Chrome ===== Use the Chrome system for consistent styling: // Different chrome types for different UI elements NinePatch windowChrome = Chrome.get(Chrome.Type.WINDOW); NinePatch buttonChrome = Chrome.get(Chrome.Type.BUTTON); NinePatch toastChrome = Chrome.get(Chrome.Type.TOAST); // Apply to your UI element NinePatch bg = Chrome.get(Chrome.Type.WINDOW); bg.size(width(), height()); add(bg); sendToBack(bg); ===== Text Handling ===== For text rendering: // Single line text Text title = PixelScene.createText("Title", GuiProperties.titleFontSize()); // Multi-line text Text multiline = PixelScene.createMultiline("This is a\nmulti-line\ntext", GuiProperties.regularFontSize()); // With markup Text highlighted = PixelScene.createMultilineHighlighted("_Highlighted text_", GuiProperties.regularFontSize()); // Styling title.hardlight(0xFF0000); // Red color title.align(TextAlignment.CENTER_ALIGN); ===== Best Practices for UI Modding ===== - **Use Layout Containers**: Leverage VBox, HBox, and VHBox for complex arrangements - **Pixel-perfect positioning**: Use PixelScene.align() for precise alignment - **Follow Design Patterns**: Use the same patterns as the base game for consistency - **Responsive UI**: Consider different screen sizes in your layouts - **Touch-friendly**: Make sure interactive elements are large enough for touch - **Memory Management**: Properly destroy UI components to prevent memory leaks - **Performance**: Minimize layout recalculations with proper dirty flag patterns ===== Example: Custom Item Slot ===== Here's a more complex example showing how to create a custom item display slot: public class CustomItemSlot extends Component { private Item item; private ItemSlot slot; private Text level; public CustomItemSlot(Item item) { super(); createChildren(); item(item); } @Override protected void createChildren() { slot = new ItemSlot(); add(slot); level = new Text(GuiProperties.regularFontSize()); add(level); } @Override protected void layout() { super.layout(); slot.setRect(x, y, height(), height()); if (level != null) { level.x = x + (width() - level.width()) / 2; level.y = y + height() - level.height(); } } public void item(Item item) { this.item = item; if (item == null) { slot.item((Item) null); level.text(""); } else { slot.item(item); if (item.levelKnown && item.level() != 0) { level.text(Integer.toString(item.level())); level.measure(); } else { level.text(""); } } layout(); } } By understanding and using these UI components properly, you can create professional-looking interfaces that integrate seamlessly with Remixed Dungeon's existing UI system.