diff options
25 files changed, 1009 insertions, 244 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/config/ConfigObject.java b/api/src/main/java/me/shedaniel/rei/api/client/config/ConfigObject.java index 45d66c860..02afcd7f4 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/config/ConfigObject.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/config/ConfigObject.java @@ -272,6 +272,9 @@ public interface ConfigObject { boolean doesCacheEntryRendering(); + @ApiStatus.Experimental + boolean doesCacheDisplayLookup(); + boolean doDebugRenderTimeRequired(); boolean doMergeDisplayUnderOne(); diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/OverlayDecider.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/OverlayDecider.java index 49b63e1f5..70db769e3 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/OverlayDecider.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/OverlayDecider.java @@ -89,6 +89,19 @@ public interface OverlayDecider extends Comparable<OverlayDecider> { } /** + * Returns the provider for rendering the overlay. + * Return {@code null} to pass the rendering to the next decider. + * + * @return the provider for rendering the overlay + * @see OverlayRendererProvider for more information + * @since 8.3 + */ + @ApiStatus.Experimental + default OverlayRendererProvider getRendererProvider() { + return null; + } + + /** * {@inheritDoc} */ @Override diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/OverlayRendererProvider.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/OverlayRendererProvider.java new file mode 100644 index 000000000..e690218b7 --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/OverlayRendererProvider.java @@ -0,0 +1,79 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022, 2023 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.api.client.registry.screen; + +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.rei.api.client.overlay.ScreenOverlay; +import org.jetbrains.annotations.ApiStatus; + +/** + * The provider for a renderer provider. + * <p> + * {@link #onApplied(Sink)} is called when this provider is selected for a screen, + * and {@link #onRemoved()} is called when this provider is removed from a screen, + * for example if the screen is now no longer applicable for this provider, or + * the screen is closed. + * <p> + * {@link Sink} is given to the provider to allow the provider to render the overlay, + * whatever it deems necessary. + */ +@ApiStatus.Experimental +public interface OverlayRendererProvider { + default void onApplied(Sink sink) { + } + + default void onRemoved() { + } + + @ApiStatus.NonExtendable + interface Sink { + /** + * Renders the overlay. + * + * @param matrices the matrices + * @param mouseX the mouse x + * @param mouseY the mouse y + * @param delta the delta + */ + void render(PoseStack matrices, int mouseX, int mouseY, float delta); + + /** + * Renders the overlay components that are supposed to be rendered last, + * for example, menu entries, or tooltips. + * + * @param matrices the matrices + * @param mouseX the mouse x + * @param mouseY the mouse y + * @param delta the delta + */ + void lateRender(PoseStack matrices, int mouseX, int mouseY, float delta); + + /** + * Returns the overlay. + * + * @return the overlay + */ + ScreenOverlay getOverlay(); + } +} diff --git a/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java b/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java index eb0449f48..bd8376e53 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java @@ -23,12 +23,10 @@ package me.shedaniel.rei.api.common.util; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import com.google.common.collect.UnmodifiableIterator; +import com.google.common.collect.*; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; import me.shedaniel.rei.api.common.entry.EntryStack; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -550,4 +548,23 @@ public class CollectionUtils { return size; } } + + public static <T> Iterable<T> distinctReferenceOf(Iterable<T> iterable) { + return () -> new AbstractIterator<T>() { + private final Set<T> set = new ReferenceOpenHashSet<>(); + private final Iterator<T> iterator = iterable.iterator(); + + @Override + protected T computeNext() { + while (iterator.hasNext()) { + T next = iterator.next(); + if (set.add(next)) { + return next; + } + } + + return endOfData(); + } + }; + } } diff --git a/fabric/src/main/java/me/shedaniel/rei/mixin/fabric/MixinInputConstantsKey.java b/fabric/src/main/java/me/shedaniel/rei/mixin/fabric/MixinInputConstantsKey.java new file mode 100644 index 000000000..a74c12d31 --- /dev/null +++ b/fabric/src/main/java/me/shedaniel/rei/mixin/fabric/MixinInputConstantsKey.java @@ -0,0 +1,57 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022, 2023 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.mixin.fabric; + +import com.mojang.blaze3d.platform.InputConstants; +import com.mojang.blaze3d.systems.RenderSystem; +import me.shedaniel.rei.api.client.config.ConfigObject; +import net.minecraft.network.chat.Component; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(InputConstants.Key.class) +public abstract class MixinInputConstantsKey { + @Shadow + public abstract String getName(); + + @Inject(method = "getDisplayName", at = @At("HEAD"), cancellable = true) + private void getDisplayName(CallbackInfoReturnable<Component> cir) { + if (isPatchingAsyncThreadCrash() && !RenderSystem.isOnRenderThread()) { + cir.setReturnValue(Component.translatable(getName())); + } + } + + @Unique + private static boolean isPatchingAsyncThreadCrash() { + try { + return ConfigObject.getInstance().isPatchingAsyncThreadCrash(); + } catch (Throwable throwable) { + return false; + } + } +} diff --git a/fabric/src/main/resources/rei.mixins.json b/fabric/src/main/resources/rei.mixins.json index 89a733346..8e34cc178 100644 --- a/fabric/src/main/resources/rei.mixins.json +++ b/fabric/src/main/resources/rei.mixins.json @@ -7,6 +7,7 @@ "MixinClientPacketListener", "MixinEffectRenderingInventoryScreen", "MixinInputConstants", + "MixinInputConstantsKey", "MixinRecipeToast", "MixinScreen" ], diff --git a/forge/src/main/java/me/shedaniel/rei/mixin/forge/MixinInputConstantsKey.java b/forge/src/main/java/me/shedaniel/rei/mixin/forge/MixinInputConstantsKey.java new file mode 100644 index 000000000..df0348de1 --- /dev/null +++ b/forge/src/main/java/me/shedaniel/rei/mixin/forge/MixinInputConstantsKey.java @@ -0,0 +1,57 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022, 2023 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.mixin.forge; + +import com.mojang.blaze3d.platform.InputConstants; +import com.mojang.blaze3d.systems.RenderSystem; +import me.shedaniel.rei.api.client.config.ConfigObject; +import net.minecraft.network.chat.Component; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(InputConstants.Key.class) +public abstract class MixinInputConstantsKey { + @Shadow + public abstract String getName(); + + @Inject(method = "getDisplayName", at = @At("HEAD"), cancellable = true) + private void getDisplayName(CallbackInfoReturnable<Component> cir) { + if (isPatchingAsyncThreadCrash() && !RenderSystem.isOnRenderThread()) { + cir.setReturnValue(Component.translatable(getName())); + } + } + + @Unique + private static boolean isPatchingAsyncThreadCrash() { + try { + return ConfigObject.getInstance().isPatchingAsyncThreadCrash(); + } catch (Throwable throwable) { + return false; + } + } +} diff --git a/forge/src/main/resources/rei.mixins.json b/forge/src/main/resources/rei.mixins.json index 838df45f2..e95039402 100644 --- a/forge/src/main/resources/rei.mixins.json +++ b/forge/src/main/resources/rei.mixins.json @@ -7,6 +7,7 @@ "MixinEffectRenderingInventoryScreen", "MixinFontSet", "MixinInputConstants", + "MixinInputConstantsKey", "MixinRecipeToast" ], "mixins": [ diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java index f1b1110e8..5d5d53d8f 100644 --- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java +++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java @@ -78,6 +78,7 @@ import me.shedaniel.rei.impl.client.registry.category.CategoryRegistryImpl; import me.shedaniel.rei.impl.client.registry.display.DisplayRegistryImpl; import me.shedaniel.rei.impl.client.registry.screen.ScreenRegistryImpl; import me.shedaniel.rei.impl.client.search.SearchProviderImpl; +import me.shedaniel.rei.impl.client.search.SearchRuntime; import me.shedaniel.rei.impl.client.search.method.InputMethodRegistryImpl; import me.shedaniel.rei.impl.client.subsets.SubsetsRegistryImpl; import me.shedaniel.rei.impl.client.transfer.TransferHandlerRegistryImpl; @@ -231,6 +232,7 @@ public class RoughlyEnoughItemsCoreClient { new FavoriteEntryTypeRegistryImpl(), new SubsetsRegistryImpl(), new TransferHandlerRegistryImpl(), + new SearchRuntime(), new REIRuntimeImpl(), new ConfigAddonRegistryImpl()), "clientPluginManager"); } @@ -351,6 +353,7 @@ public class RoughlyEnoughItemsCoreClient { } REIRuntimeImpl.getInstance().setPreviousScreen(screen); + ((ScreenRegistryImpl) ScreenRegistry.getInstance()).getLastRendererProvider(screen); } if (ConfigObject.getInstance().doesDisableRecipeBook() && screen instanceof AbstractContainerScreen) { access.getRenderables().removeIf(widget -> widget instanceof ImageButton button && button.resourceLocation.equals(recipeButtonTex)); @@ -408,53 +411,6 @@ public class RoughlyEnoughItemsCoreClient { return EventResult.interruptFalse(); return EventResult.pass(); }); - int[] rendered = {0}; - ClientGuiEvent.RENDER_PRE.register((screen, matrices, mouseX, mouseY, delta) -> { - if (shouldReturn(screen)) - return EventResult.pass(); - rendered[0] = 0; - return EventResult.pass(); - }); - ClientGuiEvent.RENDER_CONTAINER_BACKGROUND.register((screen, matrices, mouseX, mouseY, delta) -> { - if (shouldReturn(screen)) - return; - rendered[0] = 1; - resetFocused(screen); - if (!(screen instanceof DisplayScreen)) { - getOverlay().render(matrices, mouseX, mouseY, delta); - } - resetFocused(screen); - }); - ClientGuiEvent.RENDER_CONTAINER_FOREGROUND.register((screen, matrices, mouseX, mouseY, delta) -> { - if (shouldReturn(screen)) - return; - rendered[0] = 2; - resetFocused(screen); - PoseStack poseStack = RenderSystem.getModelViewStack(); - poseStack.pushPose(); - poseStack.translate(-screen.leftPos, -screen.topPos, 0.0); - RenderSystem.applyModelViewMatrix(); - ((ScreenOverlayImpl) getOverlay()).lateRender(matrices, mouseX, mouseY, delta); - poseStack.popPose(); - RenderSystem.applyModelViewMatrix(); - resetFocused(screen); - }); - ClientGuiEvent.RENDER_POST.register((screen, matrices, mouseX, mouseY, delta) -> { - if (shouldReturn(screen) || rendered[0] == 2) - return; - if (screen instanceof AbstractContainerScreen) { - InternalLogger.getInstance().warn("Screen " + screen.getClass().getName() + " did not render background and foreground! This might cause rendering issues!"); - } - resetFocused(screen); - if (rendered[0] == 0 && !(screen instanceof DisplayScreen)) { - getOverlay().render(matrices, mouseX, mouseY, delta); - } - rendered[0] = 1; - if (rendered[0] == 1) { - ((ScreenOverlayImpl) getOverlay()).lateRender(matrices, mouseX, mouseY, delta); - } - resetFocused(screen); - }); ClientScreenInputEvent.MOUSE_DRAGGED_PRE.register((minecraftClient, screen, mouseX1, mouseY1, button, mouseX2, mouseY2) -> { if (shouldReturn(screen) || screen instanceof DisplayScreen) return EventResult.pass(); @@ -504,7 +460,7 @@ public class RoughlyEnoughItemsCoreClient { }); } - private boolean resetFocused(Screen screen) { + public static boolean resetFocused(Screen screen) { if (screen.getFocused() instanceof ScreenOverlay || screen.getFocused() == screen) { screen.setFocused(null); } 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 2e7018ad8..fad1fdf6c 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 @@ -47,7 +47,6 @@ import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; 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.search.argument.Argument; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; @@ -255,7 +254,6 @@ public class REIRuntimeImpl implements REIRuntime { @Override public void startReload() { - Argument.resetCache(false); getOverlay().ifPresent(ScreenOverlay::queueReloadOverlay); lastDisplayScreen.clear(); if (!RenderSystem.isOnRenderThread()) { @@ -272,7 +270,6 @@ public class REIRuntimeImpl implements REIRuntime { @Override public void endReload(ReloadStage stage) { - Argument.resetCache(true); getOverlay().ifPresent(ScreenOverlay::queueReloadOverlay); } 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 f8e1f02d0..47f84a7c4 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 @@ -303,6 +303,11 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { } @Override + public boolean doesCacheDisplayLookup() { + return advanced.miscellaneous.cachingDisplayLookup; + } + + @Override public boolean doDebugRenderTimeRequired() { return advanced.layout.debugRenderTimeRequired; } @@ -726,6 +731,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { private boolean newFastEntryRendering = true; @ConfigEntry.Gui.PrefixText private boolean cachingFastEntryRendering = false; + private boolean cachingDisplayLookup = true; } public static class Filtering { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java index a95d52069..c0e9e2b01 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java @@ -54,10 +54,7 @@ import net.minecraft.util.Mth; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; @ApiStatus.Internal public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen { @@ -183,7 +180,7 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen ViewSearchBuilder.builder().addAllCategories().open(); }).tooltip(Component.translatable("text.rei.view_all_categories")).noShadow().color(0xFF404040, 0xFFBBBBBB).hoveredColor(0xFF0041FF, 0xFFFFBD4D)); - this.children().addAll(buttonList); + this.widgets.add(new ButtonListWidget(buttonList)); this.children().addAll(widgets); } @@ -270,6 +267,7 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen @Override public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + this.widgets.sort(Comparator.comparingDouble(Widget::getZRenderingPriority)); if (ConfigObject.getInstance().isCompositeScrollBarPermanent()) { scrollBarAlphaFutureTime = System.currentTimeMillis(); scrollBarAlphaFuture = 0; @@ -294,32 +292,12 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen } scrolling.updatePosition(delta); renderBackground(matrices); - int yOffset = 0; getOverlay().render(matrices, mouseX, mouseY, delta); super.render(matrices, mouseX, mouseY, delta); for (Widget widget : widgets) { RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); widget.render(matrices, mouseX, mouseY, delta); } - matrices.pushPose(); - ScissorsHandler.INSTANCE.scissor(scrolling.getBounds()); - for (Button button : buttonList) { - button.getBounds().y = scrollListBounds.y + 1 + yOffset - scrolling.scrollAmountInt(); - if (button.getBounds().getMaxY() > scrollListBounds.getMinY() && button.getBounds().getMinY() < scrollListBounds.getMaxY()) { - button.render(matrices, mouseX, mouseY, delta); - } - yOffset += button.getBounds().height; - } - for (int i = 0; i < buttonList.size(); i++) { - if (buttonList.get(i).getBounds().getMaxY() > scrollListBounds.getMinY() && buttonList.get(i).getBounds().getMinY() < scrollListBounds.getMaxY()) { - displayRenderers.get(i).setZ(1); - displayRenderers.get(i).render(matrices, buttonList.get(i).getBounds(), mouseX, mouseY, delta); - Optional.ofNullable(displayRenderers.get(i).getTooltip(TooltipContext.of(new Point(mouseX, mouseY)))).ifPresent(Tooltip::queue); - } - } - scrolling.renderScrollBar(0, scrollBarAlpha, REIRuntime.getInstance().isDarkThemeEnabled() ? 0.8f : 1f); - ScissorsHandler.INSTANCE.removeLastScissor(); - matrices.popPose(); } @Override @@ -379,4 +357,41 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen } return super.keyPressed(keyCode, scanCode, modifiers); } + + private class ButtonListWidget extends Widget { + private final List<Button> buttonList; + + public ButtonListWidget(List<Button> buttonList) { + this.buttonList = buttonList; + } + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + int yOffset = 0; + matrices.pushPose(); + ScissorsHandler.INSTANCE.scissor(scrolling.getBounds()); + for (Button button : buttonList) { + button.getBounds().y = scrollListBounds.y + 1 + yOffset - scrolling.scrollAmountInt(); + if (button.getBounds().getMaxY() > scrollListBounds.getMinY() && button.getBounds().getMinY() < scrollListBounds.getMaxY()) { + button.render(matrices, mouseX, mouseY, delta); + } + yOffset += button.getBounds().height; + } + for (int i = 0; i < buttonList.size(); i++) { + if (buttonList.get(i).getBounds().getMaxY() > scrollListBounds.getMinY() && buttonList.get(i).getBounds().getMinY() < scrollListBounds.getMaxY()) { + displayRenderers.get(i).setZ(1); + displayRenderers.get(i).render(matrices, buttonList.get(i).getBounds(), mouseX, mouseY, delta); + Optional.ofNullable(displayRenderers.get(i).getTooltip(TooltipContext.of(new Point(mouseX, mouseY)))).ifPresent(Tooltip::queue); + } + } + scrolling.renderScrollBar(0, scrollBarAlpha, REIRuntime.getInstance().isDarkThemeEnabled() ? 0.8f : 1f); + ScissorsHandler.INSTANCE.removeLastScissor(); + matrices.popPose(); + } + + @Override + public List<? extends GuiEventListener> children() { + return buttonList; + } + } } 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 7d23a89d7..777b44d06 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 @@ -60,6 +60,8 @@ import me.shedaniel.rei.impl.client.gui.InternalTextures; import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; import me.shedaniel.rei.impl.client.gui.dragging.CurrentDraggingStack; import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesListWidget; +import me.shedaniel.rei.impl.client.registry.display.DisplayRegistryImpl; +import me.shedaniel.rei.impl.client.registry.display.DisplaysHolder; import me.shedaniel.rei.impl.client.view.ViewsImpl; import net.minecraft.ChatFormatting; import net.minecraft.CrashReport; @@ -317,22 +319,24 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget { try { DisplayRegistry displayRegistry = DisplayRegistry.getInstance(); + DisplaysHolder displaysHolder = ((DisplayRegistryImpl) displayRegistry).displaysHolder(); CategoryRegistry categoryRegistry = CategoryRegistry.getInstance(); Map<CategoryIdentifier<?>, Boolean> filteringQuickCraftCategories = ConfigObject.getInstance().getFilteringQuickCraftCategories(); - for (Map.Entry<CategoryIdentifier<?>, List<Display>> entry : displayRegistry.getAll().entrySet()) { + boolean shouldFilterDisplays = ConfigObject.getInstance().shouldFilterDisplays(); + + for (Display display : displaysHolder.getAllDisplaysByOutputs(getEntries())) { + CategoryIdentifier<?> categoryIdentifier = display.getCategoryIdentifier(); Optional<? extends CategoryRegistry.CategoryConfiguration<?>> configuration; - if ((configuration = categoryRegistry.tryGet(entry.getKey())).isEmpty() - || categoryRegistry.isCategoryInvisible(configuration.get().getCategory())) continue; - if (!filteringQuickCraftCategories.getOrDefault(entry.getKey(), configuration.get().isQuickCraftingEnabledByDefault())) continue; - for (Display display : entry.getValue()) { - if ((!ConfigObject.getInstance().shouldFilterDisplays() || displayRegistry.isDisplayVisible(display)) - && ViewsImpl.isRecipesFor(getEntries(), display)) { - AutoCraftingEvaluator.AutoCraftingResult result = AutoCraftingEvaluator.evaluateAutoCrafting(false, false, display, null); - if (result.successful) { - this.display = display; - this.displayTooltipComponent = Suppliers.memoize(() -> new DisplayTooltipComponent(display)); - return result.successfulHandler; - |
