From aba4c079befd4bb32f732b65c746a22559644d35 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Mon, 8 Nov 2021 23:15:08 +0800 Subject: Big Visual and Functional Changes - Fix #503 - Shift Click to select page, normal click to go back to page 1 - Allow non-consuming draggable visitors - Add scale down animation when dragging a stack to the main item list to dismiss it - Make Cheat Mode not active in Display Screens - Add colors to cosmetic transfer handler errors - Implement JEI animations, fix #501 - Allow favorites dragged stacks to go back to where they are if they are ignored, instead of being at the end of the favorites - Implement favorites & entry list column and row limits - Implement display page height limit - Updated localizations --- .../shedaniel/rei/impl/client/REIRuntimeImpl.java | 21 +++++- .../rei/impl/client/config/ConfigObjectImpl.java | 40 +++++++++- .../rei/impl/client/gui/ScreenOverlayImpl.java | 86 ++++++++++++++++++---- .../client/gui/dragging/CurrentDraggingStack.java | 43 +++++++---- .../gui/screen/DefaultDisplayViewingScreen.java | 84 +++++++-------------- .../gui/widget/DefaultDisplayChoosePageWidget.java | 22 +++--- .../client/gui/widget/EntryListEntryWidget.java | 8 +- .../impl/client/gui/widget/EntryListWidget.java | 37 +++++++--- .../client/gui/widget/EntryStacksRegionWidget.java | 51 ++++++++----- .../rei/impl/client/gui/widget/EntryWidget.java | 5 +- .../client/gui/widget/FavoritesListWidget.java | 9 +++ .../impl/client/gui/widget/InternalWidgets.java | 2 +- .../rei/impl/client/gui/widget/TabWidget.java | 5 +- .../client/gui/widget/region/RealRegionEntry.java | 2 - .../gui/widget/region/RegionDraggableStack.java | 16 +++- .../gui/widget/region/RegionEntryListEntry.java | 4 + .../client/gui/widget/region/RegionListener.java | 2 + .../client/registry/screen/ExclusionZonesImpl.java | 8 +- .../client/runtime/DefaultClientRuntimePlugin.java | 4 +- 19 files changed, 298 insertions(+), 151 deletions(-) (limited to 'runtime/src/main/java/me') diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java index b674d0099..d5d89a653 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java @@ -33,6 +33,7 @@ import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigManager; import me.shedaniel.rei.api.client.config.ConfigObject; +import me.shedaniel.rei.api.client.gui.config.DisplayPanelLocation; import me.shedaniel.rei.api.client.gui.config.SearchFieldLocation; import me.shedaniel.rei.api.client.gui.screen.DisplayScreen; import me.shedaniel.rei.api.client.gui.widgets.TextField; @@ -55,6 +56,8 @@ import org.jetbrains.annotations.Nullable; import java.util.*; +import static me.shedaniel.rei.impl.client.gui.widget.EntryListWidget.entrySize; + @ApiStatus.Internal @Environment(EnvType.CLIENT) public class REIRuntimeImpl implements REIRuntime { @@ -194,8 +197,7 @@ public class REIRuntimeImpl implements REIRuntime { } @Override - public Rectangle calculateEntryListArea() { - Rectangle bounds = ScreenRegistry.getInstance().getOverlayBounds(ConfigObject.getInstance().getDisplayPanelLocation(), Minecraft.getInstance().screen); + public Rectangle calculateEntryListArea(Rectangle bounds) { SearchFieldLocation searchFieldLocation = getContextualSearchFieldLocation(); int yOffset = 2; @@ -212,7 +214,20 @@ public class REIRuntimeImpl implements REIRuntime { int yOffset = 8; if (!ConfigObject.getInstance().isLowerConfigButton()) yOffset += 25; - return new Rectangle(bounds.x, bounds.y + yOffset, bounds.width, bounds.height - 3 - yOffset); + bounds = new Rectangle(bounds.x, bounds.y + yOffset, bounds.width, bounds.height - 3 - yOffset); + + int widthReduction = (int) Math.round(bounds.width * (1 - ConfigObject.getInstance().getFavoritesHorizontalEntriesBoundariesPercentage())); + if (ConfigObject.getInstance().getDisplayPanelLocation() == DisplayPanelLocation.LEFT) + bounds.x += widthReduction; + bounds.width -= widthReduction; + int maxWidth = (int) Math.ceil(entrySize() * ConfigObject.getInstance().getFavoritesHorizontalEntriesBoundariesColumns() + entrySize() * 0.75) + 8; + if (bounds.width > maxWidth) { + if (ConfigObject.getInstance().getDisplayPanelLocation() == DisplayPanelLocation.LEFT) + bounds.x += bounds.width - maxWidth; + bounds.width = maxWidth; + } + + return bounds; } @Override diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java index 096a49e8b..73521ae30 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java @@ -169,6 +169,11 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { return advanced.layout.maxRecipesPerPage; } + @Override + public int getMaxRecipesPageHeight() { + return advanced.layout.maxRecipesPageHeight; + } + @Override public boolean doesDisableRecipeBook() { return functionality.disableRecipeBook; @@ -349,16 +354,39 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { @ApiStatus.Experimental @Override - public double getHorizontalEntriesBoundaries() { + public double getHorizontalEntriesBoundariesPercentage() { return Mth.clamp(appearance.horizontalEntriesBoundaries, 0.1, 1); } @ApiStatus.Experimental @Override - public double getVerticalEntriesBoundaries() { + public double getVerticalEntriesBoundariesPercentage() { return Mth.clamp(appearance.verticalEntriesBoundaries, 0.1, 1); } + @ApiStatus.Experimental + @Override + public double getHorizontalEntriesBoundariesColumns() { + return Mth.clamp(appearance.horizontalEntriesBoundariesColumns, 1, 1000); + } + + @ApiStatus.Experimental + @Override + public double getVerticalEntriesBoundariesRows() { + return Mth.clamp(appearance.verticalEntriesBoundariesRows, 1, 1000); + } + + @ApiStatus.Experimental + @Override + public double getFavoritesHorizontalEntriesBoundariesPercentage() { + return Mth.clamp(appearance.favoritesHorizontalEntriesBoundaries, 0.1, 1); + } + + @Override + public double getFavoritesHorizontalEntriesBoundariesColumns() { + return Mth.clamp(appearance.favoritesHorizontalEntriesBoundariesColumns, 1, 1000); + } + @Override public SyntaxHighlightingMode getSyntaxHighlightingMode() { return appearance.syntaxHighlightingMode; @@ -469,6 +497,10 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { @UsePercentage(min = 0.1, max = 1.0, prefix = "Limit: ") private double horizontalEntriesBoundaries = 1.0; @UsePercentage(min = 0.1, max = 1.0, prefix = "Limit: ") private double verticalEntriesBoundaries = 1.0; + private int horizontalEntriesBoundariesColumns = 50; + private int verticalEntriesBoundariesRows = 1000; + @UsePercentage(min = 0.1, max = 1.0, prefix = "Limit: ") private double favoritesHorizontalEntriesBoundaries = 1.0; + private int favoritesHorizontalEntriesBoundariesColumns = 50; @UseSpecialSearchFilterSyntaxHighlightingScreen private SyntaxHighlightingMode syntaxHighlightingMode = SyntaxHighlightingMode.COLORFUL; } @@ -506,7 +538,9 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON) private EntryPanelOrderingConfig entryPanelOrdering = EntryPanelOrderingConfig.REGISTRY_ASCENDING; @Comment("Declares the maximum amount of recipes displayed in a page if possible.") @ConfigEntry.BoundedDiscrete(min = 2, max = 99) - private int maxRecipesPerPage = 3; + private int maxRecipesPerPage = 8; + @Comment("Declares the maximum amount of recipes displayed in a page if possible.") @ConfigEntry.BoundedDiscrete(min = 100, max = 1000) + private int maxRecipesPageHeight = 300; @Comment("Declares whether entry rendering time should be debugged.") private boolean debugRenderTimeRequired = false; @Comment("Merges displays with equal contents under 1 display.") private boolean mergeDisplayUnderOne = true; } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java index bc53fca48..f95afd48b 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java @@ -37,10 +37,12 @@ import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigManager; import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.favorites.FavoriteEntry; +import me.shedaniel.rei.api.client.gui.config.DisplayPanelLocation; import me.shedaniel.rei.api.client.gui.config.SearchFieldLocation; import me.shedaniel.rei.api.client.gui.drag.DraggableStackProvider; import me.shedaniel.rei.api.client.gui.drag.DraggableStackVisitor; import me.shedaniel.rei.api.client.gui.drag.DraggingContext; +import me.shedaniel.rei.api.client.gui.screen.DisplayScreen; import me.shedaniel.rei.api.client.gui.widgets.Button; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import me.shedaniel.rei.api.client.gui.widgets.Widget; @@ -63,11 +65,7 @@ import me.shedaniel.rei.impl.client.REIRuntimeImpl; import me.shedaniel.rei.impl.client.gui.craftable.CraftableFilter; import me.shedaniel.rei.impl.client.gui.dragging.CurrentDraggingStack; import me.shedaniel.rei.impl.client.gui.modules.Menu; -import me.shedaniel.rei.impl.client.gui.screen.DefaultDisplayViewingScreen; -import me.shedaniel.rei.impl.client.gui.widget.EntryListWidget; -import me.shedaniel.rei.impl.client.gui.widget.FavoritesListWidget; -import me.shedaniel.rei.impl.client.gui.widget.InternalWidgets; -import me.shedaniel.rei.impl.client.gui.widget.LateRenderable; +import me.shedaniel.rei.impl.client.gui.widget.*; import me.shedaniel.rei.impl.client.gui.widget.search.OverlaySearchField; import me.shedaniel.rei.impl.common.util.Weather; import net.minecraft.client.Minecraft; @@ -97,6 +95,8 @@ import java.util.*; import java.util.function.Consumer; import java.util.function.Predicate; +import static me.shedaniel.rei.impl.client.gui.widget.EntryListWidget.entrySize; + @ApiStatus.Internal public class ScreenOverlayImpl extends ScreenOverlay { private static final ResourceLocation CHEST_GUI_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/recipecontainer.png"); @@ -112,6 +112,8 @@ public class ScreenOverlayImpl extends ScreenOverlay { private Button leftButton, rightButton; private Widget configButton; private CurrentDraggingStack draggingStack = new CurrentDraggingStack(); + @Nullable + public DefaultDisplayChoosePageWidget choosePageWidget; @Nullable private ScreenOverlayImpl.OverlayMenu overlayMenu = null; @@ -231,7 +233,7 @@ public class ScreenOverlayImpl extends ScreenOverlay { this.children().clear(); this.closeOverlayMenu(); this.window = Minecraft.getInstance().getWindow(); - this.bounds = ScreenRegistry.getInstance().getOverlayBounds(ConfigObject.getInstance().getDisplayPanelLocation(), Minecraft.getInstance().screen); + this.bounds = calculateOverlayBounds(); widgets.add(ENTRY_LIST_WIDGET); if (ConfigObject.getInstance().isFavoritesEnabled()) { if (favoritesListWidget == null) { @@ -240,7 +242,7 @@ public class ScreenOverlayImpl extends ScreenOverlay { favoritesListWidget.favoritePanel.resetRows(); widgets.add(favoritesListWidget); } - ENTRY_LIST_WIDGET.updateArea(REIRuntimeImpl.getSearchField() == null ? "" : REIRuntimeImpl.getSearchField().getText()); + ENTRY_LIST_WIDGET.updateArea(this.bounds, REIRuntimeImpl.getSearchField() == null ? "" : REIRuntimeImpl.getSearchField().getText()); REIRuntimeImpl.getSearchField().getBounds().setBounds(getSearchFieldArea()); this.widgets.add(REIRuntimeImpl.getSearchField()); REIRuntimeImpl.getSearchField().setResponder(s -> ENTRY_LIST_WIDGET.updateSearch(s, false)); @@ -280,7 +282,7 @@ public class ScreenOverlayImpl extends ScreenOverlay { ConfigManager.getInstance().openConfigScreen(REIRuntime.getInstance().getPreviousScreen()); }) .onRender((matrices, button) -> { - if (ClientHelper.getInstance().isCheating() && ClientHelperImpl.getInstance().hasOperatorPermission()) { + if (ClientHelper.getInstance().isCheating() && !(Minecraft.getInstance().screen instanceof DisplayScreen) && ClientHelperImpl.getInstance().hasOperatorPermission()) { button.setTint(ClientHelperImpl.getInstance().hasPermissionToUsePackets() ? 721354752 : 1476440063); } else { button.removeTint(); @@ -326,9 +328,16 @@ public class ScreenOverlayImpl extends ScreenOverlay { } if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) { widgets.add(Widgets.createClickableLabel(new Point(bounds.x + (bounds.width / 2), bounds.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 10), NarratorChatListener.NO_TITLE, label -> { - ENTRY_LIST_WIDGET.setPage(0); - ENTRY_LIST_WIDGET.updateEntriesPosition(); - }).tooltipLine(I18n.get("text.rei.go_back_first_page")).focusable(false).onRender((matrices, label) -> { + if (!Screen.hasShiftDown()) { + ENTRY_LIST_WIDGET.setPage(0); + ENTRY_LIST_WIDGET.updateEntriesPosition(); + } else { + ScreenOverlayImpl.getInstance().choosePageWidget = new DefaultDisplayChoosePageWidget(page -> { + ENTRY_LIST_WIDGET.setPage(page); + ENTRY_LIST_WIDGET.updateEntriesPosition(); + }, ENTRY_LIST_WIDGET.getPage(), ENTRY_LIST_WIDGET.getTotalPages()); + } + }).tooltipLine(I18n.get("text.rei.go_back_first_page") + "\n \n§7" + I18n.get("text.rei.shift_click_to", I18n.get("text.rei.choose_page"))).focusable(false).onRender((matrices, label) -> { label.setClickable(ENTRY_LIST_WIDGET.getTotalPages() > 1); label.setMessage(new TextComponent(String.format("%s/%s", ENTRY_LIST_WIDGET.getPage() + 1, Math.max(ENTRY_LIST_WIDGET.getTotalPages(), 1)))); }).rainbow(new Random().nextFloat() < 1.0E-4D || ClientHelperImpl.getInstance().isAprilFools.get())); @@ -464,7 +473,7 @@ public class ScreenOverlayImpl extends ScreenOverlay { @Override public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { - if (shouldReload) { + if (shouldReload || !calculateOverlayBounds().equals(bounds)) { ENTRY_LIST_WIDGET.updateSearch(REIRuntimeImpl.getSearchField().getText(), true); init(); } else { @@ -515,6 +524,23 @@ public class ScreenOverlayImpl extends ScreenOverlay { } } + private static Rectangle calculateOverlayBounds() { + Rectangle bounds = ScreenRegistry.getInstance().getOverlayBounds(ConfigObject.getInstance().getDisplayPanelLocation(), Minecraft.getInstance().screen); + + int widthReduction = (int) Math.round(bounds.width * (1 - ConfigObject.getInstance().getHorizontalEntriesBoundariesPercentage())); + if (ConfigObject.getInstance().getDisplayPanelLocation() == DisplayPanelLocation.RIGHT) + bounds.x += widthReduction; + bounds.width -= widthReduction; + int maxWidth = (int) Math.ceil(entrySize() * ConfigObject.getInstance().getHorizontalEntriesBoundariesColumns() + entrySize() * 0.75); + if (bounds.width > maxWidth) { + if (ConfigObject.getInstance().getDisplayPanelLocation() == DisplayPanelLocation.RIGHT) + bounds.x += bounds.width - maxWidth; + bounds.width = maxWidth; + } + + return bounds; + } + public void lateRender(PoseStack matrices, int mouseX, int mouseY, float delta) { if (REIRuntime.getInstance().isOverlayVisible()) { REIRuntimeImpl.getSearchField().laterRender(matrices, mouseX, mouseY, delta); @@ -532,9 +558,15 @@ public class ScreenOverlayImpl extends ScreenOverlay { overlayMenu.wrappedMenu.render(matrices, mouseX, mouseY, delta); } } + if (choosePageWidget != null) { + setBlitOffset(500); + this.fillGradient(matrices, 0, 0, window.getGuiScaledWidth(), window.getGuiScaledHeight(), -1072689136, -804253680); + setBlitOffset(0); + choosePageWidget.render(matrices, mouseX, mouseY, delta); + } } Screen currentScreen = Minecraft.getInstance().screen; - if (!(currentScreen instanceof DefaultDisplayViewingScreen) || !((DefaultDisplayViewingScreen) currentScreen).choosePageActivated) { + if (choosePageWidget == null) { for (Tooltip tooltip : TOOLTIPS) { if (tooltip != null) renderTooltip(matrices, tooltip); @@ -611,6 +643,12 @@ public class ScreenOverlayImpl extends ScreenOverlay { @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { if (REIRuntime.getInstance().isOverlayVisible()) { + if (keyCode == 256 && choosePageWidget != null) { + choosePageWidget = null; + return true; + } + if (choosePageWidget != null) + return choosePageWidget.keyPressed(keyCode, scanCode, modifiers); if (REIRuntimeImpl.getSearchField().keyPressed(keyCode, scanCode, modifiers)) return true; for (GuiEventListener listener : widgets) @@ -655,6 +693,9 @@ public class ScreenOverlayImpl extends ScreenOverlay { public boolean charTyped(char char_1, int int_1) { if (!REIRuntime.getInstance().isOverlayVisible()) return false; + if (choosePageWidget != null) { + return choosePageWidget.charTyped(char_1, int_1); + } if (REIRuntimeImpl.getSearchField().charTyped(char_1, int_1)) return true; for (GuiEventListener listener : widgets) @@ -671,6 +712,15 @@ public class ScreenOverlayImpl extends ScreenOverlay { @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { boolean visible = REIRuntime.getInstance().isOverlayVisible(); + if (choosePageWidget != null) { + if (choosePageWidget.containsMouse(mouseX, mouseY)) { + return choosePageWidget.mouseClicked(mouseX, mouseY, button); + } else { + choosePageWidget = null; + init(); + return false; + } + } if (visible && configButton.mouseClicked(mouseX, mouseY, button)) { this.setFocused(configButton); if (button == 0) @@ -756,9 +806,19 @@ public class ScreenOverlayImpl extends ScreenOverlay { public boolean mouseDragged(double double_1, double double_2, int int_1, double double_3, double double_4) { if (!REIRuntime.getInstance().isOverlayVisible()) return false; + if (choosePageWidget != null) { + return choosePageWidget.mouseDragged(double_1, double_2, int_1, double_3, double_4); + } return (this.getFocused() != null && this.isDragging() && int_1 == 0) && this.getFocused().mouseDragged(double_1, double_2, int_1, double_3, double_4); } + @Override + public GuiEventListener getFocused() { + if (choosePageWidget != null) + return choosePageWidget; + return super.getFocused(); + } + public boolean isInside(double mouseX, double mouseY) { return bounds.contains(mouseX, mouseY) && isNotInExclusionZones(mouseX, mouseY); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java index 742a5bc39..4d8bb74f8 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java @@ -28,10 +28,7 @@ import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; import me.shedaniel.rei.RoughlyEnoughItemsCoreClient; -import me.shedaniel.rei.api.client.gui.drag.DraggableStack; -import me.shedaniel.rei.api.client.gui.drag.DraggableStackProvider; -import me.shedaniel.rei.api.client.gui.drag.DraggableStackVisitor; -import me.shedaniel.rei.api.client.gui.drag.DraggingContext; +import me.shedaniel.rei.api.client.gui.drag.*; import me.shedaniel.rei.api.client.gui.widgets.Widget; import me.shedaniel.rei.api.common.util.Animator; import me.shedaniel.rei.impl.client.gui.widget.LateRenderable; @@ -118,12 +115,12 @@ public class CurrentDraggingStack extends Widget implements LateRenderable, Drag while (iterator.hasNext()) { RenderBackEntry renderBackEntry = iterator.next(); renderBackEntry.update(delta); - if (Math.abs(renderBackEntry.x.doubleValue() - renderBackEntry.x.target()) <= 2 && Math.abs(renderBackEntry.y.doubleValue() - renderBackEntry.y.target()) <= 2) { + if (renderBackEntry.width.doubleValue() < 2 || renderBackEntry.height.doubleValue() < 2 || (Math.abs(renderBackEntry.x.doubleValue() - renderBackEntry.x.target()) <= 2 && Math.abs(renderBackEntry.y.doubleValue() - renderBackEntry.y.target()) <= 2 && Math.abs(renderBackEntry.width.doubleValue() - renderBackEntry.width.target()) <= 1 && Math.abs(renderBackEntry.height.doubleValue() - renderBackEntry.height.target()) <= 1)) { iterator.remove(); } else { matrices.pushPose(); matrices.translate(0, 0, 600); - renderBackEntry.stack.render(matrices, new Rectangle(renderBackEntry.x.intValue(), renderBackEntry.y.intValue(), 16, 16), mouseX, mouseY, delta); + renderBackEntry.stack.render(matrices, new Rectangle(Math.round(renderBackEntry.x.floatValue()), Math.round(renderBackEntry.y.floatValue()), Math.round(renderBackEntry.width.floatValue()), Math.round(renderBackEntry.height.floatValue())), mouseX, mouseY, delta); matrices.popPose(); } } @@ -156,8 +153,8 @@ public class CurrentDraggingStack extends Widget implements LateRenderable, Drag private boolean drop() { if (entry != null && entry.dragging) { - boolean released = visitor.acceptDraggedStack(this, entry.stack); - entry.stack.release(released); + DraggedAcceptorResult result = visitor.acceptDraggedStackWithResult(this, entry.stack); + entry.stack.release(result); entry = null; return true; } @@ -185,7 +182,15 @@ public class CurrentDraggingStack extends Widget implements LateRenderable, Drag @Override public void renderBackToPosition(DraggableStack stack, Point initialPosition, Supplier position) { - backToOriginals.add(new RenderBackEntry(stack, initialPosition, position)); + backToOriginals.add(new RenderBackEntry(stack, new Rectangle(initialPosition.x - 8, initialPosition.y - 8, 16, 16), () -> { + Point point = position.get(); + return new Rectangle(point.x, point.y, 16, 16); + })); + } + + @Override + public void renderBackToPosition(DraggableStack stack, Rectangle initialPosition, Supplier bounds) { + backToOriginals.add(new RenderBackEntry(stack, initialPosition, bounds)); } private class DraggableEntry { @@ -238,30 +243,38 @@ public class CurrentDraggingStack extends Widget implements LateRenderable, Drag private static class RenderBackEntry { private final DraggableStack stack; - private final Supplier position; + private final Supplier position; private Animator x = new Animator(); private Animator y = new Animator(); + private Animator width = new Animator(); + private Animator height = new Animator(); private int lastDestination = -1; - public RenderBackEntry(DraggableStack stack, Point initialPosition, Supplier position) { + public RenderBackEntry(DraggableStack stack, Rectangle initialPosition, Supplier position) { this.stack = stack; - this.x.setAs(initialPosition.x - 8); - this.y.setAs(initialPosition.y - 8); + this.x.setAs(initialPosition.x); + this.y.setAs(initialPosition.y); + this.width.setAs(initialPosition.width); + this.height.setAs(initialPosition.height); this.position = position; } - public Point getPosition() { + public Rectangle getPosition() { return position.get(); } public void update(double delta) { this.x.update(delta); this.y.update(delta); - Point position = getPosition(); + this.width.update(delta); + this.height.update(delta); + Rectangle position = getPosition(); if (lastDestination != position.hashCode()) { lastDestination = position.hashCode(); this.x.setTo(position.x, 200); this.y.setTo(position.y, 200); + this.width.setTo(position.width, 200); + this.height.setTo(position.height, 200); } } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java index 3478a2cc3..37e329a95 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java @@ -51,6 +51,7 @@ import me.shedaniel.rei.api.common.util.ImmutableTextComponent; import me.shedaniel.rei.impl.client.ClientHelperImpl; import me.shedaniel.rei.impl.client.REIRuntimeImpl; import me.shedaniel.rei.impl.client.gui.RecipeDisplayExporter; +import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; import me.shedaniel.rei.impl.client.gui.widget.DefaultDisplayChoosePageWidget; import me.shedaniel.rei.impl.client.gui.widget.EntryWidget; import me.shedaniel.rei.impl.client.gui.widget.InternalWidgets; @@ -60,6 +61,7 @@ import me.shedaniel.rei.impl.display.DisplaySpec; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.chat.NarratorChatListener; import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.resources.language.I18n; import net.minecraft.client.resources.sounds.SimpleSoundInstance; @@ -84,8 +86,6 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { private final List tabs = Lists.newArrayList(); public int page; public int categoryPages = -1; - public boolean choosePageActivated = false; - public DefaultDisplayChoosePageWidget choosePageWidget; @Nullable private Panel workingStationsBaseWidget; private Button recipeBack, recipeNext, categoryBack, categoryNext; @@ -107,20 +107,12 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (keyCode == 256 && choosePageActivated) { - choosePageActivated = false; - init(); - return true; - } if (keyCode == 258 && !minecraft.options.keyInventory.matches(keyCode, scanCode)) { boolean next = !hasShiftDown(); if (!this.changeFocus(next)) this.changeFocus(next); return true; - } - if (choosePageActivated) - return choosePageWidget.keyPressed(keyCode, scanCode, modifiers); - else if (ConfigObject.getInstance().getNextPageKeybind().matchesKey(keyCode, scanCode)) { + } else if (ConfigObject.getInstance().getNextPageKeybind().matchesKey(keyCode, scanCode)) { if (recipeNext.isEnabled()) recipeNext.onClick(); return recipeNext.isEnabled(); @@ -155,9 +147,9 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { this.tabs.clear(); this.preWidgets.clear(); this.widgets.clear(); - int largestHeight = Math.max(height - 34 - 30, 100); + int largestHeight = Math.min(Math.max(height - 34 - 30, 100), ConfigObject.getInstance().getMaxRecipesPageHeight()); int maxWidthDisplay = CollectionUtils.mapAndMax(getCurrentDisplayed(), display -> getCurrentCategory().getDisplayWidth(display.provideInternalDisplay()), Comparator.naturalOrder()).orElse(150); - int maxHeight = Math.min(largestHeight, CollectionUtils., Integer>mapAndMax(categories, + int maxHeight = Math.min(largestHeight, CollectionUtils., Integer>mapAndMax(categories, category -> (category.getDisplayHeight() + 4) * Math.max(1, Math.min(getRecipesPerPage(largestHeight, category) + 1, Math.max(categoryMap.get(category).size(), ConfigObject.getInstance().getMaxRecipePerPage()))) + 36, Comparator.naturalOrder()).orElse(66)); int totalDisplayHeight = (getCurrentCategory().getDisplayHeight() + 4) * Math.max(1, getRecipesPerPage(maxHeight, getCurrentCategory()) + 1) + 36; int guiWidth = Math.max(maxWidthDisplay + 10, 190); @@ -166,7 +158,7 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { this.bounds.setLocation(this.bounds.getX(), this.bounds.getY() + 15); this.bounds.setSize(this.bounds.getWidth(), this.bounds.getHeight() - 10); } - + boolean isCompactTabs = ConfigObject.getInstance().isUsingCompactTabs(); int tabSize = isCompactTabs ? 24 : 28; this.tabsPerPage = Math.max(5, Mth.floor((guiWidth - 20d) / tabSize)); @@ -200,7 +192,7 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { .onClick(button -> nextCategory()).tooltipLine(new TranslatableComponent("text.rei.next_category"))); this.categoryBack.setEnabled(categories.size() > 1); this.categoryNext.setEnabled(categories.size() > 1); - + this.widgets.add(recipeBack = Widgets.createButton(new Rectangle(bounds.getX() + 5, bounds.getY() + 19, 12, 12), new TranslatableComponent("text.rei.left_arrow")) .onClick(button -> { page--; @@ -209,12 +201,19 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { DefaultDisplayViewingScreen.this.init(); }).tooltipLine(new TranslatableComponent("text.rei.previous_page"))); this.widgets.add(Widgets.createClickableLabel(new Point(bounds.getCenterX(), bounds.getY() + 21), NarratorChatListener.NO_TITLE, label -> { - DefaultDisplayViewingScreen.this.choosePageActivated = true; - DefaultDisplayViewingScreen.this.init(); + if (!Screen.hasShiftDown()) { + page = 0; + DefaultDisplayViewingScreen.this.init(); + } else { + ScreenOverlayImpl.getInstance().choosePageWidget = new DefaultDisplayChoosePageWidget(page -> { + DefaultDisplayViewingScreen.this.page = page; + DefaultDisplayViewingScreen.this.init(); + }, page, getCurrentTotalPages()); + } }).onRender((matrices, label) -> { label.setMessage(new ImmutableTextComponent(String.format("%d/%d", page + 1, getCurrentTotalPages()))); label.setClickable(getCurrentTotalPages() > 1); - }).tooltipSupplier(label -> label.isClickable() ? I18n.get("text.rei.choose_page") : null)); + }).tooltipSupplier(label -> label.isClickable() ? I18n.get("text.rei.go_back_first_page") + "\n \n§7" + I18n.get("text.rei.shift_click_to", I18n.get("text.rei.choose_page")) : null)); this.widgets.add(recipeNext = Widgets.createButton(new Rectangle(bounds.getMaxX() - 17, bounds.getY() + 19, 12, 12), new TranslatableComponent("text.rei.right_arrow")) .onClick(button -> { page++; @@ -238,8 +237,6 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { tab.setRenderer(categories.get(tabIndex), categories.get(tabIndex).getIcon(), categories.get(tabIndex).getTitle(), tab.getId() + categoryPages * tabsPerPage == selectedCategoryIndex); } } - - choosePageWidget = choosePageActivated ? new DefaultDisplayChoosePageWidget(this, page, getCurrentTotalPages()) : null; initDisplays(); initWorkstations(preWidgets); @@ -392,12 +389,6 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { } } } - if (choosePageActivated) { - setBlitOffset(500); - this.fillGradient(matrices, 0, 0, this.width, this.height, -1072689136, -804253680); - setBlitOffset(0); - choosePageWidget.render(matrices, mouseX, mouseY, delta); - } } @Override @@ -425,9 +416,6 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { @Override public boolean charTyped(char char_1, int int_1) { - if (choosePageActivated) { - return choosePageWidget.charTyped(char_1, int_1); - } for (GuiEventListener listener : children()) if (listener.charTyped(char_1, int_1)) return true; @@ -436,9 +424,6 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { @Override public boolean mouseDragged(double double_1, double double_2, int int_1, double double_3, double double_4) { - if (choosePageActivated) { - return choosePageWidget.mouseDragged(double_1, double_2, int_1, double_3, double_4); - } for (GuiEventListener entry : children()) if (entry.mouseDragged(double_1, double_2, int_1, double_3, double_4)) return true; @@ -447,17 +432,13 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { - if (choosePageActivated) { - return choosePageWidget.mouseReleased(mouseX, mouseY, button); - } else { - ModifierKeyCode export = ConfigObject.getInstance().getExportImageKeybind(); - if (export.matchesMouse(button)) { - for (Map.Entry> entry : recipeBounds.entrySet()) { - Rectangle bounds = entry.getKey(); - if (bounds.contains(PointHelper.ofMouse())) { - RecipeDisplayExporter.exportRecipeDisplay(bounds, entry.getValue()); - break; - } + ModifierKeyCode export = ConfigObject.getInstance().getExportImageKeybind(); + if (export.matchesMouse(button)) { + for (Map.Entry> entry : recipeBounds.entrySet()) { + Rectangle bounds = entry.getKey(); + if (bounds.contains(PointHelper.ofMouse())) { + RecipeDisplayExporter.exportRecipeDisplay(bounds, entry.getValue()); + break; } } } @@ -494,15 +475,7 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (choosePageActivated) { - if (choosePageWidget.containsMouse(mouseX, mouseY)) { - return choosePageWidget.mouseClicked(mouseX, mouseY, button); - } else { - choosePageActivated = false; - init(); - return false; - } - } else if (ConfigObject.getInstance().getNextPageKeybind().matchesMouse(button)) { + if (ConfigObject.getInstance().getNextPageKeybind().matchesMouse(button)) { if (recipeNext.isEnabled()) recipeNext.onClick(); return recipeNext.isEnabled(); @@ -521,13 +494,6 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { return super.mouseClicked(mouseX, mouseY, button); } - @Override - public GuiEventListener getFocused() { - if (choosePageActivated) - return choosePageWidget; - return super.getFocused(); - } - public static class WorkstationSlotWidget extends EntryWidget { public WorkstationSlotWidget(int x, int y, EntryIngredient widgets) { super(new Point(x, y)); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/DefaultDisplayChoosePageWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/DefaultDisplayChoosePageWidget.java index 60b798978..810a622f8 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/DefaultDisplayChoosePageWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/DefaultDisplayChoosePageWidget.java @@ -33,7 +33,7 @@ import me.shedaniel.rei.api.client.gui.widgets.Button; import me.shedaniel.rei.api.client.gui.widgets.Panel; import me.shedaniel.rei.api.client.gui.widgets.Widget; import me.shedaniel.rei.api.client.gui.widgets.Widgets; -import me.shedaniel.rei.impl.client.gui.screen.DefaultDisplayViewingScreen; +import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; import me.shedaniel.rei.impl.client.gui.widget.basewidgets.TextFieldWidget; import net.minecraft.client.Minecraft; import net.minecraft.network.chat.TranslatableComponent; @@ -43,6 +43,7 @@ import org.jetbrains.annotations.ApiStatus; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.function.IntConsumer; @ApiStatus.Internal public class DefaultDisplayChoosePageWidget extends DraggableWidget { @@ -51,14 +52,14 @@ public class DefaultDisplayChoosePageWidget extends DraggableWidget { private int maxPage; private Rectangle bounds, grabBounds, dragBounds; private List widgets; - private DefaultDisplayViewingScreen screen; + private IntConsumer callback; private TextFieldWidget textFieldWidget; private Panel base1, base2; private Button btnDone; - public DefaultDisplayChoosePageWidget(DefaultDisplayViewingScreen screen, int currentPage, int maxPage) { + public DefaultDisplayChoosePageWidget(IntConsumer callback, int currentPage, int maxPage) { super(getPointFromConfig()); - this.screen = screen; + this.callback = callback; this.currentPage = currentPage; this.maxPage = maxPage; initWidgets(getMidPoint()); @@ -110,7 +111,7 @@ public class DefaultDisplayChoosePageWidget extends DraggableWidget { this.widgets.add(base2 = Widgets.createCategoryBase(bounds)); this.widgets.add(new Widget() { - private TranslatableComponent text; + private TranslatableComponent text = new TranslatableComponent("text.rei.choose_page"); @Override public List children() { @@ -119,7 +120,6 @@ public class DefaultDisplayChoosePageWidget extends DraggableWidget { @Override public void render(PoseStack matrices, int i, int i1, float v) { - text = new TranslatableComponent("text.rei.choose_page"); font.draw(matrices, text.getVisualOrderText(), bounds.x + 5, bounds.y + 5, REIRuntime.getInstance().isDarkThemeEnabled() ? 0xFFBBBBBB : 0xFF404040); String endString = String.format(" /%d", maxPage); int width = font.width(endString); @@ -145,9 +145,8 @@ public class DefaultDisplayChoosePageWidget extends DraggableWidget { textFieldWidget.setText(String.valueOf(currentPage + 1)); widgets.add(btnDone = Widgets.createButton(new Rectangle(bounds.x + bounds.width - 45, bounds.y + bounds.height + 3, 40, 20), new TranslatableComponent("gui.done")) .onClick(button -> { - screen.page = Mth.clamp(getIntFromString(textFieldWidget.getText()).orElse(0) - 1, 0, screen.getCurrentTotalPages() - 1); - screen.choosePageActivated = false; - screen.init(); + callback.accept(Mth.clamp(getIntFromString(textFieldWidget.getText()).orElse(0) - 1, 0, maxPage - 1)); + ScreenOverlayImpl.getInstance().choosePageWidget = null; })); textFieldWidget.setFocused(true); } @@ -183,9 +182,8 @@ public class DefaultDisplayChoosePageWidget extends DraggableWidget { @Override public boolean keyPressed(int int_1, int int_2, int int_3) { if (int_1 == 335 || int_1 == 257) { - screen.page = Mth.clamp(getIntFromString(textFieldWidget.getText()).orElse(0) - 1, 0, screen.getCurrentTotalPages() - 1); - screen.choosePageActivated = false; - screen.init(); + callback.accept(Mth.clamp(getIntFromString(textFieldWidget.getText()).orElse(0) - 1, 0, maxPage - 1)); + ScreenOverlayImpl.getInstance().choosePageWidget = null; return true; } for (Widget widget : widgets) diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListEntryWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListEntryWidget.java index 143d93662..4ab46773c 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListEntryWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListEntryWidget.java @@ -28,8 +28,10 @@ import dev.architectury.fluid.FluidStack; import me.shedaniel.math.Point; import me.shedaniel.rei.api.client.ClientHelper; import me.shedaniel.rei.api.client.config.ConfigObject; +import me.shedaniel.rei.api.client.gui.screen.DisplayScreen; import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.util.EntryStacks; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -51,7 +53,7 @@ public abstract class EntryListEntryWidget extends EntryWidget { @Override public void queueTooltip(PoseStack matrices, int mouseX, int mouseY, float delta) { - if (ClientHelper.getInstance().isCheating() && !minecraft.player.containerMenu.getCarried().isEmpty()) { + if (ClientHelper.getInstance().isCheating() && !(Minecraft.getInstance().screen instanceof DisplayScreen) && !minecraft.player.containerMenu.getCarried().isEmpty()) { return; } super.queueTooltip(matrices, mouseX, mouseY, delta); @@ -74,7 +76,7 @@ public abstract class EntryListEntryWidget extends EntryWidget { } protected boolean doAction(double mouseX, double mouseY, int button) { - if (!ClientHelper.getInstance().isCheating()) return false; + if (!(ClientHelper.getInstance().isCheating() && !(Minecraft.getInstance().screen instanceof DisplayScreen))) return false; EntryStack entry = getCurrentEntry().copy(); if (!entry.isEmpty()) { if (entry.getValueType() == FluidStack.class) { @@ -96,7 +98,7 @@ public abstract class EntryListEntryWidget extends EntryWidget { protected boolean cancelDeleteItems(EntryStack stack) { if (!interactable || !ConfigObject.getInstance().isGrabbingItems()) return super.cancelDeleteItems(stack); - if (ClientHelper.getInstance().isCheating()) { + if (ClientHelper.getInstance().isCheating() && !(Minecraft.getInstance().screen instanceof DisplayScreen)) { EntryStack entry = getCurrentEntry().copy(); if (!entry.isEmpty()) { if (entry.getValueType() == FluidStack.class) { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java index 5cf28663e..df9f034d4 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java @@ -43,6 +43,11 @@ import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigManager; import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.gui.config.EntryPanelOrdering; +import me.shedaniel.rei.api.client.gui.drag.DraggableStack; +import me.shedaniel.rei.api.client.gui.drag.DraggableStackVisitorWidget; +import me.shedaniel.rei.api.client.gui.drag.DraggedAcceptorResult; +import me.shedaniel.rei.api.client.gui.drag.DraggingContext; +import me.shedaniel.rei.api.client.gui.screen.DisplayScreen; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import me.shedaniel.rei.api.client.gui.widgets.Widget; import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds; @@ -81,7 +86,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; @ApiStatus.Internal -public class EntryListWidget extends WidgetWithBounds implements OverlayListWidget { +public class EntryListWidget extends WidgetWithBounds implements OverlayListWidget, DraggableStackVisitorWidget { static final Comparator> ENTRY_NAME_COMPARER = Comparator.comparing(stack -> stack.asFormatStrippedText().getString()); static final Comparator> ENTRY_GROUP_COMPARER = Comparator.comparingInt(stack -> { if (stack.getType() == VanillaEntryTypes.ITEM) { @@ -161,12 +166,14 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg private static Rectangle updateInnerBounds(Rectangle bounds) { bounds = bounds.clone(); - int widthReduction = (int) Math.round(bounds.width * (1 - ConfigObject.getInstance().getHorizontalEntriesBoundaries())); - int heightReduction = (int) Math.round(bounds.width * (1 - ConfigObject.getInstance().getVerticalEntriesBoundaries())); - bounds.x += widthReduction; - bounds.width -= widthReduction; + int heightReduction = (int) Math.round(bounds.height * (1 - ConfigObject.getInstance().getVerticalEntriesBoundariesPercentage())); bounds.y += heightReduction / 2; bounds.height -= heightReduction; + int maxHeight = (int) Math.ceil(entrySize() * ConfigObject.getInstance().getVerticalEntriesBoundariesRows()); + if (bounds.height > maxHeight) { + bounds.y += (bounds.height - maxHeight) / 2; + bounds.height = maxHeight; + } int entrySize = entrySize(); if (ConfigObject.getInstance().isEntryListWidgetScrolled()) { int width = Math.max(Mth.floor((bounds.width - 2 - 6) / (float) entrySize), 1); @@ -181,6 +188,18 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg } } + @Override + public DraggedAcceptorResult acceptDraggedStackWithResult(DraggingContext context, DraggableStack stack) { + if (innerBounds.contains(context.getCurrentPosition())) { + Point currentPosition = context.getCurrentPosition(); + Rectangle targetBounds = new Rectangle(currentPosition.x, currentPosition.y, 1, 1); + context.renderBackToPosition(stack, new Rectangle(currentPosition.x - 8, currentPosition.y - 8, 16, 16), () -> targetBounds); + return DraggedAcceptorResult.CONSUMED; + } else { + return DraggedAcceptorResult.PASS; + } + } + @Override public boolean mouseScrolled(double mouseX, double mouseY, double amount) { if (bounds.contains(mouseX, mouseY)) { @@ -304,7 +323,7 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg matrices.popPose(); } - if (containsChecked(mouseX, mouseY) && ClientHelper.getInstance().isCheating() && !minecraft.player.containerMenu.getCarried().isEmpty() && ClientHelperImpl.getInstance().canDeleteItems()) { + if (containsChecked(mouseX, mouseY) && ClientHelper.getInstance().isCheating() && !(Minecraft.getInstance().screen instanceof DisplayScreen) && !minecraft.player.containerMenu.getCarried().isEmpty() && ClientHelperImpl.getInstance().canDeleteItems()) { EntryStack stack = EntryStacks.of(minecraft.player.containerMenu.getCarried().copy()); if (stack.getValueType() == FluidStack.class) { Item bucketItem = ((FluidStack) stack.getValue()).getFluid().getBucket(); @@ -356,8 +375,8 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg return false; } - public void updateArea(String searchTerm) { - this.bounds = REIRuntime.getInstance().calculateEntryListArea(); + public void updateArea(Rectangle bounds, String searchTerm) { + this.bounds = REIRuntime.getInstance().calculateEntryListArea(bounds); FavoritesListWidget favoritesListWidget = ScreenOverlayImpl.getFavoritesListWidget(); if (favoritesListWidget != null) { favoritesListWidget.updateFavoritesBounds(searchTerm); @@ -482,7 +501,7 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg public boolean mouseReleased(double mouseX, double mouseY, int button) { if (containsChecked(mouseX, mouseY)) { LocalPlayer player = minecraft.player; - if (ClientHelper.getInstance().isCheating() && player != null && player.containerMenu != null && !player.containerMenu.getCarried().isEmpty() && ClientHelperImpl.getInstance().canDeleteItems()) { + if (ClientHelper.getInstance().isCheating() && !(Minecraft.getInstance().screen instanceof DisplayScreen) && player != null && player.containerMenu != null && !player.containerMenu.getCarried().isEmpty() && ClientHelperImpl.getInstance().canDeleteItems()) { ClientHelper.getInstance().sendDeletePacket(); return true; } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryStacksRegionWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryStacksRegionWidget.java index bf7bbc97a..7fdc454f5 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryStacksRegionWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryStacksRegionWidget.java @@ -38,10 +38,7 @@ import me.shedaniel.math.impl.PointHelper; import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.entry.region.RegionEntry; -import me.shedaniel.rei.api.client.gui.drag.DraggableStack; -import me.shedaniel.rei.api.client.gui.drag.DraggableStackProviderWidget; -import me.shedaniel.rei.api.client.gui.drag.DraggableStackVisitorWidget; -import me.shedaniel.rei.api.client.gui.drag.DraggingContext; +import me.shedaniel.rei.api.client.gui.drag.*; import me.shedaniel.rei.api.client.gui.widgets.Widget; import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds; import me.shedaniel.rei.api.common.entry.EntrySerializer; @@ -223,15 +220,18 @@ public class EntryStacksRegionWidget> extends WidgetWit } @Override - public boolean acceptDraggedStack(DraggingContext context, DraggableStack stack) { + public DraggedAcceptorResult acceptDraggedStackWithResult(DraggingContext context, DraggableStack stack) { return checkDraggedStacks(context, stack) .filter(entry -> innerBounds.contains(context.getCurrentPosition())) .flatMap(entry -> { + if (stack instanceof RegionDraggableStack && ((RegionDraggableStack) stack).getEntry().region == this && ((RegionDraggableStack) stack).getShowcaseWidget() == null) { + return Optional.empty(); + } if (!drop(entry)) { return Optional.empty(); } return Optional.of(Unit.INSTANCE); - }).isPresent(); + }).isPresent() ? DraggedAcceptorResult.CONSUMED : DraggedAcceptorResult.PASS; } public Optional> checkDraggedStacks(DraggingContext context, DraggableStack stack) { @@ -283,16 +283,19 @@ public class EntryStacksRegionWidget> extends WidgetWit applyNewEntriesList(); updateEntriesPosition(entry -> prevEntries.containsKey(entry.hashIgnoreAmount())); - + for (RealRegionEntry removedEntry : removedEntries) { this.listener.onRemove(removedEntry); } - + for (RealRegionEntry addedEntry : addedEntries) { this.listener.onAdd(addedEntry); } this.listener.onSetNewEntries(entriesList); + this.listener.onSetNewEntries(entriesList.stream() + .map(RegionEntryListEntry::getEntry) + .map(RealRegionEntry::getEntry)); } public boolean isEmpty() { @@ -314,7 +317,7 @@ public class EntryStacksRegionWidget> extends WidgetWit int width = innerBounds.width / entrySize; int currentX = 0; int currentY = 0; - int releaseIndex = getReleaseIndex(); + int releaseIndex = getReleaseIndex(null); int slotIndex = 0; for (RealRegionEntry entry : this.entries.values()) { @@ -342,9 +345,9 @@ public class EntryStacksRegionWidget> extends WidgetWit } } - private int getReleaseIndex() { + private int getReleaseIndex(@Nullable Point position) { DraggingContext context = DraggingContext.getInstance(); - Point position = context.getCurrentPosition(); + if (position == null) position = context.getCurrentPosition(); if (context.isDraggingStack() && bounds.contains(position) && checkDraggedStacks(context.cast(), context.getCurrentStack()).isPresent()) { int entrySize = entrySize(); int width = innerBounds.width / entrySize; @@ -413,21 +416,27 @@ public class EntryStacksRegionWidget> extends WidgetWit } public boolean drop(RealRegionEntry entry) { - if (!listener.canAcceptDrop(entry)) { - return false; - } - DraggingContext context = DraggingContext.getInstance(); double x = context.getCurrentPosition().x; double y = context.getCurrentPosition().y + scrolling.scrollAmount; - entry.startedDraggingPosition = null; + return drop(entry, x, y); + } + + public boolean drop(RealRegionEntry entry, double x, double y) { + boolean contains = bounds.contains(x, y); + int newIndex = contains ? getReleaseIndex(new Point(x, y)) : Math.max(0, Iterables.indexOf(entries.values(), e -> e == entry)); + return drop(entry, x, y, newIndex < 0 ? entries.size() : newIndex); + } + + public boolean drop(RealRegionEntry entry, double x, double y, int newIndex) { + if (newIndex < 0) return drop(entry, x, y); + if (!listener.canAcceptDrop(entry)) { + return false; + } entry.x.setAs(x - 8); entry.y.setAs(y - 8); - boolean contains = bounds.contains(PointHelper.ofMouse()); - int newIndex = contains ? getReleaseIndex() : Math.max(0, Iterables.indexOf(entries.values(), e -> e == entry)); - if (entries.size() <= newIndex) { RealRegionEntry remove = this.entries.remove(entry.hashIgnoreAmount()); if (remove != null) { @@ -462,6 +471,10 @@ public class EntryStacksRegionWidget> extends WidgetWit return true; } + public int indexOf(RealRegionEntry entry) { + return entriesList.indexOf(entry.getWidget()); + } + public void remove(RealRegionEntry entry) { entries.remove(entry.hashIgnoreAmount()); setEntries(CollectionUtils.map(entries.values(), RealRegionEntry::getEntry)); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java index 69adad877..54b7678d4 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java @@ -36,6 +36,7 @@ import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.favorites.FavoriteEntry; import me.shedaniel.rei.api.client.gui.drag.DraggableStack; import me.shedaniel.rei.api.client.gui.drag.DraggableStackProviderWidget; +import me.shedaniel.rei.api.client.gui.drag.DraggedAcceptorResult; import me.shedaniel.rei.api.client.gui.drag.DraggingContext; import me.shedaniel.rei.api.client.gui.widgets.Slot; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; @@ -487,8 +488,8 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget { } @Override - public void release(boolean accepted) { - if (!accepted) { + public void release(DraggedAcceptorResult result) { + if (result == DraggedAcceptorResult.PASS) { context.renderBackToPosition(this, DraggingContext.getInstance().getCurrentPosition(), () -> new Point(getBounds().x, getBounds().y)); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java index 771708dfb..d5c16f184 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java @@ -163,6 +163,15 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt } } + @Override + public void onRemove(RealRegionEntry entry) { + if (ConfigObject.getInstance().isFavoritesEnabled()) { + List favorites = ConfigObject.getInstance().getFavoriteEntries(); + favorites.removeIf(favoriteEntry -> Objects.equals(entry.getEntry(), favoriteEntry)); + ConfigManager.getInstance().saveConfig(); + } + } + @Override @Nullable public FavoriteEntry convertDraggableStack(DraggingContext context, DraggableStack stack) { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java index ca8b15437..62b5960ad 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java @@ -112,7 +112,7 @@ public final class InternalWidgets { if (result.isSuccessful()) { button.setEnabled(true); error = null; - color = 0; + color = result.getColor(); redSlots = null; } else if (result.isApplicable()) { if (error == null) { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java index 728214a43..50e179be9 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java @@ -32,6 +32,7 @@ import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.gui.Renderer; import me.shedaniel.rei.api.client.gui.drag.DraggableStack; import me.shedaniel.rei.api.client.gui.drag.DraggableStackProviderWidget; +import me.shedaniel.rei.api.client.gui.drag.DraggedAcceptorResult; import me.shedaniel.rei.api.client.gui.drag.DraggingContext; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import me.shedaniel.rei.api.client.gui.widgets.Widget; @@ -150,8 +151,8 @@ public class TabWidget extends WidgetWithBounds implements DraggableStackProvide } @Override - public void release(boolean accepted) { - if (!accepted) { + public void release(DraggedAcceptorResult result) { + if (result == DraggedAcceptorResult.PASS) { context.renderBackToPosition(this, DraggingContext.getInstance().getCurrentPosition(), () -> new Point(getBounds().getCenterX() - 8, getBounds().getCenterY() - 8)); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RealRegionEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RealRegionEntry.java index d0925f273..4c4731c77 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RealRegionEntry.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RealRegionEntry.java @@ -23,7 +23,6 @@ package me.shedaniel.rei.impl.client.gui.widget.region; -import me.shedaniel.math.Point; import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.entry.region.RegionEntry; import me.shedaniel.rei.api.common.util.Animator; @@ -36,7 +35,6 @@ public class RealRegionEntry> { private T entry; private final RegionEntryListEntry widget; private boolean hidden; - public Point startedDraggingPosition; public Animator x = new Animator(); public Animator y = new Animator(); public Animator size = new Animator(); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RegionDraggableStack.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RegionDraggableStack.java index 33238c38e..dc3d216cd 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/