Table of Contents

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:

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:

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

  1. Use Layout Containers: Leverage VBox, HBox, and VHBox for complex arrangements
  2. Pixel-perfect positioning: Use PixelScene.align() for precise alignment
  3. Follow Design Patterns: Use the same patterns as the base game for consistency
  4. Responsive UI: Consider different screen sizes in your layouts
  5. Touch-friendly: Make sure interactive elements are large enough for touch
  6. Memory Management: Properly destroy UI components to prevent memory leaks
  7. 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.