Skip to content

Commit

Permalink
Added a little more functionality to GuiSlots
Browse files Browse the repository at this point in the history
  • Loading branch information
brandon3055 committed Feb 27, 2024
1 parent 2fbbb12 commit 7a7f8a8
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 17 deletions.
12 changes: 10 additions & 2 deletions src/main/java/codechicken/lib/gui/modular/elements/GuiElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ public T setEnableToolTip(Supplier<Boolean> enableToolTip) {
return SneakyUtils.unsafeCast(this);
}

public boolean isTooltipEnabled() {
return enableToolTip.get();
}

@Override
public boolean blockMouseOver(GuiElement<?> element, double mouseX, double mouseY) {
return getParent().blockMouseOver(element, mouseX, mouseY);
Expand Down Expand Up @@ -410,8 +414,12 @@ public boolean renderOverlay(GuiRender render, double mouseX, double mouseY, flo
return consumed || (showToolTip() && renderTooltip(render, mouseX, mouseY));
}

private boolean showToolTip() {
return isMouseOver() && enableToolTip.get() && hoverTime() >= getTooltipDelay();
/**
* @return true if all conditions are bet for this element to be rendering its tool tip.
* Meaning mouse is over the element, hover time has elapsed and tooltip is enabled.
*/
public boolean showToolTip() {
return isMouseOver() && isTooltipEnabled() && hoverTime() >= getTooltipDelay();
}

/**
Expand Down
122 changes: 107 additions & 15 deletions src/main/java/codechicken/lib/gui/modular/elements/GuiSlots.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
import codechicken.lib.gui.modular.lib.geometry.Constraint;
import codechicken.lib.gui.modular.lib.geometry.GeoParam;
import codechicken.lib.gui.modular.lib.geometry.GuiParent;
import codechicken.lib.gui.modular.lib.geometry.Position;
import codechicken.lib.gui.modular.sprite.CCGuiTextures;
import codechicken.lib.gui.modular.sprite.Material;
import net.covers1624.quack.collection.FastStream;
import net.minecraft.world.inventory.Slot;
import org.apache.logging.log4j.util.TriConsumer;
import org.jetbrains.annotations.NotNull;

import java.util.function.Function;
Expand Down Expand Up @@ -38,9 +41,10 @@ public class GuiSlots extends GuiElement<GuiSlots> implements BackgroundRender {
private final SlotGroup slots;
private final ContainerScreenAccess<?> screenAccess;

private Material slotTexture = CCGuiTextures.getUncached("widgets/slot");
private Function<Integer, Material> slotIcons = slot -> null;
private Function<Integer, Integer> highlightColour = slot -> 0x80ffffff;
private Function<Slot, Material> slotTexture = slot -> CCGuiTextures.getUncached("widgets/slot");
private Function<Slot, Material> slotIcons = slot -> null;
private Function<Slot, Integer> highlightColour = slot -> 0x80ffffff;
private TriConsumer<Slot, Position, GuiRender> slotOverlay = null;
private int xSlotSpacing = 0;
private int ySlotSpacing = 0;

Expand Down Expand Up @@ -78,6 +82,7 @@ public GuiSlots(@NotNull GuiParent<?> parent, ContainerScreenAccess<?> screenAcc
}

updateSlots(parent.getModularGui().getRoot());
setZStacking(false);
}

//=== Construction Helpers ===//
Expand Down Expand Up @@ -126,7 +131,7 @@ public static PlayerWithArmor playerWithArmor(@NotNull GuiParent<?> parent, Cont

GuiSlots armor = new GuiSlots(container, screenAccess, armorSlots, 1)
.setYSlotSpacing(groupSpacing / 3)
.setEmptyIcon(index -> slotIcons ? ARMOR_SLOTS[index] : null)
.setEmptyIconI(index -> slotIcons ? ARMOR_SLOTS[index] : null)
.constrain(TOP, Constraint.midPoint(container.get(TOP), container.get(BOTTOM), height / -2D))
.constrain(LEFT, Constraint.midPoint(container.get(LEFT), container.get(RIGHT), width / -2D));

Expand Down Expand Up @@ -155,7 +160,7 @@ public static PlayerAll playerAllSlots(@NotNull GuiParent<?> parent, ContainerSc

GuiSlots armor = new GuiSlots(container, screenAccess, armorSlots, 1)
.setYSlotSpacing(groupSpacing / 3)
.setEmptyIcon(index -> slotIcons ? ARMOR_SLOTS[index] : null)
.setEmptyIconI(index -> slotIcons ? ARMOR_SLOTS[index] : null)
.constrain(TOP, Constraint.midPoint(container.get(TOP), container.get(BOTTOM), height / -2D))
.constrain(LEFT, Constraint.midPoint(container.get(LEFT), container.get(RIGHT), width / -2D));

Expand All @@ -168,7 +173,7 @@ public static PlayerAll playerAllSlots(@NotNull GuiParent<?> parent, ContainerSc
.constrain(LEFT, match(main.get(LEFT)));

GuiSlots offHand = new GuiSlots(container, screenAccess, offhandSlots, 1)
.setEmptyIcon(index -> slotIcons ? OFF_HAND_SLOT : null)
.setEmptyIconI(index -> slotIcons ? OFF_HAND_SLOT : null)
.constrain(TOP, match(bar.get(TOP)))
.constrain(LEFT, relative(bar.get(RIGHT), groupSpacing));

Expand All @@ -181,10 +186,28 @@ public static PlayerAll playerAllSlots(@NotNull GuiParent<?> parent, ContainerSc
* Allows you to use a custom slot texture, The default is the standard vanilla slot.
*/
public GuiSlots setSlotTexture(Material slotTexture) {
this.slotTexture = e -> slotTexture;
return this;
}

/**
* Allows you to use a custom per-slot slot textures, The default is the standard vanilla texture for all slots.
*/
public GuiSlots setSlotTexture(Function<Slot, Material> slotTexture) {
this.slotTexture = slotTexture;
return this;
}

/**
* Allows you to use a custom per-slot slot textures, The default is the standard vanilla texture for all slots.
* <p>
* Similar to {@link #setSlotTexture(Function)} except you are given the index of the slot within the {@link GuiSlots} element.
*/
public GuiSlots setSlotTextureI(Function<Integer, Material> slotTexture) {
this.slotTexture = slot -> slotTexture.apply(slots.indexOf(slot) - firstSlot);
return this;
}

/**
* Sets a custom slot highlight colour (The highlight you get when your cursor is over a slot.)
*/
Expand All @@ -196,11 +219,22 @@ public GuiSlots setHighlightColour(int highlightColour) {
* Allows you to set per-slot highlight colours, The integer passed to the function is the
* index of the slot within the {@link SlotGroup}
*/
public GuiSlots setHighlightColour(Function<Integer, Integer> highlightColour) {
public GuiSlots setHighlightColour(Function<Slot, Integer> highlightColour) {
this.highlightColour = highlightColour;
return this;
}

/**
* Allows you to set per-slot highlight colours, The integer passed to the function is the
* index of the slot within the {@link SlotGroup}
* <p>
* Similar to {@link #setHighlightColour(Function)} except you are given the index of the slot within the {@link GuiSlots} element.
*/
public GuiSlots setHighlightColourI(Function<Integer, Integer> highlightColour) {
this.highlightColour = slot -> highlightColour.apply(slots.indexOf(slot) - firstSlot);
return this;
}

/**
* Applies a single empty slot icon to all slots.
* Recommended texture size is 16x16
Expand All @@ -215,11 +249,48 @@ public GuiSlots setEmptyIcon(Material texture) {
*
* @param slotIcons A function that is given the slot index within the {@link SlotGroup}, and should return a material or null.
*/
public GuiSlots setEmptyIcon(Function<Integer, Material> slotIcons) {
public GuiSlots setEmptyIcon(Function<Slot, Material> slotIcons) {
this.slotIcons = slotIcons;
return this;
}

/**
* Allows you to provide a texture to be rendered in each slot when the slot is empty.
* Recommended texture size is 16x16
* <p>
* Similar to {@link #setEmptyIcon(Function)} except you are given the index of the slot within the {@link GuiSlots} element.
*
* @param slotIcons A function that is given the slot index within the {@link SlotGroup}, and should return a material or null.
*/
public GuiSlots setEmptyIconI(Function<Integer, Material> slotIcons) {
this.slotIcons = slot -> slotIcons.apply(slots.indexOf(slot) - firstSlot);
return this;
}

/**
* Allows you to attach an overlay renderer that will get called for each slot, after all slots have been rendered.
* This can be used to render pretty much anything you want to overtop the slot.
*
* @param slotOverlay Render callback providing the slot, screen position of the slot (top-left corner) and the active GuiRender.
*/
public GuiSlots setSlotOverlay(TriConsumer<Slot, Position, GuiRender> slotOverlay) {
this.slotOverlay = slotOverlay;
return this;
}

/**
* Allows you to attach an overlay renderer that will get called for each slot, after all slots have been rendered.
* This can be used to render pretty much anything you want to overtop the slot.
* <p>
* Similar to {@link #setSlotOverlay(TriConsumer)} except you are given the index of the slot within the {@link GuiSlots} element.
*
* @param slotOverlay Render callback providing the slot, screen position of the slot (top-left corner) and the active GuiRender.
*/
public GuiSlots setSlotOverlayI(TriConsumer<Integer, Position, GuiRender> slotOverlay) {
this.slotOverlay = (slot, position, render) -> slotOverlay.accept(slots.indexOf(slot) - firstSlot, position, render);
return this;
}

public GuiSlots setXSlotSpacing(int xSlotSpacing) {
this.xSlotSpacing = xSlotSpacing;
return this;
Expand Down Expand Up @@ -275,7 +346,7 @@ 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, slot.x + root.xMin() - 1, slot.y + root.yMin() - 1, 18, 18);
render.texRect(slotTexture.apply(slot), slot.x + root.xMin() - 1, slot.y + root.yMin() - 1, 18, 18);
}

render.pose().translate(0, 0, 0.4);
Expand All @@ -284,7 +355,7 @@ public void renderBackground(GuiRender render, double mouseX, double mouseY, flo
Slot slot = slots.getSlot(index + firstSlot);
if (!slot.isActive()) continue;
if (!slot.hasItem()) {
Material icon = slotIcons.apply(index + firstSlot);
Material icon = slotIcons.apply(slot);
if (icon != null) {
render.texRect(icon, slot.x + root.xMin(), slot.y + root.yMin(), 16, 16);
}
Expand All @@ -296,17 +367,38 @@ public void renderBackground(GuiRender render, double mouseX, double mouseY, flo
}
}

render.pose().translate(0, 0, getBackgroundDepth() - 0.8);

if (slotOverlay != null) {
for (int index = 0; index < slotCount; index++) {
Slot slot = slots.getSlot(index + firstSlot);
if (!slot.isActive()) continue;
slotOverlay.accept(slot, Position.create(slot.x + root.xMin(), slot.y + root.yMin()), render);
}
}

if (highlightSlot != null) {
render.pose().translate(0, 0, getBackgroundDepth() - 0.8);
render.rect(highlightSlot.x + root.xMin(), highlightSlot.y + root.yMin(), 16, 16, highlightColour.apply(slots.indexOf(highlightSlot)));
render.rect(highlightSlot.x + root.xMin(), highlightSlot.y + root.yMin(), 16, 16, highlightColour.apply(highlightSlot));
}

render.pose().popPose();
}

public record Player(GuiElement<?> container, GuiSlots main, GuiSlots hotBar) {}
public record Player(GuiElement<?> container, GuiSlots main, GuiSlots hotBar) {
public FastStream<GuiSlots> stream() {
return FastStream.of(main, hotBar);
}
}

public record PlayerWithArmor(GuiElement<?> container, GuiSlots main, GuiSlots hotBar, GuiSlots armor) {}
public record PlayerWithArmor(GuiElement<?> container, GuiSlots main, GuiSlots hotBar, GuiSlots armor) {
public FastStream<GuiSlots> stream() {
return FastStream.of(main, hotBar, armor);
}
}

public record PlayerAll(GuiElement<?> container, GuiSlots main, GuiSlots hotBar, GuiSlots armor, GuiSlots offHand) {}
public record PlayerAll(GuiElement<?> container, GuiSlots main, GuiSlots hotBar, GuiSlots armor, GuiSlots offHand) {
public FastStream<GuiSlots> stream() {
return FastStream.of(main, hotBar, armor, offHand);
}
}
}

0 comments on commit 7a7f8a8

Please sign in to comment.