diff --git a/Common/src/main/java/mezz/jei/common/gui/overlay/FilterTextSource.java b/Common/src/main/java/mezz/jei/common/filter/FilterTextSource.java similarity index 94% rename from Common/src/main/java/mezz/jei/common/gui/overlay/FilterTextSource.java rename to Common/src/main/java/mezz/jei/common/filter/FilterTextSource.java index c5c675155..e5810d304 100644 --- a/Common/src/main/java/mezz/jei/common/gui/overlay/FilterTextSource.java +++ b/Common/src/main/java/mezz/jei/common/filter/FilterTextSource.java @@ -1,4 +1,4 @@ -package mezz.jei.common.gui.overlay; +package mezz.jei.common.filter; import java.util.ArrayList; import java.util.List; diff --git a/Common/src/main/java/mezz/jei/common/gui/overlay/IFilterTextSource.java b/Common/src/main/java/mezz/jei/common/filter/IFilterTextSource.java similarity index 85% rename from Common/src/main/java/mezz/jei/common/gui/overlay/IFilterTextSource.java rename to Common/src/main/java/mezz/jei/common/filter/IFilterTextSource.java index 538a87376..a0c33ae47 100644 --- a/Common/src/main/java/mezz/jei/common/gui/overlay/IFilterTextSource.java +++ b/Common/src/main/java/mezz/jei/common/filter/IFilterTextSource.java @@ -1,4 +1,4 @@ -package mezz.jei.common.gui.overlay; +package mezz.jei.common.filter; public interface IFilterTextSource { String getFilterText(); diff --git a/Common/src/main/java/mezz/jei/common/filter/package-info.java b/Common/src/main/java/mezz/jei/common/filter/package-info.java new file mode 100644 index 000000000..741115d68 --- /dev/null +++ b/Common/src/main/java/mezz/jei/common/filter/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package mezz.jei.common.filter; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/Forge/src/main/java/mezz/jei/forge/events/GuiEventHandler.java b/Common/src/main/java/mezz/jei/common/gui/GuiEventHandler.java similarity index 50% rename from Forge/src/main/java/mezz/jei/forge/events/GuiEventHandler.java rename to Common/src/main/java/mezz/jei/common/gui/GuiEventHandler.java index 3643ddd5b..432d280d0 100644 --- a/Forge/src/main/java/mezz/jei/forge/events/GuiEventHandler.java +++ b/Common/src/main/java/mezz/jei/common/gui/GuiEventHandler.java @@ -1,22 +1,17 @@ -package mezz.jei.forge.events; +package mezz.jei.common.gui; import com.mojang.blaze3d.vertex.PoseStack; import mezz.jei.api.gui.handlers.IGuiClickableArea; -import mezz.jei.common.util.LimitedLogger; -import mezz.jei.common.gui.GuiScreenHelper; -import mezz.jei.common.gui.TooltipRenderer; import mezz.jei.common.gui.overlay.IngredientListOverlay; import mezz.jei.common.gui.overlay.bookmarks.LeftAreaDispatcher; import mezz.jei.common.input.MouseUtil; +import mezz.jei.common.platform.IPlatformScreenHelper; +import mezz.jei.common.platform.Services; +import mezz.jei.common.util.LimitedLogger; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.network.chat.TranslatableComponent; -import net.minecraftforge.client.event.ContainerScreenEvent; -import net.minecraftforge.client.event.ScreenEvent; -import net.minecraftforge.client.event.ScreenOpenEvent; -import net.minecraftforge.event.TickEvent; -import net.minecraftforge.eventbus.api.Event; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -43,31 +38,18 @@ public GuiEventHandler( this.ingredientListOverlay = ingredientListOverlay; } - public void register(RuntimeEventSubscriptions subscriptions) { - subscriptions.register(ScreenEvent.InitScreenEvent.Post.class, this::onGuiInit); - subscriptions.register(ScreenOpenEvent.class, this::onGuiOpen); - subscriptions.register(ScreenEvent.BackgroundDrawnEvent.class, this::onDrawBackgroundEventPost); - subscriptions.register(ContainerScreenEvent.DrawForeground.class, this::onDrawForegroundEvent); - subscriptions.register(ScreenEvent.DrawScreenEvent.Post.class, this::onDrawScreenEventPost); - subscriptions.register(TickEvent.ClientTickEvent.class, this::onClientTick); - subscriptions.register(ScreenEvent.PotionSizeEvent.class, this::onPotionSizeEvent); - } - - public void onGuiInit(ScreenEvent.InitScreenEvent.Post event) { - Screen screen = event.getScreen(); + public void onGuiInit(Screen screen) { ingredientListOverlay.updateScreen(screen, false); leftAreaDispatcher.updateScreen(screen, false); } - public void onGuiOpen(ScreenOpenEvent event) { - Screen screen = event.getScreen(); + public void onGuiOpen(Screen screen) { ingredientListOverlay.updateScreen(screen, false); leftAreaDispatcher.updateScreen(screen, false); } - public void onDrawBackgroundEventPost(ScreenEvent.BackgroundDrawnEvent event) { - Screen screen = event.getScreen(); - Minecraft minecraft = screen.getMinecraft(); + public void onDrawBackgroundPost(Screen screen, PoseStack poseStack) { + Minecraft minecraft = Minecraft.getInstance(); boolean exclusionAreasChanged = guiScreenHelper.updateGuiExclusionAreas(screen); ingredientListOverlay.updateScreen(screen, exclusionAreasChanged); leftAreaDispatcher.updateScreen(screen, exclusionAreasChanged); @@ -75,7 +57,6 @@ public void onDrawBackgroundEventPost(ScreenEvent.BackgroundDrawnEvent event) { drawnOnBackground = true; double mouseX = MouseUtil.getX(); double mouseY = MouseUtil.getY(); - PoseStack poseStack = event.getPoseStack(); ingredientListOverlay.drawScreen(minecraft, poseStack, (int) mouseX, (int) mouseY, minecraft.getFrameTime()); leftAreaDispatcher.drawScreen(minecraft, poseStack, (int) mouseX, (int) mouseY, minecraft.getFrameTime()); } @@ -83,16 +64,13 @@ public void onDrawBackgroundEventPost(ScreenEvent.BackgroundDrawnEvent event) { /** * Draws above most ContainerScreen elements, but below the tooltips. */ - public void onDrawForegroundEvent(ContainerScreenEvent.DrawForeground event) { - AbstractContainerScreen screen = event.getContainerScreen(); - Minecraft minecraft = screen.getMinecraft(); - ingredientListOverlay.drawOnForeground(minecraft, event.getPoseStack(), screen, event.getMouseX(), event.getMouseY()); + public void onDrawForeground(AbstractContainerScreen screen, PoseStack poseStack, int mouseX, int mouseY) { + Minecraft minecraft = Minecraft.getInstance(); + ingredientListOverlay.drawOnForeground(minecraft, poseStack, screen, mouseX, mouseY); } - public void onDrawScreenEventPost(ScreenEvent.DrawScreenEvent.Post event) { - Screen screen = event.getScreen(); - Minecraft minecraft = screen.getMinecraft(); - PoseStack poseStack = event.getPoseStack(); + public void onDrawScreenPost(Screen screen, PoseStack poseStack, int mouseX, int mouseY) { + Minecraft minecraft = Minecraft.getInstance(); ingredientListOverlay.updateScreen(screen, false); leftAreaDispatcher.updateScreen(screen, false); @@ -102,39 +80,34 @@ public void onDrawScreenEventPost(ScreenEvent.DrawScreenEvent.Post event) { String guiName = screen.getClass().getName(); missingBackgroundLogger.log(Level.WARN, guiName, "GUI did not draw the dark background layer behind itself, this may result in display issues: {}", guiName); } - ingredientListOverlay.drawScreen(minecraft, poseStack, event.getMouseX(), event.getMouseY(), minecraft.getFrameTime()); - leftAreaDispatcher.drawScreen(minecraft, poseStack, event.getMouseX(), event.getMouseY(), minecraft.getFrameTime()); + ingredientListOverlay.drawScreen(minecraft, poseStack, mouseX, mouseY, minecraft.getFrameTime()); + leftAreaDispatcher.drawScreen(minecraft, poseStack, mouseX, mouseY, minecraft.getFrameTime()); } drawnOnBackground = false; if (screen instanceof AbstractContainerScreen guiContainer) { - guiScreenHelper.getGuiClickableArea(guiContainer, event.getMouseX() - guiContainer.getGuiLeft(), event.getMouseY() - guiContainer.getGuiTop()) + IPlatformScreenHelper screenHelper = Services.PLATFORM.getScreenHelper(); + int guiLeft = screenHelper.getGuiLeft(guiContainer); + int guiTop = screenHelper.getGuiTop(guiContainer); + guiScreenHelper.getGuiClickableArea(guiContainer, mouseX - guiLeft, mouseY - guiTop) .map(IGuiClickableArea::getTooltipStrings) .ifPresent(tooltipStrings -> { if (tooltipStrings.isEmpty()) { tooltipStrings = List.of(new TranslatableComponent("jei.tooltip.show.recipes")); } - TooltipRenderer.drawHoveringText(poseStack, tooltipStrings, event.getMouseX(), event.getMouseY()); + TooltipRenderer.drawHoveringText(poseStack, tooltipStrings, mouseX, mouseY); }); } - ingredientListOverlay.drawTooltips(minecraft, poseStack, event.getMouseX(), event.getMouseY()); - leftAreaDispatcher.drawTooltips(minecraft, poseStack, event.getMouseX(), event.getMouseY()); + ingredientListOverlay.drawTooltips(minecraft, poseStack, mouseX, mouseY); + leftAreaDispatcher.drawTooltips(minecraft, poseStack, mouseX, mouseY); } - public void onClientTick(TickEvent.ClientTickEvent event) { - if (event.phase == TickEvent.Phase.END) { - return; - } - + public void onClientTick() { ingredientListOverlay.handleTick(); } - public void onPotionSizeEvent(ScreenEvent.PotionSizeEvent event) { - if (ingredientListOverlay.isListDisplayed()) { - // Forcibly renders the potion indicators in compact mode. - // This gives the ingredient list overlay more room to display ingredients. - event.setResult(Event.Result.ALLOW); - } + public boolean renderCompactPotionIndicators() { + return ingredientListOverlay.isListDisplayed(); } } diff --git a/Common/src/main/java/mezz/jei/common/gui/overlay/IngredientListOverlay.java b/Common/src/main/java/mezz/jei/common/gui/overlay/IngredientListOverlay.java index a3fb1d792..2b306ca27 100644 --- a/Common/src/main/java/mezz/jei/common/gui/overlay/IngredientListOverlay.java +++ b/Common/src/main/java/mezz/jei/common/gui/overlay/IngredientListOverlay.java @@ -5,6 +5,7 @@ import mezz.jei.api.ingredients.IIngredientType; import mezz.jei.api.ingredients.ITypedIngredient; import mezz.jei.api.runtime.IIngredientListOverlay; +import mezz.jei.common.filter.IFilterTextSource; import mezz.jei.common.gui.GuiProperties; import mezz.jei.common.gui.GuiScreenHelper; import mezz.jei.common.gui.elements.GuiIconToggleButton; diff --git a/Common/src/main/java/mezz/jei/common/ingredients/IngredientFilter.java b/Common/src/main/java/mezz/jei/common/ingredients/IngredientFilter.java index 81661d758..b795e80e5 100644 --- a/Common/src/main/java/mezz/jei/common/ingredients/IngredientFilter.java +++ b/Common/src/main/java/mezz/jei/common/ingredients/IngredientFilter.java @@ -11,7 +11,7 @@ import mezz.jei.core.config.IClientConfig; import mezz.jei.common.config.IIngredientFilterConfig; import mezz.jei.common.gui.ingredients.IListElement; -import mezz.jei.common.gui.overlay.IFilterTextSource; +import mezz.jei.common.filter.IFilterTextSource; import mezz.jei.common.gui.overlay.IIngredientGridSource; import mezz.jei.common.search.ElementSearch; import mezz.jei.common.search.ElementSearchLowMem; diff --git a/Common/src/main/java/mezz/jei/common/ingredients/IngredientFilterApi.java b/Common/src/main/java/mezz/jei/common/ingredients/IngredientFilterApi.java index 66deab315..caccded93 100644 --- a/Common/src/main/java/mezz/jei/common/ingredients/IngredientFilterApi.java +++ b/Common/src/main/java/mezz/jei/common/ingredients/IngredientFilterApi.java @@ -2,8 +2,7 @@ import mezz.jei.api.ingredients.IIngredientType; import mezz.jei.api.runtime.IIngredientFilter; -import mezz.jei.common.gui.overlay.IFilterTextSource; -import mezz.jei.common.ingredients.IngredientFilter; +import mezz.jei.common.filter.IFilterTextSource; import mezz.jei.common.util.ErrorUtil; import java.util.List; diff --git a/Common/src/main/java/mezz/jei/common/input/ClientInputHandler.java b/Common/src/main/java/mezz/jei/common/input/ClientInputHandler.java new file mode 100644 index 000000000..43dfe1a74 --- /dev/null +++ b/Common/src/main/java/mezz/jei/common/input/ClientInputHandler.java @@ -0,0 +1,104 @@ +package mezz.jei.common.input; + +import mezz.jei.common.input.handlers.CombinedInputHandler; +import mezz.jei.core.util.ReflectionUtil; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.screens.Screen; + +import java.util.List; + +public class ClientInputHandler { + private final List charTypedHandlers; + private final CombinedInputHandler inputHandler; + private final IKeyBindings keybindings; + private final ReflectionUtil reflectionUtil = new ReflectionUtil(); + + public ClientInputHandler(List charTypedHandlers, CombinedInputHandler inputHandler, IKeyBindings keybindings) { + this.charTypedHandlers = charTypedHandlers; + this.inputHandler = inputHandler; + this.keybindings = keybindings; + } + + public void onInitGui() { + this.inputHandler.handleGuiChange(); + } + + /** + * When we have keyboard focus, use Pre + */ + public boolean onKeyboardKeyPressedPre(Screen screen, UserInput input) { + if (!isContainerTextFieldFocused(screen)) { + return this.inputHandler.handleUserInput(screen, input, keybindings) + .isPresent(); + } + return false; + } + + /** + * Without keyboard focus, use Post + */ + public boolean onKeyboardKeyPressed(Screen screen, UserInput input) { + if (isContainerTextFieldFocused(screen)) { + return this.inputHandler.handleUserInput(screen, input, keybindings) + .isPresent(); + } + return false; + } + + /** + * When we have keyboard focus, use Pre + */ + public boolean onKeyboardCharTypedPre(Screen screen, char codePoint, int modifiers) { + if (!isContainerTextFieldFocused(screen)) { + return handleCharTyped(codePoint, modifiers); + } + return false; + } + + /** + * Without keyboard focus, use Post + */ + public boolean onKeyboardCharTypedPost(Screen screen, char codePoint, int modifiers) { + if (isContainerTextFieldFocused(screen)) { + return handleCharTyped(codePoint, modifiers); + } + return false; + } + + public boolean onGuiMouseClicked(Screen screen, UserInput input) { + boolean handled = this.inputHandler.handleUserInput(screen, input, keybindings) + .isPresent(); + + if (input.is(keybindings.getLeftClick())) { + handled |= this.inputHandler.handleDragStart(screen, input) + .isPresent(); + } + return handled; + } + + public boolean onGuiMouseReleased(Screen screen, UserInput input) { + boolean handled = this.inputHandler.handleUserInput(screen, input, keybindings) + .isPresent(); + + if (input.is(keybindings.getLeftClick())) { + handled |= this.inputHandler.handleDragComplete(screen, input) + .isPresent(); + } + return handled; + } + + public boolean onGuiMouseScroll(double mouseX, double mouseY, double scrollDelta) { + return this.inputHandler.handleMouseScrolled(mouseX, mouseY, scrollDelta); + } + + private boolean handleCharTyped(char codePoint, int modifiers) { + return this.charTypedHandlers.stream() + .filter(ICharTypedHandler::hasKeyboardFocus) + .anyMatch(handler -> handler.onCharTyped(codePoint, modifiers)); + } + + private boolean isContainerTextFieldFocused(Screen screen) { + return reflectionUtil.getFieldWithClass(screen, EditBox.class) + .anyMatch(textField -> textField.isActive() && textField.isFocused()); + } +} diff --git a/Common/src/main/java/mezz/jei/common/load/PluginLoader.java b/Common/src/main/java/mezz/jei/common/load/PluginLoader.java index 92aa772e6..b144d4384 100644 --- a/Common/src/main/java/mezz/jei/common/load/PluginLoader.java +++ b/Common/src/main/java/mezz/jei/common/load/PluginLoader.java @@ -19,7 +19,7 @@ import mezz.jei.common.gui.GuiHelper; import mezz.jei.common.gui.GuiScreenHelper; import mezz.jei.common.gui.ingredients.IListElement; -import mezz.jei.common.gui.overlay.IFilterTextSource; +import mezz.jei.common.filter.IFilterTextSource; import mezz.jei.common.ingredients.IngredientBlacklistInternal; import mezz.jei.common.ingredients.IngredientFilter; import mezz.jei.common.ingredients.IngredientListElementFactory; diff --git a/Common/src/main/java/mezz/jei/common/startup/OverlayHelper.java b/Common/src/main/java/mezz/jei/common/startup/OverlayHelper.java index a76e635c6..5a44af1a3 100644 --- a/Common/src/main/java/mezz/jei/common/startup/OverlayHelper.java +++ b/Common/src/main/java/mezz/jei/common/startup/OverlayHelper.java @@ -4,7 +4,7 @@ import mezz.jei.common.config.IIngredientGridConfig; import mezz.jei.common.gui.GuiScreenHelper; import mezz.jei.common.gui.elements.DrawableNineSliceTexture; -import mezz.jei.common.gui.overlay.IFilterTextSource; +import mezz.jei.common.filter.IFilterTextSource; import mezz.jei.common.gui.overlay.IIngredientGridSource; import mezz.jei.common.gui.overlay.IngredientGrid; import mezz.jei.common.gui.overlay.IngredientGridWithNavigation; diff --git a/Forge/src/main/java/mezz/jei/forge/events/EditModeToggleEvent.java b/Forge/src/main/java/mezz/jei/forge/events/EditModeToggleEvent.java deleted file mode 100644 index b2788a411..000000000 --- a/Forge/src/main/java/mezz/jei/forge/events/EditModeToggleEvent.java +++ /dev/null @@ -1,18 +0,0 @@ -package mezz.jei.forge.events; - -public class EditModeToggleEvent extends JeiEvent { - private final boolean editModeEnabled; - - @SuppressWarnings("unused") // needed for event bus - public EditModeToggleEvent() { - editModeEnabled = false; - } - - public EditModeToggleEvent(boolean editModeEnabled) { - this.editModeEnabled = editModeEnabled; - } - - public boolean isEditModeEnabled() { - return editModeEnabled; - } -} diff --git a/Forge/src/main/java/mezz/jei/forge/events/JeiEvent.java b/Forge/src/main/java/mezz/jei/forge/events/JeiEvent.java deleted file mode 100644 index b8481ec1a..000000000 --- a/Forge/src/main/java/mezz/jei/forge/events/JeiEvent.java +++ /dev/null @@ -1,6 +0,0 @@ -package mezz.jei.forge.events; - -import net.minecraftforge.eventbus.api.Event; - -public class JeiEvent extends Event { -} diff --git a/Forge/src/main/java/mezz/jei/forge/input/InputEventHandler.java b/Forge/src/main/java/mezz/jei/forge/input/InputEventHandler.java deleted file mode 100644 index 0d102f6f1..000000000 --- a/Forge/src/main/java/mezz/jei/forge/input/InputEventHandler.java +++ /dev/null @@ -1,137 +0,0 @@ -package mezz.jei.forge.input; - -import mezz.jei.common.input.ICharTypedHandler; -import mezz.jei.common.input.IKeyBindings; -import mezz.jei.common.input.UserInput; -import mezz.jei.core.util.ReflectionUtil; -import mezz.jei.forge.events.RuntimeEventSubscriptions; -import mezz.jei.common.input.handlers.CombinedInputHandler; -import net.minecraft.client.gui.components.EditBox; -import net.minecraft.client.gui.screens.Screen; -import net.minecraftforge.client.event.ScreenEvent; - -import java.util.List; - -public class InputEventHandler { - private final List charTypedHandlers; - private final CombinedInputHandler inputHandler; - private final IKeyBindings keybindings; - private final ReflectionUtil reflectionUtil = new ReflectionUtil(); - - public InputEventHandler(List charTypedHandlers, CombinedInputHandler inputHandler, IKeyBindings keybindings) { - this.charTypedHandlers = charTypedHandlers; - this.inputHandler = inputHandler; - this.keybindings = keybindings; - } - - public void register(RuntimeEventSubscriptions subscriptions) { - subscriptions.register(ScreenEvent.InitScreenEvent.class, this::onInitGuiEvent); - - subscriptions.register(ScreenEvent.KeyboardKeyPressedEvent.Pre.class, this::onKeyboardKeyPressedEvent); - subscriptions.register(ScreenEvent.KeyboardKeyPressedEvent.Post.class, this::onKeyboardKeyPressedEvent); - - subscriptions.register(ScreenEvent.KeyboardCharTypedEvent.Pre.class, this::onKeyboardCharTypedEvent); - subscriptions.register(ScreenEvent.KeyboardCharTypedEvent.Post.class, this::onKeyboardCharTypedEvent); - - subscriptions.register(ScreenEvent.MouseClickedEvent.Pre.class, this::onGuiMouseClickedEvent); - subscriptions.register(ScreenEvent.MouseReleasedEvent.Pre.class, this::onGuiMouseReleasedEvent); - - subscriptions.register(ScreenEvent.MouseScrollEvent.Pre.class, this::onGuiMouseScrollEvent); - } - - public void onInitGuiEvent(ScreenEvent.InitScreenEvent event) { - this.inputHandler.handleGuiChange(); - } - - /** - * When we have keyboard focus, use Pre - */ - public void onKeyboardKeyPressedEvent(ScreenEvent.KeyboardKeyPressedEvent.Pre event) { - Screen screen = event.getScreen(); - if (!isContainerTextFieldFocused(screen)) { - UserInput input = ForgeUserInput.fromEvent(event); - this.inputHandler.handleUserInput(screen, input, keybindings) - .ifPresent(handler -> event.setCanceled(true)); - } - } - - /** - * Without keyboard focus, use Post - */ - public void onKeyboardKeyPressedEvent(ScreenEvent.KeyboardKeyPressedEvent.Post event) { - Screen screen = event.getScreen(); - if (isContainerTextFieldFocused(screen)) { - UserInput input = ForgeUserInput.fromEvent(event); - this.inputHandler.handleUserInput(screen, input, keybindings) - .ifPresent(handler -> event.setCanceled(true)); - } - } - - /** - * When we have keyboard focus, use Pre - */ - public void onKeyboardCharTypedEvent(ScreenEvent.KeyboardCharTypedEvent.Pre event) { - if (!isContainerTextFieldFocused(event.getScreen())) { - if (handleCharTyped(event.getCodePoint(), event.getModifiers())) { - event.setCanceled(true); - } - } - } - - /** - * Without keyboard focus, use Post - */ - public void onKeyboardCharTypedEvent(ScreenEvent.KeyboardCharTypedEvent.Post event) { - if (isContainerTextFieldFocused(event.getScreen())) { - if (handleCharTyped(event.getCodePoint(), event.getModifiers())) { - event.setCanceled(true); - } - } - } - - public void onGuiMouseClickedEvent(ScreenEvent.MouseClickedEvent.Pre event) { - ForgeUserInput.fromEvent(event) - .ifPresent(input -> { - Screen screen = event.getScreen(); - this.inputHandler.handleUserInput(screen, input, keybindings) - .ifPresent(handled -> event.setCanceled(true)); - - if (input.is(keybindings.getLeftClick())) { - this.inputHandler.handleDragStart(screen, input) - .ifPresent(handled -> event.setCanceled(true)); - } - }); - } - - public void onGuiMouseReleasedEvent(ScreenEvent.MouseReleasedEvent.Pre event) { - ForgeUserInput.fromEvent(event) - .ifPresent(input -> { - Screen screen = event.getScreen(); - - this.inputHandler.handleUserInput(screen, input, keybindings) - .ifPresent(handled -> event.setCanceled(true)); - - if (input.is(keybindings.getLeftClick())) { - this.inputHandler.handleDragComplete(screen, input) - .ifPresent(handled -> event.setCanceled(true)); - } - }); - } - - public void onGuiMouseScrollEvent(ScreenEvent.MouseScrollEvent.Pre event) { - if (this.inputHandler.handleMouseScrolled(event.getMouseX(), event.getMouseY(), event.getScrollDelta())) { - event.setCanceled(true); - } - } - - private boolean handleCharTyped(char codePoint, int modifiers) { - return this.charTypedHandlers.stream() - .filter(ICharTypedHandler::hasKeyboardFocus) - .anyMatch(handler -> handler.onCharTyped(codePoint, modifiers)); - } - - private boolean isContainerTextFieldFocused(Screen screen) { - return reflectionUtil.getFieldWithClass(screen, EditBox.class) - .anyMatch(textField -> textField.isActive() && textField.isFocused()); - } -} diff --git a/Forge/src/main/java/mezz/jei/forge/startup/ClientLifecycleHandler.java b/Forge/src/main/java/mezz/jei/forge/startup/ClientLifecycleHandler.java index 496d14961..71c070fe9 100644 --- a/Forge/src/main/java/mezz/jei/forge/startup/ClientLifecycleHandler.java +++ b/Forge/src/main/java/mezz/jei/forge/startup/ClientLifecycleHandler.java @@ -131,7 +131,8 @@ private void startJei() { } this.modIdFormattingConfig.checkForModNameFormatOverride(); - this.jeiStarter.start(this.runtimeSubscriptions); + JeiEventHandlers handlers = this.jeiStarter.start(); + EventRegistration.registerEvents(this.runtimeSubscriptions, handlers); } private void stopJei() { diff --git a/Forge/src/main/java/mezz/jei/forge/startup/EventRegistration.java b/Forge/src/main/java/mezz/jei/forge/startup/EventRegistration.java new file mode 100644 index 000000000..05312d4b7 --- /dev/null +++ b/Forge/src/main/java/mezz/jei/forge/startup/EventRegistration.java @@ -0,0 +1,131 @@ +package mezz.jei.forge.startup; + +import com.mojang.blaze3d.vertex.PoseStack; +import mezz.jei.common.gui.GuiEventHandler; +import mezz.jei.common.input.ClientInputHandler; +import mezz.jei.common.input.UserInput; +import mezz.jei.forge.events.RuntimeEventSubscriptions; +import mezz.jei.forge.input.ForgeUserInput; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraftforge.client.event.ContainerScreenEvent; +import net.minecraftforge.client.event.ScreenEvent; +import net.minecraftforge.client.event.ScreenOpenEvent; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.eventbus.api.Event; + +public class EventRegistration { + public static void registerEvents(RuntimeEventSubscriptions subscriptions, JeiEventHandlers eventHandlers) { + ClientInputHandler clientInputHandler = eventHandlers.clientInputHandler(); + registerInputHandler(subscriptions, clientInputHandler); + + GuiEventHandler guiEventHandler = eventHandlers.guiEventHandler(); + registerGuiHandler(subscriptions, guiEventHandler); + } + + private static void registerInputHandler(RuntimeEventSubscriptions subscriptions, ClientInputHandler handler) { + subscriptions.register(ScreenEvent.InitScreenEvent.class, event -> handler.onInitGui()); + + subscriptions.register(ScreenEvent.KeyboardKeyPressedEvent.Pre.class, event -> { + Screen screen = event.getScreen(); + UserInput input = ForgeUserInput.fromEvent(event); + if (handler.onKeyboardKeyPressedPre(screen, input)) { + event.setCanceled(true); + } + }); + subscriptions.register(ScreenEvent.KeyboardKeyPressedEvent.Post.class, event -> { + Screen screen = event.getScreen(); + UserInput input = ForgeUserInput.fromEvent(event); + if (handler.onKeyboardKeyPressed(screen, input)) { + event.setCanceled(true); + } + }); + + subscriptions.register(ScreenEvent.KeyboardCharTypedEvent.Pre.class, event -> { + Screen screen = event.getScreen(); + char codePoint = event.getCodePoint(); + int modifiers = event.getModifiers(); + if (handler.onKeyboardCharTypedPre(screen, codePoint, modifiers)) { + event.setCanceled(true); + } + }); + subscriptions.register(ScreenEvent.KeyboardCharTypedEvent.Post.class, event -> { + Screen screen = event.getScreen(); + char codePoint = event.getCodePoint(); + int modifiers = event.getModifiers(); + if (handler.onKeyboardCharTypedPost(screen, codePoint, modifiers)) { + event.setCanceled(true); + } + }); + + subscriptions.register(ScreenEvent.MouseClickedEvent.Pre.class, event -> + ForgeUserInput.fromEvent(event) + .ifPresent(input -> { + Screen screen = event.getScreen(); + if (handler.onGuiMouseClicked(screen, input)) { + event.setCanceled(true); + } + }) + ); + subscriptions.register(ScreenEvent.MouseReleasedEvent.Pre.class, event -> + ForgeUserInput.fromEvent(event) + .ifPresent(input -> { + Screen screen = event.getScreen(); + if (handler.onGuiMouseReleased(screen, input)){ + event.setCanceled(true); + } + }) + ); + + subscriptions.register(ScreenEvent.MouseScrollEvent.Pre.class, event -> { + double mouseX = event.getMouseX(); + double mouseY = event.getMouseY(); + double scrollDelta = event.getScrollDelta(); + if (handler.onGuiMouseScroll(mouseX, mouseY, scrollDelta)) { + event.setCanceled(true); + } + }); + } + + public static void registerGuiHandler(RuntimeEventSubscriptions subscriptions, GuiEventHandler guiEventHandler) { + subscriptions.register(ScreenEvent.InitScreenEvent.Post.class, event -> { + Screen screen = event.getScreen(); + guiEventHandler.onGuiInit(screen); + }); + subscriptions.register(ScreenOpenEvent.class, event -> { + Screen screen = event.getScreen(); + guiEventHandler.onGuiOpen(screen); + }); + subscriptions.register(ScreenEvent.BackgroundDrawnEvent.class, event -> { + Screen screen = event.getScreen(); + PoseStack poseStack = event.getPoseStack(); + guiEventHandler.onDrawBackgroundPost(screen, poseStack); + }); + subscriptions.register(ContainerScreenEvent.DrawForeground.class, event -> { + AbstractContainerScreen containerScreen = event.getContainerScreen(); + PoseStack poseStack = event.getPoseStack(); + int mouseX = event.getMouseX(); + int mouseY = event.getMouseY(); + guiEventHandler.onDrawForeground(containerScreen, poseStack, mouseX, mouseY); + }); + subscriptions.register(ScreenEvent.DrawScreenEvent.Post.class, event -> { + Screen screen = event.getScreen(); + PoseStack poseStack = event.getPoseStack(); + int mouseX = event.getMouseX(); + int mouseY = event.getMouseY(); + guiEventHandler.onDrawScreenPost(screen, poseStack, mouseX, mouseY); + }); + subscriptions.register(TickEvent.ClientTickEvent.class, event -> { + if (event.phase == TickEvent.Phase.START) { + guiEventHandler.onClientTick(); + } + }); + subscriptions.register(ScreenEvent.PotionSizeEvent.class, event -> { + if (guiEventHandler.renderCompactPotionIndicators()) { + // Forcibly renders the potion indicators in compact mode. + // This gives the ingredient list overlay more room to display ingredients. + event.setResult(Event.Result.ALLOW); + } + }); + } +} diff --git a/Forge/src/main/java/mezz/jei/forge/startup/JeiEventHandlers.java b/Forge/src/main/java/mezz/jei/forge/startup/JeiEventHandlers.java new file mode 100644 index 000000000..d5a7d7866 --- /dev/null +++ b/Forge/src/main/java/mezz/jei/forge/startup/JeiEventHandlers.java @@ -0,0 +1,10 @@ +package mezz.jei.forge.startup; + +import mezz.jei.common.gui.GuiEventHandler; +import mezz.jei.common.input.ClientInputHandler; + +public record JeiEventHandlers( + GuiEventHandler guiEventHandler, + ClientInputHandler clientInputHandler +) { +} diff --git a/Forge/src/main/java/mezz/jei/forge/startup/JeiStarter.java b/Forge/src/main/java/mezz/jei/forge/startup/JeiStarter.java index 19fc181b3..88c06dd69 100644 --- a/Forge/src/main/java/mezz/jei/forge/startup/JeiStarter.java +++ b/Forge/src/main/java/mezz/jei/forge/startup/JeiStarter.java @@ -9,9 +9,9 @@ import mezz.jei.api.runtime.IIngredientVisibility; import mezz.jei.common.Internal; import mezz.jei.common.bookmarks.BookmarkList; +import mezz.jei.common.filter.FilterTextSource; +import mezz.jei.common.filter.IFilterTextSource; import mezz.jei.common.gui.GuiScreenHelper; -import mezz.jei.common.gui.overlay.FilterTextSource; -import mezz.jei.common.gui.overlay.IFilterTextSource; import mezz.jei.common.gui.overlay.IngredientListOverlay; import mezz.jei.common.gui.overlay.bookmarks.BookmarkOverlay; import mezz.jei.common.gui.overlay.bookmarks.LeftAreaDispatcher; @@ -39,10 +39,8 @@ import mezz.jei.common.startup.StartData; import mezz.jei.common.util.ErrorUtil; import mezz.jei.common.util.LoggedTimer; -import mezz.jei.forge.events.EditModeToggleEvent; -import mezz.jei.forge.events.GuiEventHandler; -import mezz.jei.forge.events.RuntimeEventSubscriptions; -import mezz.jei.forge.input.InputEventHandler; +import mezz.jei.common.gui.GuiEventHandler; +import mezz.jei.common.input.ClientInputHandler; import java.util.List; @@ -54,7 +52,7 @@ public JeiStarter(StartData data) { this.data = data; } - public void start(RuntimeEventSubscriptions subscriptions) { + public JeiEventHandlers start() { LoggedTimer totalTime = new LoggedTimer(); totalTime.start("Starting JEI"); List plugins = data.plugins(); @@ -67,7 +65,6 @@ public void start(RuntimeEventSubscriptions subscriptions) { RegisteredIngredients registeredIngredients = pluginLoader.getRegisteredIngredients(); IngredientFilter ingredientFilter = pluginLoader.getIngredientFilter(); - subscriptions.register(EditModeToggleEvent.class, event -> ingredientFilter.updateHidden()); BookmarkList bookmarkList = pluginLoader.createBookmarkList(configData.bookmarkConfig()); RecipeManager recipeManager = pluginLoader.createRecipeManager(plugins, data.vanillaPlugin(), configData.recipeCategorySortingConfig()); @@ -129,7 +126,6 @@ public void start(RuntimeEventSubscriptions subscriptions) { LeftAreaDispatcher leftAreaDispatcher = new LeftAreaDispatcher(guiScreenHelper, bookmarkOverlay); GuiEventHandler guiEventHandler = new GuiEventHandler(guiScreenHelper, leftAreaDispatcher, ingredientListOverlay); - guiEventHandler.register(subscriptions); CombinedRecipeFocusSource recipeFocusSource = new CombinedRecipeFocusSource( recipesGui, @@ -151,13 +147,17 @@ public void start(RuntimeEventSubscriptions subscriptions) { new GlobalInputHandler(configData.worldConfig()), new GuiAreaInputHandler(registeredIngredients, guiScreenHelper, recipesGui) ); - InputEventHandler inputEventHandler = new InputEventHandler(charTypedHandlers, userInputHandler, data.keyBindings()); - inputEventHandler.register(subscriptions); + ClientInputHandler clientInputHandler = new ClientInputHandler(charTypedHandlers, userInputHandler, data.keyBindings()); // This needs to be run after all of the "Ingredients are being added at runtime" items. data.ingredientSorter().doPreSort(ingredientFilter, registeredIngredients); totalTime.stop(); + + return new JeiEventHandlers( + guiEventHandler, + clientInputHandler + ); } } diff --git a/Forge/src/test/java/mezz/jei/test/IngredientFilterTest.java b/Forge/src/test/java/mezz/jei/test/IngredientFilterTest.java index b1f1dc143..8719f16c0 100644 --- a/Forge/src/test/java/mezz/jei/test/IngredientFilterTest.java +++ b/Forge/src/test/java/mezz/jei/test/IngredientFilterTest.java @@ -11,8 +11,8 @@ import mezz.jei.core.config.IWorldConfig; import mezz.jei.core.config.IngredientBlacklistType; import mezz.jei.common.gui.ingredients.IListElement; -import mezz.jei.common.gui.overlay.FilterTextSource; -import mezz.jei.common.gui.overlay.IFilterTextSource; +import mezz.jei.common.filter.FilterTextSource; +import mezz.jei.common.filter.IFilterTextSource; import mezz.jei.common.ingredients.IListElementInfo; import mezz.jei.common.ingredients.IIngredientSorter; import mezz.jei.common.ingredients.IngredientBlacklistInternal;