From 83ec9cb3e3326b1e9221e0630309c207fb630e8e Mon Sep 17 00:00:00 2001 From: shedaniel Date: Tue, 19 Jul 2022 00:06:17 +0800 Subject: Add InputMethods, Close #574 --- .../rei/RoughlyEnoughItemsCoreClient.java | 2 + .../shedaniel/rei/RoughlyEnoughItemsNetwork.java | 1 - .../rei/impl/client/config/ConfigManagerImpl.java | 37 +- .../rei/impl/client/config/ConfigObjectImpl.java | 13 + .../client/config/addon/ConfigAddonsScreen.java | 5 +- .../config/entries/FilteringRulesScreen.java | 5 +- .../client/config/entries/ReloadPluginsEntry.java | 2 +- .../SearchFilterSyntaxHighlightingEntry.java | 4 +- .../entry/type/types/RenderingEntryDefinition.java | 2 - .../favorites/FavoriteEntryTypeRegistryImpl.java | 1 - .../rei/impl/client/gui/InternalTextures.java | 35 ++ .../rei/impl/client/gui/ScreenOverlayImpl.java | 479 +++------------------ .../rei/impl/client/gui/hints/HintProvider.java | 6 + .../rei/impl/client/gui/modules/Menu.java | 3 +- .../rei/impl/client/gui/modules/MenuAccess.java | 64 +++ .../rei/impl/client/gui/modules/MenuHolder.java | 135 ++++++ .../client/gui/modules/entries/SubMenuEntry.java | 4 +- .../gui/modules/entries/ToggleMenuEntry.java | 39 +- .../gui/screen/CompositeDisplayViewingScreen.java | 10 +- .../client/gui/screen/ConfigReloadingScreen.java | 16 +- .../gui/screen/DefaultDisplayViewingScreen.java | 17 +- .../gui/screen/UncertainDisplayViewingScreen.java | 3 - .../client/gui/widget/CachedEntryListRender.java | 3 - .../impl/client/gui/widget/ConfigButtonWidget.java | 185 ++++++++ .../gui/widget/CraftableFilterButtonWidget.java | 163 +++++++ .../client/gui/widget/DisplayCompositeWidget.java | 8 - .../impl/client/gui/widget/EntryHighlighter.java | 64 +++ .../rei/impl/client/gui/widget/EntryWidget.java | 22 +- .../impl/client/gui/widget/InternalWidgets.java | 4 - .../rei/impl/client/gui/widget/MergedWidget.java | 1 - .../rei/impl/client/gui/widget/TabWidget.java | 10 +- .../client/gui/widget/basewidgets/PanelWidget.java | 7 +- .../gui/widget/basewidgets/TextFieldWidget.java | 184 ++++---- .../widget/entrylist/EntryListSearchManager.java | 16 +- .../gui/widget/entrylist/EntryListWidget.java | 17 +- .../widget/entrylist/PaginatedEntryListWidget.java | 128 +++++- .../widget/entrylist/ScrolledEntryListWidget.java | 13 - .../gui/widget/favorites/FavoritesListWidget.java | 1 - .../gui/widget/favorites/history/DisplayEntry.java | 2 - .../listeners/FavoritesRegionListener.java | 2 - .../panel/rows/FavoritesPanelEntriesRow.java | 1 - .../gui/widget/region/RegionEntryWidget.java | 20 +- .../gui/widget/search/OverlaySearchField.java | 53 ++- .../client/registry/screen/ScreenRegistryImpl.java | 13 +- .../rei/impl/client/search/AsyncSearchManager.java | 24 +- .../rei/impl/client/search/SearchProviderImpl.java | 28 +- .../search/argument/AlternativeArgument.java | 2 + .../rei/impl/client/search/argument/Argument.java | 80 +++- .../client/search/argument/CompoundArgument.java | 2 + .../rei/impl/client/search/argument/IndexSet.java | 173 ++++++++ .../client/search/argument/InputMethodMatcher.java | 129 ++++++ .../argument/type/AlwaysMatchingArgumentType.java | 9 +- .../client/search/argument/type/ArgumentType.java | 10 +- .../argument/type/ArgumentTypesRegistry.java | 14 +- .../argument/type/IdentifierArgumentType.java | 10 +- .../search/argument/type/ModArgumentType.java | 9 +- .../search/argument/type/RegexArgumentType.java | 19 +- .../search/argument/type/TagArgumentType.java | 8 +- .../search/argument/type/TextArgumentType.java | 8 +- .../search/argument/type/TooltipArgumentType.java | 10 +- .../client/search/method/DefaultInputMethod.java | 75 ++++ .../search/method/InputMethodRegistryImpl.java | 104 +++++ .../search/method/unihan/BomopofoInputMethod.java | 141 ++++++ .../search/method/unihan/JyutpingInputMethod.java | 76 ++++ .../search/method/unihan/PinyinInputMethod.java | 135 ++++++ .../search/method/unihan/UniHanInputMethod.java | 82 ++++ .../client/search/method/unihan/UniHanManager.java | 123 ++++++ .../impl/client/subsets/SubsetsRegistryImpl.java | 6 - .../settings/EntrySettingsAdapterRegistryImpl.java | 3 - .../common/entry/type/PreFilteredEntryList.java | 8 +- .../entry/type/types/EmptyEntryDefinition.java | 1 - .../rei/impl/common/logging/FilteringLogger.java | 8 - .../autocrafting/DefaultCategoryHandler.java | 3 - .../plugin/client/DefaultClientRuntimePlugin.java | 18 +- .../rei/plugin/client/InputMethodWatcher.java | 105 +++++ .../plugin/client/PluginStageExecutionWatcher.java | 5 + .../plugin/client/SearchBarHighlightWatcher.java | 5 + .../plugin/client/SearchFilterPrepareWatcher.java | 5 + .../plugin/client/entry/ItemEntryDefinition.java | 1 - 79 files changed, 2425 insertions(+), 814 deletions(-) create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/InternalTextures.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/MenuAccess.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/MenuHolder.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/ConfigButtonWidget.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/CraftableFilterButtonWidget.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryHighlighter.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/IndexSet.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/InputMethodMatcher.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/DefaultInputMethod.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/InputMethodRegistryImpl.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/unihan/BomopofoInputMethod.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/unihan/JyutpingInputMethod.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/unihan/PinyinInputMethod.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/unihan/UniHanInputMethod.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/search/method/unihan/UniHanManager.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/plugin/client/InputMethodWatcher.java (limited to 'runtime/src/main/java') diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java index 7e1a92728..de01c37f2 100644 --- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java +++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java @@ -74,6 +74,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.method.InputMethodRegistryImpl; import me.shedaniel.rei.impl.client.subsets.SubsetsRegistryImpl; import me.shedaniel.rei.impl.client.transfer.TransferHandlerRegistryImpl; import me.shedaniel.rei.impl.client.view.ViewsImpl; @@ -226,6 +227,7 @@ public class RoughlyEnoughItemsCoreClient { }, new EntryRendererRegistryImpl(), new ViewsImpl(), + new InputMethodRegistryImpl(), new SearchProviderImpl(), new ConfigManagerImpl(), new EntryRegistryImpl(), diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsNetwork.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsNetwork.java index 6a32815b1..911cfe429 100644 --- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsNetwork.java +++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsNetwork.java @@ -30,7 +30,6 @@ import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.display.Display; import me.shedaniel.rei.impl.common.transfer.InputSlotCrafter; import net.minecraft.ChatFormatting; -import net.minecraft.Util; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java index f46bd01a7..f98d8888d 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java @@ -79,6 +79,7 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.nbt.TagParser; import net.minecraft.network.chat.*; +import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import net.minecraft.world.InteractionResult; import org.jetbrains.annotations.ApiStatus; @@ -135,6 +136,14 @@ public class ConfigManagerImpl implements ConfigManager { } private static Jankson buildJankson(Jankson.Builder builder) { + // ResourceLocation + builder.registerSerializer(ResourceLocation.class, (location, marshaller) -> { + return new JsonPrimitive(location == null ? null : location.toString()); + }); + builder.registerDeserializer(String.class, ResourceLocation.class, (value, marshaller) -> { + return value == null ? null : new ResourceLocation(value); + }); + // CheatingMode builder.registerSerializer(CheatingMode.class, (value, marshaller) -> { if (value == CheatingMode.WHEN_CREATIVE) { @@ -359,12 +368,12 @@ public class ConfigManagerImpl implements ConfigManager { if (Minecraft.getInstance().getConnection() != null && Minecraft.getInstance().getConnection().getRecipeManager() != null) { TextListEntry feedbackEntry = ConfigEntryBuilder.create().startTextDescription( new TranslatableComponent("text.rei.feedback", new TranslatableComponent("text.rei.feedback.link") - .withStyle(style -> style - .withColor(TextColor.fromRgb(0xff1fc3ff)) - .withUnderlined(true) - .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://forms.gle/5tdnK5WN1wng78pV8")) + .withStyle(style -> style + .withColor(TextColor.fromRgb(0xff1fc3ff)) + .withUnderlined(true) + .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://forms.gle/5tdnK5WN1wng78pV8")) .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ImmutableTextComponent("https://forms.gle/5tdnK5WN1wng78pV8"))) - )) + )) .withStyle(ChatFormatting.GRAY) ).build(); builder.getOrCreateCategory(new TranslatableComponent("config.roughlyenoughitems.advanced")).getEntries().add(0, feedbackEntry); @@ -383,18 +392,18 @@ public class ConfigManagerImpl implements ConfigManager { TextListEntry supportText = ConfigEntryBuilder.create().startTextDescription( new TranslatableComponent("text.rei.support.me.desc", new TranslatableComponent("text.rei.support.me.patreon") - .withStyle(style -> style - .withColor(TextColor.fromRgb(0xff1fc3ff)) - .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://patreon.com/shedaniel")) + .withStyle(style -> style + .withColor(TextColor.fromRgb(0xff1fc3ff)) + .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://patreon.com/shedaniel")) .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ImmutableTextComponent("https://patreon.com/shedaniel"))) - ), + ), new TranslatableComponent("text.rei.support.me.bisect") - .withStyle(style -> style - .withColor(TextColor.fromRgb(0xff1fc3ff)) - .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.bisecthosting.com/shedaniel")) + .withStyle(style -> style + .withColor(TextColor.fromRgb(0xff1fc3ff)) + .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.bisecthosting.com/shedaniel")) .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ImmutableTextComponent("https://www.bisecthosting.com/shedaniel"))) - ) - ) + ) + ) .withStyle(ChatFormatting.GRAY) ).build(); supportText.setScreen((AbstractConfigScreen) screen); 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 2617a480a..cb92ee97a 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 @@ -43,9 +43,11 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import net.minecraft.world.level.GameType; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -209,6 +211,16 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { return advanced.layout.maxRecipesPageHeight; } + @Override + @Nullable + public ResourceLocation getInputMethodId() { + return functionality.inputMethod; + } + + public void setInputMethodId(@Nullable ResourceLocation id) { + functionality.inputMethod = id; + } + @Override public boolean doesDisableRecipeBook() { return functionality.disableRecipeBook; @@ -599,6 +611,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { } public static class Functionality { + @ConfigEntry.Gui.Excluded @Nullable private ResourceLocation inputMethod = null; @Comment("Declares whether REI should remove the recipe book.") private boolean disableRecipeBook = false; @Comment("Declares whether subsets is enabled.") private boolean isSubsetsEnabled = false; private boolean allowInventoryHighlighting = true; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/addon/ConfigAddonsScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/addon/ConfigAddonsScreen.java index 0773483e9..9b0335d73 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/addon/ConfigAddonsScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/addon/ConfigAddonsScreen.java @@ -28,6 +28,7 @@ import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget; import me.shedaniel.rei.api.client.config.addon.ConfigAddon; import me.shedaniel.rei.api.client.config.addon.ConfigAddonRegistry; +import me.shedaniel.rei.impl.client.gui.InternalTextures; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.events.GuiEventListener; @@ -44,8 +45,6 @@ import java.util.Collections; import java.util.List; import java.util.Objects; -import static me.shedaniel.rei.impl.client.gui.screen.DefaultDisplayViewingScreen.CHEST_GUI_TEXTURE; - public class ConfigAddonsScreen extends Screen { private AddonsList rulesList; private final Screen parent; @@ -146,7 +145,7 @@ public class ConfigAddonsScreen extends Screen { @Override protected void renderBg(PoseStack matrices, Minecraft client, int mouseX, int mouseY) { super.renderBg(matrices, client, mouseX, mouseY); - RenderSystem.setShaderTexture(0, CHEST_GUI_TEXTURE); + RenderSystem.setShaderTexture(0, InternalTextures.CHEST_GUI_TEXTURE); blit(matrices, x + 3, y + 3, 0, 0, 14, 14); } }; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java index 25e87a85e..ef439a005 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java @@ -27,6 +27,7 @@ import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget; import me.shedaniel.rei.impl.client.entry.filtering.FilteringRule; import me.shedaniel.rei.impl.client.entry.filtering.rules.ManualFilteringRule; +import me.shedaniel.rei.impl.client.gui.InternalTextures; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.events.GuiEventListener; @@ -45,8 +46,6 @@ import java.util.List; import java.util.Objects; import java.util.function.BiFunction; -import static me.shedaniel.rei.impl.client.gui.screen.DefaultDisplayViewingScreen.CHEST_GUI_TEXTURE; - public class FilteringRulesScreen extends Screen { private final FilteringEntry entry; private RulesList rulesList; @@ -191,7 +190,7 @@ public class FilteringRulesScreen extends Screen { @Override protected void renderBg(PoseStack matrices, Minecraft client, int mouseX, int mouseY) { super.renderBg(matrices, client, mouseX, mouseY); - Minecraft.getInstance().getTextureManager().bind(CHEST_GUI_TEXTURE); + Minecraft.getInstance().getTextureManager().bind(InternalTextures.CHEST_GUI_TEXTURE); blit(matrices, x + 3, y + 3, 0, 0, 14, 14); } }; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java index 67a1eacd5..e133eaeee 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java @@ -56,7 +56,7 @@ public class ReloadPluginsEntry extends AbstractConfigListEntry { public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { if (PluginManager.areAnyReloading()) { Screen screen = Minecraft.getInstance().screen; - Minecraft.getInstance().setScreen(new ConfigReloadingScreen(() -> Minecraft.getInstance().setScreen(screen))); + Minecraft.getInstance().setScreen(new ConfigReloadingScreen(Component.translatable("text.rei.config.is.reloading"), PluginManager::areAnyReloading, () -> Minecraft.getInstance().setScreen(screen))); } else { super.render(matrices, mouseX, mouseY, delta); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/SearchFilterSyntaxHighlightingEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/SearchFilterSyntaxHighlightingEntry.java index 0b736b38d..5f3980281 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/SearchFilterSyntaxHighlightingEntry.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/SearchFilterSyntaxHighlightingEntry.java @@ -45,7 +45,9 @@ public class SearchFilterSyntaxHighlightingEntry extends TooltipListEntry save; - private final AbstractWidget buttonWidget = new Button(0, 0, 0, 20, NarratorChatListener.NO_TITLE, $ -> {}) { + private final AbstractWidget buttonWidget = new Button(0, 0, 0, 20, NarratorChatListener.NO_TITLE, $ -> { + type = SyntaxHighlightingMode.values()[(type.ordinal() + 1) % SyntaxHighlightingMode.values().length]; + }) { @Override public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { setMessage(new TextComponent(type.toString())); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/type/types/RenderingEntryDefinition.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/type/types/RenderingEntryDefinition.java index bf38add70..a58b2ead0 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/type/types/RenderingEntryDefinition.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/type/types/RenderingEntryDefinition.java @@ -24,9 +24,7 @@ package me.shedaniel.rei.impl.client.entry.type.types; 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.entry.renderer.EntryRenderer; import me.shedaniel.rei.api.client.entry.type.BuiltinClientEntryTypes; import me.shedaniel.rei.api.client.gui.Renderer; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/FavoriteEntryTypeRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/FavoriteEntryTypeRegistryImpl.java index 1ae064940..47996d9d3 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/FavoriteEntryTypeRegistryImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/FavoriteEntryTypeRegistryImpl.java @@ -44,7 +44,6 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/InternalTextures.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/InternalTextures.java new file mode 100644 index 000000000..4823008b6 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/InternalTextures.java @@ -0,0 +1,35 @@ +/* + * 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; + +import net.minecraft.resources.ResourceLocation; + +public class InternalTextures { + public static final ResourceLocation ARROW_LEFT_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/arrow_left.png"); + public static final ResourceLocation ARROW_RIGHT_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/arrow_right.png"); + public static final ResourceLocation ARROW_LEFT_SMALL_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/arrow_left_small.png"); + public static final ResourceLocation ARROW_RIGHT_SMALL_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/arrow_right_small.png"); + public static final ResourceLocation CHEST_GUI_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/recipecontainer.png"); + public static final ResourceLocation CHEST_GUI_TEXTURE_DARK = new ResourceLocation("roughlyenoughitems", "textures/gui/recipecontainer_dark.png"); +} 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 7041b6a1a..57fc72fd5 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 @@ -27,27 +27,21 @@ 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 com.mojang.math.Vector4f; import dev.architectury.injectables.annotations.ExpectPlatform; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; -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.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.config.SyntaxHighlightingMode; 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.screen.DisplayScreen; -import me.shedaniel.rei.api.client.gui.widgets.Button; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import me.shedaniel.rei.api.client.gui.widgets.Widget; -import me.shedaniel.rei.api.client.gui.widgets.Widgets; 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; @@ -56,93 +50,65 @@ 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.api.common.util.EntryStacks; -import me.shedaniel.rei.impl.client.ClientHelperImpl; import me.shedaniel.rei.impl.client.REIRuntimeImpl; -import me.shedaniel.rei.impl.client.config.ConfigManagerImpl; -import me.shedaniel.rei.impl.client.config.ConfigObjectImpl; -import me.shedaniel.rei.impl.client.gui.changelog.ChangelogLoader; import me.shedaniel.rei.impl.client.gui.craftable.CraftableFilter; import me.shedaniel.rei.impl.client.gui.dragging.CurrentDraggingStack; -import me.shedaniel.rei.impl.client.gui.modules.Menu; -import me.shedaniel.rei.impl.client.gui.modules.MenuEntry; -import me.shedaniel.rei.impl.client.gui.modules.entries.*; -import me.shedaniel.rei.impl.client.gui.widget.DefaultDisplayChoosePageWidget; -import me.shedaniel.rei.impl.client.gui.widget.InternalWidgets; -import me.shedaniel.rei.impl.client.gui.widget.LateRenderable; -import me.shedaniel.rei.impl.client.gui.widget.entrylist.EntryListSearchManager; +import me.shedaniel.rei.impl.client.gui.modules.MenuAccess; +import me.shedaniel.rei.impl.client.gui.modules.MenuHolder; +import me.shedaniel.rei.impl.client.gui.widget.*; 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; import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesListWidget; import me.shedaniel.rei.impl.client.gui.widget.search.OverlaySearchField; -import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.chat.NarratorChatListener; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; -import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.InteractionResult; -import net.minecraft.world.inventory.Slot; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.Blocks; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; -import java.util.*; -import java.util.function.Consumer; -import java.util.function.Predicate; +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 class ScreenOverlayImpl extends ScreenOverlay { - private static final ResourceLocation CHEST_GUI_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/recipecontainer.png"); - public static final ResourceLocation ARROW_LEFT_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/arrow_left.png"); - public static final ResourceLocation ARROW_RIGHT_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/arrow_right.png"); - public static final ResourceLocation ARROW_LEFT_SMALL_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/arrow_left_small.png"); - public static final ResourceLocation ARROW_RIGHT_SMALL_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/arrow_right_small.png"); private static final List TOOLTIPS = Lists.newArrayList(); - private static final List AFTER_RENDER = Lists.newArrayList(); private static EntryListWidget entryListWidget = null; private static FavoritesListWidget favoritesListWidget = null; private final List widgets = Lists.newLinkedList(); public boolean shouldReload = false; public boolean shouldReloadSearch = false; - private Rectangle screenBounds; private Rectangle bounds; private Window window; - private Button leftButton, rightButton; private Widget configButton; private CurrentDraggingStack draggingStack = new CurrentDraggingStack(); @Nullable public DefaultDisplayChoosePageWidget choosePageWidget; - - @Nullable - private ScreenOverlayImpl.OverlayMenu overlayMenu = null; - + private MenuHolder menuHolder = new MenuHolder(); public static EntryListWidget getEntryListWidget() { + boolean widgetScrolled = ConfigObject.getInstance().isEntryListWidgetScrolled(); + if (entryListWidget != null) { - if (ConfigObject.getInstance().isEntryListWidgetScrolled() && entryListWidget instanceof ScrolledEntryListWidget) { + if (widgetScrolled && entryListWidget instanceof ScrolledEntryListWidget) { return entryListWidget; - } else if (!ConfigObject.getInstance().isEntryListWidgetScrolled() && entryListWidget instanceof PaginatedEntryListWidget) { + } else if (!widgetScrolled && entryListWidget instanceof PaginatedEntryListWidget) { return entryListWidget; } } - if (ConfigObject.getInstance().isEntryListWidgetScrolled()) { - entryListWidget = new ScrolledEntryListWidget(); - } else if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) { - entryListWidget = new PaginatedEntryListWidget(); - } + entryListWidget = widgetScrolled ? new ScrolledEntryListWidget() : new PaginatedEntryListWidget(); - Rectangle overlayBounds = ScreenOverlayImpl.getInstance().bounds; + ScreenOverlayImpl overlay = ScreenOverlayImpl.getInstance(); + Rectangle overlayBounds = overlay.bounds; entryListWidget.updateArea(Objects.requireNonNullElse(overlayBounds, new Rectangle()), REIRuntimeImpl.getSearchField() == null ? "" : REIRuntimeImpl.getSearchField().getText()); entryListWidget.updateEntriesPosition(); @@ -167,67 +133,12 @@ public class ScreenOverlayImpl extends ScreenOverlay { } } - private static class OverlayMenu { - private UUID uuid; - private Menu menu; - private Widget wrappedMenu; - private Predicate inBounds; - - public OverlayMenu(UUID uuid, Menu menu, Widget wrappedMenu, Predicate or, Predicate and) { - this.uuid = uuid; - this.menu = menu; - this.wrappedMenu = wrappedMenu; - this.inBounds = or.or(menu::containsMouse).and(and); - } - } - - public boolean isMenuOpened(UUID uuid) { - return overlayMenu != null && overlayMenu.uuid.equals(uuid); - } - - public boolean isAnyMenuOpened() { - return overlayMenu != null; - } - - public boolean isMenuInBounds(UUID uuid) { - return isMenuOpened(uuid) && overlayMenu.inBounds.test(PointHelper.ofMouse()); - } - - private void proceedOpenMenu(UUID uuid, Runnable runnable) { - proceedOpenMenuOrElse(uuid, runnable, menu -> {}); - } - - private void proceedOpenMenuOrElse(UUID uuid, Runnable runnable, Consumer orElse) { - if (overlayMenu == null || !overlayMenu.uuid.equals(uuid)) { - closeOverlayMenu(); - runnable.run(); - } else { - orElse.accept(this.overlayMenu); - } - } - - public void openMenu(UUID uuid, Menu menu) { - openMenu(uuid, menu, point -> false, point -> true); - } - - public void openMenu(UUID uuid, Menu menu, Predicate or, Predicate and) { - this.overlayMenu = new OverlayMenu(uuid, menu, Widgets.withTranslate(menu, 0, 0, 400), or, and); - } - - @ApiStatus.Internal - @Override - public void closeOverlayMenu() { - OverlayMenu tmpOverlayMenu = this.overlayMenu; - if (tmpOverlayMenu != null) - AFTER_RENDER.add(() -> this.widgets.remove(tmpOverlayMenu.wrappedMenu)); - this.overlayMenu = null; - } - @Override public void queueReloadOverlay() { shouldReload = true; } + @Override public void queueReloadSearch() { shouldReloadSearch = true; } @@ -242,248 +153,39 @@ public class ScreenOverlayImpl extends ScreenOverlay { } public void init() { - draggingStack.set(DraggableComponentProvider.from(ScreenRegistry.getInstance()::getDraggableComponentProviders), + this.draggingStack.set(DraggableComponentProvider.from(ScreenRegistry.getInstance()::getDraggableComponentProviders), DraggableComponentVisitor.from(ScreenRegistry.getInstance()::getDraggableComponentVisitors)); this.shouldReload = false; this.shouldReloadSearch = false; - //Update Variables this.children().clear(); this.window = Minecraft.getInstance().getWindow(); - this.screenBounds = ScreenRegistry.getInstance().getScreenBounds(Minecraft.getInstance().screen); this.bounds = calculateOverlayBounds(); + if (ConfigObject.getInstance().isFavoritesEnabled()) { if (favoritesListWidget == null) { favoritesListWidget = new FavoritesListWidget(); } favoritesListWidget.favoritePanel.resetRows(); - widgets.add(favoritesListWidget); - } - getEntryListWidget().updateArea(this.bounds, REIRuntimeImpl.getSearchField() == null ? "" : REIRuntimeImpl.getSearchField().getText()); - widgets.add(getEntryListWidget()); - REIRuntimeImpl.getSearchField().getBounds().setBounds(getSearchFieldArea()); - this.widgets.add(REIRuntimeImpl.getSearchField()); - REIRuntimeImpl.getSearchField().setResponder(s -> getEntryListWidget().updateSearch(s, false)); - if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) { - widgets.add(leftButton = Widgets.createButton(new Rectangle(bounds.x, bounds.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 5, 16, 16), new TextComponent("")) - .onClick(button -> { - getEntryListWidget().previousPage(); - if (getEntryListWidget().getPage() < 0) - getEntryListWidget().setPage(getEntryListWidget().getTotalPages() - 1); - getEntryListWidget().updateEntriesPosition(); - }) - .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y)) - .tooltipLine(new TranslatableComponent("text.rei.previous_page")) - .focusable(false)); - widgets.add(Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { - helper.setBlitOffset(helper.getBlitOffset() + 1); - RenderSystem.setShaderTexture(0, ARROW_LEFT_TEXTURE); - Rectangle bounds = leftButton.getBounds(); - matrices.pushPose(); - blit(matrices, bounds.x + 4, bounds.y + 4, 0, 0, 8, 8, 8, 8); - matrices.popPose(); - helper.setBlitOffset(helper.getBlitOffset() - 1); - })); - Button changelogButton; - widgets.add(changelogButton = Widgets.createButton(new Rectangle(bounds.x + bounds.width - 18 - 18, bounds.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 5, 16, 16), new TextComponent("")) - .onClick(button -> { - ChangelogLoader.show(); - }) - .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y)) - .tooltipLine(new TranslatableComponent("text.rei.changelog.title")) - .focusable(false)); - widgets.add(Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { - helper.setBlitOffset(helper.getBlitOffset() + 1); - Minecraft.getInstance().getTextureManager().bind(CHEST_GUI_TEXTURE); - Rectangle bounds = changelogButton.getBounds(); - matrices.pushPose(); - matrices.translate(0.5f, 0, 0); - helper.blit(matrices, bounds.x + 1, bounds.y + 2, !ChangelogLoader.hasVisited() ? 28 : 14, 0, 14, 14); - matrices.popPose(); - helper.setBlitOffset(helper.getBlitOffset() - 1); - })); - widgets.add(rightButton = Widgets.createButton(new Rectangle(bounds.x + bounds.width - 18, bounds.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 5, 16, 16), new TextComponent("")) - .onClick(button -> { - getEntryListWidget().nextPage(); - if (getEntryListWidget().getPage() >= getEntryListWidget().getTotalPages()) - getEntryListWidget().setPage(0); - getEntryListWidget().updateEntriesPosition(); - }) - .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y)) - .tooltipLine(new TranslatableComponent("text.rei.next_page")) - .focusable(false)); - widgets.add(Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { - helper.setBlitOffset(helper.getBlitOffset() + 1); - RenderSystem.setShaderTexture(0, ARROW_RIGHT_TEXTURE); - Rectangle bounds = rightButton.getBounds(); - matrices.pushPose(); - blit(matrices, bounds.x + 4, bounds.y + 4, 0, 0, 8, 8, 8, 8); - matrices.popPose(); - helper.setBlitOffset(helper.getBlitOffset() - 1); - })); + this.widgets.add(favoritesListWidget); } - final Rectangle configButtonArea = getConfigButtonArea(); - UUID configButtonUuid = UUID.fromString("4357bc36-0a4e-47d2-8e07-ddc220df4a0f"); - widgets.add(configButton = InternalWidgets.wrapLateRenderable( - - InternalWidgets.concatWidgets( - Widgets.createButton(configButtonArea, 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) && ClientHelperImpl.getInstance().hasOperatorPermission()) { - button.setTint(ClientHelperImpl.getInstance().hasPermissionToUsePackets() ? 721354752 : 1476440063); - } else { - button.removeTint(); - } - - boolean isOpened = isMenuOpened(configButtonUuid); - if (isOpened || !isAnyMenuOpened()) { - boolean inBounds = (isNotInExclusionZones(PointHelper.getMouseFloatingX(), PointHelper.getMouseFloatingY()) && button.containsMouse(PointHelper.ofMouse())) || isMenuInBounds(configButtonUuid); - if (isOpened != inBounds) { - if (inBounds) { - Menu menu = new Menu(button.getBounds(), provideConfigButtonMenu(), false); - openMenu(configButtonUuid, menu, button::containsMouse, point -> true); - } else { - closeOverlayMenu(); - } - } - } - }) - .focusable(false) - .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y)), - Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { - helper.setBlitOffset(helper.getBlitOffset() + 1); - Minecraft.getInstance().getTextureManager().bind(CHEST_GUI_TEXTURE); - helper.blit(matrices, configButtonArea.x + 3, configButtonArea.y + 3, 0, 0, 14, 14); - helper.setBlitOffset(helper.getBlitOffset() - 1); - }) - ) - )); - if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) { - widgets.add(Widgets.createClickableLabel(new Point(bounds.x + ((bounds.width - 18) / 2), bounds.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 10), NarratorChatListener.NO_TITLE, label -> { - if (!Screen.hasShiftDown()) { - getEntryListWidget().setPage(0); - getEntryListWidget().updateEntriesPosition(); - } else { - ScreenOverlayImpl.getInstance().choosePageWidget = new DefaultDisplayChoosePageWidget(page -> { - getEntryListWidget().setPage(page); - getEntryListWidget().updateEntriesPosition(); - }, getEntryListWidget().getPage(), getEntryListWidget().getTotalPages()); - } - }).tooltip(new TranslatableComponent("text.rei.go_back_first_page"), new TextComponent(" "), new TranslatableComponent("text.rei.shift_click_to", new TranslatableComponent("text.rei.choose_page")).withStyle(ChatFormatting.GRAY)).focusable(false).onRender((matrices, label) -> { - label.setClickable(getEntryListWidget().getTotalPages() > 1); - label.setMessage(new TextComponent(String.format("%s/%s", getEntryListWidget().getPage() + 1, Math.max(getEntryListWidget().getTotalPages(), 1)))); - }).rainbow(new Random().nextFloat() < 1.0E-4D || ClientHelperImpl.getInstance().isAprilFools.get())); - } + OverlaySearchField searchField = REIRuntimeImpl.getSearchField(); + searchField.getBounds().setBounds(getSearchFieldArea()); + this.widgets.add(searchField); + + EntryListWidget entryListWidget = getEntryListWidget(); + entryListWidget.updateArea(this.bounds, searchField.getText()); + this.widgets.add(entryListWidget); + searchField.setResponder(s -> entryListWidget.updateSearch(s, false)); + entryListWidget.init(this); + + this.widgets.add(configButton = ConfigButtonWidget.create(this)); if (ConfigObject.getInstance().isCraftableFilterEnabled()) { - Rectangle area = getCraftableToggleArea(); - ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); - ItemStack icon = new ItemStack(Blocks.CRAFTING_TABLE); - this.widgets.add(InternalWidgets.wrapLateRenderable(InternalWidgets.concatWidgets( - Widgets.createButton(area, NarratorChatListener.NO_TITLE) - .focusable(false) - .onClick(button -> { - ConfigManager.getInstance().toggleCraftableOnly(); - getEntryListWidget().updateSearch(REIRuntimeImpl.getSearchField().getText(), true); - }) - .onRender((matrices, button) -> button.setTint(ConfigManager.getInstance().isCraftableOnlyEnabled() ? 939579655 : 956235776)) - .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y)) - .tooltipLineSupplier(button -> new TranslatableComponent(ConfigManager.getInstance().isCraftableOnlyEnabled() ? "text.rei.showing_craftable" : "text.rei.showing_all")), - Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { - Vector4f vector = new Vector4f(area.x + 2, area.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; - })) - )); + this.widgets.add(CraftableFilterButtonWidget.create(this)); } - widgets.add(draggingStack); - } - - private Collection provideConfigButtonMenu() { - ConfigObjectImpl config = ConfigManagerImpl.getInstance().getConfig(); - return Arrays.asList( - 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 (!ClientHelperImpl.getInstance().hasOperatorPermission()) { - if (minecraft.gameMode.hasInfiniteItems()) - return new TranslatableComponent("text.rei.cheating_limited_creative_enabled"); - else return new TranslatableComponent("text.rei.cheating_enabled_no_perms"); - } else if (ClientHelperImpl.getInstance().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 -> { - config.setUsingDarkTheme(dark); - return false; - } - ), - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.craftable_filter"), - config::isCraftableFilterEnabled, - config::setCraftableFilterEnabled - ), - new SubMenuEntry(new TranslatableComponent("text.rei.config.menu.display"), Arrays.asList( - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.remove_recipe_book"), - config::doesDisableRecipeBook, - disableRecipeBook -> { - config.setDisableRecipeBook(disableRecipeBook); - Screen screen = Minecraft.getInstance().screen; - - if (screen != null) { - screen.init(minecraft, screen.width, screen.height); - } - } - ), - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.left_side_panel"), - config::isLeftHandSidePanel, - bool -> config.setDisplayPanelLocation(bool ? DisplayPanelLocation.LEFT : DisplayPanelLocation.RIGHT) - ), - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.scrolling_side_panel"), - config::isEntryListWidgetScrolled, - config::setEntryListWidgetScrolled - ), - new SeparatorMenuEntry(), - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.caching_entry_rendering"), - config::doesCacheEntryRendering, - config::setDoesCacheEntryRendering - ), - new SeparatorMenuEntry(), - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.side_search_field"), - () -> config.getSearchFieldLocation() != SearchFieldLocation.CENTER, - bool -> config.setSearchFieldLocation(bool ? SearchFieldLocation.BOTTOM_SIDE : SearchFieldLocation.CENTER) - ), - ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.syntax_highlighting"), - () -> config.getSyntaxHighlightingMode() == SyntaxHighlightingMode.COLORFUL || config.getSyntaxHighlightingMode() == SyntaxHighlightingMode.COLORFUL_UNDERSCORED, - bool -> config.setSyntaxHighlightingMode(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; - }) - ); + this.widgets.add(draggingStack); } private Rectangle getSearchFieldArea() { @@ -508,28 +210,7 @@ public class ScreenOverlayImpl extends ScreenOverlay { private Rectangle getCenterSearchFieldArea(int widthRemoved) { Rectangle screenBounds = ScreenRegistry.getInstance().getScreenBounds(minecraft.screen); - return getBottomCenterSearchFieldArea(screenBounds, widthRemoved); - } - - private Rectangle getBottomCenterSearchFieldArea(Rectangle containerBounds, int widthRemoved) { - return new Rectangle(containerBounds.x, window.getGuiScaledHeight() - 22, containerBounds.width - widthRemoved, 18); - } - - private Rectangle getCraftableToggleArea() { - Rectangle area = getSearchFieldArea(); - area.setLocation(area.x + area.width + 4, area.y - 1); - area.setSize(20, 20); - return area; - } - - private Rectangle getConfigButtonArea() { - if (ConfigObject.getInstance().isLowerConfigButton()) { - Rectangle area = getSearchFieldArea(); - area.setLocation(area.x + area.width + (ConfigObject.getInstance().isCraftableFilterEnabled() ? 26 : 4), area.y - 1); - area.setSize(20, 20); - return area; - } - return new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getGuiScaledWidth() - 30 : 10, 10, 20, 20); + return new Rectangle(screenBounds.x, window.getGuiScaledHeight() - 22, screenBounds.width - widthRemoved, 18); } @Override @@ -537,10 +218,6 @@ public class ScreenOverlayImpl extends ScreenOverlay { return bounds; } - public Rectangle getScreenBounds() { - return screenBounds; - } - @Override public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { if (shouldReload || !calculateOverlayBounds().equals(bounds)) { @@ -559,33 +236,7 @@ public class ScreenOverlayImpl extends ScreenOverlay { getEntryListWidget().updateSearch(REIRuntimeImpl.getSearchField().getText(), true); } if (OverlaySearchField.isHighlighting) { - RenderSystem.disableDepthTest(); - RenderSystem.colorMask(true, true, true, false); - if (Minecraft.getInstance().screen instanceof AbstractContainerScreen) { - AbstractContainerScreen containerScreen = (AbstractContainerScreen) Minecraft.getInstance().screen; - int x = containerScreen.leftPos, y = containerScreen.topPos; - for (Slot slot : containerScreen.getMenu().slots) { - if (!slot.hasItem() || !EntryListSearchManager.INSTANCE.matches(EntryStacks.of(slot.getItem()))) { - matrices.pushPose(); - matrices.translate(0, 0, 500f); - fillGradient(matrices, x + slot.x, y + slot.y, x + slot.x + 16, y + slot.y + 16, 0xdc202020, 0xdc202020); - matrices.popPose(); - } else { - matrices.pushPose(); - matrices.translate(0, 0, 200f); - fillGradient(matrices, x + slot.x, y + slot.y, x + slot.x + 16, y + slot.y + 16, 0x345fff3b, 0x345fff3b); - - fillGradient(matrices, x + slot.x - 1, y + slot.y - 1, x + slot.x, y + slot.y + 16 + 1, 0xff5fff3b, 0xff5fff3b); - fillGradient(matrices, x + slot.x + 16, y + slot.y - 1, x + slot.x + 16 + 1, y + slot.y + 16 + 1, 0xff5fff3b, 0xff5fff3b); - fillGradient(matrices, x + slot.x - 1, y + slot.y - 1, x + slot.x + 16, y + slot.y, 0xff5fff3b, 0xff5fff3b); - fillGradient(matrices, x + slot.x - 1, y + slot.y + 16, x + slot.x + 16, y + slot.y + 16 + 1, 0xff5fff3b, 0xff5fff3b); - - matrices.popPose(); - } - } - } - RenderSystem.colorMask(true, true, true, true); - RenderSystem.enableDepthTest(); + EntryHighlighter.render(matrices); } if (!hasSpace()) return; RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); @@ -635,19 +286,13 @@ public class ScreenOverlayImpl extends ScreenOverlay { if (REIRuntime.getInstance().isOverlayVisible() && hasSpace()) { REIRuntimeImpl.getSearchField().laterRender(matrices, mouseX, mouseY, delta); for (Widget widget : widgets) { - if (widget instanceof LateRenderable && (overlayMenu == null || overlayMenu.wrappedMenu != widget)) + if (widget instanceof LateRenderable && widget != menuHolder.widget()) widget.render(matrices, mouseX, mouseY, delta); } - if (overlayMenu != null) { - if (!overlayMenu.inBounds.test(PointHelper.ofMouse())) { - closeOverlayMenu(); - } else { - if (overlayMenu.wrappedMenu.containsMouse(mouseX, mouseY)) { - TOOLTIPS.clear(); - } - overlayMenu.wrappedMenu.render(matrices, mouseX, mouseY, delta); - } - } + matrices.pushPose(); + matrices.translate(0, 0, 500); + menuHolder.lateRender(matrices, mouseX, mouseY, delta); + matrices.popPose(); if (choosePageWidget != null) { setBlitOffset(500); this.fillGradient(matrices, 0, 0, window.getGuiScaledWidth(), window.getGuiScaledHeight(), -1072689136, -804253680); @@ -662,10 +307,7 @@ public class ScreenOverlayImpl extends ScreenOverlay { } TOOLTIPS.clear(); if (REIRuntime.getInstance().isOverlayVisible()) { - for (Runnable runnable : AFTER_RENDER) { - runnable.run(); - } - AFTER_RENDER.clear(); + menuHolder.afterRender(); } } @@ -693,10 +335,6 @@ public class ScreenOverlayImpl extends ScreenOverlay { public void renderWidgets(PoseStack matrices, int mouseX, int mouseY, float delta) { if (!REIRuntime.getInstance().isOverlayVisible()) return; - if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) { - leftButton.setEnabled(getEntryListWidget().getTotalPages() > 1); - rightButton.setEnabled(getEntryListWidget().getTotalPages() > 1); - } for (Widget widget : widgets) { if (!(widget instanceof LateRenderable)) widget.render(matrices, mouseX, mouseY, delta); @@ -707,21 +345,10 @@ public class ScreenOverlayImpl extends ScreenOverlay { public boolean mouseScrolled(double mouseX, double mouseY, double amount) { if (!REIRuntime.getInstance().isOverlayVisible()) return false; - if (overlayMenu != null && overlayMenu.wrappedMenu.mouseScrolled(mouseX, mouseY, amount)) + if (menuHolder.mouseScrolled(mouseX, mouseY, amount)) + return true; + if (isInside(mouseX, mouseY) && getEntryListWidget().mouseScrolled(mouseX, mouseY, amount)) { return true; - if (isInside(PointHelper.ofMouse())) { - if (getEntryListWidget().mouseScrolled(mouseX, mouseY, amount)) { - return true; - } - if (!Screen.hasControlDown() && !ConfigObject.getInstance().isEntryListWidgetScrolled()) { - if (amount > 0 && leftButton.isEnabled()) - leftButton.onClick(); - else if (amount < 0 && rightButton.isEnabled()) - rightButton.onClick(); - else - return false; - return true; - } } if (isNotInExclusionZones(PointHelper.getMouseX(), PointHelper.getMouseY())) { if (favoritesListWidget != null && favoritesListWidget.mouseScrolled(mouseX, mouseY, amount)) @@ -729,7 +356,7 @@ public class ScreenOverlayImpl extends ScreenOverlay { } for (Widget widget : widgets) if (widget != getEntryListWidget() && (favoritesListWidget == null || widget != favoritesListWidget) - && (overlayMenu == null || widget != overlayMenu.wrappedMenu) + && widget != menuHolder.widget() && widget.mouseScrolled(mouseX, mouseY, amount)) return true; return false; @@ -852,10 +479,10 @@ public class ScreenOverlayImpl extends ScreenOverlay { return true; } } - if (visible && overlayMenu != null) { - if (overlayMenu.wrappedMenu.mouseClicked(mouseX, mouseY, button)) { - if (overlayMenu != null) this.setFocused(overlayMenu.wrappedMenu); - else this.setFocused(null); + if (visible) { + Widget menuWidget = menuHolder.widget(); + if (menuWidget != null && menuWidget.mouseClicked(mouseX, mouseY, button)) { + this.setFocused(menuWidget); if (button == 0) this.setDragging(true); REIRuntimeImpl.getSearchField().setFocused(false); @@ -873,7 +500,7 @@ public class ScreenOverlayImpl extends ScreenOverlay { return false; } for (GuiEventListener element : widgets) { - if (element != configButton && (overlayMenu == null || element != overlayMenu.wrappedMenu) && element.mouseClicked(mouseX, mouseY, button)) { +