diff --git a/src/main/java/noppes/npcs/client/gui/hud/GuiHudEditor.java b/src/main/java/noppes/npcs/client/gui/hud/GuiHudEditor.java index 35c2899c0..d37651b61 100644 --- a/src/main/java/noppes/npcs/client/gui/hud/GuiHudEditor.java +++ b/src/main/java/noppes/npcs/client/gui/hud/GuiHudEditor.java @@ -6,6 +6,9 @@ import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.ScaledResolution; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; + +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.ArrayList; @@ -25,6 +28,11 @@ public class GuiHudEditor extends GuiScreen { private final int HANDLE_SIZE = 10; private final int RESET_POSITION_ID = 100; + // IDs for cycle buttons. + private final int CYCLE_LEFT_ID = 101; + private final int CYCLE_RIGHT_ID = 102; + private final int COMPONENT_LABEL_ID = 103; + public GuiHudEditor(GuiScreen parent) { this.parent = parent; // For example, default to QuestTracker if available. @@ -41,37 +49,37 @@ public class GuiHudEditor extends GuiScreen { /** * Updates the custom buttons shown on screen. - * Removes all buttons except the global Save button (id 0) - * then adds the selected component's custom buttons plus a Reset Position button. - * Buttons are now arranged in two columns. + * Removes all buttons except the global Save (id 0) and then adds: + * - The selected component's custom buttons plus its Reset Position button, + * - Followed by the cycle buttons at the very bottom. + * Custom buttons are arranged in two columns. */ private void updateCustomButtons() { - // Remove any buttons that are not the global Save (id 0) + // Remove all buttons except the global Save (id 0) and cycle buttons (101,102,103) for (int i = buttonList.size() - 1; i >= 0; i--) { GuiButton btn = (GuiButton) buttonList.get(i); - if (btn.id != 0) { + if (btn.id != 0 && btn.id != CYCLE_LEFT_ID && btn.id != CYCLE_RIGHT_ID && btn.id != COMPONENT_LABEL_ID) { buttonList.remove(i); } } + if (selectedComponent != null) { List customButtons = new ArrayList<>(); selectedComponent.addEditorButtons(customButtons); - // Arrange buttons in 2 columns. + // Arrange custom buttons in 2 columns. int spacingX = 10; int spacingY = 5; int buttonWidth = 120; // assuming uniform width - int startXLeft = width / 2 - buttonWidth - spacingX/2; - int startXRight = width / 2 + spacingX/2; + int startXLeft = width / 2 - buttonWidth - spacingX / 2; + int startXRight = width / 2 + spacingX / 2; int rowHeight = 0; int numButtons = customButtons.size(); for (int i = 0; i < numButtons; i += 2) { - // If two buttons in this row. if (i + 1 < numButtons) { GuiButton btnLeft = customButtons.get(i); - GuiButton btnRight = customButtons.get(i+1); + GuiButton btnRight = customButtons.get(i + 1); btnLeft.xPosition = startXLeft; btnRight.xPosition = startXRight; - // Determine row y based on button height. int rowY = height - 70 - rowHeight; btnLeft.yPosition = rowY; btnRight.yPosition = rowY; @@ -79,7 +87,6 @@ public class GuiHudEditor extends GuiScreen { buttonList.add(btnLeft); buttonList.add(btnRight); } else { - // One button: center it. GuiButton btn = customButtons.get(i); btn.xPosition = width / 2 - buttonWidth / 2; btn.yPosition = height - 70 - rowHeight; @@ -91,6 +98,37 @@ public class GuiHudEditor extends GuiScreen { GuiButton resetPos = new GuiButton(RESET_POSITION_ID, width / 2 - buttonWidth / 2, height - 70 - rowHeight, buttonWidth, 20, "Reset Position"); buttonList.add(resetPos); } + + // Now update (or add if missing) the cycle buttons at the very bottom. + // We define a group width of 160: left arrow (20), wide center label (120), right arrow (20) + int groupWidth = 160; + int groupX = (width - groupWidth) / 2; + int cycleY = height - 20; // positioned near the very bottom + + boolean hasLeft = false, hasRight = false, hasLabel = false; + for (Object button : buttonList) { + GuiButton btn = (GuiButton) button; + if (btn.id == CYCLE_LEFT_ID) { + hasLeft = true; + } else if (btn.id == CYCLE_RIGHT_ID) { + hasRight = true; + } else if (btn.id == COMPONENT_LABEL_ID) { + // Update the label text. + btn.displayString = selectedComponent != null ? selectedComponent.getClass().getSimpleName() : "None"; + hasLabel = true; + } + } + if (!hasLeft) { + buttonList.add(new GuiButton(CYCLE_LEFT_ID, groupX, cycleY, 20, 20, "<")); + } + if (!hasLabel) { + GuiButton labelBtn = new GuiButton(COMPONENT_LABEL_ID, groupX + 20, cycleY, 120, 20, selectedComponent != null ? selectedComponent.getClass().getSimpleName() : "None"); + labelBtn.enabled = false; + buttonList.add(labelBtn); + } + if (!hasRight) { + buttonList.add(new GuiButton(CYCLE_RIGHT_ID, groupX + 140, cycleY, 20, 20, ">")); + } } @Override @@ -105,23 +143,18 @@ public class GuiHudEditor extends GuiScreen { @Override protected void mouseClicked(int mouseX, int mouseY, int mouseButton) { - // Iterate over HUD components to check for selection. - // First, check for Compass width adjust hitbox if the mouse is near a CompassHudComponent. + // Check for Compass width adjust hitbox. for (HudComponent hud : ClientHudManager.getInstance().getHudComponents().values()) { if (!(hud instanceof CompassHudComponent)) continue; - ScaledResolution res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); float effectiveScale = hud.getEffectiveScale(res); int actualX = (int)(hud.posX / 100F * res.getScaledWidth()); int actualY = (int)(hud.posY / 100F * res.getScaledHeight()); - - // Even if the mouse is outside the hud bounds, we want to check for the floating adjust bar. int margin = 5; int barWidth = 6; // same as WIDTH_BAR_SIZE - // The adjust bar is drawn to the right of the component. int barX = actualX + (int)(hud.overlayWidth * effectiveScale) + margin; - int barY = actualY + (int)(((hud.overlayHeight - 20) / 2.0F) * effectiveScale); // 20 = BAR_HEIGHT + int barY = actualY + (int)(((hud.overlayHeight - 20) / 2.0F) * effectiveScale); int barHeight = (int)(20 * effectiveScale); if (mouseX >= barX && mouseX <= barX + barWidth && mouseY >= barY && mouseY <= barY + barHeight) { @@ -134,7 +167,7 @@ public class GuiHudEditor extends GuiScreen { } } - // Next, proceed with the normal hit detection for dragging/resizing of the HUD components. + // Normal hit detection for dragging/resizing. for (HudComponent hud : ClientHudManager.getInstance().getHudComponents().values()) { ScaledResolution res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); float effectiveScale = hud.getEffectiveScale(res); @@ -144,7 +177,6 @@ public class GuiHudEditor extends GuiScreen { int absHeight = (int)(hud.overlayHeight * effectiveScale); if (mouseX >= actualX && mouseX <= actualX + absWidth && mouseY >= actualY && mouseY <= actualY + absHeight) { - // Check if clicking on the resize handle (bottom-right). if (mouseX >= actualX + absWidth - HANDLE_SIZE && mouseY >= actualY + absHeight - HANDLE_SIZE) { resizing = true; selectedComponent = hud; @@ -196,7 +228,7 @@ public class GuiHudEditor extends GuiScreen { if (resizing) { int currentMouseX = Mouse.getX() * width / mc.displayWidth; int deltaX = currentMouseX - initialMouseX; - selectedComponent.scale = initialScale + deltaX; // 1 pixel = 1% change. + selectedComponent.scale = initialScale + deltaX; if (selectedComponent.scale < 50) selectedComponent.scale = 50; if (selectedComponent.scale > 300) selectedComponent.scale = 300; } @@ -216,14 +248,31 @@ public class GuiHudEditor extends GuiScreen { if (button.id == 0) { close(); } else if (button.id == RESET_POSITION_ID) { - // Reset position for selected HUD. + // Global Reset Position: center the selected HUD component. if (selectedComponent != null) { - selectedComponent.posX = 50; - selectedComponent.posY = 50; + ScaledResolution res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + float effectiveScale = selectedComponent.getEffectiveScale(res); + int compWidth, compHeight; + if (selectedComponent instanceof CompassHudComponent) { + int margin = 5; + int widthBar = 6; // as used in CompassHudComponent. + compWidth = (int)((selectedComponent.overlayWidth + margin + widthBar) * effectiveScale); + compHeight = (int)(selectedComponent.overlayHeight * effectiveScale); + } else { + compWidth = (int)(selectedComponent.overlayWidth * effectiveScale); + compHeight = (int)(selectedComponent.overlayHeight * effectiveScale); + } + int centerX = (res.getScaledWidth() - compWidth) / 2; + int centerY = (res.getScaledHeight() - compHeight) / 2; + selectedComponent.posX = (int)(100F * centerX / res.getScaledWidth()); + selectedComponent.posY = (int)(100F * centerY / res.getScaledHeight()); updateCustomButtons(); } + } else if (button.id == CYCLE_LEFT_ID) { + cycleComponent(-1); + } else if (button.id == CYCLE_RIGHT_ID) { + cycleComponent(1); } else { - // Dispatch other button actions to the selected component. if (selectedComponent != null) { selectedComponent.onEditorButtonPressed(button); updateCustomButtons(); @@ -231,6 +280,24 @@ public class GuiHudEditor extends GuiScreen { } } + private void cycleComponent(int direction) { + // Clear any dragging/resizing state. + dragging = false; + resizing = false; + resizingWidth = false; + + List components = new ArrayList<>(ClientHudManager.getInstance().getHudComponents().values()); + if (components.isEmpty()) return; + int index = components.indexOf(selectedComponent); + if (index < 0) index = 0; + index = (index + direction) % components.size(); + if (index < 0) { + index += components.size(); + } + selectedComponent = components.get(index); + updateCustomButtons(); // Refresh buttons, without resetting the entire GUI. + } + @Override protected void keyTyped(char typedChar, int keyCode) { if (keyCode == 1) { diff --git a/src/main/java/noppes/npcs/client/gui/hud/QuestTrackingComponent.java b/src/main/java/noppes/npcs/client/gui/hud/QuestTrackingComponent.java index 12335cbd6..f172b1ac7 100644 --- a/src/main/java/noppes/npcs/client/gui/hud/QuestTrackingComponent.java +++ b/src/main/java/noppes/npcs/client/gui/hud/QuestTrackingComponent.java @@ -211,8 +211,14 @@ public class QuestTrackingComponent extends HudComponent { textAlign = (textAlign + 1) % 3; button.displayString = getAlignText(); } else if (button.id == 3) { // Reset to center. - posX = 50; - posY = 50; + ScaledResolution res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + float effectiveScale = getEffectiveScale(res); + int compWidth = (int)(overlayWidth * effectiveScale); + int compHeight = (int)(overlayHeight * effectiveScale); + int centerX = (res.getScaledWidth() - compWidth) / 2; + int centerY = (res.getScaledHeight() - compHeight) / 2; + posX = (int)(100F * centerX / res.getScaledWidth()); + posY = (int)(100F * centerY / res.getScaledHeight()); } else { super.onEditorButtonPressed(button); } @@ -227,7 +233,7 @@ public class QuestTrackingComponent extends HudComponent { } } - // ---------- Helper rendering methods ----------- + // ---------- Helper rendering methods ----------- (methods unchanged) ... private int renderTextBlock(List lines, int startY, int align, int color) { int y = startY; FontRenderer font = mc.fontRenderer;