From c8357cdffd1b859d61f4884824f2b84a5dd846c3 Mon Sep 17 00:00:00 2001 From: mezz Date: Tue, 1 Oct 2024 09:28:52 +0900 Subject: [PATCH] add an IPlaceable interface for GUI elements that can have their position set --- .../common/gui/elements/OffsetDrawable.java | 18 ++- .../jei/common/gui/elements/TextWidget.java | 98 ++++++++--------- .../api/gui/builder/IRecipeLayoutBuilder.java | 24 +++- .../api/gui/builder/IRecipeSlotBuilder.java | 3 +- .../gui/placement/HorizontalAlignment.java | 32 ++++++ .../jei/api/gui/placement/IPlaceable.java | 37 +++++++ .../api/gui/placement/VerticalAlignment.java | 32 ++++++ .../jei/api/gui/placement/package-info.java | 7 ++ .../api/gui/widgets/IRecipeExtrasBuilder.java | 104 +++++++++++++++++- .../mezz/jei/api/gui/widgets/ITextWidget.java | 57 ++++++++-- .../mezz/jei/api/recipe/IRecipeManager.java | 26 ++++- .../mezz/jei/gui/recipes/RecipeCatalysts.java | 11 +- .../jei/library/gui/recipes/RecipeLayout.java | 38 ++++--- .../layout/builder/RecipeLayoutBuilder.java | 8 +- .../layout/builder/RecipeSlotBuilder.java | 20 +++- .../builder/IngredientSlotBuilder.java | 22 ++++ .../builder/IngredientSupplierBuilder.java | 10 ++ .../debug/DebugFocusRecipeCategory.java | 1 - .../jei/tags/TagInfoRecipeCategory.java | 9 +- .../vanilla/anvil/AnvilRecipeCategory.java | 10 +- .../vanilla/anvil/SmithingRecipeCategory.java | 2 +- .../brewing/BrewingRecipeCategory.java | 3 +- .../CompostableRecipeCategory.java | 9 +- .../cooking/AbstractCookingCategory.java | 20 ++-- .../cooking/CampfireCookingCategory.java | 6 +- .../cooking/fuel/FurnaceFuelCategory.java | 12 +- .../StoneCuttingRecipeCategory.java | 2 +- .../jei/library/recipes/RecipeManager.java | 4 +- gradle.properties | 2 +- 29 files changed, 497 insertions(+), 130 deletions(-) create mode 100644 CommonApi/src/main/java/mezz/jei/api/gui/placement/HorizontalAlignment.java create mode 100644 CommonApi/src/main/java/mezz/jei/api/gui/placement/IPlaceable.java create mode 100644 CommonApi/src/main/java/mezz/jei/api/gui/placement/VerticalAlignment.java create mode 100644 CommonApi/src/main/java/mezz/jei/api/gui/placement/package-info.java diff --git a/Common/src/main/java/mezz/jei/common/gui/elements/OffsetDrawable.java b/Common/src/main/java/mezz/jei/common/gui/elements/OffsetDrawable.java index 92dd9ce87..b34372894 100644 --- a/Common/src/main/java/mezz/jei/common/gui/elements/OffsetDrawable.java +++ b/Common/src/main/java/mezz/jei/common/gui/elements/OffsetDrawable.java @@ -1,12 +1,13 @@ package mezz.jei.common.gui.elements; -import net.minecraft.client.gui.GuiGraphics; import mezz.jei.api.gui.drawable.IDrawable; +import mezz.jei.api.gui.placement.IPlaceable; +import net.minecraft.client.gui.GuiGraphics; /** * Draws with a built-in offset. */ -public class OffsetDrawable implements IDrawable { +public class OffsetDrawable implements IDrawable, IPlaceable { public static IDrawable create(IDrawable drawable, int xOffset, int yOffset) { if (xOffset == 0 && yOffset == 0) { return drawable; @@ -15,10 +16,10 @@ public static IDrawable create(IDrawable drawable, int xOffset, int yOffset) { } private final IDrawable drawable; - private final int xOffset; - private final int yOffset; + private int xOffset; + private int yOffset; - private OffsetDrawable(IDrawable drawable, int xOffset, int yOffset) { + public OffsetDrawable(IDrawable drawable, int xOffset, int yOffset) { this.drawable = drawable; this.xOffset = xOffset; this.yOffset = yOffset; @@ -47,4 +48,11 @@ public void draw(GuiGraphics guiGraphics, int xOffset, int yOffset) { public void draw(GuiGraphics guiGraphics) { this.drawable.draw(guiGraphics, this.xOffset, this.yOffset); } + + @Override + public OffsetDrawable setPosition(int xPos, int yPos) { + this.xOffset = xPos; + this.yOffset = yPos; + return this; + } } diff --git a/Common/src/main/java/mezz/jei/common/gui/elements/TextWidget.java b/Common/src/main/java/mezz/jei/common/gui/elements/TextWidget.java index de5cc5b12..83c044684 100644 --- a/Common/src/main/java/mezz/jei/common/gui/elements/TextWidget.java +++ b/Common/src/main/java/mezz/jei/common/gui/elements/TextWidget.java @@ -1,13 +1,13 @@ package mezz.jei.common.gui.elements; import mezz.jei.api.gui.builder.ITooltipBuilder; +import mezz.jei.api.gui.placement.HorizontalAlignment; +import mezz.jei.api.gui.placement.VerticalAlignment; import mezz.jei.api.gui.widgets.IRecipeWidget; import mezz.jei.api.gui.widgets.ITextWidget; import mezz.jei.common.config.DebugConfig; -import mezz.jei.common.util.HorizontalAlignment; import mezz.jei.common.util.ImmutableRect2i; import mezz.jei.common.util.StringUtil; -import mezz.jei.common.util.VerticalAlignment; import mezz.jei.core.util.Pair; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; @@ -22,7 +22,7 @@ public class TextWidget implements ITextWidget, IRecipeWidget { private final List text; - private final ImmutableRect2i area; + private ImmutableRect2i availableArea; private HorizontalAlignment horizontalAlignment; private VerticalAlignment verticalAlignment; @@ -30,11 +30,12 @@ public class TextWidget implements ITextWidget, IRecipeWidget { private int color; private boolean shadow; private int lineSpacing; - private List tooltipText = List.of(); + private @Nullable List wrappedText; + private boolean truncated = false; public TextWidget(List text, int xPos, int yPos, int maxWidth, int maxHeight) { - this.area = new ImmutableRect2i(xPos, yPos, maxWidth, maxHeight); + this.availableArea = new ImmutableRect2i(xPos, yPos, maxWidth, maxHeight); Minecraft minecraft = Minecraft.getInstance(); this.font = minecraft.font; this.color = 0xFF000000; @@ -44,69 +45,79 @@ public TextWidget(List text, int xPos, int yPos, int maxWidth, in this.verticalAlignment = VerticalAlignment.TOP; } - @Override - public ITextWidget alignHorizontalLeft() { - this.horizontalAlignment = HorizontalAlignment.LEFT; - return this; + private void invalidateCachedValues() { + wrappedText = null; + truncated = false; } @Override - public ITextWidget alignHorizontalRight() { - this.horizontalAlignment = HorizontalAlignment.RIGHT; - return this; + public int getWidth() { + return availableArea.width(); } @Override - public ITextWidget alignHorizontalCenter() { - this.horizontalAlignment = HorizontalAlignment.CENTER; - return this; + public int getHeight() { + return availableArea.height(); } @Override - public ITextWidget alignVerticalTop() { - this.verticalAlignment = VerticalAlignment.TOP; + public TextWidget setPosition(int xPos, int yPos) { + this.availableArea = this.availableArea.setPosition(xPos, yPos); + invalidateCachedValues(); return this; } @Override - public ITextWidget alignVerticalCenter() { - this.verticalAlignment = VerticalAlignment.CENTER; + public TextWidget setTextAlignment(HorizontalAlignment horizontalAlignment) { + if (this.horizontalAlignment.equals(horizontalAlignment)) { + return this; + } + this.horizontalAlignment = horizontalAlignment; + invalidateCachedValues(); return this; } @Override - public ITextWidget alignVerticalBottom() { - this.verticalAlignment = VerticalAlignment.BOTTOM; + public TextWidget setTextAlignment(VerticalAlignment verticalAlignment) { + if (this.verticalAlignment.equals(verticalAlignment)) { + return this; + } + this.verticalAlignment = verticalAlignment; + invalidateCachedValues(); return this; } @Override public ITextWidget setFont(Font font) { this.font = font; + invalidateCachedValues(); return this; } @Override public ITextWidget setColor(int color) { this.color = color; + invalidateCachedValues(); return this; } @Override public ITextWidget setLineSpacing(int lineSpacing) { this.lineSpacing = lineSpacing; + invalidateCachedValues(); return this; } @Override public ITextWidget setShadow(boolean shadow) { this.shadow = shadow; + invalidateCachedValues(); return this; } @Override public ScreenPosition getPosition() { - return area.getScreenPosition(); + return availableArea.getScreenPosition(); } private List calculateWrappedText() { @@ -114,18 +125,13 @@ private List calculateWrappedText() { return wrappedText; } int lineHeight = getLineHeight(); - int maxLines = area.height() / lineHeight; - if (maxLines * lineHeight + font.lineHeight <= area.height()) { + int maxLines = availableArea.height() / lineHeight; + if (maxLines * lineHeight + font.lineHeight <= availableArea.height()) { maxLines++; } - Pair, Boolean> result = StringUtil.splitLines(font, text, area.width(), maxLines); + Pair, Boolean> result = StringUtil.splitLines(font, text, availableArea.width(), maxLines); this.wrappedText = result.first(); - boolean truncated = result.second(); - if (truncated) { - this.tooltipText = text; - } else { - this.tooltipText = List.of(); - } + this.truncated = result.second(); return wrappedText; } @@ -148,38 +154,30 @@ public void drawWidget(GuiGraphics guiGraphics, double mouseX, double mouseY) { } if (DebugConfig.isDebugGuisEnabled()) { - guiGraphics.fill(0,0, area.width(), area.height(), 0xAAAAAA00); + guiGraphics.fill(0,0, availableArea.width(), availableArea.height(), 0xAAAAAA00); } } @Override public void getTooltip(ITooltipBuilder tooltip, double mouseX, double mouseY) { - if (mouseX >= 0 && mouseX < area.width() && mouseY >= 0 && mouseY < area.height()) { + if (mouseX >= 0 && mouseX < availableArea.width() && mouseY >= 0 && mouseY < availableArea.height()) { calculateWrappedText(); - tooltip.addAll(tooltipText); + if (truncated) { + tooltip.addAll(text); + } } } private int getXPos(FormattedCharSequence text) { - return switch (horizontalAlignment) { - case LEFT -> 0; - case RIGHT -> this.area.width() - font.width(text); - case CENTER -> Math.round((this.area.width() - font.width(text)) / 2f); - }; + return getXPos(font.width(text)); } - private int getYPosStart(int lineHeight, List text) { - if (verticalAlignment == VerticalAlignment.TOP) { - return 0; - } + private int getXPos(int lineWidth) { + return horizontalAlignment.getXPos(this.availableArea.width(), lineWidth); + } + private int getYPosStart(int lineHeight, List text) { int linesHeight = (lineHeight * text.size()) - lineSpacing - 1; - if (verticalAlignment == VerticalAlignment.BOTTOM) { - return area.height() - linesHeight; - } else if (verticalAlignment == VerticalAlignment.CENTER) { - return Math.round((area.height() - linesHeight) / 2f); - } else { - throw new IllegalArgumentException("Unknown verticalAlignment " + verticalAlignment); - } + return verticalAlignment.getYPos(this.availableArea.height(), linesHeight); } } diff --git a/CommonApi/src/main/java/mezz/jei/api/gui/builder/IRecipeLayoutBuilder.java b/CommonApi/src/main/java/mezz/jei/api/gui/builder/IRecipeLayoutBuilder.java index 5c85ec7ec..d5cebc577 100644 --- a/CommonApi/src/main/java/mezz/jei/api/gui/builder/IRecipeLayoutBuilder.java +++ b/CommonApi/src/main/java/mezz/jei/api/gui/builder/IRecipeLayoutBuilder.java @@ -1,5 +1,6 @@ package mezz.jei.api.gui.builder; +import mezz.jei.api.gui.placement.IPlaceable; import mezz.jei.api.gui.widgets.ISlottedWidgetFactory; import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.RecipeIngredientRole; @@ -24,7 +25,8 @@ public interface IRecipeLayoutBuilder { * @since 19.19.0 */ default IRecipeSlotBuilder addInputSlot(int x, int y) { - return addSlot(RecipeIngredientRole.INPUT, x, y); + return addSlot(RecipeIngredientRole.INPUT) + .setPosition(x, y); } /** @@ -37,20 +39,34 @@ default IRecipeSlotBuilder addInputSlot(int x, int y) { * @since 19.19.0 */ default IRecipeSlotBuilder addOutputSlot(int x, int y) { - return addSlot(RecipeIngredientRole.OUTPUT, x, y); + return addSlot(RecipeIngredientRole.OUTPUT) + .setPosition(x, y); } /** * Add a slot that will be drawn at the given position relative to the recipe layout. * - * @param recipeIngredientRole the {@link RecipeIngredientRole} of this slot (for lookups). + * @param role the {@link RecipeIngredientRole} of this slot (for lookups). * @param x relative x position of the slot on the recipe layout. * @param y relative y position of the slot on the recipe layout. * @return a {@link IRecipeSlotBuilder} that has further methods for adding ingredients, etc. * * @since 9.3.0 */ - IRecipeSlotBuilder addSlot(RecipeIngredientRole recipeIngredientRole, int x, int y); + default IRecipeSlotBuilder addSlot(RecipeIngredientRole role, int x, int y) { + return addSlot(role) + .setPosition(x, y); + } + + /** + * Add a slot and set its position using {@link IPlaceable} methods. + * + * @param role the {@link RecipeIngredientRole} of this slot (for lookups). + * @return a {@link IRecipeSlotBuilder} that has further methods for adding ingredients, etc. + * + * @since 19.19.1 + */ + IRecipeSlotBuilder addSlot(RecipeIngredientRole role); /** * Assign this slot to a {@link ISlottedWidgetFactory}, diff --git a/CommonApi/src/main/java/mezz/jei/api/gui/builder/IRecipeSlotBuilder.java b/CommonApi/src/main/java/mezz/jei/api/gui/builder/IRecipeSlotBuilder.java index 65815f67e..8ac61cd10 100644 --- a/CommonApi/src/main/java/mezz/jei/api/gui/builder/IRecipeSlotBuilder.java +++ b/CommonApi/src/main/java/mezz/jei/api/gui/builder/IRecipeSlotBuilder.java @@ -3,6 +3,7 @@ import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IRecipeSlotRichTooltipCallback; import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.gui.placement.IPlaceable; import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.ingredients.IIngredientRenderer; import mezz.jei.api.ingredients.IIngredientType; @@ -21,7 +22,7 @@ * @since 9.3.0 */ @ApiStatus.NonExtendable -public interface IRecipeSlotBuilder extends IIngredientAcceptor { +public interface IRecipeSlotBuilder extends IIngredientAcceptor, IPlaceable { /** * Add a callback to alter the tooltip for these ingredients. * diff --git a/CommonApi/src/main/java/mezz/jei/api/gui/placement/HorizontalAlignment.java b/CommonApi/src/main/java/mezz/jei/api/gui/placement/HorizontalAlignment.java new file mode 100644 index 000000000..9897dde1d --- /dev/null +++ b/CommonApi/src/main/java/mezz/jei/api/gui/placement/HorizontalAlignment.java @@ -0,0 +1,32 @@ +package mezz.jei.api.gui.placement; + +/** + * Represents a horizontal alignment of an element inside a larger area. + * @since 19.19.1 + */ +public enum HorizontalAlignment { + LEFT { + @Override + public int getXPos(int availableWidth, int elementWidth) { + return 0; + } + }, + CENTER { + @Override + public int getXPos(int availableWidth, int elementWidth) { + return Math.round((availableWidth - elementWidth) / 2f); + } + }, + RIGHT { + @Override + public int getXPos(int availableWidth, int elementWidth) { + return availableWidth - elementWidth; + } + }; + + /** + * Calculate the x position needed to align an element with the given width inside the availableArea. + * @since 19.19.1 + */ + public abstract int getXPos(int availableWidth, int elementWidth); +} diff --git a/CommonApi/src/main/java/mezz/jei/api/gui/placement/IPlaceable.java b/CommonApi/src/main/java/mezz/jei/api/gui/placement/IPlaceable.java new file mode 100644 index 000000000..b1fa96972 --- /dev/null +++ b/CommonApi/src/main/java/mezz/jei/api/gui/placement/IPlaceable.java @@ -0,0 +1,37 @@ +package mezz.jei.api.gui.placement; + +/** + * Interface for things that can have their position set, and be aligned vertically and horizontally in an area. + * + * @since 19.19.1 + */ +public interface IPlaceable> { + /** + * Place this element at the given position. + * @since 19.19.1 + */ + THIS setPosition(int xPos, int yPos); + + /** + * Place this element inside the given area, with the given alignment. + * + * @since 19.19.1 + */ + default THIS setPosition(int areaX, int areaY, int areaWidth, int areaHeight, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) { + int x = areaX + horizontalAlignment.getXPos(areaWidth, getWidth()); + int y = areaY + verticalAlignment.getYPos(areaHeight, getHeight()); + return setPosition(x, y); + } + + /** + * Get the width of this element. + * @since 19.19.1 + */ + int getWidth(); + + /** + * Get the height of this element. + * @since 19.19.1 + */ + int getHeight(); +} diff --git a/CommonApi/src/main/java/mezz/jei/api/gui/placement/VerticalAlignment.java b/CommonApi/src/main/java/mezz/jei/api/gui/placement/VerticalAlignment.java new file mode 100644 index 000000000..a274a12ae --- /dev/null +++ b/CommonApi/src/main/java/mezz/jei/api/gui/placement/VerticalAlignment.java @@ -0,0 +1,32 @@ +package mezz.jei.api.gui.placement; + +/** + * Represents a vertical alignment of an element inside a larger box (availableArea). + * @since 19.19.1 + */ +public enum VerticalAlignment { + TOP { + @Override + public int getYPos(int availableHeight, int elementHeight) { + return 0; + } + }, + CENTER { + @Override + public int getYPos(int availableHeight, int elementHeight) { + return Math.round((availableHeight - elementHeight) / 2f); + } + }, + BOTTOM { + @Override + public int getYPos(int availableHeight, int elementHeight) { + return availableHeight - elementHeight; + } + }; + + /** + * Calculate the y position needed to align an element with the given height inside the availableArea. + * @since 19.19.1 + */ + public abstract int getYPos(int availableHeight, int elementHeight); +} diff --git a/CommonApi/src/main/java/mezz/jei/api/gui/placement/package-info.java b/CommonApi/src/main/java/mezz/jei/api/gui/placement/package-info.java new file mode 100644 index 000000000..76e2e0cab --- /dev/null +++ b/CommonApi/src/main/java/mezz/jei/api/gui/placement/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package mezz.jei.api.gui.placement; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/CommonApi/src/main/java/mezz/jei/api/gui/widgets/IRecipeExtrasBuilder.java b/CommonApi/src/main/java/mezz/jei/api/gui/widgets/IRecipeExtrasBuilder.java index d944ba3e9..dbe7a4326 100644 --- a/CommonApi/src/main/java/mezz/jei/api/gui/widgets/IRecipeExtrasBuilder.java +++ b/CommonApi/src/main/java/mezz/jei/api/gui/widgets/IRecipeExtrasBuilder.java @@ -3,6 +3,7 @@ import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.inputs.IJeiGuiEventListener; import mezz.jei.api.gui.inputs.IJeiInputHandler; +import mezz.jei.api.gui.placement.IPlaceable; import mezz.jei.api.recipe.category.IRecipeCategory; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.network.chat.FormattedText; @@ -32,6 +33,13 @@ public interface IRecipeExtrasBuilder { */ void addDrawable(IDrawable drawable, int xPos, int yPos); + /** + * Add a {@link IDrawable} for the recipe category, and place it after with {@link IPlaceable} methods. + * + * @since 19.19.1 + */ + IPlaceable addDrawable(IDrawable drawable); + /** * Add a {@link IRecipeWidget} for the recipe category. * @@ -67,29 +75,105 @@ public interface IRecipeExtrasBuilder { * Add a vanilla-style recipe arrow to the recipe layout. * * @since 19.19.0 + * @deprecated use {@link #addRecipeArrow()} and then set the position with {@link IPlaceable} methods. */ - void addRecipeArrow(int xPos, int yPos); + @Deprecated(since = "19.19.1", forRemoval = true) + default void addRecipeArrow(int xPos, int yPos) { + addRecipeArrow() + .setPosition(xPos, yPos); + } + + /** + * Add a vanilla-style recipe arrow to the recipe layout. + * + * @since 19.19.1 + */ + IPlaceable addRecipeArrow(); /** * Add a vanilla-style recipe plus sign to the recipe layout. * * @since 19.19.0 + * @deprecated use {@link #addRecipePlusSign()} and then set the position with {@link IPlaceable} methods. + */ + @Deprecated(since = "19.19.1", forRemoval = true) + default void addRecipePlusSign(int xPos, int yPos) { + addRecipePlusSign() + .setPosition(xPos, yPos); + } + + /** + * Add a vanilla-style recipe plus sign to the recipe layout. + * + * @since 19.19.1 */ - void addRecipePlusSign(int xPos, int yPos); + IPlaceable addRecipePlusSign(); /** * Add a vanilla-style recipe arrow that fills over time in a loop. * * @since 19.19.0 + * @deprecated use {@link #addAnimatedRecipeArrow(int)} and then set the position with {@link IPlaceable} methods. */ - void addAnimatedRecipeArrow(int ticksPerCycle, int xPos, int yPos); + @Deprecated(since = "19.19.1", forRemoval = true) + default void addAnimatedRecipeArrow(int ticksPerCycle, int xPos, int yPos) { + addAnimatedRecipeArrow(ticksPerCycle) + .setPosition(xPos, yPos); + } + + /** + * Add a vanilla-style recipe arrow that fills over time in a loop. + * + * @since 19.19.1 + */ + IPlaceable addAnimatedRecipeArrow(int ticksPerCycle); /** * Add a vanilla-style recipe flame that empties over time in a loop. * * @since 19.19.0 + * @deprecated use {@link #addAnimatedRecipeFlame(int)} and then set the position with {@link IPlaceable} methods. + */ + @Deprecated(since = "19.19.1", forRemoval = true) + default void addAnimatedRecipeFlame(int cookTime, int xPos, int yPos) { + addAnimatedRecipeFlame(cookTime) + .setPosition(xPos, yPos); + } + + /** + * Add a vanilla-style recipe flame that empties over time in a loop. + * + * @since 19.19.1 + */ + IPlaceable addAnimatedRecipeFlame(int cookTime); + + /** + * Add text to the recipe layout. + * + * Automatically supports text wrapping and truncation of very long lines. + * If text is truncated, it will be displayed with an ellipsis (...) and can be viewed fully with a tooltip. + * + * Text can be vertically and horizontally aligned using the methods in {@link ITextWidget}. + * By default, text is vertically aligned "top" and horizontally aligned "left" inside the area given. + * + * @since 19.19.1 */ - void addAnimatedRecipeFlame(int cookTime, int xPos, int yPos); + default ITextWidget addText(FormattedText text, int maxWidth, int maxHeight) { + return addText(List.of(text), maxWidth, maxHeight); + } + + /** + * Add text to the recipe layout. + * + * Automatically supports text wrapping and truncation of very long lines. + * If text is truncated, it will be displayed with an ellipsis (...) and can be viewed fully with a tooltip. + * + * Text can be vertically and horizontally aligned using the methods in {@link ITextWidget}. + * By default, text is vertically aligned "top" and horizontally aligned "left" inside the area given. + * + * @since 19.19.1 + */ + ITextWidget addText(List text, int maxWidth, int maxHeight); /** * Add text to the recipe layout. @@ -101,9 +185,12 @@ public interface IRecipeExtrasBuilder { * By default, text is vertically aligned "top" and horizontally aligned "left" inside the area given. * * @since 19.19.0 + * @deprecated use {@link #addText(FormattedText, int, int)} and then set the position. */ + @Deprecated(since = "19.19.1", forRemoval = true) default ITextWidget addText(FormattedText text, int xPos, int yPos, int maxWidth, int maxHeight) { - return addText(List.of(text), xPos, yPos, maxWidth, maxHeight); + return addText(List.of(text), maxWidth, maxHeight) + .setPosition(xPos, yPos); } /** @@ -116,7 +203,12 @@ default ITextWidget addText(FormattedText text, int xPos, int yPos, int maxWidth * By default, text is vertically aligned "top" and horizontally aligned "left" inside the area given. * * @since 19.19.0 + * @deprecated use {@link #addText(List, int, int)} and then set the position. */ - ITextWidget addText(List text, int xPos, int yPos, int maxWidth, int maxHeight); + @Deprecated(since = "19.19.1", forRemoval = true) + default ITextWidget addText(List text, int xPos, int yPos, int maxWidth, int maxHeight) { + return addText(text, maxWidth, maxHeight) + .setPosition(xPos, yPos); + } } diff --git a/CommonApi/src/main/java/mezz/jei/api/gui/widgets/ITextWidget.java b/CommonApi/src/main/java/mezz/jei/api/gui/widgets/ITextWidget.java index 4631a3ccd..0ed03ea8e 100644 --- a/CommonApi/src/main/java/mezz/jei/api/gui/widgets/ITextWidget.java +++ b/CommonApi/src/main/java/mezz/jei/api/gui/widgets/ITextWidget.java @@ -1,5 +1,8 @@ package mezz.jei.api.gui.widgets; +import mezz.jei.api.gui.placement.HorizontalAlignment; +import mezz.jei.api.gui.placement.IPlaceable; +import mezz.jei.api.gui.placement.VerticalAlignment; import net.minecraft.client.gui.Font; /** @@ -12,7 +15,7 @@ * * @since 19.19.0 */ -public interface ITextWidget { +public interface ITextWidget extends IPlaceable { /** * Set the font used by this text widget when drawing text. * Defaults to the minecraft client font. @@ -45,45 +48,85 @@ public interface ITextWidget { */ ITextWidget setShadow(boolean shadow); + /** + * Set the horizontal alignment of the text within the {@link #getScreenRectangle()} area. + * The default setting is {@link HorizontalAlignment#LEFT}. + * + * @since 19.19.1 + */ + ITextWidget setTextAlignment(HorizontalAlignment horizontalAlignment); + + /** + * Set the vertical alignment of the text within the {@link #getScreenRectangle()} area. + * The default setting is {@link VerticalAlignment#TOP}. + * + * @since 19.19.1 + */ + ITextWidget setTextAlignment(VerticalAlignment verticalAlignment); + /** * Horizontally align text to the left within the given bounds. (default) * * @since 19.19.0 + * @deprecated use {@link #setTextAlignment(HorizontalAlignment)} */ - ITextWidget alignHorizontalLeft(); + @Deprecated(since = "19.19.0", forRemoval = true) + default ITextWidget alignHorizontalLeft() { + return setTextAlignment(HorizontalAlignment.LEFT); + } /** * Horizontally align text in the center of the given bounds. * * @since 19.19.0 + * @deprecated use {@link #setTextAlignment(HorizontalAlignment)} */ - ITextWidget alignHorizontalCenter(); + @Deprecated(since = "19.19.0", forRemoval = true) + default ITextWidget alignHorizontalCenter() { + return setTextAlignment(HorizontalAlignment.CENTER); + } /** * Horizontally align text to the right within the given bounds. * * @since 19.19.0 + * @deprecated use {@link #setTextAlignment(HorizontalAlignment)} */ - ITextWidget alignHorizontalRight(); + @Deprecated(since = "19.19.0", forRemoval = true) + default ITextWidget alignHorizontalRight() { + return setTextAlignment(HorizontalAlignment.RIGHT); + } /** * Vertically align text to the top of the given bounds. (default) * * @since 19.19.0 + * @deprecated use {@link #setTextAlignment(VerticalAlignment)} */ - ITextWidget alignVerticalTop(); + @Deprecated(since = "19.19.0", forRemoval = true) + default ITextWidget alignVerticalTop() { + return setTextAlignment(VerticalAlignment.TOP); + } /** * Vertically align text in the center of the given bounds. * * @since 19.19.0 + * @deprecated use {@link #setTextAlignment(VerticalAlignment)} */ - ITextWidget alignVerticalCenter(); + @Deprecated(since = "19.19.0", forRemoval = true) + default ITextWidget alignVerticalCenter() { + return setTextAlignment(VerticalAlignment.CENTER); + } /** * Vertically align text to the bottom of the given bounds. * * @since 19.19.0 + * @deprecated use {@link #setTextAlignment(VerticalAlignment)} */ - ITextWidget alignVerticalBottom(); + @Deprecated(since = "19.19.0", forRemoval = true) + default ITextWidget alignVerticalBottom() { + return setTextAlignment(VerticalAlignment.BOTTOM); + } } diff --git a/CommonApi/src/main/java/mezz/jei/api/recipe/IRecipeManager.java b/CommonApi/src/main/java/mezz/jei/api/recipe/IRecipeManager.java index 4b65aa5ae..dffe0d0c4 100644 --- a/CommonApi/src/main/java/mezz/jei/api/recipe/IRecipeManager.java +++ b/CommonApi/src/main/java/mezz/jei/api/recipe/IRecipeManager.java @@ -153,6 +153,22 @@ Optional> createRecipeLayoutDrawable( int borderSize ); + /** + * Returns a drawable recipe slot, for addons that want to draw the slots somewhere. + * + * @param role the recipe ingredient role of this slot + * @param ingredients a non-null list of optional ingredients for the slot + * @param focusedIngredients indexes of the focused ingredients in "ingredients" + * @param ingredientCycleOffset the starting index for cycling the list of ingredients when rendering. + * @since 19.19.1 + */ + IRecipeSlotDrawable createRecipeSlotDrawable( + RecipeIngredientRole role, + List>> ingredients, + Set focusedIngredients, + int ingredientCycleOffset + ); + /** * Returns a drawable recipe slot, for addons that want to draw the slots somewhere. * @@ -163,15 +179,21 @@ Optional> createRecipeLayoutDrawable( * @param yPos the y position of the slot on the screen * @param ingredientCycleOffset the starting index for cycling the list of ingredients when rendering. * @since 11.5.0 + * @deprecated use {@link #createRecipeSlotDrawable(RecipeIngredientRole, List, Set, int)} and then set the position */ - IRecipeSlotDrawable createRecipeSlotDrawable( + @Deprecated(since = "19.19.1") + default IRecipeSlotDrawable createRecipeSlotDrawable( RecipeIngredientRole role, List>> ingredients, Set focusedIngredients, int xPos, int yPos, int ingredientCycleOffset - ); + ) { + IRecipeSlotDrawable recipeSlotDrawable = createRecipeSlotDrawable(role, ingredients, focusedIngredients, ingredientCycleOffset); + recipeSlotDrawable.setPosition(xPos, yPos); + return recipeSlotDrawable; + } /** * Get the ingredients for a given recipe. diff --git a/Gui/src/main/java/mezz/jei/gui/recipes/RecipeCatalysts.java b/Gui/src/main/java/mezz/jei/gui/recipes/RecipeCatalysts.java index 662a49a8c..f4101fa39 100644 --- a/Gui/src/main/java/mezz/jei/gui/recipes/RecipeCatalysts.java +++ b/Gui/src/main/java/mezz/jei/gui/recipes/RecipeCatalysts.java @@ -87,16 +87,17 @@ public void updateLayout(List> ingredients, ImmutableRect2i private IRecipeSlotDrawable createSlot(ITypedIngredient typedIngredient, int index, int maxIngredientsPerColumn) { int column = index / maxIngredientsPerColumn; int row = index % maxIngredientsPerColumn; - int xPos = left + borderSize + (column * ingredientSize) + ingredientBorderSize; - int yPos = top + borderSize + (row * ingredientSize) + ingredientBorderSize; - return recipeManager.createRecipeSlotDrawable( + IRecipeSlotDrawable recipeSlotDrawable = recipeManager.createRecipeSlotDrawable( RecipeIngredientRole.CATALYST, List.of(Optional.of(typedIngredient)), IntSet.of(0), - xPos, - yPos, 0 ); + recipeSlotDrawable.setPosition( + left + borderSize + (column * ingredientSize) + ingredientBorderSize, + top + borderSize + (row * ingredientSize) + ingredientBorderSize + ); + return recipeSlotDrawable; } public Optional draw(GuiGraphics guiGraphics, int mouseX, int mouseY) { diff --git a/Library/src/main/java/mezz/jei/library/gui/recipes/RecipeLayout.java b/Library/src/main/java/mezz/jei/library/gui/recipes/RecipeLayout.java index 8added2b0..e78363d6c 100644 --- a/Library/src/main/java/mezz/jei/library/gui/recipes/RecipeLayout.java +++ b/Library/src/main/java/mezz/jei/library/gui/recipes/RecipeLayout.java @@ -11,6 +11,7 @@ import mezz.jei.api.gui.inputs.IJeiGuiEventListener; import mezz.jei.api.gui.inputs.IJeiInputHandler; import mezz.jei.api.gui.inputs.RecipeSlotUnderMouse; +import mezz.jei.api.gui.placement.IPlaceable; import mezz.jei.api.gui.widgets.IRecipeExtrasBuilder; import mezz.jei.api.gui.widgets.IRecipeWidget; import mezz.jei.api.gui.widgets.IScrollBoxWidget; @@ -24,6 +25,7 @@ import mezz.jei.common.Internal; import mezz.jei.common.gui.JeiTooltip; import mezz.jei.common.gui.elements.DrawableAnimated; +import mezz.jei.common.gui.elements.DrawableCombined; import mezz.jei.common.gui.elements.DrawableNineSliceTexture; import mezz.jei.common.gui.elements.OffsetDrawable; import mezz.jei.common.gui.elements.TextWidget; @@ -403,6 +405,13 @@ public void addDrawable(IDrawable drawable, int xPos, int yPos) { this.drawables.add(OffsetDrawable.create(drawable, xPos, yPos)); } + @Override + public IPlaceable addDrawable(IDrawable drawable) { + OffsetDrawable offsetDrawable = new OffsetDrawable(drawable, 0, 0); + this.drawables.add(offsetDrawable); + return offsetDrawable; + } + @Override public void addWidget(IRecipeWidget widget) { this.allWidgets.add(widget); @@ -430,42 +439,45 @@ public IScrollBoxWidget addScrollBoxWidget(int width, int height, int xPos, int } @Override - public void addRecipeArrow(int xPos, int yPos) { + public IPlaceable addRecipeArrow() { Textures textures = Internal.getTextures(); IDrawable drawable = textures.getRecipeArrow(); - addDrawable(drawable, xPos, yPos); + return addDrawable(drawable); } @Override - public void addRecipePlusSign(int xPos, int yPos) { + public IPlaceable addRecipePlusSign() { Textures textures = Internal.getTextures(); IDrawable drawable = textures.getRecipePlusSign(); - addDrawable(drawable, xPos, yPos); + return addDrawable(drawable); } @Override - public void addAnimatedRecipeArrow(int ticksPerCycle, int xPos, int yPos) { + public IPlaceable addAnimatedRecipeArrow(int ticksPerCycle) { Textures textures = Internal.getTextures(); IDrawableStatic recipeArrowFilled = textures.getRecipeArrowFilled(); - IDrawableAnimated animatedFill = new DrawableAnimated(recipeArrowFilled, ticksPerCycle, IDrawableAnimated.StartDirection.LEFT, false); - addDrawable(textures.getRecipeArrow(), xPos, yPos); - addDrawable(animatedFill, xPos, yPos); + IDrawable animatedFill = new DrawableAnimated(recipeArrowFilled, ticksPerCycle, IDrawableAnimated.StartDirection.LEFT, false); + IDrawable drawableCombined = new DrawableCombined(textures.getRecipeArrow(), animatedFill); + OffsetDrawable offsetDrawable = new OffsetDrawable(drawableCombined, 0, 0); + return addDrawable(offsetDrawable); } @Override - public void addAnimatedRecipeFlame(int cookTime, int xPos, int yPos) { + public IPlaceable addAnimatedRecipeFlame(int cookTime) { Textures textures = Internal.getTextures(); IDrawableStatic flameIcon = textures.getFlameIcon(); IDrawableAnimated animatedFill = new DrawableAnimated(flameIcon, cookTime, IDrawableAnimated.StartDirection.TOP, true); - addDrawable(textures.getFlameEmptyIcon(), xPos, yPos); - addDrawable(animatedFill, xPos, yPos); + + IDrawable drawableCombined = new DrawableCombined(textures.getFlameEmptyIcon(), animatedFill); + OffsetDrawable offsetDrawable = new OffsetDrawable(drawableCombined, 0, 0); + return addDrawable(offsetDrawable); } @Override - public ITextWidget addText(List text, int xPos, int yPos, int maxWidth, int maxHeight) { - TextWidget textWidget = new TextWidget(text, xPos, yPos, maxWidth, maxHeight); + public ITextWidget addText(List text, int maxWidth, int maxHeight) { + TextWidget textWidget = new TextWidget(text, 0, 0, maxWidth, maxHeight); addWidget(textWidget); return textWidget; } diff --git a/Library/src/main/java/mezz/jei/library/gui/recipes/layout/builder/RecipeLayoutBuilder.java b/Library/src/main/java/mezz/jei/library/gui/recipes/layout/builder/RecipeLayoutBuilder.java index 9cf11d8b8..b24b2885b 100644 --- a/Library/src/main/java/mezz/jei/library/gui/recipes/layout/builder/RecipeLayoutBuilder.java +++ b/Library/src/main/java/mezz/jei/library/gui/recipes/layout/builder/RecipeLayoutBuilder.java @@ -8,7 +8,6 @@ import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.drawable.IScalableDrawable; import mezz.jei.api.gui.ingredient.IRecipeSlotDrawable; -import mezz.jei.api.gui.widgets.IRecipeWidget; import mezz.jei.api.gui.widgets.ISlottedWidgetFactory; import mezz.jei.api.ingredients.ITypedIngredient; import mezz.jei.api.recipe.IFocusGroup; @@ -44,7 +43,6 @@ public class RecipeLayoutBuilder implements IRecipeLayoutBuilder { private final List slots = new ArrayList<>(); private final List> focusLinkedSlots = new ArrayList<>(); - private final List widgets = new ArrayList<>(); private final IIngredientManager ingredientManager; private final IRecipeCategory recipeCategory; @@ -64,8 +62,8 @@ public RecipeLayoutBuilder(IRecipeCategory recipeCategory, T recipe, IIngredi } @Override - public IRecipeSlotBuilder addSlot(RecipeIngredientRole role, int x, int y) { - RecipeSlotBuilder slot = new RecipeSlotBuilder(ingredientManager, nextSlotIndex++, role, x, y); + public IRecipeSlotBuilder addSlot(RecipeIngredientRole role) { + RecipeSlotBuilder slot = new RecipeSlotBuilder(ingredientManager, nextSlotIndex++, role); if (role == RecipeIngredientRole.OUTPUT) { addOutputSlotTooltipCallback(slot); @@ -77,7 +75,7 @@ public IRecipeSlotBuilder addSlot(RecipeIngredientRole role, int x, int y) { @Override public IRecipeSlotBuilder addSlotToWidget(RecipeIngredientRole role, ISlottedWidgetFactory widgetFactory) { - RecipeSlotBuilder slot = new RecipeSlotBuilder(ingredientManager, nextSlotIndex++, role, 0, 0) + RecipeSlotBuilder slot = new RecipeSlotBuilder(ingredientManager, nextSlotIndex++, role) .assignToWidgetFactory(widgetFactory); if (role == RecipeIngredientRole.OUTPUT) { diff --git a/Library/src/main/java/mezz/jei/library/gui/recipes/layout/builder/RecipeSlotBuilder.java b/Library/src/main/java/mezz/jei/library/gui/recipes/layout/builder/RecipeSlotBuilder.java index 4f39381bc..aecd1e456 100644 --- a/Library/src/main/java/mezz/jei/library/gui/recipes/layout/builder/RecipeSlotBuilder.java +++ b/Library/src/main/java/mezz/jei/library/gui/recipes/layout/builder/RecipeSlotBuilder.java @@ -49,9 +49,9 @@ public class RecipeSlotBuilder implements IRecipeSlotBuilder { private @Nullable String slotName; private @Nullable ISlottedWidgetFactory assignedWidgetFactory; - public RecipeSlotBuilder(IIngredientManager ingredientManager, int slotIndex, RecipeIngredientRole role, int x, int y) { + public RecipeSlotBuilder(IIngredientManager ingredientManager, int slotIndex, RecipeIngredientRole role) { this.ingredients = new DisplayIngredientAcceptor(ingredientManager); - this.rect = new ImmutableRect2i(x, y, 16, 16); + this.rect = new ImmutableRect2i(0, 0, 16, 16); this.role = role; this.slotIndex = slotIndex; } @@ -188,6 +188,22 @@ public IRecipeSlotBuilder setSlotName(String slotName) { return this; } + @Override + public int getWidth() { + return this.rect.width(); + } + + @Override + public int getHeight() { + return this.rect.height(); + } + + @Override + public IRecipeSlotBuilder setPosition(int xPos, int yPos) { + this.rect = this.rect.setPosition(xPos, yPos); + return this; + } + public RecipeSlotBuilder assignToWidgetFactory(ISlottedWidgetFactory widgetFactory) { ErrorUtil.checkNotNull(widgetFactory, "widgetFactory"); diff --git a/Library/src/main/java/mezz/jei/library/gui/recipes/supplier/builder/IngredientSlotBuilder.java b/Library/src/main/java/mezz/jei/library/gui/recipes/supplier/builder/IngredientSlotBuilder.java index 413d43020..131f30236 100644 --- a/Library/src/main/java/mezz/jei/library/gui/recipes/supplier/builder/IngredientSlotBuilder.java +++ b/Library/src/main/java/mezz/jei/library/gui/recipes/supplier/builder/IngredientSlotBuilder.java @@ -3,6 +3,8 @@ import mezz.jei.api.gui.builder.IRecipeSlotBuilder; import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.ingredient.IRecipeSlotRichTooltipCallback; +import mezz.jei.api.gui.placement.HorizontalAlignment; +import mezz.jei.api.gui.placement.VerticalAlignment; import mezz.jei.api.ingredients.IIngredientRenderer; import mezz.jei.api.ingredients.IIngredientType; import mezz.jei.api.ingredients.ITypedIngredient; @@ -121,6 +123,26 @@ public IRecipeSlotBuilder setSlotName(String slotName) { return this; } + @Override + public int getWidth() { + return 16; + } + + @Override + public int getHeight() { + return 16; + } + + @Override + public IRecipeSlotBuilder setPosition(int xPos, int yPos) { + return this; + } + + @Override + public IRecipeSlotBuilder setPosition(int areaX, int areaY, int areaWidth, int areaHeight, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) { + return this; + } + public List> getAllIngredients() { return this.ingredients.getAllIngredients(); } diff --git a/Library/src/main/java/mezz/jei/library/gui/recipes/supplier/builder/IngredientSupplierBuilder.java b/Library/src/main/java/mezz/jei/library/gui/recipes/supplier/builder/IngredientSupplierBuilder.java index 80b70eff4..0a8622b31 100644 --- a/Library/src/main/java/mezz/jei/library/gui/recipes/supplier/builder/IngredientSupplierBuilder.java +++ b/Library/src/main/java/mezz/jei/library/gui/recipes/supplier/builder/IngredientSupplierBuilder.java @@ -35,6 +35,16 @@ public IRecipeSlotBuilder addSlot(RecipeIngredientRole role, int x, int y) { return slot; } + @Override + public IRecipeSlotBuilder addSlot(RecipeIngredientRole role) { + IngredientSlotBuilder slot = ingredientSlotBuilders.get(role); + if (slot == null) { + slot = new IngredientSlotBuilder(ingredientManager); + ingredientSlotBuilders.put(role, slot); + } + return slot; + } + @Override public IRecipeSlotBuilder addSlotToWidget(RecipeIngredientRole role, ISlottedWidgetFactory widgetFactory) { return addSlot(role, 0, 0); diff --git a/Library/src/main/java/mezz/jei/library/plugins/debug/DebugFocusRecipeCategory.java b/Library/src/main/java/mezz/jei/library/plugins/debug/DebugFocusRecipeCategory.java index e82f54906..904d5f2a4 100644 --- a/Library/src/main/java/mezz/jei/library/plugins/debug/DebugFocusRecipeCategory.java +++ b/Library/src/main/java/mezz/jei/library/plugins/debug/DebugFocusRecipeCategory.java @@ -4,7 +4,6 @@ import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.builder.IRecipeSlotBuilder; import mezz.jei.api.gui.drawable.IDrawable; -import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.helpers.IPlatformFluidHelper; import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.RecipeIngredientRole; diff --git a/Library/src/main/java/mezz/jei/library/plugins/jei/tags/TagInfoRecipeCategory.java b/Library/src/main/java/mezz/jei/library/plugins/jei/tags/TagInfoRecipeCategory.java index a30db3a13..3db5f1817 100644 --- a/Library/src/main/java/mezz/jei/library/plugins/jei/tags/TagInfoRecipeCategory.java +++ b/Library/src/main/java/mezz/jei/library/plugins/jei/tags/TagInfoRecipeCategory.java @@ -2,6 +2,8 @@ import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.gui.placement.HorizontalAlignment; +import mezz.jei.api.gui.placement.VerticalAlignment; import mezz.jei.api.gui.widgets.IRecipeExtrasBuilder; import mezz.jei.api.gui.widgets.IScrollGridWidgetFactory; import mezz.jei.api.helpers.IGuiHelper; @@ -78,11 +80,12 @@ public void createRecipeExtras(IRecipeExtrasBuilder builder, R recipe, IRecipeSl tagName, Component.literal(tag.location().toString()).withStyle(ChatFormatting.GRAY) ); - builder.addText(text, 22, 0, getWidth() - 22, 20) + builder.addText(text, getWidth() - 22, 20) + .setPosition(22, 0) .setColor(0xFF505050) .setLineSpacing(0) - .alignVerticalCenter() - .alignHorizontalCenter(); + .setTextAlignment(VerticalAlignment.CENTER) + .setTextAlignment(HorizontalAlignment.CENTER); } @Override diff --git a/Library/src/main/java/mezz/jei/library/plugins/vanilla/anvil/AnvilRecipeCategory.java b/Library/src/main/java/mezz/jei/library/plugins/vanilla/anvil/AnvilRecipeCategory.java index 5ea38230b..64a382b31 100644 --- a/Library/src/main/java/mezz/jei/library/plugins/vanilla/anvil/AnvilRecipeCategory.java +++ b/Library/src/main/java/mezz/jei/library/plugins/vanilla/anvil/AnvilRecipeCategory.java @@ -5,6 +5,7 @@ import mezz.jei.api.gui.builder.IRecipeSlotBuilder; import mezz.jei.api.gui.ingredient.IRecipeSlotView; import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.gui.placement.HorizontalAlignment; import mezz.jei.api.gui.widgets.IRecipeExtrasBuilder; import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.recipe.IFocusGroup; @@ -68,8 +69,8 @@ public void setRecipe(IRecipeLayoutBuilder builder, IJeiAnvilRecipe recipe, IFoc @Override public void createRecipeExtras(IRecipeExtrasBuilder builder, IJeiAnvilRecipe recipe, IRecipeSlotsView recipeSlotsView, IFocusGroup focuses) { - builder.addRecipePlusSign(27, 3); - builder.addRecipeArrow(76, 1); + builder.addRecipePlusSign().setPosition(27, 3); + builder.addRecipeArrow().setPosition(76, 1); Integer cost = getCost(recipeSlotsView); if (cost != null) { @@ -81,10 +82,11 @@ public void createRecipeExtras(IRecipeExtrasBuilder builder, IJeiAnvilRecipe rec // Show red if the player doesn't have enough levels int textColor = playerHasEnoughLevels(player, cost) ? 0xFF80FF20 : 0xFFFF6060; - builder.addText(text, 2, 27, getWidth() - 4, 10) + builder.addText(text, getWidth() - 4, 10) + .setPosition(2, 27) .setColor(textColor) .setShadow(true) - .alignHorizontalRight(); + .setTextAlignment(HorizontalAlignment.RIGHT); } } diff --git a/Library/src/main/java/mezz/jei/library/plugins/vanilla/anvil/SmithingRecipeCategory.java b/Library/src/main/java/mezz/jei/library/plugins/vanilla/anvil/SmithingRecipeCategory.java index 24d9a95e5..10c7f0c8e 100644 --- a/Library/src/main/java/mezz/jei/library/plugins/vanilla/anvil/SmithingRecipeCategory.java +++ b/Library/src/main/java/mezz/jei/library/plugins/vanilla/anvil/SmithingRecipeCategory.java @@ -89,7 +89,7 @@ public void onDisplayedIngredientsUpdate(RecipeHolder recipeHold @Override public void createRecipeExtras(IRecipeExtrasBuilder builder, RecipeHolder recipe, IRecipeSlotsView recipeSlotsView, IFocusGroup focuses) { - builder.addRecipeArrow(61, 6); + builder.addRecipeArrow().setPosition(61, 6); } @Override diff --git a/Library/src/main/java/mezz/jei/library/plugins/vanilla/brewing/BrewingRecipeCategory.java b/Library/src/main/java/mezz/jei/library/plugins/vanilla/brewing/BrewingRecipeCategory.java index cd85ea5d8..283854444 100644 --- a/Library/src/main/java/mezz/jei/library/plugins/vanilla/brewing/BrewingRecipeCategory.java +++ b/Library/src/main/java/mezz/jei/library/plugins/vanilla/brewing/BrewingRecipeCategory.java @@ -62,7 +62,8 @@ public void createRecipeExtras(IRecipeExtrasBuilder builder, IJeiBrewingRecipe r String brewingStepsString = brewingSteps < Integer.MAX_VALUE ? Integer.toString(brewingSteps) : "?"; Component steps = Component.translatable("gui.jei.category.brewing.steps", brewingStepsString); - builder.addText(steps, 70, 28, 42, 12) + builder.addText(steps, 42, 12) + .setPosition(70, 28) .setColor(0xFF808080); } diff --git a/Library/src/main/java/mezz/jei/library/plugins/vanilla/compostable/CompostableRecipeCategory.java b/Library/src/main/java/mezz/jei/library/plugins/vanilla/compostable/CompostableRecipeCategory.java index 06d08eee6..c75718e16 100644 --- a/Library/src/main/java/mezz/jei/library/plugins/vanilla/compostable/CompostableRecipeCategory.java +++ b/Library/src/main/java/mezz/jei/library/plugins/vanilla/compostable/CompostableRecipeCategory.java @@ -3,6 +3,8 @@ import mezz.jei.api.constants.RecipeTypes; import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.gui.placement.HorizontalAlignment; +import mezz.jei.api.gui.placement.VerticalAlignment; import mezz.jei.api.gui.widgets.IRecipeExtrasBuilder; import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.recipe.IFocusGroup; @@ -35,9 +37,10 @@ public void createRecipeExtras(IRecipeExtrasBuilder builder, IJeiCompostingRecip float chance = recipe.getChance(); int chancePercent = (int) Math.floor(chance * 100); Component text = Component.translatable("gui.jei.category.compostable.chance", chancePercent); - builder.addText(text, 24, 0, getWidth() - 24, getHeight()) - .alignVerticalCenter() - .alignHorizontalCenter() + builder.addText(text, getWidth() - 24, getHeight()) + .setPosition(24, 0) + .setTextAlignment(HorizontalAlignment.CENTER) + .setTextAlignment(VerticalAlignment.CENTER) .setColor(0xFF808080); } diff --git a/Library/src/main/java/mezz/jei/library/plugins/vanilla/cooking/AbstractCookingCategory.java b/Library/src/main/java/mezz/jei/library/plugins/vanilla/cooking/AbstractCookingCategory.java index b98a062e3..569150d95 100644 --- a/Library/src/main/java/mezz/jei/library/plugins/vanilla/cooking/AbstractCookingCategory.java +++ b/Library/src/main/java/mezz/jei/library/plugins/vanilla/cooking/AbstractCookingCategory.java @@ -3,6 +3,8 @@ import com.mojang.serialization.Codec; import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.gui.placement.HorizontalAlignment; +import mezz.jei.api.gui.placement.VerticalAlignment; import mezz.jei.api.gui.widgets.IRecipeExtrasBuilder; import mezz.jei.api.helpers.ICodecHelper; import mezz.jei.api.helpers.IGuiHelper; @@ -59,8 +61,10 @@ public void createRecipeExtras(IRecipeExtrasBuilder builder, RecipeHolder rec if (cookTime <= 0) { cookTime = regularCookTime; } - builder.addAnimatedRecipeArrow(cookTime, 26, 17); - builder.addAnimatedRecipeFlame(300, 1, 20); + builder.addAnimatedRecipeArrow(cookTime) + .setPosition(26, 17); + builder.addAnimatedRecipeFlame(300) + .setPosition(1, 20); addExperience(builder, recipeHolder); addCookTime(builder, recipeHolder); @@ -71,8 +75,9 @@ protected void addExperience(IRecipeExtrasBuilder builder, RecipeHolder recip float experience = recipe.getExperience(); if (experience > 0) { Component experienceString = Component.translatable("gui.jei.category.smelting.experience", experience); - builder.addText(experienceString, 20, 0, getWidth() - 20, 10) - .alignHorizontalRight() + builder.addText(experienceString, getWidth() - 20, 10) + .setPosition(0, 0, getWidth(), getHeight(), HorizontalAlignment.RIGHT, VerticalAlignment.TOP) + .setTextAlignment(HorizontalAlignment.RIGHT) .setColor(0xFF808080); } } @@ -86,9 +91,10 @@ protected void addCookTime(IRecipeExtrasBuilder builder, RecipeHolder recipeH if (cookTime > 0) { int cookTimeSeconds = cookTime / 20; Component timeString = Component.translatable("gui.jei.category.smelting.time.seconds", cookTimeSeconds); - builder.addText(timeString, 20, getHeight() - 10, getWidth() - 20, 10) - .alignHorizontalRight() - .alignVerticalBottom() + builder.addText(timeString, getWidth() - 20, 10) + .setPosition(0, 0, getWidth(), getHeight(), HorizontalAlignment.RIGHT, VerticalAlignment.BOTTOM) + .setTextAlignment(HorizontalAlignment.RIGHT) + .setTextAlignment(VerticalAlignment.BOTTOM) .setColor(0xFF808080); } } diff --git a/Library/src/main/java/mezz/jei/library/plugins/vanilla/cooking/CampfireCookingCategory.java b/Library/src/main/java/mezz/jei/library/plugins/vanilla/cooking/CampfireCookingCategory.java index e2ab9fc5a..3d902b6ec 100644 --- a/Library/src/main/java/mezz/jei/library/plugins/vanilla/cooking/CampfireCookingCategory.java +++ b/Library/src/main/java/mezz/jei/library/plugins/vanilla/cooking/CampfireCookingCategory.java @@ -35,8 +35,10 @@ public void createRecipeExtras(IRecipeExtrasBuilder builder, RecipeHolder recipe, IRecipeSlotsView recipeSlotsView, IFocusGroup focuses) { - builder.addRecipeArrow(26, 9); + builder.addRecipeArrow().setPosition(26, 9); } @Override diff --git a/Library/src/main/java/mezz/jei/library/recipes/RecipeManager.java b/Library/src/main/java/mezz/jei/library/recipes/RecipeManager.java index 01caed752..8682f976c 100644 --- a/Library/src/main/java/mezz/jei/library/recipes/RecipeManager.java +++ b/Library/src/main/java/mezz/jei/library/recipes/RecipeManager.java @@ -112,8 +112,8 @@ public Optional> createRecipeLayoutDrawable( } @Override - public IRecipeSlotDrawable createRecipeSlotDrawable(RecipeIngredientRole role, List>> ingredients, Set focusedIngredients, int xPos, int yPos, int ingredientCycleOffset) { - RecipeSlotBuilder builder = new RecipeSlotBuilder(ingredientManager, 0, role, xPos, yPos); + public IRecipeSlotDrawable createRecipeSlotDrawable(RecipeIngredientRole role, List>> ingredients, Set focusedIngredients, int ingredientCycleOffset) { + RecipeSlotBuilder builder = new RecipeSlotBuilder(ingredientManager, 0, role); builder.addOptionalTypedIngredients(ingredients); CycleTimer cycleTimer = CycleTimer.create(ingredientCycleOffset); Pair result = builder.build(focusedIngredients, cycleTimer); diff --git a/gradle.properties b/gradle.properties index 2198502b6..197d3b5a7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -74,4 +74,4 @@ modrinthId=u6dRKJwZ jUnitVersion=5.8.2 # Version -specificationVersion=19.19.0 +specificationVersion=19.19.1