refactor UI layout and text rendering logic for ability screens

This commit is contained in:
2026-05-20 22:47:18 +02:00
parent fda16edcef
commit 30310b6eb9
2 changed files with 66 additions and 23 deletions
@@ -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);
}
private void drawDescription(GuiGraphics gfx, int x, int y, int bottomY) {
int width = PANEL_WIDTH - PANEL_PADDING * 2;
List<FormattedText> 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;
}
}
}
@@ -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;
}
}