From 7f936e8f7276158ce58690cd8ea9aff7f5254366 Mon Sep 17 00:00:00 2001 From: brandon3055 Date: Sat, 16 Mar 2024 18:11:49 +1100 Subject: [PATCH] A few minor GUI fixes and additions. --- .../lib/gui/modular/elements/GuiElement.java | 35 ++++++- .../gui/modular/elements/GuiManipulable.java | 91 +++++++++++++++---- .../lib/gui/modular/elements/GuiSlots.java | 5 +- .../modular/ModularGuiContainerMenu.java | 8 +- 4 files changed, 113 insertions(+), 26 deletions(-) diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiElement.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiElement.java index 4ea5e1ac..1282998c 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiElement.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiElement.java @@ -19,9 +19,7 @@ import org.jetbrains.annotations.Nullable; import java.security.InvalidParameterException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; import java.util.function.Consumer; import java.util.function.Supplier; @@ -53,6 +51,7 @@ public class GuiElement> extends ConstrainedGeometry private final List> removeQueue = new ArrayList<>(); private final List> childElements = new ArrayList<>(); private final List> childElementsUnmodifiable = Collections.unmodifiableList(childElements); + private final Map, Integer> reorderMap = new HashMap<>(); public boolean initialized = false; private Minecraft mc; @@ -119,6 +118,15 @@ public void addChild(GuiElement child) { } protected void applyQueuedChildUpdates() { + if (!reorderMap.isEmpty()) { + reorderMap.forEach((element, index) -> { + if (!childElements.contains(element)) return; + childElements.remove(element); + childElements.add(Math.min(index, childElements.size()), element); + }); + reorderMap.clear(); + } + if (!removeQueue.isEmpty()) { childElements.removeAll(removeQueue); removeQueue.clear(); @@ -155,6 +163,27 @@ public void removeChild(GuiElement child) { addedQueue.remove(child); } + /** + * Sets a child as the last element in the child lest, meaning it will render over all other elements. + */ + public void bringChildToForeground(GuiElement child) { + sendChildToIndex(child, childElements.size() - 1); + } + + /** + * sends a child to a specific index in the child lest. + */ + public void sendChildToIndex(GuiElement child, int index) { + reorderMap.put(child, index); + } + + /** + * Sets a child as the first element in the child lest, meaning it will render under all other elements. + */ + public void sendChildToBackground(GuiElement child) { + sendChildToIndex(child, 0); + } + @Override public boolean isDescendantOf(GuiElement ancestor) { return ancestor == parent || parent.isDescendantOf(ancestor); diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiManipulable.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiManipulable.java index d95835e4..d85daf4a 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiManipulable.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiManipulable.java @@ -8,10 +8,11 @@ import codechicken.lib.gui.modular.lib.geometry.Rectangle; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; -import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.function.Consumer; + import static codechicken.lib.gui.modular.lib.geometry.Constraint.literal; import static codechicken.lib.gui.modular.lib.geometry.Constraint.match; import static codechicken.lib.gui.modular.lib.geometry.GeoParam.*; @@ -44,6 +45,7 @@ public class GuiManipulable extends GuiElement implements Conten private boolean dragBottom = false; private boolean dragRight = false; private boolean enableCursors = false; + private boolean resetOnUiInit = true; //Made available for external position restraints public int xMin = 0; @@ -53,8 +55,8 @@ public class GuiManipulable extends GuiElement implements Conten protected Rectangle minSize = Rectangle.create(0, 0, 50, 50); protected Rectangle maxSize = Rectangle.create(0, 0, 256, 256); - protected Runnable onMovedCallback = null; - protected Runnable onResizedCallback = null; + protected Consumer onMovedCallback = null; + protected Consumer onResizedCallback = null; protected PositionRestraint positionRestraint = draggable -> { if (xMin < 0) { int move = -xMin; @@ -112,7 +114,15 @@ public GuiManipulable constrain(GeoParam param, @Nullable Constraint constraint) @Override public void onScreenInit(Minecraft mc, Font font, int screenWidth, int screenHeight) { super.onScreenInit(mc, font, screenWidth, screenHeight); - resetBounds(); + if (resetOnUiInit) resetBounds(); + } + + /** + * @param resetOnUiInit If true, element bounds will be reset on UI init. (Default: true) + */ + public GuiManipulable setResetOnUiInit(boolean resetOnUiInit) { + this.resetOnUiInit = resetOnUiInit; + return this; } @Override @@ -137,6 +147,11 @@ public GuiManipulable addTopHandle(int handleSize) { return this; } + public GuiManipulable setTopHandle(GuiElement topHandle) { + this.topHandle = topHandle; + return this; + } + public GuiManipulable addBottomHandle(int handleSize) { this.bottomHandle .constrain(BOTTOM, match(contentElement.get(BOTTOM))) @@ -146,6 +161,11 @@ public GuiManipulable addBottomHandle(int handleSize) { return this; } + public GuiManipulable setBottomHandle(GuiElement bottomHandle) { + this.bottomHandle = bottomHandle; + return this; + } + public GuiManipulable addLeftHandle(int handleSize) { this.leftHandle .constrain(LEFT, match(contentElement.get(LEFT))) @@ -155,6 +175,11 @@ public GuiManipulable addLeftHandle(int handleSize) { return this; } + public GuiManipulable setLeftHandle(GuiElement leftHandle) { + this.leftHandle = leftHandle; + return this; + } + public GuiManipulable addRightHandle(int handleSize) { this.rightHandle .constrain(RIGHT, match(contentElement.get(RIGHT))) @@ -164,6 +189,11 @@ public GuiManipulable addRightHandle(int handleSize) { return this; } + public GuiManipulable setRightHandle(GuiElement rightHandle) { + this.rightHandle = rightHandle; + return this; + } + public GuiManipulable addMoveHandle(int handleSize) { this.moveHandle .constrain(TOP, match(contentElement.get(TOP))) @@ -173,6 +203,11 @@ public GuiManipulable addMoveHandle(int handleSize) { return this; } + public GuiManipulable setMoveHandle(GuiElement moveHandle) { + this.moveHandle = moveHandle; + return this; + } + /** * You can use this to retrieve the current move handle. * You are free to update the constraints on this handle, but it must be constrained relative to the content element. @@ -222,11 +257,21 @@ public GuiManipulable enableCursors(boolean enableCursors) { } public GuiManipulable setOnMovedCallback(Runnable onMovedCallback) { + this.onMovedCallback = finished -> onMovedCallback.run(); + return this; + } + + public GuiManipulable setOnMovedCallback(Consumer onMovedCallback) { this.onMovedCallback = onMovedCallback; return this; } public GuiManipulable setOnResizedCallback(Runnable onResizedCallback) { + this.onResizedCallback = finished -> onResizedCallback.run(); + return this; + } + + public GuiManipulable setOnResizedCallback(Consumer onResizedCallback) { this.onResizedCallback = onResizedCallback; return this; } @@ -324,13 +369,12 @@ public void mouseMoved(double mouseX, double mouseY) { int xMove = (int) (mouseX - dragXOffset) - xMin; int yMove = (int) (mouseY - dragYOffset) - yMin; if (dragPos) { - Rectangle previous = Rectangle.create(xMin, yMin, xMax - xMin, yMax - yMin); xMin += xMove; xMax += xMove; yMin += yMove; yMax += yMove; - validatePosition(); - onMoved(); + validatePosition(false); + onMoved(false); } else { Rectangle min = getMinSize(); Rectangle max = getMaxSize(); @@ -358,8 +402,8 @@ public void mouseMoved(double mouseX, double mouseY) { if (xMax - xMin > max.width()) xMax = xMin + (int) max.width(); if (xMax > scaledScreenWidth()) xMax = scaledScreenWidth(); } - validatePosition(); - onResized(); + validatePosition(false); + onResized(false); } } super.mouseMoved(mouseX, mouseY); @@ -367,34 +411,45 @@ public void mouseMoved(double mouseX, double mouseY) { @Override public boolean mouseReleased(double mouseX, double mouseY, int button, boolean consumed) { - if (isDragging) { - validatePosition(); + if (isMoving()) { + validatePosition(true); + } + if (isResizing()) { + onResized(true); } isDragging = dragPos = dragTop = dragLeft = dragBottom = dragRight = false; return super.mouseReleased(mouseX, mouseY, button, consumed); } - protected void validatePosition() { + protected void validatePosition(boolean finished) { double x = xMin; double y = yMin; positionRestraint.restrainPosition(this); - if ((x != xMin || y != yMin) && onMovedCallback != null) { - onMovedCallback.run(); + if ((x != xMin || y != yMin)) { + onMoved(finished); } } - protected void onMoved() { + protected void onMoved(boolean finished) { if (onMovedCallback != null) { - onMovedCallback.run(); + onMovedCallback.accept(finished); } } - protected void onResized() { + protected void onResized(boolean finished) { if (onResizedCallback != null) { - onResizedCallback.run(); + onMovedCallback.accept(finished); } } + public boolean isMoving() { + return dragPos; + } + + public boolean isResizing() { + return dragTop || dragLeft || dragBottom || dragRight; + } + public interface PositionRestraint { void restrainPosition(GuiManipulable draggable); } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiSlots.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiSlots.java index c2bfd086..4fb97fdb 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiSlots.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiSlots.java @@ -346,7 +346,10 @@ public void renderBackground(GuiRender render, double mouseX, double mouseY, flo for (int index = 0; index < slotCount; index++) { Slot slot = slots.getSlot(index + firstSlot); - render.texRect(slotTexture.apply(slot), slot.x + root.xMin() - 1, slot.y + root.yMin() - 1, 18, 18); + Material tex = slotTexture.apply(slot); + if (tex != null) { + render.texRect(tex, slot.x + root.xMin() - 1, slot.y + root.yMin() - 1, 18, 18); + } } render.pose().translate(0, 0, 0.4); diff --git a/src/main/java/codechicken/lib/inventory/container/modular/ModularGuiContainerMenu.java b/src/main/java/codechicken/lib/inventory/container/modular/ModularGuiContainerMenu.java index f6f043cc..02338869 100644 --- a/src/main/java/codechicken/lib/inventory/container/modular/ModularGuiContainerMenu.java +++ b/src/main/java/codechicken/lib/inventory/container/modular/ModularGuiContainerMenu.java @@ -244,12 +244,12 @@ protected boolean moveItemStackTo(ItemStack stack, List targets, boolean r itemStack2 = slot.getItem(); if (!itemStack2.isEmpty() && ItemStack.isSameItemSameTags(stack, itemStack2)) { int l = itemStack2.getCount() + stack.getCount(); - if (l <= stack.getMaxStackSize()) { + if (l <= Math.min(stack.getMaxStackSize(), slot.getMaxStackSize(stack))) { stack.setCount(0); itemStack2.setCount(l); slot.setChanged(); moved = true; - } else if (itemStack2.getCount() < stack.getMaxStackSize()) { + } else if (itemStack2.getCount() < Math.min(stack.getMaxStackSize(), slot.getMaxStackSize(stack))) { stack.shrink(stack.getMaxStackSize() - itemStack2.getCount()); itemStack2.setCount(stack.getMaxStackSize()); slot.setChanged(); @@ -284,8 +284,8 @@ protected boolean moveItemStackTo(ItemStack stack, List targets, boolean r slot = targets.get(position); itemStack2 = slot.getItem(); if (itemStack2.isEmpty() && slot.mayPlace(stack)) { - if (stack.getCount() > slot.getMaxStackSize()) { - slot.set(stack.split(slot.getMaxStackSize())); + if (stack.getCount() > slot.getMaxStackSize(stack)) { + slot.set(stack.split(slot.getMaxStackSize(stack))); } else { slot.set(stack.split(stack.getCount())); }