From a6900532610247cae49f1c782442d07d8f7b1d2d Mon Sep 17 00:00:00 2001 From: shedaniel Date: Fri, 26 Aug 2022 16:48:42 +0900 Subject: It compiles now --- .../rei/RoughlyEnoughItemsCoreClient.java | 9 +- .../shedaniel/rei/impl/client/REIRuntimeImpl.java | 5 +- .../rei/impl/client/gui/ScreenOverlayImpl.java | 486 +++---------------- .../impl/client/gui/changelog/ChangelogLoader.java | 85 ++-- .../rei/impl/client/gui/changelog/JParseDown.java | 30 +- .../gui/changelog/JParseDownToMinecraft.java | 18 +- .../client/gui/dragging/CurrentDraggingStack.java | 4 +- .../client/gui/overlay/AbstractScreenOverlay.java | 345 ++++++++++++++ .../client/gui/overlay/InternalOverlayBounds.java | 51 ++ .../gui/screen/AbstractDisplayViewingScreen.java | 49 +- .../gui/screen/CompositeDisplayViewingScreen.java | 8 +- .../gui/screen/DefaultDisplayViewingScreen.java | 44 +- .../gui/widget/AutoCraftingButtonWidget.java | 29 +- .../client/gui/widget/AutoCraftingEvaluator.java | 196 -------- .../gui/widget/CraftableFilterButtonWidget.java | 7 +- .../gui/widget/DefaultDisplayChoosePageWidget.java | 193 -------- .../client/gui/widget/DisplayedEntryWidget.java | 95 ++-- .../impl/client/gui/widget/DraggableWidget.java | 104 ----- .../rei/impl/client/gui/widget/EntryWidget.java | 515 --------------------- .../gui/widget/entrylist/EntryListStackEntry.java | 151 +++--- .../gui/widget/entrylist/EntryListWidget.java | 37 +- .../widget/entrylist/PaginatedEntryListWidget.java | 78 ++-- .../widget/entrylist/ScrolledEntryListWidget.java | 40 +- .../gui/widget/favorites/history/DisplayEntry.java | 28 +- .../panel/rows/FavoritesPanelEntriesRow.java | 66 +-- .../gui/widget/region/EntryStacksRegionWidget.java | 29 +- .../client/gui/widget/region/RealRegionEntry.java | 13 +- .../gui/widget/region/RegionEntryWidget.java | 39 +- .../gui/widget/search/DelegateTextField.java | 10 + .../gui/widget/search/OverlaySearchField.java | 23 +- .../me/shedaniel/rei/impl/common/util/Weather.java | 61 --- .../client/runtime/DefaultClientRuntimePlugin.java | 2 +- 32 files changed, 926 insertions(+), 1924 deletions(-) create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/AbstractScreenOverlay.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/InternalOverlayBounds.java delete mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/AutoCraftingEvaluator.java delete mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/DefaultDisplayChoosePageWidget.java delete mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/DraggableWidget.java delete mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java delete mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/common/util/Weather.java (limited to 'runtime/src/main/java/me') diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java index 2c8abbdb7..435bdc722 100644 --- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java +++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java @@ -51,6 +51,7 @@ import me.shedaniel.rei.api.common.util.EntryStacks; import me.shedaniel.rei.api.common.util.ImmutableTextComponent; import me.shedaniel.rei.impl.client.ClientInternals; import me.shedaniel.rei.impl.client.REIRuntimeImpl; +import me.shedaniel.rei.impl.client.gui.InternalCursorState; import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; import me.shedaniel.rei.impl.client.gui.widget.CatchingExceptionUtils; import me.shedaniel.rei.impl.client.gui.widget.TooltipImpl; @@ -94,8 +95,6 @@ import java.util.stream.Stream; @Environment(EnvType.CLIENT) public class RoughlyEnoughItemsCoreClient { - public static boolean isLeftMousePressed = false; - public static void attachClientInternals() { CatchingExceptionUtils.attach(); ClientInternals.attachInstance((Function>) (object) -> { @@ -260,7 +259,8 @@ public class RoughlyEnoughItemsCoreClient { } }); ClientScreenInputEvent.MOUSE_CLICKED_PRE.register((minecraftClient, screen, mouseX, mouseY, button) -> { - isLeftMousePressed = true; + if (button == 0) InternalCursorState.isLeftMousePressed = true; + if (button == 1) InternalCursorState.isRightMousePressed = true; if (shouldReturn(screen) || screen instanceof DisplayScreen) return EventResult.pass(); resetFocused(screen); @@ -274,7 +274,8 @@ public class RoughlyEnoughItemsCoreClient { return EventResult.pass(); }); ClientScreenInputEvent.MOUSE_RELEASED_PRE.register((minecraftClient, screen, mouseX, mouseY, button) -> { - isLeftMousePressed = false; + if (button == 0) InternalCursorState.isLeftMousePressed = false; + if (button == 1) InternalCursorState.isRightMousePressed = false; if (shouldReturn(screen) || screen instanceof DisplayScreen) return EventResult.pass(); resetFocused(screen); 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 5cff0c22d..88f2d8bdd 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 @@ -48,6 +48,7 @@ import me.shedaniel.rei.impl.client.gui.TooltipQueue; import me.shedaniel.rei.impl.client.gui.hints.HintProvider; import me.shedaniel.rei.impl.client.gui.widget.CachedEntryListRender; import me.shedaniel.rei.impl.client.gui.widget.search.OverlaySearchField; +import me.shedaniel.rei.impl.client.provider.OverlayTicker; import me.shedaniel.rei.impl.common.Internals; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -274,7 +275,9 @@ public class REIRuntimeImpl implements REIRuntime { ClientTickEvent.CLIENT_POST.register(minecraft -> { if (isOverlayVisible() && REIRuntime.getInstance().getOverlay().isPresent()) { REIRuntime.getInstance().getSearchTextField().tick(); - ScreenOverlayImpl.getInstance().tick(); + for (OverlayTicker ticker : ClientInternals.getOverlayTickers()) { + ticker.tick(); + } } }); } 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 3f8fb9be9..1943ad379 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 @@ -23,37 +23,17 @@ package me.shedaniel.rei.impl.client.gui; -import com.google.common.collect.Lists; import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.PoseStack; -import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; -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.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.DraggingContext; -import me.shedaniel.rei.api.client.gui.drag.component.DraggableComponentProvider; -import me.shedaniel.rei.api.client.gui.drag.component.DraggableComponentVisitor; import me.shedaniel.rei.api.client.gui.widgets.TextField; -import me.shedaniel.rei.api.client.gui.widgets.Tooltip; -import me.shedaniel.rei.api.client.gui.widgets.Widget; import me.shedaniel.rei.api.client.overlay.OverlayListWidget; -import me.shedaniel.rei.api.client.overlay.ScreenOverlay; -import me.shedaniel.rei.api.client.registry.screen.ClickArea; -import me.shedaniel.rei.api.client.registry.screen.OverlayDecider; import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry; -import me.shedaniel.rei.api.client.view.ViewSearchBuilder; -import me.shedaniel.rei.api.common.entry.EntryStack; -import me.shedaniel.rei.api.common.plugins.PluginManager; -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.menu.MenuAccess; -import me.shedaniel.rei.impl.client.gui.menu.MenuAccessImpl; -import me.shedaniel.rei.impl.client.gui.widget.*; +import me.shedaniel.rei.impl.client.gui.overlay.AbstractScreenOverlay; +import me.shedaniel.rei.impl.client.gui.widget.ConfigButtonWidget; +import me.shedaniel.rei.impl.client.gui.widget.CraftableFilterButtonWidget; import me.shedaniel.rei.impl.client.gui.widget.entrylist.EntryListWidget; import me.shedaniel.rei.impl.client.gui.widget.entrylist.PaginatedEntryListWidget; import me.shedaniel.rei.impl.client.gui.widget.entrylist.ScrolledEntryListWidget; @@ -61,137 +41,54 @@ import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesListWidget; import me.shedaniel.rei.impl.client.gui.widget.search.OverlaySearchField; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.events.GuiEventListener; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.network.chat.Component; -import net.minecraft.world.InteractionResult; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; -import java.util.List; import java.util.Objects; import java.util.Optional; -import static me.shedaniel.rei.impl.client.gui.widget.entrylist.EntryListWidget.entrySize; - @ApiStatus.Internal -public abstract class ScreenOverlayImpl extends ScreenOverlay { - private static EntryListWidget entryListWidget = null; - private static FavoritesListWidget favoritesListWidget = null; - private static OverlaySearchField searchField = null; - private final List widgets = Lists.newLinkedList(); - public boolean shouldReload = false; - public boolean shouldReloadSearch = false; - private Rectangle bounds; - private Widget configButton; - private CurrentDraggingStack draggingStack = new CurrentDraggingStack(); - @Nullable - public DefaultDisplayChoosePageWidget choosePageWidget; - private MenuAccessImpl menuAccess = new MenuAccessImpl(); +public abstract class ScreenOverlayImpl extends AbstractScreenOverlay { + private EntryListWidget entryListWidget = null; + private FavoritesListWidget favoritesListWidget = null; + private OverlaySearchField searchField = null; public static EntryListWidget getEntryListWidget() { - boolean widgetScrolled = ConfigObject.getInstance().isEntryListWidgetScrolled(); - - if (entryListWidget != null) { - if (widgetScrolled && entryListWidget instanceof ScrolledEntryListWidget) { - return entryListWidget; - } else if (!widgetScrolled && entryListWidget instanceof PaginatedEntryListWidget) { - return entryListWidget; - } - } - - entryListWidget = widgetScrolled ? new ScrolledEntryListWidget() : new PaginatedEntryListWidget(); - - ScreenOverlayImpl overlay = ScreenOverlayImpl.getInstance(); - Rectangle overlayBounds = overlay.bounds; - entryListWidget.updateArea(Objects.requireNonNullElse(overlayBounds, new Rectangle()), overlay.getSearchField().getText()); - entryListWidget.updateEntriesPosition(); - - return entryListWidget; + return getInstance().getEntryList(); } @Nullable public static FavoritesListWidget getFavoritesListWidget() { - return favoritesListWidget; + return getInstance().getFavoritesListNullable(); } public static ScreenOverlayImpl getInstance() { return (ScreenOverlayImpl) REIRuntime.getInstance().getOverlay().get(); } - public void tick() { - if (searchField != null) { - if (Minecraft.getInstance().player != null && !PluginManager.areAnyReloading() && Minecraft.getInstance().player.tickCount % 5 == 0) { - CraftableFilter.INSTANCE.tick(); - } - } - } - @Override - public void queueReloadOverlay() { - shouldReload = true; - } - - @Override - public void queueReloadSearch() { - shouldReloadSearch = true; - } - - @Override - public boolean isOverlayReloadQueued() { - return shouldReload; - } - - @Override - public boolean isSearchReloadQueued() { - return shouldReloadSearch || shouldReload; - } - - @Override - public DraggingContext getDraggingContext() { - return draggingStack; - } - - protected boolean hasSpace() { - return !this.bounds.isEmpty(); - } - public void init() { - this.draggingStack.set(DraggableComponentProvider.from(ScreenRegistry.getInstance()::getDraggableComponentProviders), - DraggableComponentVisitor.from(ScreenRegistry.getInstance()::getDraggableComponentVisitors)); + super.init(); - this.shouldReload = false; - this.shouldReloadSearch = false; - this.children().clear(); - this.bounds = calculateOverlayBounds(); - - if (choosePageWidget != null) { - this.widgets.add(choosePageWidget); - } + TextField searchField = getSearchField(); + searchField.asWidget().getBounds().setBounds(getSearchFieldArea()); + this.children().add(searchField.asWidget()); if (ConfigObject.getInstance().isFavoritesEnabled()) { - if (favoritesListWidget == null) { - favoritesListWidget = new FavoritesListWidget(); - } - favoritesListWidget.favoritePanel.resetRows(); - this.widgets.add(favoritesListWidget); + getFavoritesListWidget().favoritePanel.resetRows(); + this.children().add(getFavoritesListWidget()); } - TextField searchField = getSearchField(); - searchField.asWidget().getBounds().setBounds(getSearchFieldArea()); - this.widgets.add(searchField.asWidget()); - EntryListWidget entryListWidget = getEntryListWidget(); - entryListWidget.updateArea(this.bounds, searchField.getText()); - this.widgets.add(entryListWidget); + entryListWidget.updateArea(this.getBounds(), searchField.getText()); + this.children().add(entryListWidget); searchField.setResponder(s -> entryListWidget.updateSearch(s, false)); entryListWidget.init(this); - this.widgets.add(configButton = ConfigButtonWidget.create(this)); + this.children().add(ConfigButtonWidget.create(this)); if (ConfigObject.getInstance().isCraftableFilterEnabled()) { - this.widgets.add(CraftableFilterButtonWidget.create(this)); + this.children().add(CraftableFilterButtonWidget.create(this)); } - - this.widgets.add(draggingStack); } private Rectangle getSearchFieldArea() { @@ -207,12 +104,12 @@ public abstract class ScreenOverlayImpl extends ScreenOverlay { } private Rectangle getTopSideSearchFieldArea(int widthRemoved) { - return new Rectangle(bounds.x + 2, 4, bounds.width - 6 - widthRemoved, 18); + return new Rectangle(getBounds().x + 2, 4, getBounds().width - 6 - widthRemoved, 18); } private Rectangle getBottomSideSearchFieldArea(int widthRemoved) { Window window = Minecraft.getInstance().getWindow(); - return new Rectangle(bounds.x + 2, window.getGuiScaledHeight() - 22, bounds.width - 6 - widthRemoved, 18); + return new Rectangle(getBounds().x + 2, window.getGuiScaledHeight() - 22, getBounds().width - 6 - widthRemoved, 18); } private Rectangle getCenterSearchFieldArea(int widthRemoved) { @@ -222,179 +119,15 @@ public abstract class ScreenOverlayImpl extends ScreenOverlay { } @Override - public Rectangle getBounds() { - return bounds; - } - - @Override - public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { - if (shouldReload || !calculateOverlayBounds().equals(bounds)) { - init(); - getEntryListWidget().updateSearch(REIRuntime.getInstance().getSearchTextField().getText(), true); - } else { - for (OverlayDecider decider : ScreenRegistry.getInstance().getDeciders(minecraft.screen)) { - if (decider != null && decider.shouldRecalculateArea(ConfigObject.getInstance().getDisplayPanelLocation(), bounds)) { - init(); - break; - } - } - } - if (shouldReloadSearch) { - shouldReloadSearch = false; - getEntryListWidget().updateSearch(getSearchField().getText(), true); - } - if (OverlaySearchField.isHighlighting) { - EntryHighlighter.render(matrices); - } - if (!hasSpace()) return; - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - this.renderWidgets(matrices, mouseX, mouseY, delta); - if (ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) { - Screen screen = Minecraft.getInstance().screen; - ClickArea.ClickAreaContext context = createClickAreaContext(mouseX, mouseY, screen); - List clickAreaTooltips = ScreenRegistry.getInstance().getClickAreaTooltips((Class) screen.getClass(), context); - if (clickAreaTooltips != null && !clickAreaTooltips.isEmpty()) { - Tooltip.create(clickAreaTooltips).queue(); - } - } - } - - private ClickArea.ClickAreaContext createClickAreaContext(double mouseX, double mouseY, Screen screen) { - return new ClickArea.ClickAreaContext<>() { - @Override - public Screen getScreen() { - return screen; - } - - @Override - public Point getMousePosition() { - return new Point(mouseX, mouseY); - } - }; - } - - 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() && hasSpace()) { - getSearchField().laterRender(matrices, mouseX, mouseY, delta); - for (Widget widget : widgets) { - if (widget instanceof LateRenderable && widget != menuAccess.widget()) - widget.render(matrices, mouseX, mouseY, delta); - } - matrices.pushPose(); - matrices.translate(0, 0, 500); - menuAccess.lateRender(matrices, mouseX, mouseY, delta); - matrices.popPose(); - if (choosePageWidget != null) { - setBlitOffset(500); - Window window = Minecraft.getInstance().getWindow(); - this.fillGradient(matrices, 0, 0, window.getGuiScaledWidth(), window.getGuiScaledHeight(), -1072689136, -804253680); - setBlitOffset(0); - choosePageWidget.render(matrices, mouseX, mouseY, delta); - } - } - if (choosePageWidget == null) { - Tooltip tooltip = TooltipQueue.get(); - - if (tooltip != null) { - renderTooltip(matrices, tooltip); - } - } - - REIRuntime.getInstance().clearTooltips(); - if (REIRuntime.getInstance().isOverlayVisible()) { - menuAccess.afterRender(); - } - } - - @Override - public void renderTooltip(PoseStack matrices, Tooltip tooltip) { - renderTooltipInner(minecraft.screen, matrices, tooltip, tooltip.getX(), tooltip.getY()); - } - - protected abstract void renderTooltipInner(Screen screen, PoseStack matrices, Tooltip tooltip, int mouseX, int mouseY); - - public void renderWidgets(PoseStack matrices, int mouseX, int mouseY, float delta) { - if (!REIRuntime.getInstance().isOverlayVisible()) - return; - for (Widget widget : widgets) { - if (!(widget instanceof LateRenderable)) - widget.render(matrices, mouseX, mouseY, delta); - } - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double amount) { - if (!REIRuntime.getInstance().isOverlayVisible()) - return false; - if (menuAccess.mouseScrolled(mouseX, mouseY, amount)) - return true; - if (isInside(mouseX, mouseY) && getEntryListWidget().mouseScrolled(mouseX, mouseY, amount)) { - return true; - } - if (isNotInExclusionZones(PointHelper.getMouseX(), PointHelper.getMouseY())) { - if (favoritesListWidget != null && favoritesListWidget.mouseScrolled(mouseX, mouseY, amount)) - return true; - } - for (Widget widget : widgets) - if (widget != getEntryListWidget() && (favoritesListWidget == null || widget != favoritesListWidget) - && widget != menuAccess.widget() - && widget.mouseScrolled(mouseX, mouseY, amount)) - return true; - return false; + protected void updateSearch() { + getEntryListWidget().updateSearch(getSearchField().getText(), true); } @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (super.keyPressed(keyCode, scanCode, modifiers)) return true; if (!hasSpace()) return false; - if (REIRuntime.getInstance().isOverlayVisible()) { - if (keyCode == 256 && choosePageWidget != null) { - choosePageWidget = null; - return true; - } - if (choosePageWidget != null) - return choosePageWidget.keyPressed(keyCode, scanCode, modifiers); - if (getSearchField().keyPressed(keyCode, scanCode, modifiers)) - return true; - for (GuiEventListener listener : widgets) - if (listener != getSearchField() && listener.keyPressed(keyCode, scanCode, modifiers)) - return true; - } - if (ConfigObject.getInstance().getHideKeybind().matchesKey(keyCode, scanCode)) { - REIRuntime.getInstance().toggleOverlayVisible(); - return true; - } - EntryStack stack = ScreenRegistry.getInstance().getFocusedStack(Minecraft.getInstance().screen, PointHelper.ofMouse()); - if (stack != null && !stack.isEmpty()) { - stack = stack.copy(); - if (ConfigObject.getInstance().getRecipeKeybind().matchesKey(keyCode, scanCode)) { - return ViewSearchBuilder.builder().addRecipesFor(stack).open(); - } else if (ConfigObject.getInstance().getUsageKeybind().matchesKey(keyCode, scanCode)) { - return ViewSearchBuilder.builder().addUsagesFor(stack).open(); - } else if (ConfigObject.getInstance().getFavoriteKeyCode().matchesKey(keyCode, scanCode)) { - FavoriteEntry favoriteEntry = FavoriteEntry.fromEntryStack(stack); - ConfigObject.getInstance().getFavoriteEntries().add(favoriteEntry); - return true; - } - } - if (!REIRuntime.getInstance().isOverlayVisible()) - return false; + if (!REIRuntime.getInstance().isOverlayVisible()) return false; if (ConfigObject.getInstance().getFocusSearchFieldKeybind().matchesKey(keyCode, scanCode)) { getSearchField().setFocused(true); setFocused(getSearchField()); @@ -405,108 +138,11 @@ public abstract class ScreenOverlayImpl extends ScreenOverlay { return false; } - @Override - public boolean keyReleased(int keyCode, int scanCode, int modifiers) { - if (!hasSpace()) return false; - if (REIRuntime.getInstance().isOverlayVisible()) { - if (choosePageWidget == null) { - if (getSearchField().keyReleased(keyCode, scanCode, modifiers)) - return true; - for (GuiEventListener listener : widgets) - if (listener != getSearchField() && listener == getFocused() && listener.keyPressed(keyCode, scanCode, modifiers)) - return true; - } - } - return false; - } - - @Override - public boolean charTyped(char character, int modifiers) { - if (!REIRuntime.getInstance().isOverlayVisible()) - return false; - if (!hasSpace()) return false; - if (choosePageWidget != null) { - return choosePageWidget.charTyped(character, modifiers); - } - if (getSearchField().charTyped(character, modifiers)) - return true; - for (GuiEventListener listener : widgets) - if (listener != getSearchField() && listener.charTyped(character, modifiers)) - return true; - return false; - } - - @Override - public List children() { - return widgets; - } - @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (super.mouseClicked(mouseX, mouseY, button)) return true; 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 (!hasSpace()) return false; - if (visible && configButton.mouseClicked(mouseX, mouseY, button)) { - this.setFocused(configButton); - if (button == 0) - this.setDragging(true); - return true; - } - if (ConfigObject.getInstance().getHideKeybind().matchesMouse(button)) { - REIRuntime.getInstance().toggleOverlayVisible(); - return REIRuntime.getInstance().isOverlayVisible(); - } - EntryStack stack = ScreenRegistry.getInstance().getFocusedStack(Minecraft.getInstance().screen, PointHelper.ofMouse()); - if (stack != null && !stack.isEmpty()) { - stack = stack.copy(); - if (ConfigObject.getInstance().getRecipeKeybind().matchesMouse(button)) { - return ViewSearchBuilder.builder().addRecipesFor(stack).open(); - } else if (ConfigObject.getInstance().getUsageKeybind().matchesMouse(button)) { - return ViewSearchBuilder.builder().addUsagesFor(stack).open(); - } else if (visible && ConfigObject.getInstance().getFavoriteKeyCode().matchesMouse(button)) { - FavoriteEntry favoriteEntry = FavoriteEntry.fromEntryStack(stack); - ConfigObject.getInstance().getFavoriteEntries().add(favoriteEntry); - return true; - } - } - if (visible) { - Widget menuWidget = menuAccess.widget(); - if (menuWidget != null && menuWidget.mouseClicked(mouseX, mouseY, button)) { - this.setFocused(menuWidget); - if (button == 0) - this.setDragging(true); - getSearchField().setFocused(false); - return true; - } - } - if (ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) { - Screen screen = Minecraft.getInstance().screen; - ClickArea.ClickAreaContext context = createClickAreaContext(mouseX, mouseY, screen); - if (ScreenRegistry.getInstance().executeClickArea((Class) screen.getClass(), context)) { - return true; - } - } - if (!visible) { - return false; - } - for (GuiEventListener element : widgets) { - if (element != configButton && element != menuAccess.widget() && element.mouseClicked(mouseX, mouseY, button)) { - this.setFocused(element); - if (button == 0) - this.setDragging(true); - if (!(element instanceof OverlaySearchField)) - getSearchField().setFocused(false); - return true; - } - } + if (!hasSpace() || !visible) return false; if (ConfigObject.getInstance().getFocusSearchFieldKeybind().matchesMouse(button)) { getSearchField().setFocused(true); setFocused(getSearchField().asWidget()); @@ -518,53 +154,47 @@ public abstract class ScreenOverlayImpl extends ScreenOverlay { } @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { - if (!REIRuntime.getInstance().isOverlayVisible()) - return false; - if (!hasSpace()) return false; - if (choosePageWidget != null) { - return choosePageWidget.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); - } - return (this.getFocused() != null && this.isDragging() && button == 0) && this.getFocused().mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + public void setFocused(@Nullable GuiEventListener focused) { + super.setFocused(focused); + getSearchField().setFocused(focused == getSearchField().asWidget()); } @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); - } - - @Override - public boolean isNotInExclusionZones(double mouseX, double mouseY) { - for (OverlayDecider decider : ScreenRegistry.getInstance().getDeciders(Minecraft.getInstance().screen)) { - InteractionResult in = decider.isInZone(mouseX, mouseY); - if (in != InteractionResult.PASS) - return in == InteractionResult.SUCCESS; + public EntryListWidget getEntryList() { + boolean widgetScrolled = ConfigObject.getInstance().isEntryListWidgetScrolled(); + + if (entryListWidget != null) { + if (widgetScrolled && entryListWidget instanceof ScrolledEntryListWidget) { + return entryListWidget; + } else if (!widgetScrolled && entryListWidget instanceof PaginatedEntryListWidget) { + return entryListWidget; + } } - return true; - } - - public boolean isInside(Point point) { - return isInside(point.getX(), point.getY()); - } - - @Override - public OverlayListWidget getEntryList() { - return getEntryListWidget(); + + entryListWidget = widgetScrolled ? new ScrolledEntryListWidget() : new PaginatedEntryListWidget(); + + Rectangle overlayBounds = getBounds(); + entryListWidget.updateArea(Objects.requireNonNullElse(overlayBounds, new Rectangle()), getSearchField().getText()); + entryListWidget.updateEntriesPosition(); + + return entryListWidget; } @Override public Optional getFavoritesList() { - return Optional.ofNullable(getFavoritesListWidget()); + return Optional.ofNullable(getFavoritesListNullable()); } - public MenuAccess menuAccess() { - return menuAccess; + private FavoritesListWidget getFavoritesListNullable() { + if (ConfigObject.getInstance().isFavoritesEnabled()) { + if (favoritesListWidget == null) { + favoritesListWidget = new FavoritesListWidget(); + } + + return favoritesListWidget; + } else { + return favoritesListWidget = null; + } } @Override diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/changelog/ChangelogLoader.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/changelog/ChangelogLoader.java index ae5a41def..b2bd91d0e 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/changelog/ChangelogLoader.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/changelog/ChangelogLoader.java @@ -62,13 +62,14 @@ public class ChangelogLoader { try (InputStreamReader reader = new FileReader(file)) { String version = IOUtils.toString(reader).trim(); - InputStream changesJsonStream = ChangelogLoader.class.getClassLoader().getResourceAsStream("roughlyenoughitems.changes.json"); - if (changesJsonStream != null) { - JsonObject object = JsonParser.parseReader(new InputStreamReader(changesJsonStream)) - .getAsJsonObject(); - String currentVersion = object.getAsJsonPrimitive("version").getAsString(); - if (currentVersion.equals(version)) { - visited = true; + try (InputStream changesJsonStream = ChangelogLoader.class.getClassLoader().getResourceAsStream("roughlyenoughitems.changes.json")) { + if (changesJsonStream != null) { + JsonObject object = JsonParser.parseReader(new InputStreamReader(changesJsonStream)) + .getAsJsonObject(); + String currentVersion = object.getAsJsonPrimitive("version").getAsString(); + if (currentVersion.equals(version)) { + visited = true; + } } } } catch (IOException e) { @@ -92,47 +93,49 @@ public class ChangelogLoader { visited = true; BuilderImpl builder = new BuilderImpl(); - InputStream changesJsonStream = ChangelogLoader.class.getClassLoader().getResourceAsStream("roughlyenoughitems.changes.json"); - if (changesJsonStream == null) { - builder.add(new TranslatableComponent("rei.changelog.error.missingChangelogFile")); - } else { - JsonObject object = JsonParser.parseReader(new InputStreamReader(changesJsonStream)) - .getAsJsonObject(); - String version = object.getAsJsonPrimitive("version").getAsString(); - Path file = Platform.getConfigFolder().resolve("roughlyenoughitems/changelog.txt"); - try { - Files.write(file, version.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); - } catch (IOException e) { - e.printStackTrace(); - } - - InputStream changelogStream = ChangelogLoader.class.getClassLoader().getResourceAsStream("roughlyenoughitems/" + version + "/changelog.md"); - - if (changelogStream == null) { + try (InputStream changesJsonStream = ChangelogLoader.class.getClassLoader().getResourceAsStream("roughlyenoughitems.changes.json")) { + if (changesJsonStream == null) { builder.add(new TranslatableComponent("rei.changelog.error.missingChangelogFile")); } else { + JsonObject object = JsonParser.parseReader(new InputStreamReader(changesJsonStream)) + .getAsJsonObject(); + String version = object.getAsJsonPrimitive("version").getAsString(); + Path file = Platform.getConfigFolder().resolve("roughlyenoughitems/changelog.txt"); try { - JParseDown parseDown = new JParseDown(); - LinkedList blocks = parseDown.linesElements(IOUtils.readLines(changelogStream, StandardCharsets.UTF_8).toArray(new String[0])); - for (JParseDown.Block block : blocks) { - if (block.autoBreak) { - builder.add(width -> new ErrorsEntryListWidget.EmptyEntry(6)); - } - Builder blockBuilder = builder; - if (block instanceof JParseDown.BlockHeader) { - blockBuilder = function -> { - builder.add(width -> new ErrorsEntryListWidget.ScaledEntry(function.apply(Math.round(width / 1.5F)), 1.5F)); - }; - } - JParseDownToMinecraft.build(blockBuilder, block); - if (block.autoBreak) { - builder.add(width -> new ErrorsEntryListWidget.EmptyEntry(6)); + Files.writeString(file, version, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + } catch (IOException e) { + e.printStackTrace(); + } + + try (InputStream changelogStream = ChangelogLoader.class.getClassLoader().getResourceAsStream("roughlyenoughitems/" + version + "/changelog.md")) { + if (changelogStream == null) { + builder.add(new TranslatableComponent("rei.changelog.error.missingChangelogFile")); + } else { + try { + JParseDown parseDown = new JParseDown(); + LinkedList blocks = parseDown.linesElements(IOUtils.readLines(changelogStream, StandardCharsets.UTF_8).toArray(new String[0])); + for (JParseDown.Block block : blocks) { + if (block.autoBreak) { + builder.add(width -> new ErrorsEntryListWidget.EmptyEntry(6)); + } + Builder blockBuilder = builder; + if (block instanceof JParseDown.BlockHeader) { + blockBuilder = function -> { + builder.add(width -> new ErrorsEntryListWidget.ScaledEntry(function.apply(Math.round(width / 1.5F)), 1.5F)); + }; + } + JParseDownToMinecraft.build(blockBuilder, block); + if (block.autoBreak) { + builder.add(width -> new ErrorsEntryListWidget.EmptyEntry(6)); + } + } + } catch (IOException e) { + builder.add(new TranslatableComponent("rei.changelog.error.failedToReadChangelogFile")); } } - } catch (IOException e) { - builder.add(new TranslatableComponent("rei.changelog.error.failedToReadChangelogFile")); } } + } catch (IOException e) { } Minecraft.getInstance().setScreen(new ErrorsScreen(new TranslatableComponent("text.rei.changelog.title"), builder.components, Minecraft.getInstance().screen, true)); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/changelog/JParseDown.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/changelog/JParseDown.java index 6165f6a7a..01c306726 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/changelog/JParseDown.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/changelog/JParseDown.java @@ -64,10 +64,13 @@ public class JParseDown { } } - public abstract static class Component { + public static class Component { public String markup = null; public boolean hidden = false; public HashSet> nonNestables = new HashSet<>(); + + protected Component() { + } } public interface BlockType { @@ -366,11 +369,11 @@ public class JParseDown { public String markerTypeRegex; public LinkedList lines = new LinkedList<>(); - + public BlockList() { autoBreak = true; } - + public static Block startBlock(JParseDown parseDown, Line line, Block block) { boolean ordered; String pattern; @@ -404,9 +407,9 @@ public class JParseDown { b.pattern = pattern; b.ordered = ordered; b.marker = marker; - b.markerType = !ordered ? - markerWithoutWhitespace : - markerWithoutWhitespace.substring(markerWithoutWhitespace.length() - 1, markerWithoutWhitespace.length()); + b.markerType = ordered ? + markerWithoutWhitespace.substring(markerWithoutWhitespace.length() - 1) : + markerWithoutWhitespace; b.markerTypeRegex = Pattern.quote(b.markerType); b.lines.add(body); @@ -476,9 +479,8 @@ public class JParseDown { @Override public Block completeBlock() { - if (loose) { - if (!lines.getLast().isEmpty()) - lines.add(""); + if (loose && !lines.getLast().isEmpty()) { + lines.add(""); } return this; } @@ -573,7 +575,7 @@ public class JParseDown { public BlockHorizontalRule() { autoBreak = true; } - + @Override public Collection inline(JParseDown parseDown) { return Collections.singletonList(new InlineHorizontalRule()); @@ -613,7 +615,7 @@ public class JParseDown { public static Block startBlock(JParseDown parseDown, Line line, Block block) { Matcher m; if (line.text.indexOf(']') >= 0 && (m = Pattern.compile("^\\[(.+?)\\]:[ ]*+?(?:[ ]+[\"\\'(](.+)[\"\\')])?[ ]*+$").matcher(line.text)).find()) { - String id = m.group(1).toLowerCase(); + String id = m.group(1).toLowerCase(Locale.ROOT); ReferenceData data = new ReferenceData(parseDown.convertUrl(m.group(2)), m.group(3)); parseDown.referenceDefinitions.put(id, data); return new BlockReference(id, data); @@ -634,11 +636,11 @@ public class JParseDown { } } - public abstract static class Inline extends Component { + public static class Inline extends Component { public int extent; public int position = -1; - public Inline() { + protected Inline() { } public Inline setExtent(String s) { @@ -834,7 +836,7 @@ public class JParseDown { InlineLink link = (InlineLink) InlineLink.inline(parseDown, text, context); if (link == null) return null; - + return new InlineImage(link.url, link.text).setExtent(link.extent + 1); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/changelog/JParseDownToMinecraft.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/changelog/JParseDownToMinecraft.java index 9145a6298..0b0afaa00 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/changelog/JParseDownToMinecraft.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/changelog/JParseDownToMinecraft.java @@ -73,15 +73,17 @@ public class JParseDownToMinecraft { } else if (inline instanceof JParseDown.InlineHorizontalRule) { builder.add(ErrorsEntryListWidget.HorizontalRuleEntry::new); } else if (inline instanceof JParseDown.InlineImage) { - InputStream stream = builder.getClass().getClassLoader().getResourceAsStream(((JParseDown.InlineImage) inline).src); - if (stream != null) { - try { - DynamicTexture texture = new DynamicTexture(NativeImage.read(stream)); - ResourceLocation id = Minecraft.getInstance().getTextureManager().register("rei_md_image_", texture); - builder.add(width -> new ErrorsEntryListWidget.ImageEntry(width, texture, id)); - } catch (IOException e) { - e.printStackTrace(); + try (InputStream stream = builder.getClass().getClassLoader().getResourceAsStream(((JParseDown.InlineImage) inline).src)) { + if (stream != null) { + try { + DynamicTexture texture = new DynamicTexture(NativeImage.read(stream)); + ResourceLocation id = Minecraft.getInstance().getTextureManager().register("rei_md_image_", texture); + builder.add(width -> new ErrorsEntryListWidget.ImageEntry(width, texture, id)); + } catch (IOException e) { + e.printStackTrace(); + } } + } catch (IOException e) { } } } 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 add5f947b..50d6ab020 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 @@ -29,7 +29,6 @@ import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.FloatingRectangle; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; -import me.shedaniel.rei.RoughlyEnoughItemsCoreClient; import me.shedaniel.rei.api.client.gui.drag.DraggableBoundsProvider; import me.shedaniel.rei.api.client.gui.drag.DraggableStack; import me.shedaniel.rei.api.client.gui.drag.DraggedAcceptorResult; @@ -38,6 +37,7 @@ import me.shedaniel.rei.api.client.gui.drag.component.DraggableComponent; import me.shedaniel.rei.api.client.gui.drag.component.DraggableComponentProvider; import me.shedaniel.rei.api.client.gui.drag.component.DraggableComponentVisitor; import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.impl.client.gui.InternalCursorState; import me.shedaniel.rei.impl.client.gui.widget.LateRenderable; import net.minecraft.Util; import net.minecraft.client.Minecraft; @@ -101,7 +101,7 @@ public class CurrentDraggingStack extends Widget implements LateRenderable, Drag hash = shapeBounds.hash; } - if (!RoughlyEnoughItemsCoreClient.isLeftMousePressed) { + if (!InternalCursorState.isLeftMousePressed) { drop(); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/AbstractScreenOverlay.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/AbstractScreenOverlay.java new file mode 100644 index 000000000..e78f36704 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/AbstractScreenOverlay.java @@ -0,0 +1,345 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.client.gui.overlay; + +import com.google.common.collect.Lists; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +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.favorites.FavoriteEntry; +import me.shedaniel.rei.api.client.gui.drag.DraggingContext; +import me.shedaniel.rei.api.client.gui.drag.component.DraggableComponentProvider; +import me.shedaniel.rei.api.client.gui.drag.component.DraggableComponentVisitor; +import me.shedaniel.rei.api.client.gui.widgets.Tooltip; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.overlay.ScreenOverlay; +import me.shedaniel.rei.api.client.registry.screen.ClickArea; +import me.shedaniel.rei.api.client.registry.screen.OverlayDecider; +import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry; +import me.shedaniel.rei.api.client.view.ViewSearchBuilder; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.impl.client.gui.dragging.CurrentDraggingStack; +import me.shedaniel.rei.impl.client.gui.menu.MenuAccess; +import me.shedaniel.rei.impl.client.gui.menu.MenuAccessImpl; +import me.shedaniel.rei.impl.client.gui.widget.EntryHighlighter; +import me.shedaniel.rei.impl.client.gui.widget.LateRenderable; +import me.shedaniel.rei.impl.client.gui.widget.search.OverlaySearchField; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionResult; + +import java.util.List; + +public abstract class AbstractScreenOverlay extends ScreenOverlay { + private final List widgets = Lists.newLinkedList(); + private final CurrentDraggingStack draggingStack = new CurrentDraggingStack(); + private final MenuAccessImpl menuAccess = new MenuAccessImpl(); + private final Rectangle bounds = new Rectangle(); + private boolean shouldReload = false; + private boolean shouldReloadSearch = false; + + @Override + public void queueReloadOverlay() { + shouldReload = true; + } + + @Override + public void queueReloadSearch() { + shouldReloadSearch = true; + } + + @Override + public boolean isOverlayReloadQueued() { + return shouldReload; + } + + @Override + public boolean isSearchReloadQueued() { + return shouldReloadSearch || shouldReload; + } + + @Override + public DraggingContext getDraggingContext() { + return draggingStack; + } + + @Override + public List children() { + return widgets; + } + + @Override + public Rectangle getBounds() { + return bounds; + } + + protected boolean hasSpace() { + return !this.bounds.isEmpty(); + } + + public void init() { + this.draggingStack.set(DraggableComponentProvider.from(ScreenRegistry.getInstance()::getDraggableComponentProviders), + DraggableComponentVisitor.from(ScreenRegistry.getInstance()::getDraggableComponentVisitors)); + + this.shouldReload = false; + this.shouldReloadSearch = false; + this.bounds.setBounds(InternalOverlayBounds.calculateOverlayBounds()); + this.widgets.clear(); + this.widgets.add(draggingStack); + } + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + if (shouldReload || !InternalOverlayBounds.calculateOverlayBounds().equals(bounds)) { + init(); + updateSearch(); + } else { + for (OverlayDecider decider : ScreenRegistry.getInstance().getDeciders(minecraft.screen)) { + if (decider != null && decider.shouldRecalculateArea(ConfigObject.getInstance().getDisplayPanelLocation(), bounds)) { + init(); + break; + } + } + } + if (shouldReloadSearch) { + shouldReloadSearch = false; + updateSearch(); + } + if (OverlaySearchField.isHighlighting) { + EntryHighlighter.render(matrices); + } + if (!hasSpace()) return; + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + this.renderWidgets(matrices, mouseX, mouseY, delta); + if (ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) { + Screen screen = Minecraft.getInstance().screen; + ClickArea.ClickAreaContext context = createClickAreaContext(mouseX, mouseY, screen); + List clickAreaTooltips = ScreenRegistry.getInstance().getClickAreaTooltips((Class) screen.getClass(), context); + if (clickAreaTooltips != null && !clickAreaTooltips.isEmpty()) { + Tooltip.create(clickAreaTooltips).queue(); + } + } + } + + public void lateRender(PoseStack matrices, int mouseX, int mouseY, float delta) { + if (REIRuntime.getInstance().isOverlayVisible() && hasSpace()) { + getSearchField().asWidget().render(matrices, mouseX, mouseY, delta); + for (Widget widget : widgets) { + if (widget instanceof LateRenderable && widget != menuAccess.widget()) + widget.render(matrices, mouseX, mouseY, delta); + } + matrices.pushPose(); + matrices.translate(0, 0, 500); + menuAccess.lateRender(matrices, mouseX, mouseY, delta); + matrices.popPose(); + } + + REIRuntime.getInstance().clearTooltips(); + if (REIRuntime.getInstance().isOverlayVisible()) { + menuAccess.afterRender(); + } + } + + @Override + public void renderTooltip(PoseStack matrices, Tooltip tooltip) { + renderTooltipInner(minecraft.screen, matrices, tooltip, tooltip.getX(), tooltip.getY()); + } + + protected abstract void renderTooltipInner(Screen screen, PoseStack matrices, Tooltip tooltip, int mouseX, int mouseY); + + public void renderWidgets(PoseStack matrices, int mouseX, int mouseY, float delta) { + if (!REIRuntime.getInstance().isOverlayVisible()) + return; + for (Widget widget : widgets) { + if (!(widget instanceof LateRenderable)) + widget.render(matrices, mouseX, mouseY, delta); + } + } + + private ClickArea.ClickAreaContext createClickAreaContext(double mouseX, double mouseY, Screen screen) { + return new ClickArea.ClickAreaContext<>() { + @Override + public Screen getScreen() { + return screen; + } + + @Override + public Point getMousePosition() { + return new Point(mouseX, mouseY); + } + }; + } + + protected abstract void updateSearch(); + + public MenuAccess menuAccess() { + return menuAccess; + } + + public boolean isInside(double mouseX, double mouseY) { + return bounds.contains(mouseX, mouseY) && isNotInExclusionZones(mouseX, mouseY); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + boolean visible = REIRuntime.getInstance().isOverlayVisible(); + if (!hasSpace()) return false; + if (ConfigObject.getInstance().getHideKeybind().matchesMouse(button)) { + REIRuntime.getInstance().toggleOverlayVisible(); + return REIRuntime.getInstance().isOverlayVisible(); + } + EntryStack stack = ScreenRegistry.getInstance().getFocusedStack(Minecraft.getInstance().screen, PointHelper.ofMouse()); + if (stack != null && !stack.isEmpty()) { + stack = stack.copy(); + if (ConfigObject.getInstance().getRecipeKeybind().matchesMouse(button)) { + return ViewSearchBuilder.builder().addRecipesFor(stack).open(); + } else if (ConfigObject.getInstance().getUsageKeybind().matchesMouse(button)) { + return ViewSearchBuilder.builder().addUsagesFor(stack).open(); + } else if (visible && ConfigObject.getInstance().getFavoriteKeyCode().matchesMouse(button)) { + FavoriteEntry favoriteEntry = FavoriteEntry.fromEntryStack(stack); + ConfigObject.getInstance().getFavoriteEntries().add(favoriteEntry); + return true; + } + } + if (visible) { + Widget menuWidget = menuAccess.widget(); + if (menuWidget != null && menuWidget.mouseClicked(mouseX, mouseY, button)) { + this.setFocused(menuWidget); + if (button == 0) + this.setDragging(true); + return true; + } + } + if (ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) { + Screen screen = Minecraft.getInstance().screen; + ClickArea.ClickAreaContext context = createClickAreaContext(mouseX, mouseY, screen); + if (ScreenRegistry.getInstance().executeClickArea((Class) screen.getClass(), context)) { + return true; + } + } + if (!visible) { + return false; + } + for (GuiEventListener element : widgets) { + if (element != menuAccess.widget() && element.mouseClicked(mouseX, mouseY, button)) { + this.setFocused(element); + if (button == 0) + this.setDragging(true); + return true; + } + } + return false; + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double amount) { + if (!REIRuntime.getInstance().isOverlayVisible()) + return false; + if (menuAccess.mouseScrolled(mouseX, mouseY, amount)) + return true; + for (Widget widget : widgets) + if (widget != menuAccess.widget() + && widget.mouseScrolled(mouseX, mouseY, amount)) + return true; + return false; + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + if (!REIRuntime.getInstance().isOverlayVisible()) + return false; + if (!hasSpace()) return false; + return (this.getFocused() != null && this.isDragging() && button == 0) && this.getFocused().mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (!hasSpace()) return false; + if (REIRuntime.getInstance().isOverlayVisible()) { + for (GuiEventListener listener : widgets) + if (listener.keyPressed(keyCode, scanCode, modifiers)) + return true; + } + if (ConfigObject.getInstance().getHideKeybind().matchesKey(keyCode, scanCode)) { + REIRuntime.getInstance().toggleOverlayVisible(); + return true; + } + EntryStack stack = ScreenRegistry.getInstance().getFocusedStack(Minecraft.getInstance().screen, PointHelper.ofMouse()); + if (stack != null && !stack.isEmpty()) { + stack = stack.copy(); + if (ConfigObject.getInstance().getRecipeKeybind().matchesKey(keyCode, scanCode)) { + return ViewSearchBuilder.builder().addRecipesFor(stack).open(); + } else if (ConfigObject.getInstance().getUsageKeybind().matchesKey(keyCode, scanCode)) { + return ViewSearchBuilder.builder().addUsagesFor(stack).open(); + } else if (ConfigObject.getInstance().getFavoriteKeyCode().matchesKey(keyCode, scanCode)) { + FavoriteEntry favoriteEntry = FavoriteEntry.fromEntryStack(stack); + ConfigObject.getInstance().getFavoriteEntries().add(favoriteEntry); + return true; + } + } + return false; + } + + @Override + public boolean keyReleased(int keyCode, int scanCode, int modifiers) { + if (!hasSpace()) return false; + if (REIRuntime.getInstance().isOverlayVisible()) { + for (GuiEventListener listener : widgets) + if (listener == getFocused() && listener.keyPressed(keyCode, scanCode, modifiers)) + return true; + } + return false; + } + + @Override + public boolean charTyped(char character, int modifiers) { + if (!REIRuntime.getInstance().isOverlayVisible()) + return false; + if (!hasSpace()) return false; + for (GuiEventListener listener : widgets) + if (listener.charTyped(character, modifiers)) + return true; + return false; + } + + @Override + public boolean isNotInExclusionZones(double mouseX, double mouseY) { + for (OverlayDecider decider : ScreenRegistry.getInstance().getDeciders(Minecraft.getInstance().screen)) { + InteractionResult in = decider.isInZone(mouseX, mouseY); + if (in != InteractionResult.PASS) + return in == InteractionResult.SUCCESS; + } + return true; + } + + public boolean isInside(Point point) { + return isInside(point.getX(), point.getY()); + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/InternalOverlayBounds.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/InternalOverlayBounds.java new file mode 100644 index 000000000..4b9aa557d --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/InternalOverlayBounds.java @@ -0,0 +1,51 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of