en:rpd:modding_ui_elements
Differences
This shows you the differences between two versions of the page.
| en:rpd:modding_ui_elements [2026/01/01 19:45] – namespace move Mike | en:rpd:modding_ui_elements [2026/01/01 19:47] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== 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: | ||
| + | |||
| + | <code java> | ||
| + | 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(" | ||
| + | add(title); | ||
| + | | ||
| + | actionButton = new RedButton(" | ||
| + | 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: | ||
| + | |||
| + | <code java> | ||
| + | VBox vbox = new VBox(); | ||
| + | vbox.setGap(2); | ||
| + | vbox.setAlign(VBox.Align.Top); | ||
| + | |||
| + | // Add UI elements | ||
| + | vbox.add(new RedButton(" | ||
| + | vbox.add(new RedButton(" | ||
| + | vbox.add(new RedButton(" | ||
| + | |||
| + | // Position the container | ||
| + | vbox.setPos(10, | ||
| + | add(vbox); | ||
| + | </ | ||
| + | |||
| + | ==== HBox (Horizontal Box) ==== | ||
| + | HBox arranges its children horizontally: | ||
| + | |||
| + | <code java> | ||
| + | HBox hbox = new HBox(200); // Maximum width | ||
| + | hbox.setGap(2); | ||
| + | hbox.setAlign(HBox.Align.Left); | ||
| + | |||
| + | // Add UI elements | ||
| + | hbox.add(new RedButton(" | ||
| + | hbox.add(new RedButton(" | ||
| + | hbox.add(new RedButton(" | ||
| + | |||
| + | // Position the container | ||
| + | hbox.setPos(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: | ||
| + | |||
| + | <code java> | ||
| + | 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, | ||
| + | text.maxWidth(WIDTH - MARGIN * 2); | ||
| + | text.measure(); | ||
| + | add(text); | ||
| + | |||
| + | // Layout window | ||
| + | resize(WIDTH, | ||
| + | |||
| + | // Add close button | ||
| + | IconButton closeBtn = new IconButton(Icons.get(Icons.CLOSE)); | ||
| + | closeBtn.setPos(width() - closeBtn.width() - 2, 2); | ||
| + | add(closeBtn); | ||
| + | closeBtn.setClickListener(this:: | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== UI Styling and Chrome ===== | ||
| + | |||
| + | Use the Chrome system for consistent styling: | ||
| + | |||
| + | <code java> | ||
| + | // 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(), | ||
| + | add(bg); | ||
| + | sendToBack(bg); | ||
| + | </ | ||
| + | |||
| + | ===== Text Handling ===== | ||
| + | |||
| + | For text rendering: | ||
| + | |||
| + | <code java> | ||
| + | // Single line text | ||
| + | Text title = PixelScene.createText(" | ||
| + | |||
| + | // Multi-line text | ||
| + | Text multiline = PixelScene.createMultiline(" | ||
| + | GuiProperties.regularFontSize()); | ||
| + | |||
| + | // With markup | ||
| + | Text highlighted = PixelScene.createMultilineHighlighted(" | ||
| + | | ||
| + | |||
| + | // Styling | ||
| + | title.hardlight(0xFF0000); | ||
| + | title.align(TextAlignment.CENTER_ALIGN); | ||
| + | </ | ||
| + | |||
| + | ===== Best Practices for UI Modding ===== | ||
| + | |||
| + | - **Use Layout Containers**: | ||
| + | - **Pixel-perfect positioning**: | ||
| + | - **Follow Design Patterns**: Use the same patterns as the base game for consistency | ||
| + | - **Responsive UI**: Consider different screen sizes in your layouts | ||
| + | - **Touch-friendly**: | ||
| + | - **Memory Management**: | ||
| + | - **Performance**: | ||
| + | |||
| + | ===== Example: Custom Item Slot ===== | ||
| + | |||
| + | Here's a more complex example showing how to create a custom item display slot: | ||
| + | |||
| + | <code java> | ||
| + | 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, | ||
| + | | ||
| + | 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' | ||
