diff --git a/src/main/java/codechicken/lib/compat/JEIPlugin.java b/src/main/java/codechicken/lib/compat/JEIPlugin.java index c9608464..f9184811 100644 --- a/src/main/java/codechicken/lib/compat/JEIPlugin.java +++ b/src/main/java/codechicken/lib/compat/JEIPlugin.java @@ -1,14 +1,23 @@ package codechicken.lib.compat; import codechicken.lib.CodeChickenLib; +import codechicken.lib.gui.modular.ModularGui; import codechicken.lib.gui.modular.ModularGuiContainer; +import codechicken.lib.gui.modular.elements.GuiElement; import mezz.jei.api.IModPlugin; import mezz.jei.api.JeiPlugin; +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.gui.handlers.IGhostIngredientHandler; import mezz.jei.api.gui.handlers.IGuiContainerHandler; +import mezz.jei.api.ingredients.ITypedIngredient; import mezz.jei.api.registration.IGuiHandlerRegistration; +import net.covers1624.quack.collection.FastStream; import net.minecraft.client.renderer.Rect2i; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -18,7 +27,8 @@ public class JEIPlugin implements IModPlugin { private static final ResourceLocation ID = new ResourceLocation(CodeChickenLib.MOD_ID, "jei_plugin"); - public JEIPlugin() {} + public JEIPlugin() { + } @Override public ResourceLocation getPluginUid() { @@ -30,8 +40,48 @@ public void registerGuiHandlers(IGuiHandlerRegistration registration) { registration.addGuiContainerHandler(ModularGuiContainer.class, new IGuiContainerHandler<>() { @Override public List getGuiExtraAreas(ModularGuiContainer screen) { - return screen.getModularGui().getJeiExclusions().map(e -> e.getRectangle().toRect2i()).toList(); + return FastStream.of(screen.getModularGui().getJeiExclusions()).map(e -> e.getRectangle().toRect2i()).toList(); } }); + registration.addGhostIngredientHandler(ModularGuiContainer.class, new IngredientDropHandler()); + } + + private static class IngredientDropHandler implements IGhostIngredientHandler { + private ModularGui gui; + private boolean highlight = true; + + @Override + public List> getTargetsTyped(ModularGuiContainer screen, ITypedIngredient ingredient, boolean doStart) { + gui = screen.getModularGui(); + gui.setJeiHighlightTime(doStart ? 60 * 20 : 3 * 20); + highlight = !doStart; + if (!doStart) return Collections.emptyList(); + List> targets = new ArrayList<>(); + ingredient.getIngredient(VanillaTypes.ITEM_STACK).ifPresent(stack -> gui.getJeiDropTargets().forEach(e -> targets.add(new DropTarget<>(e)))); + return targets; + } + + @Override + public void onComplete() { + highlight = true; + gui.setJeiHighlightTime(0); + } + + @Override + public boolean shouldHighlightTargets() { + return highlight; + } + } + + private record DropTarget(GuiElement element) implements IGhostIngredientHandler.Target { + @Override + public Rect2i getArea() { + return element.getRectangle().toRect2i(); + } + + @Override + public void accept(I ingredient) { + element.getJeiDropConsumer().accept((ItemStack) ingredient); + } } } diff --git a/src/main/java/codechicken/lib/gui/modular/ModularGui.java b/src/main/java/codechicken/lib/gui/modular/ModularGui.java index b0a9d527..242ca4c0 100644 --- a/src/main/java/codechicken/lib/gui/modular/ModularGui.java +++ b/src/main/java/codechicken/lib/gui/modular/ModularGui.java @@ -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. @@ -68,7 +65,7 @@ public class ModularGui implements GuiParent { private final List> preKeyPressListeners = new ArrayList<>(); private final List> postKeyPressListeners = new ArrayList<>(); - private final List> 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. @@ -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); } @@ -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(); @@ -260,6 +258,7 @@ public void tick() { tickListeners.forEach(Runnable::run); root.tick(mouseX, mouseY); CursorHelper.setCursor(newCursor); + if (jeiHighlightTime > 0) jeiHighlightTime--; } /** @@ -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> 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> getJeiDropTargets() { + return root.addJeiDropTargets(new ArrayList<>()); + } + + public void setJeiHighlightTime(int jeiHighlightTime) { + this.jeiHighlightTime = jeiHighlightTime; } - public FastStream> getJeiExclusions() { - return FastStream.of(jeiExclusions).filter(GuiElement::isEnabled); + public int getJeiHighlightTime() { + return jeiHighlightTime; } /** diff --git a/src/main/java/codechicken/lib/gui/modular/ModularGuiContainer.java b/src/main/java/codechicken/lib/gui/modular/ModularGuiContainer.java index 0063b6a6..8e74eba6 100644 --- a/src/main/java/codechicken/lib/gui/modular/ModularGuiContainer.java +++ b/src/main/java/codechicken/lib/gui/modular/ModularGuiContainer.java @@ -29,6 +29,10 @@ public class ModularGuiContainer extends AbstractContainerScreen implements ContainerScreenAccess { public final ModularGui modularGui; + /** + * Flag used to disable vanilla slot highlight rendering. + * */ + private boolean renderingSlots = false; public ModularGuiContainer(T containerMenu, Inventory inventory, ContainerGuiProvider provider) { super(containerMenu, inventory, Component.empty()); @@ -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); @@ -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(); @@ -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 @@ -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 diff --git a/src/main/java/codechicken/lib/gui/modular/ModularGuiScreen.java b/src/main/java/codechicken/lib/gui/modular/ModularGuiScreen.java index 10fd1060..2e6251fd 100644 --- a/src/main/java/codechicken/lib/gui/modular/ModularGuiScreen.java +++ b/src/main/java/codechicken/lib/gui/modular/ModularGuiScreen.java @@ -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); } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiContextMenu.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiContextMenu.java index 77c2b343..704c701b 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiContextMenu.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiContextMenu.java @@ -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; @@ -26,14 +22,17 @@ public class GuiContextMenu extends GuiElement { private BiFunction, GuiButton> buttonBuilder = (menu, label) -> GuiButton.flatColourButton(menu, label, hover -> hover ? 0xFF475b6a : 0xFF151515).constrain(HEIGHT, literal(12)); - private final Map, Runnable> options = new HashMap<>(); + private final Map, Runnable> options = new LinkedHashMap<>(); private final Map, Supplier>> tooltips = new HashMap<>(); private final List 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) { @@ -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. */ @@ -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 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)); } @@ -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; @@ -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); } 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 8942e51f..f692118d 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiElement.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiElement.java @@ -1,5 +1,6 @@ package codechicken.lib.gui.modular.elements; +import codechicken.lib.colour.ColourARGB; import com.google.common.collect.Lists; import com.mojang.blaze3d.vertex.PoseStack; import codechicken.lib.gui.modular.ModularGui; @@ -13,6 +14,7 @@ import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -20,6 +22,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.function.Consumer; import java.util.function.Supplier; /** @@ -68,6 +71,9 @@ public class GuiElement> extends ConstrainedGeometry private Supplier> toolTip = null; private Rectangle renderCull = Rectangle.create(Position.create(0, 0), () -> (double) screenWidth, () -> (double) screenHeight); + private Consumer jeiDropConsumer = null; + private boolean isJeiExcluded = false; + /** * @param parent parent {@link GuiParent}. */ @@ -265,24 +271,6 @@ public String toString() { '}'; } - /** - * Add this 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 T jeiExclude() { - getModularGui().jeiExclude(this); - return SneakyUtils.unsafeCast(this); - } - - /** - * Remove this element from the list of jei exclusions. - */ - public T removeJEIExclude() { - getModularGui().removeJEIExclude(this); - return SneakyUtils.unsafeCast(this); - } - //=== Render / Update ===// /** @@ -488,4 +476,72 @@ public T setTooltip(@Nullable Supplier> tooltip) { this.toolTip = tooltip; return SneakyUtils.unsafeCast(this); } + + //=== JEI Integration ===// + + /** + * Add this 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 T jeiExclude() { + isJeiExcluded = true; + return SneakyUtils.unsafeCast(this); + } + + public T setJeiExcluded(boolean jeiExcluded) { + isJeiExcluded = jeiExcluded; + return SneakyUtils.unsafeCast(this); + } + + public boolean isJeiExcluded() { + return isJeiExcluded; + } + + /** + * Allows you get notified when a player drags and drops an ItemStack from jai onto this element. + * If using the standard highlight then you should call this after adding any other required child elements to ensure the highlight is on top. + */ + public T setJeiDropTarget(Consumer onDrop, boolean installStandardHighlight) { + jeiDropConsumer = onDrop; + if (installStandardHighlight) { + GuiRectangle highlight = new GuiRectangle(this) + .setEnabled(() -> getModularGui().getJeiHighlightTime() > 0) + .fill(() -> ColourARGB.packARGB(0, 0xFF, 0, Math.min(getModularGui().getJeiHighlightTime() * 2, 0x50))); + Constraints.bind(highlight, this); + } + return SneakyUtils.unsafeCast(this); + } + + public Consumer getJeiDropConsumer() { + return jeiDropConsumer; + } + + public boolean isJeiDropTarget() { + return jeiDropConsumer != null; + } + + public List> addJeiExclusions(List> list) { + if (isJeiExcluded()) { + list.add(this); + } + for (GuiElement child : childElements) { + if (child.isEnabled()) { + child.addJeiExclusions(list); + } + } + return list; + } + + public List> addJeiDropTargets(List> list) { + if (isJeiDropTarget()) { + list.add(this); + } + for (GuiElement child : childElements) { + if (child.isEnabled()) { + child.addJeiDropTargets(list); + } + } + return list; + } } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiEntityRenderer.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiEntityRenderer.java index ac09f9b3..f3e3b0db 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiEntityRenderer.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiEntityRenderer.java @@ -160,7 +160,9 @@ public GuiEntityRenderer setForce2dSize(boolean force2dSize) { @Override public double getBackgroundDepth() { Rectangle rect = getRectangle(); + if (invalidEntity || entity == null) return 0.01; float scale = (float) (force2dSize ? (Math.min(rect.height() / entity.getBbHeight(), rect.width() / entity.getBbWidth())) : rect.height() / entity.getBbHeight()); + if (Float.isInfinite(scale)) scale = 1; return scale * 2; } @@ -182,6 +184,11 @@ public void renderBackground(GuiRender render, double mouseX, double mouseY, flo } else { renderEntityInInventoryWithRotation(render, xPos, yPos, scale, rotation, living); } + } else { + Quaternionf quaternionf = new Quaternionf().rotateZ((float)Math.PI); + Quaternionf quaternionf1 = Axis.YP.rotationDegrees(rotation); + quaternionf.mul(quaternionf1); + renderEntityInInventory(render, xPos, yPos, scale, quaternionf, quaternionf1, entity); } } } catch (Throwable e) { @@ -242,7 +249,7 @@ public static void renderEntityInInventoryWithRotation(GuiRender render, double living.yHeadRot = f6; } - public static void renderEntityInInventory(GuiRender render, double pX, double pY, double pScale, Quaternionf quat, @Nullable Quaternionf pCameraOrientation, LivingEntity pEntity) { + public static void renderEntityInInventory(GuiRender render, double pX, double pY, double pScale, Quaternionf quat, @Nullable Quaternionf pCameraOrientation, Entity pEntity) { render.pose().pushPose(); render.pose().translate(pX, pY, 50.0D); render.pose().mulPoseMatrix((new Matrix4f()).scaling((float)pScale, (float)pScale, (float)(-pScale))); diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiItemStack.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiItemStack.java index 2ff85905..099d2c8a 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiItemStack.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiItemStack.java @@ -92,7 +92,7 @@ public double getStackSize() { @Override public double getBackgroundDepth() { - return getStackSize(); + return getStackSize() * 2; } @Override diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiList.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiList.java index 909d5d53..fe26fb75 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiList.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiList.java @@ -9,6 +9,7 @@ import java.util.*; import java.util.function.BiFunction; +import java.util.function.Predicate; import static codechicken.lib.gui.modular.lib.geometry.Constraint.*; import static codechicken.lib.gui.modular.lib.geometry.GeoParam.*; @@ -35,6 +36,7 @@ public class GuiList extends GuiElement> { */ public boolean enableScissor = true; private double yScrollPos = 0; + private double lastWidth = 0; private double contentHeight = 0; private double itemSpacing = 1; private boolean rebuild = true; @@ -43,6 +45,7 @@ public class GuiList extends GuiElement> { private final List listContent = new ArrayList<>(); private final Map> elementMap = new HashMap<>(); private final LinkedList> visible = new LinkedList<>(); + private Predicate filter = e -> true; private BiFunction, E, ? extends GuiElement> displayBuilder = (parent, e) -> { GuiText text = new GuiText(parent, () -> Component.literal(String.valueOf(e))).setWrap(true); @@ -83,6 +86,11 @@ public GuiList setDisplayBuilder(BiFunction, E, ? extends GuiEleme return this; } + public GuiList setFilter(Predicate filter) { + this.filter = filter; + return this; + } + public GuiList setItemSpacing(double itemSpacing) { this.itemSpacing = itemSpacing; return this; @@ -127,6 +135,10 @@ public double hiddenSize() { @Override public void tick(double mouseX, double mouseY) { + if (lastWidth != xSize()) { + lastWidth = xSize(); + markDirty(); + } if (rebuild) { rebuildElements(); } @@ -138,6 +150,7 @@ public void rebuildElements() { elementMap.clear(); for (E item : listContent) { + if (!filter.test(item)) continue; GuiElement next = displayBuilder.apply(this, item); next.constrain(LEFT, match(get(LEFT))); next.constrain(RIGHT, match(get(RIGHT))); 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 9ce861eb..b798be25 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiSlots.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiSlots.java @@ -291,7 +291,7 @@ public void renderBackground(GuiRender render, double mouseX, double mouseY, flo } screenAccess.renderSlot(render, slot); - if (GuiRender.isInRect(slot.x + root.xMin(), slot.y + root.yMin(), 16, 16, mouseX, mouseY) && !blockMouseOver(this, mouseX, mouseY)) { + if (GuiRender.isInRect(slot.x + root.xMin(), slot.y + root.yMin(), 16, 16, mouseX, mouseY) && !blockMouseOver(this, mouseX, mouseY) && isMouseOver()) { highlightSlot = slot; } } diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiText.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiText.java index 2776c2d5..f553d660 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiText.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiText.java @@ -204,7 +204,7 @@ public GuiText setRotatePoint(Position rotatePoint) { @Override public double getForegroundDepth() { - return 0.035; + return 0.05; } @Override diff --git a/src/main/java/codechicken/lib/gui/modular/elements/GuiTextField.java b/src/main/java/codechicken/lib/gui/modular/elements/GuiTextField.java index 680b918c..c9c0a62f 100644 --- a/src/main/java/codechicken/lib/gui/modular/elements/GuiTextField.java +++ b/src/main/java/codechicken/lib/gui/modular/elements/GuiTextField.java @@ -62,6 +62,7 @@ public class GuiTextField extends GuiElement implements Background private Supplier suggestion = null; private Supplier suggestionColour = () -> 0x7f7f80; + private Supplier suggestionShadow = () -> true; private Predicate filter = Objects::nonNull; private BiFunction formatter = (string, pos) -> FormattedCharSequence.forward(string, Style.EMPTY); @@ -162,8 +163,24 @@ public GuiTextField setSuggestion(@Nullable Supplier suggestion) { /** * Set the colour of the suggestion text. */ - public void setSuggestionColour(Supplier suggestionColour) { + public GuiTextField setSuggestionColour(Supplier suggestionColour) { this.suggestionColour = suggestionColour; + return this; + } + + public GuiTextField setSuggestionColour(int suggestionColour) { + this.suggestionColour = () -> suggestionColour; + return this; + } + + public GuiTextField setSuggestionShadow(Supplier suggestionShadow) { + this.suggestionShadow = suggestionShadow; + return this; + } + + public GuiTextField setSuggestionShadow(boolean suggestionShadow) { + this.suggestionShadow = () -> suggestionShadow; + return this; } /** @@ -630,7 +647,7 @@ public void renderBackground(GuiRender render, double mouseX, double mouseY, flo } if (suggestion != null && value.isEmpty()) { - render.drawString(suggestion.get(), (float) (k1 - 1), (float) drawY, suggestionColour.get(), shadow.get()); + render.drawString(suggestion.get(), (float) (k1 - 1), (float) drawY, suggestionColour.get(), suggestionShadow.get()); } if (cursorBlink) { diff --git a/src/main/java/codechicken/lib/gui/modular/lib/TooltipHandler.java b/src/main/java/codechicken/lib/gui/modular/lib/TooltipHandler.java index 7bc1bb20..46ebc188 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/TooltipHandler.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/TooltipHandler.java @@ -99,7 +99,8 @@ default boolean renderTooltip(GuiRender render, double mouseX, double mouseY) { if (supplier == null) return false; List list = supplier.get(); if (list.isEmpty()) return false; - render.componentTooltip(list, mouseX, mouseY); + //Run all components though split to account for newline characters in translations + render.renderTooltip(list.stream().flatMap(component -> render.font().split(component, Integer.MAX_VALUE).stream()).toList(), mouseX, mouseY); return true; } } diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 0cd041ee..3c773fef 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -67,6 +67,7 @@ public com.mojang.blaze3d.shaders.Program$Type m_85571_()I # getGlType public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_280092_(Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/world/inventory/Slot;)V # renderSlot public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_280211_(Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/world/item/ItemStack;IILjava/lang/String;)V # renderFloatingItem public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_97744_(DD)Lnet/minecraft/world/inventory/Slot; # findSlot +public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_97774_(Lnet/minecraft/world/inventory/Slot;DD)Z # isHovering public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_97818_()V # recalculateQuickCraftRemaining public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97706_ # clickedSlot public net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97711_ # draggingItem