Allow Hud Component Cycling

This commit is contained in:
Kam committed 2025-03-08 19:17:25 -05:00
1 parent cef643777f
commit 83c560e7c1
2 files changed
+102 -29

No files matched your search

@@ -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<GuiButton> 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<HudComponent> 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) {
@@ -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<String> lines, int startY, int align, int color) {
int y = startY;
FontRenderer font = mc.fontRenderer;