aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/hysky/skyblocker/skyblock/fancybars
diff options
context:
space:
mode:
authorvicisacat <victor.branchu@gmail.com>2024-04-17 23:07:49 +0200
committervicisacat <victor.branchu@gmail.com>2024-04-20 16:09:49 +0200
commitf0ff0b555621f2d7f240bc72ccc1c7667badab6f (patch)
tree76feeb4c44483a364cce571eecc4809022c13411 /src/main/java/de/hysky/skyblocker/skyblock/fancybars
parentb791e38cbd36360935164e337fa992bf514cbb36 (diff)
downloadSkyblocker-f0ff0b555621f2d7f240bc72ccc1c7667badab6f.tar.gz
Skyblocker-f0ff0b555621f2d7f240bc72ccc1c7667badab6f.tar.bz2
Skyblocker-f0ff0b555621f2d7f240bc72ccc1c7667badab6f.zip
things happened yea
rewrote the entire thing to use semi data-driven BarAnchors help button in the config screen
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/skyblock/fancybars')
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java319
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java27
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java299
3 files changed, 494 insertions, 151 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java
new file mode 100644
index 00000000..7fde9117
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/BarPositioner.java
@@ -0,0 +1,319 @@
+package de.hysky.skyblocker.skyblock.fancybars;
+
+import net.minecraft.client.gui.ScreenPos;
+import net.minecraft.client.gui.ScreenRect;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+public class BarPositioner {
+
+ private final Map<BarAnchor, LinkedList<LinkedList<StatusBar>>> map = new HashMap<>(BarAnchor.values().length);
+
+ public BarPositioner() {
+ for (BarAnchor value : BarAnchor.values()) {
+ map.put(value, new LinkedList<>());
+ }
+ }
+
+
+ public int getRowCount(@NotNull BarAnchor barAnchor) {
+ return map.get(barAnchor).size();
+ }
+
+ /**
+ * Adds a row to the end of an anchor
+ *
+ * @param barAnchor the anchor
+ */
+ public void addRow(@NotNull BarAnchor barAnchor) {
+ map.get(barAnchor).add(new LinkedList<>());
+ }
+
+ /**
+ * Adds a row at the specified index
+ *
+ * @param barAnchor the anchor
+ * @param row row index
+ */
+ public void addRow(@NotNull BarAnchor barAnchor, int row) {
+ map.get(barAnchor).add(row, new LinkedList<>());
+ }
+
+ /**
+ * adds a bar to the end of a row
+ *
+ * @param barAnchor the anchor
+ * @param row the row
+ * @param bar the bar to add
+ */
+ public void addBar(@NotNull BarAnchor barAnchor, int row, StatusBar bar) {
+ LinkedList<StatusBar> statusBars = map.get(barAnchor).get(row);
+ statusBars.add(bar);
+ bar.gridY = row;
+ bar.gridX = statusBars.lastIndexOf(bar); // optimization baby, start with the end!
+ bar.anchor = barAnchor;
+ }
+
+ /**
+ * adds a bar to the specified x in a row
+ *
+ * @param barAnchor the anchor
+ * @param row the row
+ * @param x the index in the row
+ * @param bar the bar to add
+ */
+ public void addBar(@NotNull BarAnchor barAnchor, int row, int x, StatusBar bar) {
+ LinkedList<StatusBar> statusBars = map.get(barAnchor).get(row);
+ statusBars.add(x, bar);
+ bar.gridY = row;
+ bar.gridX = statusBars.indexOf(bar);
+ bar.anchor = barAnchor;
+ }
+
+ /**
+ * removes the specified bar at x on the row. If it's row is empty after being removed, the row will be auto removed
+ *
+ * @param barAnchor the anchor
+ * @param row dah row
+ * @param x dah x
+ */
+ public void removeBar(@NotNull BarAnchor barAnchor, int row, int x) {
+ LinkedList<StatusBar> statusBars = map.get(barAnchor).get(row);
+ StatusBar remove = statusBars.remove(x);
+ remove.anchor = null;
+ for (int i = x; i < statusBars.size(); i++) {
+ statusBars.get(i).gridX--;
+ }
+ if (statusBars.isEmpty()) removeRow(barAnchor, row);
+ }
+
+ /**
+ * removes the specified bar on the row. If it's row is empty after being removed, the row will be auto removed
+ *
+ * @param barAnchor the anchor
+ * @param row dah row
+ * @param bar dah bar
+ */
+ public void removeBar(@NotNull BarAnchor barAnchor, int row, StatusBar bar) {
+ LinkedList<StatusBar> barRow = map.get(barAnchor).get(row);
+ int x = barRow.indexOf(bar);
+ if (x < 0) return; // probably a bad idea
+
+ barRow.remove(bar);
+ bar.anchor = null;
+ for (int i = x; i < barRow.size(); i++) {
+ barRow.get(i).gridX--;
+ }
+ if (barRow.isEmpty()) removeRow(barAnchor, row);
+ }
+
+ /**
+ * row must be empty
+ *
+ * @param barAnchor the anchor
+ * @param row the row to remove
+ */
+ public void removeRow(@NotNull BarAnchor barAnchor, int row) {
+ LinkedList<StatusBar> barRow = map.get(barAnchor).get(row);
+ if (!barRow.isEmpty())
+ throw new IllegalStateException("Can't remove a non-empty row (" + barAnchor + "," + row + ")");
+ map.get(barAnchor).remove(row);
+ for (int i = row; i < map.get(barAnchor).size(); i++) {
+ for (StatusBar statusBar : map.get(barAnchor).get(i)) {
+ statusBar.gridY--;
+ }
+ }
+ }
+
+
+ public LinkedList<StatusBar> getRow(@NotNull BarAnchor barAnchor, int row) {
+ return map.get(barAnchor).get(row);
+ }
+
+ public StatusBar getBar(@NotNull BarAnchor barAnchor, int row, int x) {
+ return map.get(barAnchor).get(row).get(x);
+ }
+
+ public boolean hasNeighbor(@NotNull BarAnchor barAnchor, int row, int x, boolean right) {
+ LinkedList<StatusBar> statusBars = map.get(barAnchor).get(row);
+ if (barAnchor.isRight()) {
+ return (right && x < statusBars.size() - 1) || (!right && x > 0);
+ } else {
+ return (right && x > 0) || (!right && x < statusBars.size() - 1);
+ }
+ }
+
+
+ public enum BarAnchor {
+ HOTBAR_LEFT(true, false,
+ (scaledWidth, scaledHeight) -> new ScreenPos(scaledWidth / 2 - 91 - 2, scaledHeight - 5),
+ SizeRule.freeSize(25, 2, 6)),
+
+ HOTBAR_RIGHT(true, true,
+ (scaledWidth, scaledHeight) -> new ScreenPos(scaledWidth / 2 + 91 + 2, scaledHeight - 5),
+ SizeRule.freeSize(25, 2, 6)),
+
+ HOTBAR_TOP(true, true,
+ (scaledWidth, scaledHeight) -> new ScreenPos(scaledWidth / 2 - 91, scaledHeight - 23),
+ SizeRule.targetSize(12, 182, 2),
+ anchorPosition -> new ScreenRect(anchorPosition.x(), anchorPosition.y() - 20, 182, 20)),
+
+ SCREEN_TOP_LEFT(false, true,
+ ((scaledWidth, scaledHeight) -> new ScreenPos(5, 5)),
+ SizeRule.freeSize(25, 2, 6)
+ ),
+ SCREEN_TOP_RIGHT(false, false,
+ ((scaledWidth, scaledHeight) -> new ScreenPos(scaledWidth - 5, 5)),
+ SizeRule.freeSize(25, 2, 6)
+ ),
+ SCREEN_BOTTOM_LEFT(true, true,
+ ((scaledWidth, scaledHeight) -> new ScreenPos(5, scaledHeight - 5)),
+ SizeRule.freeSize(25, 2, 6)
+ ),
+ SCREEN_BOTTOM_RIGHT(true, false,
+ ((scaledWidth, scaledHeight) -> new ScreenPos(scaledWidth - 5, scaledHeight - 5)),
+ SizeRule.freeSize(25, 2, 6)
+ ),
+ ;
+
+ private final AnchorPositionProvider positionProvider;
+ private final AnchorHitboxProvider hitboxProvider;
+ private final boolean up;
+ private final boolean right;
+ private final SizeRule sizeRule;
+
+ /**
+ * @param up whether the rows stack towards the top of the screen from the anchor (false is bottom)
+ * @param right whether the bars are line up towards the right of the screen from the anchor (false is left)
+ * @param positionProvider provides the position of the anchor for a give screen size
+ * @param sizeRule the rule the bars should follow. See {@link SizeRule}
+ * @param hitboxProvider provides the hitbox for when the anchor has no bars for the config screen
+ */
+ BarAnchor(boolean up, boolean right, AnchorPositionProvider positionProvider, SizeRule sizeRule, AnchorHitboxProvider hitboxProvider) {
+ this.positionProvider = positionProvider;
+ this.up = up;
+ this.right = right;
+ this.hitboxProvider = hitboxProvider;
+ this.sizeRule = sizeRule;
+ }
+
+ BarAnchor(boolean up, boolean right, AnchorPositionProvider positionProvider, SizeRule sizeRule) {
+ this(up, right, positionProvider, sizeRule,
+ anchorPosition -> new ScreenRect(anchorPosition.x() - (right ? 0 : 20), anchorPosition.y() - (up ? 20 : 0), 20, 20));
+ }
+
+ public ScreenPos getAnchorPosition(int scaledWidth, int scaledHeight) {
+ return positionProvider.getPosition(scaledWidth, scaledHeight);
+ }
+
+ public ScreenRect getAnchorHitbox(ScreenPos anchorPosition) {
+ return hitboxProvider.getHitbox(anchorPosition);
+ }
+
+ /**
+ * whether the rows stack towards the top of the screen from the anchor (false is bottom)
+ *
+ * @return true if towards the top, false otherwise
+ */
+ public boolean isUp() {
+ return up;
+ }
+
+ /**
+ * whether the bars are line up towards the right of the screen from the anchor (false is left)
+ *
+ * @return true if towards the right, false otherwise
+ */
+ public boolean isRight() {
+ return right;
+ }
+
+ public SizeRule getSizeRule() {
+ return sizeRule;
+ }
+
+ private static final List<BarAnchor> cached = List.of(values());
+
+ /**
+ * cached version of {@link BarAnchor#values()}
+ *
+ * @return the list of anchors
+ */
+ public static List<BarAnchor> allAnchors() {
+ return cached;
+ }
+ }
+
+ /**
+ * The rules the bars on an anchor should follow
+ *
+ * @param isTargetSize whether the bars went to fit to a target width
+ * @param targetSize the size of all the bars on a row should add up to this (target size)
+ * @param totalWidth the total width taken by all the bars on the row (target size)
+ * @param widthPerSize the width of each size "unit" (free size)
+ * @param minSize the minimum (free and target size)
+ * @param maxSize the maximum (free and target size, THIS SHOULD BE THE SAME AS {@code targetSize} FOR {@code isTargetSize = true})
+ */
+ public record SizeRule(boolean isTargetSize, int targetSize, int totalWidth, int widthPerSize, int minSize,
+ int maxSize) {
+ public static SizeRule freeSize(int widthPerSize, int minSize, int maxSize) {
+ return new SizeRule(false, -1, -1, widthPerSize, minSize, maxSize);
+ }
+
+ public static SizeRule targetSize(int targetSize, int totalWidth, int minSize) {
+ return new SizeRule(true, targetSize, totalWidth, -1, minSize, targetSize);
+ }
+ }
+
+ /**
+ * A record representing a snapshot of a bar's position
+ *
+ * @param barAnchor
+ * @param x
+ * @param y the row
+ */
+ public record BarLocation(@Nullable BarAnchor barAnchor, int x, int y) {
+
+ public static final BarLocation NULL = new BarLocation(null, -1, -1);
+
+ public static BarLocation of(StatusBar bar) {
+ return new BarLocation(bar.anchor, bar.gridX, bar.gridY);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) return true;
+ if (object == null || getClass() != object.getClass()) return false;
+
+ BarLocation that = (BarLocation) object;
+ return x == that.x && y == that.y && barAnchor == that.barAnchor;
+ }
+
+ public boolean equals(BarAnchor barAnchor, int x, int y) {
+ return x == this.x && y == this.y && barAnchor == this.barAnchor;
+ }
+ }
+
+ /**
+ * provides the position of the anchor for a give screen size
+ */
+ @FunctionalInterface
+ interface AnchorPositionProvider {
+
+ ScreenPos getPosition(int scaledWidth, int scaledHeight);
+ }
+
+ @FunctionalInterface
+ interface AnchorHitboxProvider {
+
+ /**
+ * The hitbox, as in how large the area of "snapping" is if there are no bars on this anchor
+ *
+ * @param anchorPosition the position of the anchor
+ * @return the rectangle that represents the hitbox
+ */
+ ScreenRect getHitbox(ScreenPos anchorPosition);
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java
index ea4a0388..5ece1934 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBar.java
@@ -86,12 +86,14 @@ public class StatusBar implements Widget, Drawable, Element, Selectable {
private @Nullable OnClick onClick = null;
public int gridX = 0;
public int gridY = 0;
+ public @Nullable BarPositioner.BarAnchor anchor = null;
public int size = 1;
private int width = 0;
public float fill = 0;
public float overflowFill = 0;
+ public boolean ghost = false;
private Object value = "";
@@ -116,6 +118,8 @@ public class StatusBar implements Widget, Drawable, Element, Selectable {
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
if (width <= 0) return;
+ // half works lol. only puts transparency on the filler of the bar
+ if (ghost) context.setShaderColor(1f,1f,1f,0.25f);
switch (iconPosition) {
case LEFT -> context.drawGuiTexture(icon, x, y, 9, 9);
case RIGHT -> context.drawGuiTexture(icon, x + width - 9, y, 9, 9);
@@ -130,6 +134,7 @@ public class StatusBar implements Widget, Drawable, Element, Selectable {
if (hasOverflow && overflowFill > 0) {
RenderHelper.renderNineSliceColored(context, BAR_FILL, barX + 1, y + 2, (int) ((barWith - 2) * overflowFill), 5, colors[1]);
}
+ if (ghost) context.setShaderColor(1f,1f,1f,1f);
//context.drawText(MinecraftClient.getInstance().textRenderer, gridX + " " + gridY + " s:" + size , x, y-9, Colors.WHITE, true);
}
@@ -159,13 +164,19 @@ public class StatusBar implements Widget, Drawable, Element, Selectable {
int temp_x = x;
int temp_y = y;
int temp_width = width;
+ boolean temp_ghost = ghost;
+
x = mouseX;
y = mouseY;
width = 100;
+ ghost = false;
+
render(context, mouseX, mouseY, delta);
+
x = temp_x;
y = temp_y;
width = temp_width;
+ ghost = temp_ghost;
}
// GUI shenanigans
@@ -204,14 +215,6 @@ public class StatusBar implements Widget, Drawable, Element, Selectable {
return 9;
}
- public int getMinimumSize() {
- return 2;
- }
-
- public int getMaximumSize() {
- return gridY < 0 ? 6 : 12;
- }
-
@Override
public ScreenRect getNavigationFocus() {
return Widget.super.getNavigationFocus();
@@ -267,6 +270,7 @@ public class StatusBar implements Widget, Drawable, Element, Selectable {
.append("x", x)
.append("y", y)
.append("width", width)
+ .append("anchor", anchor)
.toString();
}
@@ -315,11 +319,13 @@ public class StatusBar implements Widget, Drawable, Element, Selectable {
if (object.has("text_color")) this.textColor = new Color(Integer.parseInt(object.get("text_color").getAsString(), 16));
+ String maybeAnchor = object.get("anchor").getAsString().trim();
+ this.anchor = maybeAnchor.equals("null") ? null : BarPositioner.BarAnchor.valueOf(maybeAnchor);
this.size = object.get("size").getAsInt();
this.gridX = object.get("x").getAsInt();
this.gridY = object.get("y").getAsInt();
// these are optional too, why not
- if (object.has("icon_position")) this.iconPosition = IconPosition.valueOf(object.get("icon_position").getAsString());
+ if (object.has("icon_position")) this.iconPosition = IconPosition.valueOf(object.get("icon_position").getAsString().trim());
if (object.has("show_text")) this.showText = object.get("show_text").getAsBoolean();
}
@@ -335,6 +341,9 @@ public class StatusBar implements Widget, Drawable, Element, Selectable {
object.addProperty("text_color", Integer.toHexString(textColor.getRGB()).substring(2));
}
object.addProperty("size", size);
+ if (anchor != null) {
+ object.addProperty("anchor", anchor.toString());
+ } else object.addProperty("anchor", "null");
object.addProperty("x", gridX);
object.addProperty("y", gridY);
object.addProperty("icon_position", iconPosition.toString());
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java
index 3bcc2011..7c1aa71b 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/fancybars/StatusBarsConfigScreen.java
@@ -10,12 +10,14 @@ import net.minecraft.client.gui.ScreenPos;
import net.minecraft.client.gui.ScreenRect;
import net.minecraft.client.gui.navigation.NavigationAxis;
import net.minecraft.client.gui.navigation.NavigationDirection;
+import net.minecraft.client.gui.screen.PopupScreen;
import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text;
-import net.minecraft.util.Colors;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW;
+import de.hysky.skyblocker.skyblock.fancybars.BarPositioner.BarLocation;
import java.util.Collection;
import java.util.HashMap;
@@ -27,7 +29,7 @@ public class StatusBarsConfigScreen extends Screen {
public static final long RESIZE_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_HRESIZE_CURSOR);
- private final Map<ScreenRect, int[]> meaningFullName = new HashMap<>();
+ private final Map<ScreenRect, BarLocation> meaningFullName = new HashMap<>();
private static final int HOTBAR_WIDTH = 182;
private @Nullable StatusBar cursorBar = null;
@@ -37,21 +39,24 @@ public class StatusBarsConfigScreen extends Screen {
FancyStatusBars.updatePositions();
}
- private final int[] currentCursorCoords = new int[]{0, 0};
+ private BarLocation currentInsertLocation = new BarLocation(null, 0, 0);
- private final Pair<int[], Boolean> resizeHover = new ObjectBooleanMutablePair<>(new int[]{0, 0}, false);
+ private final Pair<BarLocation, Boolean> resizeHover = new ObjectBooleanMutablePair<>(BarLocation.NULL, false);
- private final Pair<int[], int[]> resizedBars = ObjectObjectMutablePair.of(new int[]{0, 0}, new int[]{0, 0});
+ private final Pair<BarLocation, BarLocation> resizedBars = ObjectObjectMutablePair.of(BarLocation.NULL, BarLocation.NULL);
private boolean resizing = false;
private EditBarWidget editBarWidget;
+ // prioritize left and right cuz they are much smaller space than up and down
+ private static final NavigationDirection[] DIRECTION_CHECK_ORDER = new NavigationDirection[]{NavigationDirection.LEFT, NavigationDirection.RIGHT, NavigationDirection.UP, NavigationDirection.DOWN};
+
@SuppressWarnings("UnreachableCode") // IntelliJ big stupid
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
- for (ScreenRect screenRect : meaningFullName.keySet()) {
+ /*for (ScreenRect screenRect : meaningFullName.keySet()) {
context.fillGradient(screenRect.position().x(), screenRect.position().y(), screenRect.position().x() + screenRect.width(), screenRect.position().y() + screenRect.height(), 0xFFFF0000, 0xFF0000FF);
- }
+ }*/
super.render(context, mouseX, mouseY, delta);
context.drawGuiTexture(HOTBAR_TEXTURE, width / 2 - HOTBAR_WIDTH / 2, height - 22, HOTBAR_WIDTH, 22);
editBarWidget.render(context, mouseX, mouseY, delta);
@@ -60,109 +65,99 @@ public class StatusBarsConfigScreen extends Screen {
assert client != null;
WindowAccessor window = (WindowAccessor) (Object) client.getWindow();
assert window != null;
+
if (cursorBar != null) {
cursorBar.renderCursor(context, mouseX, mouseY, delta);
- context.drawText(textRenderer, currentCursorCoords[0] + " " + currentCursorCoords[1], 100, 5, Colors.WHITE, true);
-
-
- if (FancyStatusBars.barGrid.getTopSize() == 0 && topBarZone.overlaps(mouseRect) && currentCursorCoords[1] != 1) {
- FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY);
- FancyStatusBars.barGrid.addRow(1, true);
- FancyStatusBars.barGrid.add(1, 1, cursorBar);
- currentCursorCoords[1] = 1;
- FancyStatusBars.updatePositions();
- } else if (FancyStatusBars.barGrid.getBottomLeftSize() == 0 && bottomLeftBarZone.overlaps(mouseRect) && (currentCursorCoords[0] != -1 || currentCursorCoords[1] != -1)) {
- FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY);
- FancyStatusBars.barGrid.addRow(-1, false);
- FancyStatusBars.barGrid.add(-1, -1, cursorBar);
- currentCursorCoords[0] = -1;
- currentCursorCoords[1] = -1;
- FancyStatusBars.updatePositions();
- } else if (FancyStatusBars.barGrid.getBottomRightSize() == 0 && bottomRightBarZone.overlaps(mouseRect) && (currentCursorCoords[0] != 1 || currentCursorCoords[1] != -1)) {
- FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY);
- FancyStatusBars.barGrid.addRow(-1, true);
- FancyStatusBars.barGrid.add(1, -1, cursorBar);
- currentCursorCoords[0] = 1;
- currentCursorCoords[1] = -1;
- FancyStatusBars.updatePositions();
- } else rectLoop:for (ScreenRect screenRect : meaningFullName.keySet()) {
- for (NavigationDirection direction : NavigationDirection.values()) {
+ boolean inserted = false;
+ rectLoop:
+ for (ScreenRect screenRect : meaningFullName.keySet()) {
+ for (NavigationDirection direction : DIRECTION_CHECK_ORDER) {
boolean overlaps = screenRect.getBorder(direction).add(direction).overlaps(mouseRect);
if (overlaps) {
- int[] ints = meaningFullName.get(screenRect);
- final boolean vertical = direction.getAxis().equals(NavigationAxis.VERTICAL);
- int offsetX = 0;
- int offsetY = 0;
- if (vertical) {
- if (!direction.isPositive()) {
- offsetY = ints[1] > 0 ? 1 : 0;
- } else {
- offsetY = ints[1] > 0 ? 0 : -1;
+ BarLocation barSnap = meaningFullName.get(screenRect);
+ if (direction.getAxis().equals(NavigationAxis.VERTICAL)) {
+ int neighborInsertY = getNeighborInsertY(barSnap, !direction.isPositive());
+ if (!currentInsertLocation.equals(barSnap.barAnchor(), barSnap.x(), neighborInsertY)) {
+ if (cursorBar.anchor != null)
+ FancyStatusBars.barPositioner.removeBar(cursorBar.anchor, cursorBar.gridY, cursorBar);
+ FancyStatusBars.barPositioner.addRow(barSnap.barAnchor(), neighborInsertY);
+ FancyStatusBars.barPositioner.addBar(barSnap.barAnchor(), neighborInsertY, cursorBar);
+ currentInsertLocation = BarLocation.of(cursorBar);
+ inserted = true;
}
} else {
- if (direction.isPositive()) {
- offsetX = ints[0] > 0 ? 1 : 0;
- } else {
- offsetX = ints[0] > 0 ? 0 : -1;
- }
- }
- context.drawText(textRenderer, ints[0] + offsetX + " " + ints[1] + offsetY, 100, 15, Colors.WHITE, true);
- if (ints[0] + offsetX != currentCursorCoords[0] || ints[1] + offsetY != currentCursorCoords[1]) {
- currentCursorCoords[0] = ints[0] + offsetX;
- currentCursorCoords[1] = ints[1] + offsetY;
- FancyStatusBars.barGrid.remove(cursorBar.gridX, cursorBar.gridY);
-
-
- if (vertical) {
-
- FancyStatusBars.barGrid.addRow(ints[1] + offsetY, ints[0] > 0);
- FancyStatusBars.barGrid.add(ints[0] < 0 ? -1 : 1, ints[1] + offsetY, cursorBar);
- } else {
-
- FancyStatusBars.barGrid.add(ints[0] + offsetX, ints[1], cursorBar);
+ int neighborInsertX = getNeighborInsertX(barSnap, direction.isPositive());
+ if (!currentInsertLocation.equals(barSnap.barAnchor(), neighborInsertX, barSnap.y())) {
+ if (cursorBar.anchor != null)
+ FancyStatusBars.barPositioner.removeBar(cursorBar.anchor, cursorBar.gridY, cursorBar);
+ FancyStatusBars.barPositioner.addBar(barSnap.barAnchor(), barSnap.y(), neighborInsertX, cursorBar);
+ currentInsertLocation = BarLocation.of(cursorBar);
+ inserted = true;
}
- FancyStatusBars.updatePositions();
}
break rectLoop;
}
}
}
+ if (inserted) {
+ FancyStatusBars.updatePositions();
+ return;
+ }
+ // check for hovering empty anchors
+ for (BarPositioner.BarAnchor barAnchor : BarPositioner.BarAnchor.allAnchors()) {
+ if (FancyStatusBars.barPositioner.getRowCount(barAnchor) != 0) continue;
+ ScreenRect anchorHitbox = barAnchor.getAnchorHitbox(barAnchor.getAnchorPosition(width, height));
+ context.fill(anchorHitbox.getLeft(), anchorHitbox.getTop(), anchorHitbox.getRight(), anchorHitbox.getBottom(), 0x99FFFFFF);
+ if (anchorHitbox.overlaps(mouseRect) && currentInsertLocation.barAnchor() != barAnchor) {
+ if (cursorBar.anchor != null)
+ FancyStatusBars.barPositioner.removeBar(cursorBar.anchor, cursorBar.gridY, cursorBar);
+ FancyStatusBars.barPositioner.addRow(barAnchor);
+ FancyStatusBars.barPositioner.addBar(barAnchor, 0, cursorBar);
+ currentInsertLocation = BarLocation.of(cursorBar);
+ FancyStatusBars.updatePositions();
+ }
+ }
} else {
- // RESIZING STATE
- if (resizing) {
+ if (resizing) { // actively resizing one or 2 bars
int middleX;
- boolean bottom;
- int[] left = resizedBars.left();
- int[] right = resizedBars.right();
- boolean hasRight = right[0] != 0;
- boolean hasLeft = left[0] != 0;
+ BarLocation left = resizedBars.left();
+ BarLocation right = resizedBars.right();
+ boolean hasRight = !right.equals(BarLocation.NULL);
+ boolean hasLeft = !left.equals(BarLocation.NULL);
+ BarPositioner.BarAnchor barAnchor;
if (!hasRight) {
- StatusBar bar = FancyStatusBars.barGrid.getBar(left[0], left[1]);
+ barAnchor = left.barAnchor();
+ StatusBar bar = FancyStatusBars.barPositioner.getBar(barAnchor, left.y(), left.x());
middleX = bar.getX() + bar.getWidth();
- bottom = bar.gridY < 0;
} else {
- middleX = FancyStatusBars.barGrid.getBar(right[0], right[1]).getX();
- bottom = right[1] < 0;
+ barAnchor = right.barAnchor();
+ middleX = FancyStatusBars.barPositioner.getBar(barAnchor, right.y(), right.x()).getX();
}
- int i = bottom ? 20 : 10;
+
boolean doResize = true;
StatusBar rightBar = null;
StatusBar leftBar = null;
- context.drawText(textRenderer, Integer.toString(mouseX - middleX), 100, 25, -1, true);
+ BarPositioner.SizeRule sizeRule = barAnchor.getSizeRule();
- if (mouseX < middleX) {
- if (middleX - mouseX > i) {
+ float widthPerSize;
+ if (sizeRule.isTargetSize())
+ widthPerSize = (float) sizeRule.totalWidth() / sizeRule.targetSize();
+ else
+ widthPerSize = sizeRule.widthPerSize();
+ // resize towards the left
+ if (mouseX < middleX) {
+ if (middleX - mouseX > widthPerSize / .75f) {
if (hasRight) {
- rightBar = FancyStatusBars.barGrid.getBar(right[0], right[1]);
- if (rightBar.size + 1 > rightBar.getMaximumSize()) doResize = false;
+ rightBar = FancyStatusBars.barPositioner.getBar(barAnchor, right.y(), right.x());
+ if (rightBar.size + 1 > sizeRule.maxSize()) doResize = false;
}
if (hasLeft) {
- leftBar = FancyStatusBars.barGrid.getBar(left[0], left[1]);
- if (leftBar.size - 1 < leftBar.getMinimumSize()) doResize = false;
+ leftBar = FancyStatusBars.barPositioner.getBar(barAnchor, left.y(), left.x());
+ if (leftBar.size - 1 < sizeRule.minSize()) doResize = false;
}
if (doResize) {
@@ -171,18 +166,16 @@ public class StatusBarsConfigScreen extends Screen {
FancyStatusBars.updatePositions();
}
}
- } else {
- if (mouseX - middleX > i) {
-
+ } else { // towards the right
+ if (mouseX - middleX > widthPerSize / .75f) {
if (hasRight) {
- rightBar = FancyStatusBars.barGrid.getBar(right[0], right[1]);
- if (rightBar.size - 1 < rightBar.getMinimumSize()) doResize = false;
+ rightBar = FancyStatusBars.barPositioner.getBar(barAnchor, right.y(), right.x());
+ if (rightBar.size - 1 < sizeRule.minSize()) doResize = false;
}
if (hasLeft) {
- leftBar = FancyStatusBars.barGrid.getBar(left[0], left[1]);
- if (leftBar.size + 1 > leftBar.getMaximumSize()) doResize = false;
+ leftBar = FancyStatusBars.barPositioner.getBar(barAnchor, left.y(), left.x());
+ if (leftBar.size + 1 > sizeRule.maxSize()) doResize = false;
}
- context.drawText(textRenderer, leftBar.size + " " + leftBar.getMaximumSize(), 100, 35, -1, true);
if (doResize) {
if (hasRight) rightBar.size--;
@@ -191,29 +184,26 @@ public class StatusBarsConfigScreen extends Screen {
}
}
}
- GLFW.glfwSetCursor(window.getHandle(), RESIZE_CURSOR);
- }
- // NOT RESIZING STATE
- else {
+
+ } else { // hovering bars
rectLoop:
for (ScreenRect screenRect : meaningFullName.keySet()) {
for (NavigationDirection direction : new NavigationDirection[]{NavigationDirection.LEFT, NavigationDirection.RIGHT}) {
boolean overlaps = screenRect.getBorder(direction).add(direction).overlaps(mouseRect);
if (overlaps && !editBarWidget.isMouseOver(mouseX, mouseY)) {
- int[] ints = meaningFullName.get(screenRect);
- boolean left = direction.equals(NavigationDirection.LEFT);
- if ((ints[0] == 1 && left) || (ints[0] == -1 && !left) || (!left && ints[1] > 0 && ints[0] == FancyStatusBars.barGrid.getRow(ints[1], true).size())) {
+ BarLocation barLocation = meaningFullName.get(screenRect);
+ boolean right = direction.equals(NavigationDirection.RIGHT);
+ // can't resize on the edge of a target size row!
+ if (barLocation.barAnchor().getSizeRule().isTargetSize() && !FancyStatusBars.barPositioner.hasNeighbor(barLocation.barAnchor(), barLocation.y(), barLocation.x(), right)) {
break;
}
- resizeHover.first()[0] = ints[0];
- resizeHover.first()[1] = ints[1];
- resizeHover.right(!left);
+ resizeHover.first(barLocation);
+ resizeHover.right(right);
GLFW.glfwSetCursor(window.getHandle(), RESIZE_CURSOR);
break rectLoop;
} else {
- resizeHover.first()[0] = 0;
- resizeHover.first()[1] = 0;
+ resizeHover.first(BarLocation.NULL);
GLFW.glfwSetCursor(window.getHandle(), 0);
}
}
@@ -222,9 +212,27 @@ public class StatusBarsConfigScreen extends Screen {
}
}
- private ScreenRect topBarZone = new ScreenRect(0, 0, 0, 0);
- private ScreenRect bottomLeftBarZone = new ScreenRect(0, 0, 0, 0);
- private ScreenRect bottomRightBarZone = new ScreenRect(0, 0, 0, 0);
+ private static int getNeighborInsertX(BarLocation barLocation, boolean right) {
+ BarPositioner.BarAnchor barAnchor = barLocation.barAnchor();
+ int gridX = barLocation.x();
+ if (barAnchor == null) return 0;
+ if (right) {
+ return barAnchor.isRight() ? gridX + 1 : gridX;
+ } else {
+ return barAnchor.isRight() ? gridX : gridX + 1;
+ }
+ }
+
+ private static int getNeighborInsertY(BarLocation barLocation, boolean up) {
+ BarPositioner.BarAnchor barAnchor = barLocation.barAnchor();
+ int gridY = barLocation.y();
+ if (barAnchor == null) return 0;
+ if (up) {
+ return barAnchor.isUp() ? gridY + 1 : gridY;
+ } else {
+ return barAnchor.isUp() ? gridY : gridY + 1;
+ }
+ }
@Override
protected void init() {
@@ -234,24 +242,31 @@ public class StatusBarsConfigScreen extends Screen {
addSelectableChild(editBarWidget); // rendering separately to have it above hotbar
Collection<StatusBar> values = FancyStatusBars.statusBars.values();
values.forEach(this::setup);
- checkZeroCoordinates(values);
+ checkNullAnchor(values);
updateScreenRects();
- topBarZone = new ScreenRect(width / 2 - HOTBAR_WIDTH / 2, height - 22 - 15, HOTBAR_WIDTH, 15);
- bottomLeftBarZone = new ScreenRect(width / 2 - HOTBAR_WIDTH / 2 - 20, height - 22, 20, 22);
- bottomRightBarZone = new ScreenRect(width / 2 + HOTBAR_WIDTH / 2, height - 22, 20, 22);
+ this.addDrawableChild(ButtonWidget.builder(Text.literal("?"),
+ button -> {
+ assert client != null;
+ client.setScreen(new PopupScreen.Builder(this, Text.translatable("skyblocker.bars.config.explanationTitle"))
+ .button(Text.translatable("gui.ok"), PopupScreen::close)
+ .message(Text.translatable("skyblocker.bars.config.explanation"))
+ .build());
+ })
+ .dimensions(width - 20, (height - 15) / 2, 15, 15)
+ .build());
}
private void setup(StatusBar statusBar) {
this.addDrawableChild(statusBar);
- statusBar.setOnClick(this::onClick);
+ statusBar.setOnClick(this::onBarClick);
}
- private static void checkZeroCoordinates(Iterable<StatusBar> bars) {
+ private static void checkNullAnchor(Iterable<StatusBar> bars) {
int offset = 0;
for (StatusBar statusBar : bars) {
- if (statusBar.gridX == 0 || statusBar.gridY == 0) {
+ if (statusBar.anchor == null) {
statusBar.setX(5);
- statusBar.setY(5 + offset);
+ statusBar.setY(50 + offset);
statusBar.setWidth(30);
offset += statusBar.getHeight();
}
@@ -263,6 +278,7 @@ public class StatusBarsConfigScreen extends Screen {
public void removed() {
super.removed();
FancyStatusBars.statusBars.values().forEach(statusBar -> statusBar.setOnClick(null));
+ if (cursorBar != null) cursorBar.ghost = false;
FancyStatusBars.updatePositions();
assert client != null;
GLFW.glfwSetCursor(((WindowAccessor) (Object) client.getWindow()).getHandle(), 0);
@@ -274,11 +290,14 @@ public class StatusBarsConfigScreen extends Screen {
return false;
}
- private void onClick(StatusBar statusBar, int button, int mouseX, int mouseY) {
+ private void onBarClick(StatusBar statusBar, int button, int mouseX, int mouseY) {
if (button == 0) {
cursorBar = statusBar;
- FancyStatusBars.barGrid.remove(statusBar.gridX, statusBar.gridY);
+ cursorBar.ghost = true;
+ if (statusBar.anchor != null)
+ FancyStatusBars.barPositioner.removeBar(statusBar.anchor, statusBar.gridY, statusBar);
FancyStatusBars.updatePositions();
+ cursorBar.setX(width + 5); // send it to limbo lol
updateScreenRects();
} else if (button == 1) {
int x = Math.min(mouseX - 1, width - editBarWidget.getWidth());
@@ -292,25 +311,27 @@ public class StatusBarsConfigScreen extends Screen {
private void updateScreenRects() {
meaningFullName.clear();
- FancyStatusBars.statusBars.values().forEach(statusBar1 -> meaningFullName.put(
- new ScreenRect(new ScreenPos(statusBar1.getX(), statusBar1.getY()), statusBar1.getWidth(), statusBar1.getHeight()),
- new int[]{statusBar1.gridX, statusBar1.gridY}));
+ FancyStatusBars.statusBars.values().forEach(statusBar1 -> {
+ if (statusBar1.anchor == null) return;
+ meaningFullName.put(
+ new ScreenRect(new ScreenPos(statusBar1.getX(), statusBar1.getY()), statusBar1.getWidth(), statusBar1.getHeight()),
+ BarLocation.of(statusBar1));
+ });
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
if (cursorBar != null) {
+ cursorBar.ghost = false;
cursorBar = null;
FancyStatusBars.updatePositions();
- checkZeroCoordinates(FancyStatusBars.statusBars.values());
+ checkNullAnchor(FancyStatusBars.statusBars.values());
updateScreenRects();
return true;
} else if (resizing) {
resizing = false;
- resizedBars.left()[0] = 0;
- resizedBars.left()[1] = 0;
- resizedBars.right()[0] = 0;
- resizedBars.right()[1] = 0;
+ resizedBars.left(BarLocation.NULL);
+ resizedBars.right(BarLocation.NULL);
updateScreenRects();
return true;
}
@@ -319,29 +340,23 @@ public class StatusBarsConfigScreen extends Screen {
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
- int[] first = resizeHover.first();
+ BarLocation first = resizeHover.first();
// want the right click thing to have priority
- if (!editBarWidget.isMouseOver(mouseX, mouseY) && button == 0 && first[0] != 0 && first[1] != 0) {
+ if (!editBarWidget.isMouseOver(mouseX, mouseY) && button == 0 && !first.equals(BarLocation.NULL)) {
+ BarPositioner.BarAnchor barAnchor = first.barAnchor();
+ assert barAnchor != null;
if (resizeHover.right()) {
- resizedBars.left()[0] = first[0];
- resizedBars.left()[1] = first[1];
- if (FancyStatusBars.barGrid.coordinatesExist(first[0] + 1, first[1])) {
- resizedBars.right()[0] = first[0] + 1;
- resizedBars.right()[1] = first[1];
- } else {
- resizedBars.right()[0] = 0;
- resizedBars.right()[1] = 0;
- }
+ resizedBars.left(first);
+
+ if (FancyStatusBars.barPositioner.hasNeighbor(barAnchor, first.y(), first.x(), true)) {
+ resizedBars.right(new BarLocation(barAnchor, first.x() + (barAnchor.isRight() ? 1 : -1), first.y()));
+ } else resizedBars.right(BarLocation.NULL);
} else {
- resizedBars.right()[0] = first[0];
- resizedBars.right()[1] = first[1];
- if (FancyStatusBars.barGrid.coordinatesExist(first[0] - 1, first[1])) {
- resizedBars.left()[0] = first[0] - 1;
- resizedBars.left()[1] = first[1];
- } else {
- resizedBars.left()[0] = 0;
- resizedBars.left()[1] = 0;
- }
+ resizedBars.right(first);
+
+ if (FancyStatusBars.barPositioner.hasNeighbor(barAnchor, first.y(), first.x(), false)) {
+ resizedBars.left(new BarLocation(barAnchor, first.x() + (barAnchor.isRight() ? -1 : 1), first.y()));
+ } else resizedBars.left(BarLocation.NULL);
}
resizing = true;
return true;