From b4cf6f7f364796431267f5ef662a6663df683a29 Mon Sep 17 00:00:00 2001 From: mezz Date: Sun, 23 Dec 2018 23:46:42 -0800 Subject: [PATCH] Implement GuiScreen events for mouse and keyboard (#5297) --- .../client/KeyboardListener.java.patch | 38 ++ .../minecraft/client/MouseHelper.java.patch | 42 ++ .../minecraft/client/gui/GuiScreen.java.patch | 36 +- .../client/ForgeHooksClient.java | 91 ++++ .../client/event/GuiScreenEvent.java | 411 +++++++++++++++--- 5 files changed, 539 insertions(+), 79 deletions(-) create mode 100644 patches/minecraft/net/minecraft/client/KeyboardListener.java.patch create mode 100644 patches/minecraft/net/minecraft/client/MouseHelper.java.patch diff --git a/patches/minecraft/net/minecraft/client/KeyboardListener.java.patch b/patches/minecraft/net/minecraft/client/KeyboardListener.java.patch new file mode 100644 index 000000000..6ab139000 --- /dev/null +++ b/patches/minecraft/net/minecraft/client/KeyboardListener.java.patch @@ -0,0 +1,38 @@ +--- a/net/minecraft/client/KeyboardListener.java ++++ b/net/minecraft/client/KeyboardListener.java +@@ -266,10 +266,14 @@ + GuiScreen.func_195121_a(() -> { + if (p_197961_5_ != 1 && (p_197961_5_ != 2 || !this.field_197973_b)) { + if (p_197961_5_ == 0) { +- aboolean[0] = iguieventlistener.keyReleased(p_197961_3_, p_197961_4_, p_197961_6_); ++ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiKeyReleasedPre(this.field_197972_a.field_71462_r, p_197961_3_, p_197961_4_, p_197961_6_); ++ if (!aboolean[0]) aboolean[0] = iguieventlistener.keyReleased(p_197961_3_, p_197961_4_, p_197961_6_); ++ if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiKeyReleasedPost(this.field_197972_a.field_71462_r, p_197961_3_, p_197961_4_, p_197961_6_); + } + } else { +- aboolean[0] = iguieventlistener.keyPressed(p_197961_3_, p_197961_4_, p_197961_6_); ++ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiKeyPressedPre(this.field_197972_a.field_71462_r, p_197961_3_, p_197961_4_, p_197961_6_); ++ if (!aboolean[0]) aboolean[0] = iguieventlistener.keyPressed(p_197961_3_, p_197961_4_, p_197961_6_); ++ if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiKeyPressedPost(this.field_197972_a.field_71462_r, p_197961_3_, p_197961_4_, p_197961_6_); + } + + }, "keyPressed event handler", iguieventlistener.getClass().getCanonicalName()); +@@ -346,12 +350,16 @@ + if (iguieventlistener != null) { + if (Character.charCount(p_197963_3_) == 1) { + GuiScreen.func_195121_a(() -> { +- iguieventlistener.charTyped((char)p_197963_3_, p_197963_4_); ++ if (net.minecraftforge.client.ForgeHooksClient.onGuiCharTypedPre(this.field_197972_a.field_71462_r, (char)p_197963_3_, p_197963_4_)) return; ++ if (iguieventlistener.charTyped((char)p_197963_3_, p_197963_4_)) return; ++ net.minecraftforge.client.ForgeHooksClient.onGuiCharTypedPost(this.field_197972_a.field_71462_r, (char)p_197963_3_, p_197963_4_); + }, "charTyped event handler", iguieventlistener.getClass().getCanonicalName()); + } else { + for(char c0 : Character.toChars(p_197963_3_)) { + GuiScreen.func_195121_a(() -> { +- iguieventlistener.charTyped(c0, p_197963_4_); ++ if (net.minecraftforge.client.ForgeHooksClient.onGuiCharTypedPre(this.field_197972_a.field_71462_r, c0, p_197963_4_)) return; ++ if (iguieventlistener.charTyped(c0, p_197963_4_)) return; ++ net.minecraftforge.client.ForgeHooksClient.onGuiCharTypedPost(this.field_197972_a.field_71462_r, c0, p_197963_4_); + }, "charTyped event handler", iguieventlistener.getClass().getCanonicalName()); + } + } diff --git a/patches/minecraft/net/minecraft/client/MouseHelper.java.patch b/patches/minecraft/net/minecraft/client/MouseHelper.java.patch new file mode 100644 index 000000000..83522d37d --- /dev/null +++ b/patches/minecraft/net/minecraft/client/MouseHelper.java.patch @@ -0,0 +1,42 @@ +--- a/net/minecraft/client/MouseHelper.java ++++ b/net/minecraft/client/MouseHelper.java +@@ -76,11 +76,15 @@ + final int pFinal = p_198023_3_; + if (flag) { + GuiScreen.func_195121_a(() -> { +- aboolean[0] = this.field_198036_a.field_71462_r.mouseClicked(d0, d1, pFinal); ++ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiMouseClickedPre(this.field_198036_a.field_71462_r, d0, d1, pFinal); ++ if (!aboolean[0]) aboolean[0] = this.field_198036_a.field_71462_r.mouseClicked(d0, d1, pFinal); ++ if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiMouseClickedPost(this.field_198036_a.field_71462_r, d0, d1, pFinal); + }, "mouseClicked event handler", this.field_198036_a.field_71462_r.getClass().getCanonicalName()); + } else { + GuiScreen.func_195121_a(() -> { +- aboolean[0] = this.field_198036_a.field_71462_r.mouseReleased(d0, d1, pFinal); ++ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiMouseReleasedPre(this.field_198036_a.field_71462_r, d0, d1, pFinal); ++ if (!aboolean[0]) aboolean[0] = this.field_198036_a.field_71462_r.mouseReleased(d0, d1, pFinal); ++ if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiMouseReleasedPost(this.field_198036_a.field_71462_r, d0, d1, pFinal); + }, "mouseReleased event handler", this.field_198036_a.field_71462_r.getClass().getCanonicalName()); + } + } +@@ -111,7 +115,9 @@ + if (p_198020_1_ == Minecraft.func_71410_x().field_195558_d.func_198092_i()) { + double d0 = p_198020_5_ * this.field_198036_a.field_71474_y.field_208033_V; + if (this.field_198036_a.field_71462_r != null) { +- this.field_198036_a.field_71462_r.mouseScrolled(d0); ++ if (net.minecraftforge.client.ForgeHooksClient.onGuiMouseScrollPre(this, this.field_198036_a.field_71462_r, d0)) return; ++ if (this.field_198036_a.field_71462_r.mouseScrolled(d0)) return; ++ net.minecraftforge.client.ForgeHooksClient.onGuiMouseScrollPost(this, this.field_198036_a.field_71462_r, d0); + } else if (this.field_198036_a.field_71439_g != null) { + if (this.field_200542_o != 0.0D && Math.signum(d0) != Math.signum(this.field_200542_o)) { + this.field_200542_o = 0.0D; +@@ -160,7 +166,9 @@ + double d2 = (p_198022_3_ - this.field_198040_e) * (double)this.field_198036_a.field_195558_d.func_198107_o() / (double)this.field_198036_a.field_195558_d.func_198105_m(); + double d3 = (p_198022_5_ - this.field_198041_f) * (double)this.field_198036_a.field_195558_d.func_198087_p() / (double)this.field_198036_a.field_195558_d.func_198083_n(); + GuiScreen.func_195121_a(() -> { +- iguieventlistener.mouseDragged(d0, d1, this.field_198042_g, d2, d3); ++ if (net.minecraftforge.client.ForgeHooksClient.onGuiMouseDragPre(this.field_198036_a.field_71462_r, d0, d1, this.field_198042_g, d2, d3)) return; ++ if (iguieventlistener.mouseDragged(d0, d1, this.field_198042_g, d2, d3)) return; ++ net.minecraftforge.client.ForgeHooksClient.onGuiMouseDragPost(this.field_198036_a.field_71462_r, d0, d1, this.field_198042_g, d2, d3); + }, "mouseDragged event handler", iguieventlistener.getClass().getCanonicalName()); + } + diff --git a/patches/minecraft/net/minecraft/client/gui/GuiScreen.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiScreen.java.patch index f5b5f8ef5..20e545c4d 100644 --- a/patches/minecraft/net/minecraft/client/gui/GuiScreen.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/GuiScreen.java.patch @@ -1,14 +1,6 @@ --- a/net/minecraft/client/gui/GuiScreen.java +++ b/net/minecraft/client/gui/GuiScreen.java -@@ -51,6 +51,7 @@ - public boolean field_146291_p; - protected FontRenderer field_146289_q; - private URI field_175286_t; -+ protected boolean keyHandled, mouseHandled; // Forge: allow canceling key and mouse Post events from handleMouseInput and handleKeyboardInput - - public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_) { - for(int i = 0; i < this.field_146292_n.size(); ++i) { -@@ -87,7 +88,10 @@ +@@ -87,7 +87,10 @@ } protected void func_146285_a(ItemStack p_146285_1_, int p_146285_2_, int p_146285_3_) { @@ -20,7 +12,7 @@ } public List func_191927_a(ItemStack p_191927_1_) { -@@ -106,25 +110,30 @@ +@@ -106,25 +109,30 @@ } public void func_146283_a(List p_146283_1_, int p_146283_2_, int p_146283_3_) { @@ -57,7 +49,7 @@ } if (l1 + i > this.field_146294_l) { -@@ -150,8 +159,8 @@ +@@ -150,8 +158,8 @@ this.func_73733_a(l1 - 3, i2 - 3, l1 + i + 3, i2 - 3 + 1, 1347420415, 1347420415); this.func_73733_a(l1 - 3, i2 + k + 2, l1 + i + 3, i2 + k + 3, 1344798847, 1344798847); @@ -68,7 +60,7 @@ this.field_146289_q.func_175063_a(s1, (float)l1, (float)i2, -1); if (k1 == 0) { i2 += 2; -@@ -279,9 +288,12 @@ +@@ -279,9 +287,12 @@ } public void func_175281_b(String p_175281_1_, boolean p_175281_2_) { @@ -81,7 +73,7 @@ this.field_146297_k.field_71439_g.func_71165_d(p_175281_1_); } -@@ -292,9 +304,13 @@ +@@ -292,9 +303,13 @@ this.field_146289_q = p_146280_1_.field_71466_p; this.field_146294_l = p_146280_2_; this.field_146295_m = p_146280_3_; @@ -95,11 +87,19 @@ } public List func_195074_b() { -@@ -313,6 +329,7 @@ - - public void func_146276_q_() { - this.func_146270_b(0); +@@ -318,6 +333,7 @@ + public void func_146270_b(int p_146270_1_) { + if (this.field_146297_k.field_71441_e != null) { + this.func_73733_a(0, 0, this.field_146294_l, this.field_146295_m, -1072689136, -804253680); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.BackgroundDrawnEvent(this)); + } else { + this.func_146278_c(p_146270_1_); + } +@@ -338,6 +354,7 @@ + bufferbuilder.func_181662_b((double)this.field_146294_l, 0.0D, 0.0D).func_187315_a((double)((float)this.field_146294_l / 32.0F), (double)p_146278_1_).func_181669_b(64, 64, 64, 255).func_181675_d(); + bufferbuilder.func_181662_b(0.0D, 0.0D, 0.0D).func_187315_a(0.0D, (double)p_146278_1_).func_181669_b(64, 64, 64, 255).func_181675_d(); + tessellator.func_78381_a(); + net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.BackgroundDrawnEvent(this)); } - public void func_146270_b(int p_146270_1_) { + public boolean func_73868_f() { diff --git a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java index b9e024be0..939b3f18c 100644 --- a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java @@ -37,6 +37,7 @@ import javax.vecmath.Matrix4f; import javax.vecmath.Vector3f; import javax.vecmath.Vector4f; +import net.minecraft.client.MouseHelper; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -120,6 +121,7 @@ import net.minecraftforge.common.model.ITransformation; import net.minecraftforge.common.model.TRSRTransformation; import net.minecraftforge.fml.VersionChecker; import net.minecraftforge.fml.client.registry.ClientRegistry; +import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.resource.ReloadRequirements; import net.minecraftforge.resource.SelectiveReloadStateHandler; import net.minecraftforge.resource.VanillaResourceType; @@ -717,6 +719,95 @@ public class ForgeHooksClient SelectiveReloadStateHandler.INSTANCE.beginReload(ReloadRequirements.include(types)); mc.refreshResources(); SelectiveReloadStateHandler.INSTANCE.endReload(); + } + public static boolean onGuiMouseClickedPre(GuiScreen guiScreen, double mouseX, double mouseY, int button) + { + Event event = new GuiScreenEvent.MouseClickedEvent.Pre(guiScreen, mouseX, mouseY, button); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseClickedPost(GuiScreen guiScreen, double mouseX, double mouseY, int button) + { + Event event = new GuiScreenEvent.MouseClickedEvent.Post(guiScreen, mouseX, mouseY, button); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseReleasedPre(GuiScreen guiScreen, double mouseX, double mouseY, int button) + { + Event event = new GuiScreenEvent.MouseReleasedEvent.Pre(guiScreen, mouseX, mouseY, button); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseReleasedPost(GuiScreen guiScreen, double mouseX, double mouseY, int button) + { + Event event = new GuiScreenEvent.MouseReleasedEvent.Post(guiScreen, mouseX, mouseY, button); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseDragPre(GuiScreen guiScreen, double mouseX, double mouseY, int mouseButton, double dragX, double dragY) + { + Event event = new GuiScreenEvent.MouseDragEvent.Pre(guiScreen, mouseX, mouseY, mouseButton, dragX, dragY); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseDragPost(GuiScreen guiScreen, double mouseX, double mouseY, int mouseButton, double dragX, double dragY) + { + Event event = new GuiScreenEvent.MouseDragEvent.Post(guiScreen, mouseX, mouseY, mouseButton, dragX, dragY); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseScrollPre(MouseHelper mouseHelper, GuiScreen guiScreen, double scrollDelta) + { + MainWindow mainWindow = guiScreen.mc.mainWindow; + double mouseX = mouseHelper.getMouseX() * (double) mainWindow.getScaledWidth() / (double) mainWindow.getWidth(); + double mouseY = mouseHelper.getMouseY() * (double) mainWindow.getScaledHeight() / (double) mainWindow.getHeight(); + Event event = new GuiScreenEvent.MouseScrollEvent.Pre(guiScreen, mouseX, mouseY, scrollDelta); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseScrollPost(MouseHelper mouseHelper, GuiScreen guiScreen, double scrollDelta) + { + MainWindow mainWindow = guiScreen.mc.mainWindow; + double mouseX = mouseHelper.getMouseX() * (double) mainWindow.getScaledWidth() / (double) mainWindow.getWidth(); + double mouseY = mouseHelper.getMouseY() * (double) mainWindow.getScaledHeight() / (double) mainWindow.getHeight(); + Event event = new GuiScreenEvent.MouseScrollEvent.Post(guiScreen, mouseX, mouseY, scrollDelta); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiKeyPressedPre(GuiScreen guiScreen, int keyCode, int scanCode, int modifiers) + { + Event event = new GuiScreenEvent.KeyboardKeyPressedEvent.Pre(guiScreen, keyCode, scanCode, modifiers); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiKeyPressedPost(GuiScreen guiScreen, int keyCode, int scanCode, int modifiers) + { + Event event = new GuiScreenEvent.KeyboardKeyPressedEvent.Post(guiScreen, keyCode, scanCode, modifiers); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiKeyReleasedPre(GuiScreen guiScreen, int keyCode, int scanCode, int modifiers) + { + Event event = new GuiScreenEvent.KeyboardKeyReleasedEvent.Pre(guiScreen, keyCode, scanCode, modifiers); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiKeyReleasedPost(GuiScreen guiScreen, int keyCode, int scanCode, int modifiers) + { + Event event = new GuiScreenEvent.KeyboardKeyReleasedEvent.Post(guiScreen, keyCode, scanCode, modifiers); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiCharTypedPre(GuiScreen guiScreen, char codePoint, int modifiers) + { + Event event = new GuiScreenEvent.KeyboardCharTypedEvent.Pre(guiScreen, codePoint, modifiers); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiCharTypedPost(GuiScreen guiScreen, char codePoint, int modifiers) + { + Event event = new GuiScreenEvent.KeyboardCharTypedEvent.Post(guiScreen, codePoint, modifiers); + return MinecraftForge.EVENT_BUS.post(event); } } diff --git a/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java b/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java index 85ad64c96..6a287b908 100644 --- a/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java +++ b/src/main/java/net/minecraftforge/client/event/GuiScreenEvent.java @@ -22,21 +22,23 @@ package net.minecraftforge.client.event; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.concurrent.Callable; import java.util.function.Consumer; -import java.util.function.Function; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.IGuiEventListener; import net.minecraft.client.renderer.InventoryEffectRenderer; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.util.InputMappings; import net.minecraftforge.eventbus.api.Cancelable; import net.minecraftforge.eventbus.api.Event; +import org.lwjgl.glfw.GLFW; + /** * Event classes for GuiScreen events. * @@ -163,8 +165,8 @@ public class GuiScreenEvent extends Event } /** - * This event fires just before {@link GuiScreen#drawScreen(int, int, float)} is called. - * Cancel this event to skip {@link GuiScreen#drawScreen(int, int, float)}. + * This event fires just before {@link GuiScreen#render(int, int, float)} is called. + * Cancel this event to skip {@link GuiScreen#render(int, int, float)}. */ @Cancelable public static class Pre extends DrawScreenEvent @@ -176,7 +178,7 @@ public class GuiScreenEvent extends Event } /** - * This event fires just after {@link GuiScreen#drawScreen(int, int, float)} is called. + * This event fires just after {@link GuiScreen#render(int, int, float)} is called. */ public static class Post extends DrawScreenEvent { @@ -188,42 +190,15 @@ public class GuiScreenEvent extends Event } /** - * This event fires at the end of {@link GuiScreen#drawDefaultBackground()} and before the rest of the Gui draws. + * This event fires at the end of {@link GuiScreen#drawBackground(int)} and before the rest of the Gui draws. * This allows drawing next to Guis, above the background but below any tooltips. */ public static class BackgroundDrawnEvent extends GuiScreenEvent { - //private final int mouseX; - //private final int mouseY; - public BackgroundDrawnEvent(GuiScreen gui) { super(gui); - /* - final ScaledResolution scaledresolution = new ScaledResolution(gui.mc); - final int scaledWidth = scaledresolution.getScaledWidth(); - final int scaledHeight = scaledresolution.getScaledHeight(); - this.mouseX = Mouse.getX() * scaledWidth / gui.mc.displayWidth; - this.mouseY = scaledHeight - Mouse.getY() * scaledHeight / gui.mc.displayHeight - 1; - */ } - - /** - * The x coordinate of the mouse pointer on the screen. - * / - public int getMouseX() - { - return mouseX; - } - - /** - * The y coordinate of the mouse pointer on the screen. - * / - public int getMouseY() - { - return mouseY; - } - */ } /** @@ -305,74 +280,388 @@ public class GuiScreenEvent extends Event } } - public static class MouseInputEvent extends GuiScreenEvent + public static abstract class MouseInputEvent extends GuiScreenEvent { - public MouseInputEvent(GuiScreen gui) + private final double mouseX; + private final double mouseY; + + public MouseInputEvent(GuiScreen gui, double mouseX, double mouseY) { super(gui); + this.mouseX = mouseX; + this.mouseY = mouseY; + } + + public double getMouseX() + { + return mouseX; + } + + public double getMouseY() + { + return mouseY; + } + } + + public static abstract class MouseClickedEvent extends MouseInputEvent + { + private final int button; + + public MouseClickedEvent(GuiScreen gui, double mouseX, double mouseY, int button) + { + super(gui, mouseX, mouseY); + this.button = button; + } + + public int getButton() + { + return button; } /** - * This event fires when mouse input is detected by a GuiScreen. - * Cancel this event to bypass {@link GuiScreen#handleMouseInput()}. + * This event fires when a mouse click is detected for a GuiScreen, before it is handled. + * Cancel this event to bypass {@link IGuiEventListener#mouseClicked(double, double, int)}. */ @Cancelable - public static class Pre extends MouseInputEvent + public static class Pre extends MouseClickedEvent { - public Pre(GuiScreen gui) + public Pre(GuiScreen gui, double mouseX, double mouseY, int button) { - super(gui); + super(gui, mouseX, mouseY, button); } } /** - * This event fires after {@link GuiScreen#handleMouseInput()} provided that the active - * screen has not been changed as a result of {@link GuiScreen#handleMouseInput()} and - * the {@link GuiScreen#mouseHandled} flag has not been set. - * Cancel this event when you successfully use the mouse input to prevent other handlers from using the same input. + * This event fires after {@link IGuiEventListener#mouseClicked(double, double, int)} if the click was not already handled. + * Cancel this event when you successfully use the mouse click, to prevent other handlers from using the same input. */ @Cancelable - public static class Post extends MouseInputEvent + public static class Post extends MouseClickedEvent { - public Post(GuiScreen gui) + public Post(GuiScreen gui, double mouseX, double mouseY, int button) { - super(gui); + super(gui, mouseX, mouseY, button); } } } - public static class KeyboardInputEvent extends GuiScreenEvent + public static abstract class MouseReleasedEvent extends MouseInputEvent { - public KeyboardInputEvent(GuiScreen gui) + private final int button; + + public MouseReleasedEvent(GuiScreen gui, double mouseX, double mouseY, int button) { - super(gui); + super(gui, mouseX, mouseY); + this.button = button; + } + + public int getButton() + { + return button; } /** - * This event fires when keyboard input is detected by a GuiScreen. - * Cancel this event to bypass {@link GuiScreen#handleKeyboardInput()}. + * This event fires when a mouse release is detected for a GuiScreen, before it is handled. + * Cancel this event to bypass {@link IGuiEventListener#mouseReleased(double, double, int)}. */ @Cancelable - public static class Pre extends KeyboardInputEvent + public static class Pre extends MouseReleasedEvent { - public Pre(GuiScreen gui) + public Pre(GuiScreen gui, double mouseX, double mouseY, int button) { - super(gui); + super(gui, mouseX, mouseY, button); } } /** - * This event fires after {@link GuiScreen#handleKeyboardInput()} provided that the active - * screen has not been changed as a result of {@link GuiScreen#handleKeyboardInput()} and - * the {@link GuiScreen#keyHandled} flag has not been set. + * This event fires after {@link IGuiEventListener#mouseReleased(double, double, int)} if the release was not already handled. + * Cancel this event when you successfully use the mouse release, to prevent other handlers from using the same input. + */ + @Cancelable + public static class Post extends MouseReleasedEvent + { + public Post(GuiScreen gui, double mouseX, double mouseY, int button) + { + super(gui, mouseX, mouseY, button); + } + } + } + + public static abstract class MouseDragEvent extends MouseInputEvent + { + private final int mouseButton; + private final double dragX; + private final double dragY; + + public MouseDragEvent(GuiScreen gui, double mouseX, double mouseY, int mouseButton, double dragX, double dragY) + { + super(gui, mouseX, mouseY); + this.mouseButton = mouseButton; + this.dragX = dragX; + this.dragY = dragY; + } + + public int getMouseButton() + { + return mouseButton; + } + + public double getDragX() + { + return dragX; + } + + public double getDragY() + { + return dragY; + } + + /** + * This event fires when a mouse drag is detected for a GuiScreen, before it is handled. + * Cancel this event to bypass {@link IGuiEventListener#mouseDragged(double, double, int, double, double)}. + */ + @Cancelable + public static class Pre extends MouseDragEvent + { + public Pre(GuiScreen gui, double mouseX, double mouseY, int mouseButton, double dragX, double dragY) + { + super(gui, mouseX, mouseY, mouseButton, dragX, dragY); + } + } + + /** + * This event fires after {@link IGuiEventListener#mouseDragged(double, double, int, double, double)} if the drag was not already handled. + * Cancel this event when you successfully use the mouse drag, to prevent other handlers from using the same input. + */ + @Cancelable + public static class Post extends MouseDragEvent + { + public Post(GuiScreen gui, double mouseX, double mouseY, int mouseButton, double dragX, double dragY) + { + super(gui, mouseX, mouseY, mouseButton, dragX, dragY); + } + } + } + + public static abstract class MouseScrollEvent extends MouseInputEvent + { + private final double scrollDelta; + + public MouseScrollEvent(GuiScreen gui, double mouseX, double mouseY, double scrollDelta) + { + super(gui, mouseX, mouseY); + this.scrollDelta = scrollDelta; + } + + public double getScrollDelta() + { + return scrollDelta; + } + + /** + * This event fires when a mouse scroll is detected for a GuiScreen, before it is handled. + * Cancel this event to bypass {@link IGuiEventListener#mouseScrolled(double)}. + */ + @Cancelable + public static class Pre extends MouseScrollEvent + { + public Pre(GuiScreen gui, double mouseX, double mouseY, double scrollDelta) + { + super(gui, mouseX, mouseY, scrollDelta); + } + } + + /** + * This event fires after {@link IGuiEventListener#mouseScrolled(double)} if the scroll was not already handled. + * Cancel this event when you successfully use the mouse scroll, to prevent other handlers from using the same input. + */ + @Cancelable + public static class Post extends MouseScrollEvent + { + public Post(GuiScreen gui, double mouseX, double mouseY, double scrollDelta) + { + super(gui, mouseX, mouseY, scrollDelta); + } + } + } + + public static abstract class KeyboardKeyEvent extends GuiScreenEvent + { + private final int keyCode; + private final int scanCode; + private final int modifiers; + + public KeyboardKeyEvent(GuiScreen gui, int keyCode, int scanCode, int modifiers) + { + super(gui); + this.keyCode = keyCode; + this.scanCode = scanCode; + this.modifiers = modifiers; + } + + /** + * The keyboard key that was pressed or released + * https://www.glfw.org/docs/latest/group__keys.html + * + * @see GLFW key constants starting with "GLFW_KEY_" + */ + public int getKeyCode() + { + return keyCode; + } + + /** + * Platform-specific scan code. + * Used for {@link InputMappings#getInputByCode(int, int)} + * + * The scan code is unique for every key, regardless of whether it has a key code. + * Scan codes are platform-specific but consistent over time, so keys will have different scan codes depending + * on the platform but they are safe to save to disk as custom key bindings. + */ + public int getScanCode() + { + return scanCode; + } + + /** + * Bit field representing the modifier keys pressed. + * https://www.glfw.org/docs/latest/group__mods.html + * + * @see GLFW#GLFW_MOD_SHIFT + * @see GLFW#GLFW_MOD_CONTROL + * @see GLFW#GLFW_MOD_ALT + * @see GLFW#GLFW_MOD_SUPER + */ + public int getModifiers() + { + return modifiers; + } + } + + public static abstract class KeyboardKeyPressedEvent extends KeyboardKeyEvent + { + public KeyboardKeyPressedEvent(GuiScreen gui, int keyCode, int scanCode, int modifiers) + { + super(gui, keyCode, scanCode, modifiers); + } + + /** + * This event fires when keyboard input is detected for a GuiScreen, before it is handled. + * Cancel this event to bypass {@link IGuiEventListener#keyPressed(int, int, int)}. + */ + @Cancelable + public static class Pre extends KeyboardKeyPressedEvent + { + public Pre(GuiScreen gui, int keyCode, int scanCode, int modifiers) + { + super(gui, keyCode, scanCode, modifiers); + } + } + + /** + * This event fires after {@link IGuiEventListener#keyPressed(int, int, int)} if the key was not already handled. * Cancel this event when you successfully use the keyboard input to prevent other handlers from using the same input. */ @Cancelable - public static class Post extends KeyboardInputEvent + public static class Post extends KeyboardKeyPressedEvent { - public Post(GuiScreen gui) + public Post(GuiScreen gui, int keyCode, int scanCode, int modifiers) { - super(gui); + super(gui, keyCode, scanCode, modifiers); + } + } + } + + public static abstract class KeyboardKeyReleasedEvent extends KeyboardKeyEvent + { + public KeyboardKeyReleasedEvent(GuiScreen gui, int keyCode, int scanCode, int modifiers) + { + super(gui, keyCode, scanCode, modifiers); + } + + /** + * This event fires when keyboard input is detected for a GuiScreen, before it is handled. + * Cancel this event to bypass {@link IGuiEventListener#keyReleased(int, int, int)}. + */ + @Cancelable + public static class Pre extends KeyboardKeyReleasedEvent + { + public Pre(GuiScreen gui, int keyCode, int scanCode, int modifiers) + { + super(gui, keyCode, scanCode, modifiers); + } + } + + /** + * This event fires after {@link IGuiEventListener#keyReleased(int, int, int)} if the key was not already handled. + * Cancel this event when you successfully use the keyboard input to prevent other handlers from using the same input. + */ + @Cancelable + public static class Post extends KeyboardKeyReleasedEvent + { + public Post(GuiScreen gui, int keyCode, int scanCode, int modifiers) + { + super(gui, keyCode, scanCode, modifiers); + } + } + } + + public static class KeyboardCharTypedEvent extends GuiScreenEvent + { + private final char codePoint; + private final int modifiers; + + public KeyboardCharTypedEvent(GuiScreen gui, char codePoint, int modifiers) + { + super(gui); + this.codePoint = codePoint; + this.modifiers = modifiers; + } + + /** + * The code point typed, used for text entry. + */ + public char getCodePoint() + { + return codePoint; + } + + /** + * Bit field representing the modifier keys pressed. + * + * @see GLFW#GLFW_MOD_SHIFT + * @see GLFW#GLFW_MOD_CONTROL + * @see GLFW#GLFW_MOD_ALT + * @see GLFW#GLFW_MOD_SUPER + */ + public int getModifiers() + { + return modifiers; + } + + /** + * This event fires when keyboard character input is detected for a GuiScreen, before it is handled. + * Cancel this event to bypass {@link IGuiEventListener#charTyped(char, int)}. + */ + @Cancelable + public static class Pre extends KeyboardCharTypedEvent + { + public Pre(GuiScreen gui, char codePoint, int modifiers) + { + super(gui, codePoint, modifiers); + } + } + + /** + * This event fires after {@link IGuiEventListener#charTyped(char, int)} if the character was not already handled. + * Cancel this event when you successfully use the keyboard input to prevent other handlers from using the same input. + */ + @Cancelable + public static class Post extends KeyboardCharTypedEvent + { + public Post(GuiScreen gui, char codePoint, int modifiers) + { + super(gui, codePoint, modifiers); } } }