Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev/gui improvements #455

Merged
merged 4 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ dependencies {

compileOnly(fg.deobf("mezz.jei:jei-${mc_version}-common-api:${jei_version}"))
compileOnly(fg.deobf("mezz.jei:jei-${mc_version}-forge-api:${jei_version}"))
runtimeOnly(fg.deobf("mezz.jei:jei-${mc_version}-forge:${jei_version}"))
}

test {
Expand Down
37 changes: 0 additions & 37 deletions src/main/java/codechicken/lib/compat/JEIPlugin.java

This file was deleted.

39 changes: 16 additions & 23 deletions src/main/java/codechicken/lib/gui/modular/ModularGui.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,15 @@
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.util.TriConsumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Stream;

/**
* The modular gui system is built around "Gui Elements" but those elements need to be rendered by a base parent element. That's what this class is.
Expand Down Expand Up @@ -68,7 +65,7 @@ public class ModularGui implements GuiParent<ModularGui> {
private final List<TriConsumer<Integer, Integer, Integer>> preKeyPressListeners = new ArrayList<>();
private final List<TriConsumer<Integer, Integer, Integer>> postKeyPressListeners = new ArrayList<>();

private final List<GuiElement<?>> jeiExclusions = new ArrayList<>();
private int jeiHighlightTime = 0;

/**
* @param provider The gui builder that will be used to construct this modular gui when the screen is initialized.
Expand Down Expand Up @@ -208,6 +205,7 @@ public boolean vanillaSlotRendering() {
* @param buffers BufferSource can be retried from {@link GuiGraphics}
* @return A new {@link GuiRender} for the current render call.
*/
@Deprecated //If you have the GuiGraphics, use GuiRender#convert to ensure the underlying PoseStack is carried over. That will ensure things like the JEI overlay will be rendered at a
public GuiRender createRender(MultiBufferSource.BufferSource buffers) {
return new GuiRender(mc, buffers);
}
Expand All @@ -216,7 +214,7 @@ public GuiRender createRender(MultiBufferSource.BufferSource buffers) {
* Primary render method for ModularGui. The screen implementing ModularGui must call this in its render method.
* Followed by the {@link #renderOverlay(GuiRender, float)} method to handle overlay rendering.
*
* @param render A new gui render call should be constructed for each frame via {@link #createRender(MultiBufferSource.BufferSource)}
* @param render GuiRender instance converted from Minecraft's {@link GuiGraphics} via {@link GuiRender#convert(GuiGraphics)}
*/
public void render(GuiRender render, float partialTicks) {
root.clearGeometryCache();
Expand Down Expand Up @@ -260,6 +258,7 @@ public void tick() {
tickListeners.forEach(Runnable::run);
root.tick(mouseX, mouseY);
CursorHelper.setCursor(newCursor);
if (jeiHighlightTime > 0) jeiHighlightTime--;
}

/**
Expand Down Expand Up @@ -524,26 +523,20 @@ public void setCursor(ResourceLocation cursor) {
this.newCursor = cursor;
}

/**
* Add an element to the list of jei exclusions.
* Use this for any elements that render outside the normal gui bounds.
* This will ensure JEI does not try to render on top of these elements.
*/
public void jeiExclude(GuiElement<?> element) {
if (!jeiExclusions.contains(element)) {
jeiExclusions.add(element);
}
public List<GuiElement<?>> getJeiExclusions() {
return root.addJeiExclusions(new ArrayList<>());
}

/**
* Remove an element from the list of jei exclusions.
*/
public void removeJEIExclude(GuiElement<?> element) {
jeiExclusions.remove(element);
public List<GuiElement<?>> getJeiDropTargets() {
return root.addJeiDropTargets(new ArrayList<>());
}

public void setJeiHighlightTime(int jeiHighlightTime) {
this.jeiHighlightTime = jeiHighlightTime;
}

public FastStream<GuiElement<?>> getJeiExclusions() {
return FastStream.of(jeiExclusions).filter(GuiElement::isEnabled);
public int getJeiHighlightTime() {
return jeiHighlightTime;
}

/**
Expand Down
27 changes: 24 additions & 3 deletions src/main/java/codechicken/lib/gui/modular/ModularGuiContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
public class ModularGuiContainer<T extends AbstractContainerMenu> extends AbstractContainerScreen<T> implements ContainerScreenAccess<T> {

public final ModularGui modularGui;
/**
* Flag used to disable vanilla slot highlight rendering.
* */
private boolean renderingSlots = false;

public ModularGuiContainer(T containerMenu, Inventory inventory, ContainerGuiProvider<T> provider) {
super(containerMenu, inventory, Component.empty());
Expand Down Expand Up @@ -74,7 +78,7 @@ public void render(@NotNull GuiGraphics graphics, int mouseX, int mouseY, float
if (modularGui.renderBackground()) {
renderBackground(graphics);
}
GuiRender render = modularGui.createRender(graphics.bufferSource());
GuiRender render = GuiRender.convert(graphics);//modularGui.createRender(graphics.bufferSource());
modularGui.render(render, partialTicks);

super.render(graphics, mouseX, mouseY, partialTicks);
Expand Down Expand Up @@ -125,7 +129,7 @@ protected boolean handleFloatingItemRender(GuiRender render, int mouseX, int mou
protected boolean renderHoveredStackToolTip(GuiRender guiGraphics, int mouseX, int mouseY) {
if (this.menu.getCarried().isEmpty() && this.hoveredSlot != null && this.hoveredSlot.hasItem()) {
GuiElement<?> handler = modularGui.getSlotHandler(hoveredSlot);
if (handler != null && handler.blockMouseOver(handler, mouseX, mouseY)) {
if (handler != null && (handler.blockMouseOver(handler, mouseX, mouseY) || !handler.isMouseOver())) {
return false;
}
ItemStack itemStack = this.hoveredSlot.getItem();
Expand Down Expand Up @@ -191,7 +195,11 @@ protected void renderBg(GuiGraphics guiGraphics, float f, int i, int j) {

@Override
public void renderSlot(GuiGraphics guiGraphics, Slot slot) {
if (modularGui.vanillaSlotRendering()) super.renderSlot(guiGraphics, slot);
if (modularGui.vanillaSlotRendering()) {
super.renderSlot(guiGraphics, slot);
} else {
renderingSlots = true;
}
}

//Modular gui friendly version of the slot render
Expand Down Expand Up @@ -240,8 +248,21 @@ public void renderSlot(GuiRender render, Slot slot) {
}
}

@Override
public boolean isHovering(Slot pSlot, double pMouseX, double pMouseY) {
boolean ret = super.isHovering(pSlot, pMouseX, pMouseY);
//Override the isHovering check before renderSlotHighlight is called.
if (ret && renderingSlots && pSlot.isActive()) {
//This breaks the default hoveredSlot assignment, so we need to handle that here.
hoveredSlot = pSlot;
return false;
}
return ret;
}

@Override //Disable vanilla title and inventory name rendering
protected void renderLabels(GuiGraphics guiGraphics, int i, int j) {
renderingSlots = false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public void render(@NotNull GuiGraphics graphics, int mouseX, int mouseY, float
if (modularGui.renderBackground()) {
renderBackground(graphics);
}
GuiRender render = modularGui.createRender(graphics.bufferSource());
GuiRender render = GuiRender.convert(graphics);
modularGui.render(render, partialTicks);
modularGui.renderOverlay(render, partialTicks);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@
import codechicken.lib.gui.modular.ModularGui;
import codechicken.lib.gui.modular.lib.Constraints;
import codechicken.lib.gui.modular.lib.geometry.GuiParent;
import net.covers1624.quack.collection.FastStream;
import net.minecraft.network.chat.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Supplier;

Expand All @@ -26,14 +22,17 @@
public class GuiContextMenu extends GuiElement<GuiContextMenu> {

private BiFunction<GuiContextMenu, Supplier<Component>, GuiButton> buttonBuilder = (menu, label) -> GuiButton.flatColourButton(menu, label, hover -> hover ? 0xFF475b6a : 0xFF151515).constrain(HEIGHT, literal(12));
private final Map<Supplier<Component>, Runnable> options = new HashMap<>();
private final Map<Supplier<Component>, Runnable> options = new LinkedHashMap<>();
private final Map<Supplier<Component>, Supplier<List<Component>>> tooltips = new HashMap<>();
private final List<GuiButton> buttons = new ArrayList<>();
private boolean closeOnItemClicked = true;
private boolean closeOnOutsideClick = true;
private boolean actionOnClick = false;

public GuiContextMenu(ModularGui gui) {
super(gui.getRoot());
jeiExclude();
setOpaque(true);
}

public static GuiContextMenu tooltipStyleMenu(GuiParent<?> parent) {
Expand All @@ -52,6 +51,16 @@ public GuiContextMenu setCloseOnOutsideClick(boolean closeOnOutsideClick) {
return this;
}

/**
* By default, the option action fires on mouse button release (like pretty much any UI button in existence)
* Calling this will change that to action on mouse button press, (What minecraft uses for its buttons)
*/
public GuiContextMenu actionOnClick() {
this.actionOnClick = true;
rebuildButtons();
return this;
}

/**
* Only height should be constrained, with will be set automatically to accommodate the provided label.
*/
Expand Down Expand Up @@ -87,16 +96,20 @@ private void rebuildButtons() {

//Menu options can be dynamic so the width constraint needs to be dynamic.
//This is probably a little expensive, but its only while a context menu is open.
constrain(WIDTH, dynamic(() -> FastStream.of(options.keySet()).map(Supplier::get).intSum(font()::width) + 6D + 4D));
constrain(WIDTH, dynamic(() -> options.keySet().stream().mapToInt(e -> font().width(e.get())).max().orElse(0) + 6D + 4D));

double height = 3;
for (Supplier<Component> label : options.keySet()) {
Runnable action = options.get(label);
GuiButton button = buttonBuilder.apply(this, label)
.onPress(action)
.constrain(TOP, relative(get(TOP), height))
.constrain(LEFT, relative(get(LEFT), 3))
.constrain(RIGHT, relative(get(RIGHT), -3));
if (actionOnClick) {
button.onClick(action);
} else {
button.onPress(action);
}
if (tooltips.containsKey(label)) {
button.setTooltip(tooltips.get(label));
}
Expand All @@ -111,10 +124,12 @@ private void rebuildButtons() {
public boolean mouseClicked(double mouseX, double mouseY, int button, boolean consumed) {
consumed = super.mouseClicked(mouseX, mouseY, button, consumed);
if (isMouseOver() || consumed) {
if (consumed && closeOnItemClicked) {
close();
if (actionOnClick) {
if (consumed && closeOnItemClicked) {
close();
}
return true;
}
return true;
} else if (closeOnOutsideClick) {
close();
return true;
Expand All @@ -123,6 +138,20 @@ public boolean mouseClicked(double mouseX, double mouseY, int button, boolean co
return consumed;
}

@Override
public boolean mouseReleased(double mouseX, double mouseY, int button, boolean consumed) {
consumed = super.mouseReleased(mouseX, mouseY, button, consumed);
if (isMouseOver() || consumed) {
if (!actionOnClick) {
if (consumed && closeOnItemClicked) {
close();
}
return true;
}
}
return consumed;
}

public void close() {
getParent().removeChild(this);
}
Expand Down
Loading
Loading