From fb91ed996b01f986492de4007cb86be5e68ad192 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sun, 28 Aug 2022 20:48:46 +0900 Subject: More internal changes --- .../overlay/entries/CollapsedEntriesTooltip.java | 2 +- .../gui/overlay/entries/EntryListStackEntry.java | 2 +- .../gui/overlay/entries/EntryListWidgetImpl.java | 29 +- .../entries/scrolled/ScrolledEntryListWidget.java | 2 +- .../gui/overlay/widgets/ConfigButtonWidget.java | 192 --------- .../widgets/ConfigButtonWidgetProvider.java | 192 +++++++++ .../widgets/CraftableFilterButtonWidget.java | 174 --------- .../CraftableFilterButtonWidgetProvider.java | 174 +++++++++ .../overlay/widgets/SearchFieldWidgetProvider.java | 25 ++ .../overlay/widgets/search/DelegateTextField.java | 182 +++++++++ .../overlay/widgets/search/OverlaySearchField.java | 430 +++++++++++++++++++++ .../OverlaySearchFieldSyntaxHighlighter.java | 87 +++++ 12 files changed, 1096 insertions(+), 395 deletions(-) delete mode 100644 runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/ConfigButtonWidget.java create mode 100644 runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/ConfigButtonWidgetProvider.java delete mode 100644 runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/CraftableFilterButtonWidget.java create mode 100644 runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/CraftableFilterButtonWidgetProvider.java create mode 100644 runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/SearchFieldWidgetProvider.java create mode 100644 runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/search/DelegateTextField.java create mode 100644 runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/search/OverlaySearchField.java create mode 100644 runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/search/OverlaySearchFieldSyntaxHighlighter.java (limited to 'runtime-frontend/overlay-entries/src/main/java') diff --git a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/CollapsedEntriesTooltip.java b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/CollapsedEntriesTooltip.java index 264ac057e..9521c2e5b 100644 --- a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/CollapsedEntriesTooltip.java +++ b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/CollapsedEntriesTooltip.java @@ -37,7 +37,7 @@ import net.minecraft.network.chat.TextComponent; import net.minecraft.util.Mth; import net.minecraft.world.inventory.tooltip.TooltipComponent; -import static me.shedaniel.rei.impl.client.gui.overlay.InternalOverlayBounds.entrySize; +import static me.shedaniel.rei.impl.client.util.InternalEntryBounds.entrySize; public class CollapsedEntriesTooltip implements ClientTooltipComponent, TooltipComponent { private static final int MAX_WIDTH = 140; diff --git a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/EntryListStackEntry.java b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/EntryListStackEntry.java index e1ec62fa4..a093050f5 100644 --- a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/EntryListStackEntry.java +++ b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/EntryListStackEntry.java @@ -49,7 +49,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; -import static me.shedaniel.rei.impl.client.gui.overlay.InternalOverlayBounds.entrySize; +import static me.shedaniel.rei.impl.client.util.InternalEntryBounds.entrySize; @SuppressWarnings("UnstableApiUsage") public class EntryListStackEntry extends DisplayedEntryWidget { diff --git a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/EntryListWidgetImpl.java b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/EntryListWidgetImpl.java index 8fd0d1bd7..c9c4b3d85 100644 --- a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/EntryListWidgetImpl.java +++ b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/EntryListWidgetImpl.java @@ -24,8 +24,6 @@ package me.shedaniel.rei.impl.client.gui.overlay.entries; import com.mojang.blaze3d.vertex.PoseStack; -import me.shedaniel.clothconfig2.api.animator.NumberAnimator; -import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.ClientHelper; @@ -54,7 +52,6 @@ import me.shedaniel.rei.impl.client.gui.overlay.widgets.ScaleIndicatorWidget; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.player.LocalPlayer; -import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.util.Mth; import net.minecraft.world.InteractionResult; @@ -64,7 +61,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; -import static me.shedaniel.rei.impl.client.gui.overlay.InternalOverlayBounds.entrySize; +import static me.shedaniel.rei.impl.client.util.InternalEntryBounds.entrySize; @ApiStatus.Internal public abstract class EntryListWidgetImpl extends WidgetWithBounds implements EntryListWidget, DraggableStackVisitorWidget { @@ -75,28 +72,8 @@ public abstract class EntryListWidgetImpl extends WidgetWithBounds implements En private final ScaleIndicatorWidget scaleIndicator = new ScaleIndicatorWidget(); public static boolean notSteppingOnExclusionZones(int left, int top, int width, int height) { - Minecraft instance = Minecraft.getInstance(); - for (OverlayDecider decider : ScreenRegistry.getInstance().getDeciders(instance.screen)) { - InteractionResult fit = canItemSlotWidgetFit(left, top, width, height, decider); - if (fit != InteractionResult.PASS) - return fit == InteractionResult.SUCCESS; - } - return true; - } - - private static InteractionResult canItemSlotWidgetFit(int left, int top, int width, int height, OverlayDecider decider) { - InteractionResult fit; - fit = decider.isInZone(left, top); - if (fit != InteractionResult.PASS) - return fit; - fit = decider.isInZone(left + width, top); - if (fit != InteractionResult.PASS) - return fit; - fit = decider.isInZone(left, top + height); - if (fit != InteractionResult.PASS) - return fit; - fit = decider.isInZone(left + width, top + height); - return fit; + ScreenOverlay overlay = ScreenOverlay.getInstance().get(); + return overlay.isNotInExclusionZones(new Rectangle(left, top, width, height)); } private boolean containsChecked(Point point, boolean inner) { diff --git a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/scrolled/ScrolledEntryListWidget.java b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/scrolled/ScrolledEntryListWidget.java index d539c4848..cda032b0d 100644 --- a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/scrolled/ScrolledEntryListWidget.java +++ b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/scrolled/ScrolledEntryListWidget.java @@ -48,7 +48,7 @@ import java.util.Collections; import java.util.List; import java.util.stream.Stream; -import static me.shedaniel.rei.impl.client.gui.overlay.InternalOverlayBounds.entrySize; +import static me.shedaniel.rei.impl.client.util.InternalEntryBounds.entrySize; public class ScrolledEntryListWidget extends CollapsingEntryListWidget { private List | EntryIngredient*/ Object> stacks = new ArrayList<>(); diff --git a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/ConfigButtonWidget.java b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/ConfigButtonWidget.java deleted file mode 100644 index faffe97dd..000000000 --- a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/ConfigButtonWidget.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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.widgets; - -import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.systems.RenderSystem; -import me.shedaniel.math.Rectangle; -import me.shedaniel.rei.api.client.ClientHelper; -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.AppearanceTheme; -import me.shedaniel.rei.api.client.gui.config.DisplayPanelLocation; -import me.shedaniel.rei.api.client.gui.config.SyntaxHighlightingMode; -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.TextField; -import me.shedaniel.rei.api.client.gui.widgets.Widget; -import me.shedaniel.rei.api.client.gui.widgets.Widgets; -import me.shedaniel.rei.api.client.overlay.ScreenOverlay; -import me.shedaniel.rei.api.common.networking.NetworkingHelper; -import me.shedaniel.rei.impl.client.config.ConfigManagerInternal; -import me.shedaniel.rei.impl.client.gui.InternalTextures; -import me.shedaniel.rei.impl.client.gui.menu.MenuAccess; -import me.shedaniel.rei.impl.client.gui.menu.MenuEntry; -import me.shedaniel.rei.impl.client.gui.menu.entries.*; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.chat.NarratorChatListener; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.network.chat.TranslatableComponent; - -import java.util.Collection; -import java.util.List; -import java.util.UUID; -import java.util.function.Consumer; -import java.util.function.UnaryOperator; - -public class ConfigButtonWidget implements OverlayWidgetProvider { - private static final UUID CONFIG_MENU_UUID = UUID.fromString("4357bc36-0a4e-47d2-8e07-ddc220df4a0f"); - - @Override - public List provide(ScreenOverlay overlay, MenuAccess access, Consumer textFieldSink, UnaryOperator lateRenderable) { - return List.of(create(overlay, access, lateRenderable)); - } - - public static Widget create(ScreenOverlay overlay, MenuAccess access, UnaryOperator lateRenderable) { - Rectangle bounds = getConfigButtonBounds(); - Button configButton = Widgets.createButton(bounds, NarratorChatListener.NO_TITLE) - .onClick(button -> { - if (Screen.hasShiftDown() || Screen.hasControlDown()) { - ClientHelper.getInstance().setCheating(!ClientHelper.getInstance().isCheating()); - return; - } - ConfigManager.getInstance().openConfigScreen(REIRuntime.getInstance().getPreviousScreen()); - }) - .onRender((matrices, button) -> { - if (ClientHelper.getInstance().isCheating() && !(Minecraft.getInstance().screen instanceof DisplayScreen) && NetworkingHelper.getInstance().client().hasOperatorPermission()) { - button.setTint(NetworkingHelper.getInstance().client().hasPermissionToUsePackets() ? 721354752 : 1476440063); - } else { - button.removeTint(); - } - - access.openOrClose(CONFIG_MENU_UUID, button.getBounds(), ConfigButtonWidget::menuEntries); - }) - .focusable(false) - .containsMousePredicate((button, point) -> button.getBounds().contains(point) && overlay.isNotInExclusionZones(point.x, point.y)); - Widget overlayWidget = Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { - helper.setBlitOffset(helper.getBlitOffset() + 1); - RenderSystem.setShaderTexture(0, InternalTextures.CHEST_GUI_TEXTURE); - helper.blit(matrices, bounds.x + 3, bounds.y + 3, 0, 0, 14, 14); - helper.setBlitOffset(helper.getBlitOffset() - 1); - }); - return lateRenderable.apply(Widgets.concat(configButton, overlayWidget)); - } - - private static Collection menuEntries() { - ConfigManagerInternal manager = ConfigManagerInternal.getInstance(); - ConfigObject config = ConfigObject.getInstance(); - return List.of( - ToggleMenuEntry.of(new TranslatableComponent("text.rei.cheating"), - config::isCheating, - config::setCheating - ), - new EmptyMenuEntry(4), - new TextMenuEntry(() -> { - if (!ClientHelper.getInstance().isCheating()) - return new TranslatableComponent("text.rei.cheating_disabled"); - else if (!NetworkingHelper.getInstance().client().hasOperatorPermission()) { - if (Minecraft.getInstance().gameMode.hasInfiniteItems()) - return new TranslatableComponent("text.rei.cheating_limited_creative_enabled"); - else return new TranslatableComponent("text.rei.cheating_enabled_no_perms"); - } else if (NetworkingHelper.getInstance().client().hasPermissionToUsePackets()) - return new TranslatableComponent("text.rei.cheating_enabled"); - else - return new TranslatableComponent("text.rei.cheating_limited_enabled"); - }), - new SeparatorMenuEntry(), - ToggleMenuEntry.ofDeciding(new TranslatableComponent("text.rei.config.menu.dark_theme"), - config::isUsingDarkTheme, - dark -> { - manager.set("appearance.theme", dark ? AppearanceTheme.DARK : AppearanceTheme.LIGHT); - return false; - } - ), - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.craftable_filter"), - config::isCraftableFilterEnabled, - bool -> manager.set("appearance.layout.showCraftableOnlyButton", bool) - ), - new SubMenuEntry(new TranslatableComponent("text.rei.config.menu.display"), List.of( - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.remove_recipe_book"), - config::doesDisableRecipeBook, - disableRecipeBook -> { - manager.set("functionality.disableRecipeBook", disableRecipeBook); - Screen screen = Minecraft.getInstance().screen; - - if (screen != null) { - screen.init(Minecraft.getInstance(), screen.width, screen.height); - } - } - ), - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.left_side_mob_effects"), - config::isLeftSideMobEffects, - disableRecipeBook -> { - manager.set("functionality.leftSideMobEffects", disableRecipeBook); - Screen screen = Minecraft.getInstance().screen; - - if (screen != null) { - screen.init(Minecraft.getInstance(), screen.width, screen.height); - } - } - ), - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.left_side_panel"), - config::isLeftHandSidePanel, - bool -> manager.set("advanced.accessibility.displayPanelLocation", bool ? DisplayPanelLocation.LEFT : DisplayPanelLocation.RIGHT) - ), - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.scrolling_side_panel"), - config::isEntryListWidgetScrolled, - bool -> manager.set("appearance.scrollingEntryListWidget", bool) - ), - new SeparatorMenuEntry(), - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.caching_entry_rendering"), - config::doesCacheEntryRendering, - bool -> manager.set("advanced.miscellaneous.cachingFastEntryRendering", bool) - ), - new SeparatorMenuEntry(), - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.syntax_highlighting"), - () -> config.getSyntaxHighlightingMode() == SyntaxHighlightingMode.COLORFUL || config.getSyntaxHighlightingMode() == SyntaxHighlightingMode.COLORFUL_UNDERSCORED, - bool -> manager.set("appearance.syntaxHighlightingMode", bool ? SyntaxHighlightingMode.COLORFUL : SyntaxHighlightingMode.PLAIN_UNDERSCORED) - ) - )), - new SeparatorMenuEntry(), - ToggleMenuEntry.ofDeciding(new TranslatableComponent("text.rei.config.menu.config"), - () -> false, - $ -> { - ConfigManager.getInstance().openConfigScreen(REIRuntime.getInstance().getPreviousScreen()); - return false; - }) - ); - } - - private static Rectangle getConfigButtonBounds() { - if (ConfigObject.getInstance().isLowerConfigButton()) { - Rectangle area = REIRuntime.getInstance().getSearchTextField().asWidget().getBounds().clone(); - area.setLocation(area.x + area.width + (ConfigObject.getInstance().isCraftableFilterEnabled() ? 26 : 4), area.y - 1); - area.setSize(20, 20); - return area; - } - Window window = Minecraft.getInstance().getWindow(); - return new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getGuiScaledWidth() - 30 : 10, 10, 20, 20); - } -} diff --git a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/ConfigButtonWidgetProvider.java b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/ConfigButtonWidgetProvider.java new file mode 100644 index 000000000..eabe883a5 --- /dev/null +++ b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/ConfigButtonWidgetProvider.java @@ -0,0 +1,192 @@ +/* + * 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.widgets; + +import com.mojang.blaze3d.platform.Window; +import com.mojang.blaze3d.systems.RenderSystem; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.ClientHelper; +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.FavoriteMenuEntry; +import me.shedaniel.rei.api.client.gui.config.AppearanceTheme; +import me.shedaniel.rei.api.client.gui.config.DisplayPanelLocation; +import me.shedaniel.rei.api.client.gui.config.SyntaxHighlightingMode; +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.TextField; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.gui.widgets.Widgets; +import me.shedaniel.rei.api.client.overlay.ScreenOverlay; +import me.shedaniel.rei.api.common.networking.NetworkingHelper; +import me.shedaniel.rei.impl.client.config.ConfigManagerInternal; +import me.shedaniel.rei.impl.client.gui.InternalTextures; +import me.shedaniel.rei.impl.client.gui.menu.MenuAccess; +import me.shedaniel.rei.impl.client.gui.overlay.menu.entries.*; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.chat.NarratorChatListener; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.TranslatableComponent; + +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import java.util.function.Consumer; +import java.util.function.UnaryOperator; + +public class ConfigButtonWidgetProvider implements OverlayWidgetProvider { + private static final UUID CONFIG_MENU_UUID = UUID.fromString("4357bc36-0a4e-47d2-8e07-ddc220df4a0f"); + + @Override + public List provide(ScreenOverlay overlay, MenuAccess access, Consumer textFieldSink, UnaryOperator lateRenderable) { + return List.of(create(overlay, access, lateRenderable)); + } + + public static Widget create(ScreenOverlay overlay, MenuAccess access, UnaryOperator lateRenderable) { + Rectangle bounds = getConfigButtonBounds(); + Button configButton = Widgets.createButton(bounds, NarratorChatListener.NO_TITLE) + .onClick(button -> { + if (Screen.hasShiftDown() || Screen.hasControlDown()) { + ClientHelper.getInstance().setCheating(!ClientHelper.getInstance().isCheating()); + return; + } + ConfigManager.getInstance().openConfigScreen(REIRuntime.getInstance().getPreviousScreen()); + }) + .onRender((matrices, button) -> { + if (ClientHelper.getInstance().isCheating() && !(Minecraft.getInstance().screen instanceof DisplayScreen) && NetworkingHelper.getInstance().client().hasOperatorPermission()) { + button.setTint(NetworkingHelper.getInstance().client().hasPermissionToUsePackets() ? 721354752 : 1476440063); + } else { + button.removeTint(); + } + + access.openOrClose(CONFIG_MENU_UUID, button.getBounds(), ConfigButtonWidgetProvider::menuEntries); + }) + .focusable(false) + .containsMousePredicate((button, point) -> button.getBounds().contains(point) && overlay.isNotInExclusionZones(point.x, point.y)); + Widget overlayWidget = Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { + helper.setBlitOffset(helper.getBlitOffset() + 1); + RenderSystem.setShaderTexture(0, InternalTextures.CHEST_GUI_TEXTURE); + helper.blit(matrices, bounds.x + 3, bounds.y + 3, 0, 0, 14, 14); + helper.setBlitOffset(helper.getBlitOffset() - 1); + }); + return lateRenderable.apply(Widgets.concat(configButton, overlayWidget)); + } + + private static Collection menuEntries() { + ConfigManagerInternal manager = ConfigManagerInternal.getInstance(); + ConfigObject config = ConfigObject.getInstance(); + return List.of( + ToggleMenuEntry.of(new TranslatableComponent("text.rei.cheating"), + config::isCheating, + config::setCheating + ), + new EmptyMenuEntry(4), + new TextMenuEntry(() -> { + if (!ClientHelper.getInstance().isCheating()) + return new TranslatableComponent("text.rei.cheating_disabled"); + else if (!NetworkingHelper.getInstance().client().hasOperatorPermission()) { + if (Minecraft.getInstance().gameMode.hasInfiniteItems()) + return new TranslatableComponent("text.rei.cheating_limited_creative_enabled"); + else return new TranslatableComponent("text.rei.cheating_enabled_no_perms"); + } else if (NetworkingHelper.getInstance().client().hasPermissionToUsePackets()) + return new TranslatableComponent("text.rei.cheating_enabled"); + else + return new TranslatableComponent("text.rei.cheating_limited_enabled"); + }), + new SeparatorMenuEntry(), + ToggleMenuEntry.ofDeciding(new TranslatableComponent("text.rei.config.menu.dark_theme"), + config::isUsingDarkTheme, + dark -> { + manager.set("appearance.theme", dark ? AppearanceTheme.DARK : AppearanceTheme.LIGHT); + return false; + } + ), + ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.craftable_filter"), + config::isCraftableFilterEnabled, + bool -> manager.set("appearance.layout.showCraftableOnlyButton", bool) + ), + new SubMenuEntry(new TranslatableComponent("text.rei.config.menu.display"), List.of( + ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.remove_recipe_book"), + config::doesDisableRecipeBook, + disableRecipeBook -> { + manager.set("functionality.disableRecipeBook", disableRecipeBook); + Screen screen = Minecraft.getInstance().screen; + + if (screen != null) { + screen.init(Minecraft.getInstance(), screen.width, screen.height); + } + } + ), + ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.left_side_mob_effects"), + config::isLeftSideMobEffects, + disableRecipeBook -> { + manager.set("functionality.leftSideMobEffects", disableRecipeBook); + Screen screen = Minecraft.getInstance().screen; + + if (screen != null) { + screen.init(Minecraft.getInstance(), screen.width, screen.height); + } + } + ), + ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.left_side_panel"), + config::isLeftHandSidePanel, + bool -> manager.set("advanced.accessibility.displayPanelLocation", bool ? DisplayPanelLocation.LEFT : DisplayPanelLocation.RIGHT) + ), + ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.scrolling_side_panel"), + config::isEntryListWidgetScrolled, + bool -> manager.set("appearance.scrollingEntryListWidget", bool) + ), + new SeparatorMenuEntry(), + ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.caching_entry_rendering"), + config::doesCacheEntryRendering, + bool -> manager.set("advanced.miscellaneous.cachingFastEntryRendering", bool) + ), + new SeparatorMenuEntry(), + ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.syntax_highlighting"), + () -> config.getSyntaxHighlightingMode() == SyntaxHighlightingMode.COLORFUL || config.getSyntaxHighlightingMode() == SyntaxHighlightingMode.COLORFUL_UNDERSCORED, + bool -> manager.set("appearance.syntaxHighlightingMode", bool ? SyntaxHighlightingMode.COLORFUL : SyntaxHighlightingMode.PLAIN_UNDERSCORED) + ) + )), + new SeparatorMenuEntry(), + ToggleMenuEntry.ofDeciding(new TranslatableComponent("text.rei.config.menu.config"), + () -> false, + $ -> { + ConfigManager.getInstance().openConfigScreen(REIRuntime.getInstance().getPreviousScreen()); + return false; + }) + ); + } + + private static Rectangle getConfigButtonBounds() { + if (ConfigObject.getInstance().isLowerConfigButton()) { + Rectangle area = REIRuntime.getInstance().getSearchTextField().asWidget().getBounds().clone(); + area.setLocation(area.x + area.width + (ConfigObject.getInstance().isCraftableFilterEnabled() ? 26 : 4), area.y - 1); + area.setSize(20, 20); + return area; + } + Window window = Minecraft.getInstance().getWindow(); + return new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getGuiScaledWidth() - 30 : 10, 10, 20, 20); + } +} diff --git a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/CraftableFilterButtonWidget.java b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/CraftableFilterButtonWidget.java deleted file mode 100644 index 63ff5fd0d..000000000 --- a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/CraftableFilterButtonWidget.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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.widgets; - -import com.mojang.math.Vector4f; -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.SearchFieldLocation; -import me.shedaniel.rei.api.client.gui.widgets.*; -import me.shedaniel.rei.api.client.overlay.OverlayListWidget; -import me.shedaniel.rei.api.client.overlay.ScreenOverlay; -import me.shedaniel.rei.api.client.search.method.InputMethod; -import me.shedaniel.rei.api.client.search.method.InputMethodRegistry; -import me.shedaniel.rei.api.common.util.CollectionUtils; -import me.shedaniel.rei.impl.client.config.ConfigManagerInternal; -import me.shedaniel.rei.impl.client.gui.menu.MenuAccess; -import me.shedaniel.rei.impl.client.gui.menu.MenuEntry; -import me.shedaniel.rei.impl.client.gui.menu.entries.SubMenuEntry; -import me.shedaniel.rei.impl.client.gui.menu.entries.ToggleMenuEntry; -import me.shedaniel.rei.impl.client.gui.screen.ConfigReloadingScreen; -import me.shedaniel.rei.impl.common.InternalLogger; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.chat.NarratorChatListener; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.renderer.entity.ItemRenderer; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.Blocks; - -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; -import java.util.function.UnaryOperator; - -public class CraftableFilterButtonWidget implements OverlayWidgetProvider { - public static final UUID FILTER_MENU_UUID = UUID.fromString("2839e998-1679-4f9e-a257-37411d16f1e6"); - - @Override - public List provide(ScreenOverlay overlay, MenuAccess access, Consumer textFieldSink, UnaryOperator lateRenderable) { - if (ConfigObject.getInstance().isCraftableFilterEnabled()) { - return List.of(create(overlay, access, lateRenderable)); - } else { - return List.of(); - } - } - - private static Widget create(ScreenOverlay overlay, MenuAccess access, UnaryOperator lateRenderable) { - Rectangle bounds = getCraftableFilterBounds(); - ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); - ItemStack icon = new ItemStack(Blocks.CRAFTING_TABLE); - Button filterButton = Widgets.createButton(bounds, NarratorChatListener.NO_TITLE) - .focusable(false) - .onClick(button -> { - ConfigManager.getInstance().toggleCraftableOnly(); - REIRuntime.getInstance().getOverlay().map(ScreenOverlay::getEntryList).ifPresent(OverlayListWidget::queueReloadSearch); - }) - .onRender((matrices, button) -> { - button.setTint(ConfigManager.getInstance().isCraftableOnlyEnabled() ? 0x3800d907 : 0x38ff0000); - - access.openOrClose(FILTER_MENU_UUID, button.getBounds(), CraftableFilterButtonWidget::menuEntries); - }) - .containsMousePredicate((button, point) -> button.getBounds().contains(point) && overlay.isNotInExclusionZones(point.x, point.y)) - .tooltipLineSupplier(button -> new TranslatableComponent(ConfigManager.getInstance().isCraftableOnlyEnabled() ? "text.rei.showing_craftable" : "text.rei.showing_all")); - Widget overlayWidget = Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { - Vector4f vector = new Vector4f(bounds.x + 2, bounds.y + 2, helper.getBlitOffset() - 10, 1.0F); - vector.transform(matrices.last().pose()); - itemRenderer.blitOffset = vector.z(); - itemRenderer.renderGuiItem(icon, (int) vector.x(), (int) vector.y()); - itemRenderer.blitOffset = 0.0F; - }); - return lateRenderable.apply(Widgets.concat(filterButton, overlayWidget)); - } - - private static Collection menuEntries() { - ConfigManagerInternal manager = ConfigManagerInternal.getInstance(); - ConfigObject config = ConfigObject.getInstance(); - ArrayList entries = new ArrayList<>(List.of( - new SubMenuEntry(new TranslatableComponent("text.rei.config.menu.search_field.position"), Arrays.stream(SearchFieldLocation.values()) - .map(location -> ToggleMenuEntry.of(new TextComponent(location.toString()), - () -> config.getSearchFieldLocation() == location, - bool -> manager.set("appearance.layout.searchFieldLocation", location)) - .withActive(() -> config.getSearchFieldLocation() != location) - ) - .toList()) - )); - - List>> applicableInputMethods = getApplicableInputMethods(); - if (applicableInputMethods.size() > 1) { - entries.add(new SubMenuEntry(new TranslatableComponent("text.rei.config.menu.search_field.input_method"), createInputMethodEntries(applicableInputMethods))); - } - - return entries; - } - - public static List>> getApplicableInputMethods() { - String languageCode = Minecraft.getInstance().options.languageCode; - return InputMethodRegistry.getInstance().getAll().entrySet().stream() - .filter(entry -> CollectionUtils.anyMatch(entry.getValue().getMatchingLocales(), locale -> locale.code().equals(languageCode))) - .toList(); - } - - public static List createInputMethodEntries(List>> applicableInputMethods) { - ConfigManagerInternal manager = ConfigManagerInternal.getInstance(); - ConfigObject config = ConfigObject.getInstance(); - return applicableInputMethods.stream() - .map(pair -> ToggleMenuEntry.of(pair.getValue().getName(), - () -> Objects.equals(config.getInputMethodId(), pair.getKey()), - bool -> { - ExecutorService service = Executors.newSingleThreadExecutor(); - InputMethod active = InputMethod.active(); - active.dispose(service).whenComplete((unused, throwable) -> { - if (throwable != null) { - InternalLogger.getInstance().error("Failed to dispose input method", throwable); - } - - manager.set("functionality.inputMethod", new ResourceLocation("rei:default")); - }).join(); - CompletableFuture future = pair.getValue().prepare(service).whenComplete((unused, throwable) -> { - if (throwable != null) { - InternalLogger.getInstance().error("Failed to prepare input method", throwable); - manager.set("functionality.inputMethod", new ResourceLocation("rei:default")); - } else { - manager.set("functionality.inputMethod", pair.getKey()); - } - }); - Screen screen = Minecraft.getInstance().screen; - Minecraft.getInstance().setScreen(new ConfigReloadingScreen(new TranslatableComponent("text.rei.input.methods.initializing"), - () -> !future.isDone(), () -> { - Minecraft.getInstance().setScreen(screen); - })); - future.whenComplete((unused, throwable) -> { - service.shutdown(); - }); - }) - .withActive(() -> !Objects.equals(config.getInputMethodId(), pair.getKey())) - .withTooltip(() -> Tooltip.create(TooltipContext.ofMouse(), pair.getValue().getDescription())) - ) - .toList(); - } - - private static Rectangle getCraftableFilterBounds() { - Rectangle area = REIRuntime.getInstance().getSearchTextField().asWidget().getBounds().clone(); - area.setLocation(area.x + area.width + 4, area.y - 1); - area.setSize(20, 20); - return area; - } -} diff --git a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/CraftableFilterButtonWidgetProvider.java b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/CraftableFilterButtonWidgetProvider.java new file mode 100644 index 000000000..f5fbc42a0 --- /dev/null +++ b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/CraftableFilterButtonWidgetProvider.java @@ -0,0 +1,174 @@ +/* + * 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.widgets; + +import com.mojang.math.Vector4f; +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.favorites.FavoriteMenuEntry; +import me.shedaniel.rei.api.client.gui.config.SearchFieldLocation; +import me.shedaniel.rei.api.client.gui.widgets.*; +import me.shedaniel.rei.api.client.overlay.OverlayListWidget; +import me.shedaniel.rei.api.client.overlay.ScreenOverlay; +import me.shedaniel.rei.api.client.search.method.InputMethod; +import me.shedaniel.rei.api.client.search.method.InputMethodRegistry; +import me.shedaniel.rei.api.common.util.CollectionUtils; +import me.shedaniel.rei.impl.client.config.ConfigManagerInternal; +import me.shedaniel.rei.impl.client.gui.menu.MenuAccess; +import me.shedaniel.rei.impl.client.gui.overlay.menu.entries.SubMenuEntry; +import me.shedaniel.rei.impl.client.gui.overlay.menu.entries.ToggleMenuEntry; +import me.shedaniel.rei.impl.client.gui.screen.ConfigReloadingScreen; +import me.shedaniel.rei.impl.common.InternalLogger; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.chat.NarratorChatListener; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Blocks; + +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.function.Consumer; +import java.util.function.UnaryOperator; + +public class CraftableFilterButtonWidgetProvider implements OverlayWidgetProvider { + public static final UUID FILTER_MENU_UUID = UUID.fromString("2839e998-1679-4f9e-a257-37411d16f1e6"); + + @Override + public List provide(ScreenOverlay overlay, MenuAccess access, Consumer textFieldSink, UnaryOperator lateRenderable) { + if (ConfigObject.getInstance().isCraftableFilterEnabled()) { + return List.of(create(overlay, access, lateRenderable)); + } else { + return List.of(); + } + } + + private static Widget create(ScreenOverlay overlay, MenuAccess access, UnaryOperator lateRenderable) { + Rectangle bounds = getCraftableFilterBounds(); + ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); + ItemStack icon = new ItemStack(Blocks.CRAFTING_TABLE); + Button filterButton = Widgets.createButton(bounds, NarratorChatListener.NO_TITLE) + .focusable(false) + .onClick(button -> { + ConfigManager.getInstance().toggleCraftableOnly(); + REIRuntime.getInstance().getOverlay().map(ScreenOverlay::getEntryList).ifPresent(OverlayListWidget::queueReloadSearch); + }) + .onRender((matrices, button) -> { + button.setTint(ConfigManager.getInstance().isCraftableOnlyEnabled() ? 0x3800d907 : 0x38ff0000); + + access.openOrClose(FILTER_MENU_UUID, button.getBounds(), CraftableFilterButtonWidgetProvider::menuEntries); + }) + .containsMousePredicate((button, point) -> button.getBounds().contains(point) && overlay.isNotInExclusionZones(point.x, point.y)) + .tooltipLineSupplier(button -> new TranslatableComponent(ConfigManager.getInstance().isCraftableOnlyEnabled() ? "text.rei.showing_craftable" : "text.rei.showing_all")); + Widget overlayWidget = Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { + Vector4f vector = new Vector4f(bounds.x + 2, bounds.y + 2, helper.getBlitOffset() - 10, 1.0F); + vector.transform(matrices.last().pose()); + itemRenderer.blitOffset = vector.z(); + itemRenderer.renderGuiItem(icon, (int) vector.x(), (int) vector.y()); + itemRenderer.blitOffset = 0.0F; + }); + return lateRenderable.apply(Widgets.concat(filterButton, overlayWidget)); + } + + private static Collection menuEntries() { + ConfigManagerInternal manager = ConfigManagerInternal.getInstance(); + ConfigObject config = ConfigObject.getInstance(); + ArrayList entries = new ArrayList<>(List.of( + new SubMenuEntry(new TranslatableComponent("text.rei.config.menu.search_field.position"), Arrays.stream(SearchFieldLocation.values()) + .map(location -> ToggleMenuEntry.of(new TextComponent(location.toString()), + () -> config.getSearchFieldLocation() == location, + bool -> manager.set("appearance.layout.searchFieldLocation", location)) + .withActive(() -> config.getSearchFieldLocation() != location) + ) + .toList()) + )); + + List>> applicableInputMethods = getApplicableInputMethods(); + if (applicableInputMethods.size() > 1) { + entries.add(new SubMenuEntry(new TranslatableComponent("text.rei.config.menu.search_field.input_method"), createInputMethodEntries(applicableInputMethods))); + } + + return entries; + } + + public static List>> getApplicableInputMethods() { + String languageCode = Minecraft.getInstance().options.languageCode; + return InputMethodRegistry.getInstance().getAll().entrySet().stream() + .filter(entry -> CollectionUtils.anyMatch(entry.getValue().getMatchingLocales(), locale -> locale.code().equals(languageCode))) + .toList(); + } + + public static List createInputMethodEntries(List>> applicableInputMethods) { + ConfigManagerInternal manager = ConfigManagerInternal.getInstance(); + ConfigObject config = ConfigObject.getInstance(); + return applicableInputMethods.stream() + .map(pair -> ToggleMenuEntry.of(pair.getValue().getName(), + () -> Objects.equals(config.getInputMethodId(), pair.getKey()), + bool -> { + ExecutorService service = Executors.newSingleThreadExecutor(); + InputMethod active = InputMethod.active(); + active.dispose(service).whenComplete((unused, throwable) -> { + if (throwable != null) { + InternalLogger.getInstance().error("Failed to dispose input method", throwable); + } + + manager.set("functionality.inputMethod", new ResourceLocation("rei:default")); + }).join(); + CompletableFuture future = pair.getValue().prepare(service).whenComplete((unused, throwable) -> { + if (throwable != null) { + InternalLogger.getInstance().error("Failed to prepare input method", throwable); + manager.set("functionality.inputMethod", new ResourceLocation("rei:default")); + } else { + manager.set("functionality.inputMethod", pair.getKey()); + } + }); + Screen screen = Minecraft.getInstance().screen; + Minecraft.getInstance().setScreen(new ConfigReloadingScreen(new TranslatableComponent("text.rei.input.methods.initializing"), + () -> !future.isDone(), () -> { + Minecraft.getInstance().setScreen(screen); + })); + future.whenComplete((unused, throwable) -> { + service.shutdown(); + }); + }) + .withActive(() -> !Objects.equals(config.getInputMethodId(), pair.getKey())) + .withTooltip(() -> Tooltip.create(TooltipContext.ofMouse(), pair.getValue().getDescription())) + ) + .toList(); + } + + private static Rectangle getCraftableFilterBounds() { + Rectangle area = REIRuntime.getInstance().getSearchTextField().asWidget().getBounds().clone(); + area.setLocation(area.x + area.width + 4, area.y - 1); + area.setSize(20, 20); + return area; + } +} diff --git a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/SearchFieldWidgetProvider.java b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/SearchFieldWidgetProvider.java new file mode 100644 index 000000000..7fb67cf34 --- /dev/null +++ b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/SearchFieldWidgetProvider.java @@ -0,0 +1,25 @@ +package me.shedaniel.rei.impl.client.gui.overlay.widgets; + +import me.shedaniel.rei.api.client.gui.widgets.TextField; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.overlay.ScreenOverlay; +import me.shedaniel.rei.impl.client.gui.menu.MenuAccess; +import me.shedaniel.rei.impl.client.gui.overlay.widgets.search.OverlaySearchField; + +import java.util.List; +import java.util.function.Consumer; +import java.util.function.UnaryOperator; + +public class SearchFieldWidgetProvider implements OverlayWidgetProvider { + private OverlaySearchField searchField; + + @Override + public List provide(ScreenOverlay overlay, MenuAccess access, Consumer textFieldSink, UnaryOperator lateRenderable) { + if (searchField == null) { + searchField = new OverlaySearchField(access); + } + + textFieldSink.accept(searchField); + return List.of(lateRenderable.apply(searchField)); + } +} diff --git a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/search/DelegateTextField.java b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/search/DelegateTextField.java new file mode 100644 index 000000000..d52764bff --- /dev/null +++ b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/search/DelegateTextField.java @@ -0,0 +1,182 @@ +/* + * 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.widgets.search; + +import com.mojang.blaze3d.platform.InputConstants; +import it.unimi.dsi.fastutil.booleans.BooleanConsumer; +import me.shedaniel.rei.api.client.gui.widgets.TextField; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Consumer; +import java.util.function.Function; + +public interface DelegateTextField extends TextField { + TextField delegateTextField(); + + @Override + default void setFocusedResponder(BooleanConsumer responder) { + delegateTextField().setFocusedResponder(responder); + } + + @Override + @Nullable + default String getSuggestion() { + return delegateTextField().getSuggestion(); + } + + @Override + default void setSuggestion(@Nullable String suggestion) { + delegateTextField().setSuggestion(suggestion); + } + + @Override + default void setBorderColorProvider(BorderColorProvider borderColorProvider) { + delegateTextField().setBorderColorProvider(borderColorProvider); + } + + @Override + default void setFormatter(TextFormatter formatter) { + delegateTextField().setFormatter(formatter); + } + + @Override + default TextFormatter getFormatter() { + return delegateTextField().getFormatter(); + } + + @Override + default void setSuggestionRenderer(SuggestionRenderer renderer) { + delegateTextField().setSuggestionRenderer(renderer); + } + + @Override + default SuggestionRenderer getSuggestionRenderer() { + return delegateTextField().getSuggestionRenderer(); + } + + @Override + default void setTextTransformer(Function textTransformer) { + delegateTextField().setTextTransformer(textTransformer); + } + + @Override + default void setResponder(Consumer responder) { + delegateTextField().setResponder(responder); + } + + @Override + default String getText() { + return delegateTextField().getText(); + } + + @Override + default void setText(String text) { + delegateTextField().setText(text); + } + + @Override + default String getSelectedText() { + return delegateTextField().getSelectedText(); + } + + @Override + default void addText(String text) { + delegateTextField().addText(text); + } + + @Override + default void moveCursorTo(int cursor) { + delegateTextField().moveCursorTo(cursor); + } + + @Override + default void moveCursorToStart() { + delegateTextField().moveCursorToStart(); + } + + @Override + default void moveCursorToEnd() { + delegateTextField().moveCursorToEnd(); + } + + @Override + default int getMaxLength() { + return delegateTextField().getMaxLength(); + } + + @Override + default void setMaxLength(int maxLength) { + delegateTextField().setMaxLength(maxLength); + } + + @Override + default int getCursor() { + return delegateTextField().getCursor(); + } + + @Override + default void setCursorPosition(int cursor) { + delegateTextField().setCursorPosition(cursor); + } + + @Override + default boolean hasBorder() { + return delegateTextField().hasBorder(); + } + + @Override + default void setHasBorder(boolean hasBorder) { + delegateTextField().setHasBorder(hasBorder); + } + + @Override + default void setEditableColor(int editableColor) { + delegateTextField().setEditableColor(editableColor); + } + + @Override + default void setNotEditableColor(int notEditableColor) { + delegateTextField().setNotEditableColor(notEditableColor); + } + + @Override + default boolean isFocused() { + return delegateTextField().isFocused(); + } + + @Override + default void setFocused(boolean focused) { + delegateTextField().setFocused(focused); + } + + @Override + default void setFocusedFromKey(boolean focused, InputConstants.Key key) { + delegateTextField().setFocusedFromKey(focused, key); + } + + @Override + default void tick() { + delegateTextField().tick(); + } +} diff --git a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/search/OverlaySearchField.java b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/search/OverlaySearchField.java new file mode 100644 index 000000000..6484f82e2 --- /dev/null +++ b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/widgets/search/OverlaySearchField.java @@ -0,0 +1,430 @@ +/* + * 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.widgets.search; + +import com.google.common.collect.Lists; +import com.mojang.blaze3d.platform.InputConstants; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.*; +import com.mojang.datafixers.util.Pair; +import com.mojang.math.Matrix4f; +import me.shedaniel.clothconfig2.api.animator.NumberAnimator; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; +import me.shedaniel.math.Color; +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