From 30310b6eb97d2b83d486b2f51701d80fb431a587 Mon Sep 17 00:00:00 2001 From: fretuks Date: Wed, 20 May 2026 22:47:18 +0200 Subject: [PATCH] refactor UI layout and text rendering logic for ability screens --- .../client/AbilityBindingScreen.java | 57 +++++++++++++------ .../client/AbilitySlotsScreen.java | 32 ++++++++--- 2 files changed, 66 insertions(+), 23 deletions(-) diff --git a/src/main/java/net/fretux/skillengine/client/AbilityBindingScreen.java b/src/main/java/net/fretux/skillengine/client/AbilityBindingScreen.java index c1d2238..d45c0cc 100644 --- a/src/main/java/net/fretux/skillengine/client/AbilityBindingScreen.java +++ b/src/main/java/net/fretux/skillengine/client/AbilityBindingScreen.java @@ -9,13 +9,20 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.FormattedText; import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.NotNull; +import java.util.List; + public class AbilityBindingScreen extends Screen { - private static final int PANEL_WIDTH = 220; - private static final int PANEL_HEIGHT = 160; + private static final int PANEL_WIDTH = 280; + private static final int PANEL_HEIGHT = 180; + private static final int PANEL_PADDING = 10; + private static final int SLOT_BUTTON_WIDTH = 76; + private static final int BUTTON_HEIGHT = 20; + private static final int BUTTON_GAP = 8; private final AbilityNode ability; @@ -28,29 +35,30 @@ public class AbilityBindingScreen extends Screen { protected void init() { int x = (width - PANEL_WIDTH) / 2; int y = (height - PANEL_HEIGHT) / 2; - int buttonX = x + 20; - int buttonY = y + 80; + int buttonRowWidth = SLOT_BUTTON_WIDTH * 3 + BUTTON_GAP * 2; + int buttonX = x + (PANEL_WIDTH - buttonRowWidth) / 2; + int buttonY = y + PANEL_HEIGHT - 54; int boundSlot = SkilltreeClientState.getSlotOfAbility(ability.getId()); - Button yBtn = addRenderableWidget(Button.builder(Component.literal("Bind to First Slot"), - b -> bind(1)).pos(buttonX, buttonY).size(80, 20).build()); + Button yBtn = addRenderableWidget(Button.builder(Component.literal("Slot 1"), + b -> bind(1)).pos(buttonX, buttonY).size(SLOT_BUTTON_WIDTH, BUTTON_HEIGHT).build()); if (boundSlot == 1) { yBtn.active = false; - yBtn.setMessage(Component.literal("Bound to First Slot")); + yBtn.setMessage(Component.literal("Bound 1")); } - Button xBtn = addRenderableWidget(Button.builder(Component.literal("Bind to Second Slot"), - b -> bind(2)).pos(buttonX + 90, buttonY).size(80, 20).build()); + Button xBtn = addRenderableWidget(Button.builder(Component.literal("Slot 2"), + b -> bind(2)).pos(buttonX + SLOT_BUTTON_WIDTH + BUTTON_GAP, buttonY).size(SLOT_BUTTON_WIDTH, BUTTON_HEIGHT).build()); if (boundSlot == 2) { xBtn.active = false; - xBtn.setMessage(Component.literal("Bound to Second Slot")); + xBtn.setMessage(Component.literal("Bound 2")); } - Button cBtn = addRenderableWidget(Button.builder(Component.literal("Bind to Third Slot"), - b -> bind(3)).pos(buttonX, buttonY + 30).size(80, 20).build()); + Button cBtn = addRenderableWidget(Button.builder(Component.literal("Slot 3"), + b -> bind(3)).pos(buttonX + (SLOT_BUTTON_WIDTH + BUTTON_GAP) * 2, buttonY).size(SLOT_BUTTON_WIDTH, BUTTON_HEIGHT).build()); if (boundSlot == 3) { cBtn.active = false; - cBtn.setMessage(Component.literal("Bound to Third Slot")); + cBtn.setMessage(Component.literal("Bound 3")); } addRenderableWidget(Button.builder(Component.literal("Cancel"), - b -> onClose()).pos(buttonX + 90, buttonY + 30).size(80, 20).build()); + b -> onClose()).pos(x + PANEL_WIDTH / 2 - 40, y + PANEL_HEIGHT - 28).size(80, BUTTON_HEIGHT).build()); } private void bind(int slot) { @@ -87,9 +95,26 @@ public class AbilityBindingScreen extends Screen { } gfx.drawCenteredString(font, ability.getTitle(), x + PANEL_WIDTH / 2, y + 35, 0xFFFFFF); if (ability.getDescription() != null) { - gfx.drawWordWrap(font, ability.getDescription(), x + 10, y + 50, PANEL_WIDTH - 20, 0xDDDDDD); + drawDescription(gfx, x + PANEL_PADDING, y + 50, y + PANEL_HEIGHT - 60); } super.render(gfx, mouseX, mouseY, partialTick); } -} \ No newline at end of file + + private void drawDescription(GuiGraphics gfx, int x, int y, int bottomY) { + int width = PANEL_WIDTH - PANEL_PADDING * 2; + List lines = font.getSplitter().splitLines( + ability.getDescription(), + width, + ability.getDescription().getStyle() + ); + int lineY = y; + for (FormattedText line : lines) { + if (lineY + font.lineHeight > bottomY) { + break; + } + gfx.drawString(font, line.getString(), x, lineY, 0xDDDDDD); + lineY += font.lineHeight; + } + } +} diff --git a/src/main/java/net/fretux/skillengine/client/AbilitySlotsScreen.java b/src/main/java/net/fretux/skillengine/client/AbilitySlotsScreen.java index 9371d62..98f7bea 100644 --- a/src/main/java/net/fretux/skillengine/client/AbilitySlotsScreen.java +++ b/src/main/java/net/fretux/skillengine/client/AbilitySlotsScreen.java @@ -13,6 +13,8 @@ import org.jetbrains.annotations.NotNull; public class AbilitySlotsScreen extends Screen { private static final int PANEL_WIDTH = 260; private static final int PANEL_HEIGHT = 180; + private static final int SLOT_TEXT_RIGHT_PADDING = 8; + private static final int REBIND_BUTTON_WIDTH = 80; public AbilitySlotsScreen() { super(Component.literal("Abilities")); } @@ -22,18 +24,17 @@ public class AbilitySlotsScreen extends Screen { int x = (width - PANEL_WIDTH) / 2; int y = (height - PANEL_HEIGHT) / 2; int rowY = y + 40; - int buttonW = 80; int buttonH = 20; - int buttonX = x + PANEL_WIDTH - buttonW - 15; + int buttonX = x + PANEL_WIDTH - REBIND_BUTTON_WIDTH - 15; // Y slot = 1 addRenderableWidget(Button.builder(Component.literal("Rebind"), b -> openSelect(1)) - .pos(buttonX, rowY).size(buttonW, buttonH).build()); + .pos(buttonX, rowY).size(REBIND_BUTTON_WIDTH, buttonH).build()); // X slot = 2 addRenderableWidget(Button.builder(Component.literal("Rebind"), b -> openSelect(2)) - .pos(buttonX, rowY + 35).size(buttonW, buttonH).build()); + .pos(buttonX, rowY + 35).size(REBIND_BUTTON_WIDTH, buttonH).build()); // C slot = 3 addRenderableWidget(Button.builder(Component.literal("Rebind"), b -> openSelect(3)) - .pos(buttonX, rowY + 70).size(buttonW, buttonH).build()); + .pos(buttonX, rowY + 70).size(REBIND_BUTTON_WIDTH, buttonH).build()); addRenderableWidget(Button.builder(Component.literal("Close"), b -> onClose()) .pos(x + PANEL_WIDTH - 70, y + PANEL_HEIGHT - 28).size(60, 20).build()); } @@ -83,9 +84,26 @@ public class AbilitySlotsScreen extends Screen { } if (icon != null) { gfx.blit(icon, x + 20, y - 2, 0, 0, 20, 20, 20, 20); - gfx.drawString(font, title, x + 46, y + 6, 0xDDDDDD); + int textX = x + 46; + gfx.drawString(font, fitTitle(title, textX), textX, y + 6, 0xDDDDDD); } else { - gfx.drawString(font, title, x + 20, y + 6, 0x888888); + int textX = x + 20; + gfx.drawString(font, fitTitle(title, textX), textX, y + 6, 0x888888); } } + + private String fitTitle(String title, int textX) { + int panelX = (width - PANEL_WIDTH) / 2; + int buttonX = panelX + PANEL_WIDTH - REBIND_BUTTON_WIDTH - 15; + int availableWidth = buttonX - SLOT_TEXT_RIGHT_PADDING - textX; + if (availableWidth <= 0 || font.width(title) <= availableWidth) { + return title; + } + String suffix = "..."; + int suffixWidth = font.width(suffix); + if (availableWidth <= suffixWidth) { + return ""; + } + return font.plainSubstrByWidth(title, availableWidth - suffixWidth) + suffix; + } }