diff options
author | Juuxel <6596629+Juuxel@users.noreply.github.com> | 2021-02-27 16:48:15 +0200 |
---|---|---|
committer | Juuxel <6596629+Juuxel@users.noreply.github.com> | 2021-02-27 16:48:15 +0200 |
commit | 319727b72bbc0d87d926c4585a88ea5c1e15e17f (patch) | |
tree | d10ec740b16e89b17c3e32e7275835fbc36a7696 | |
parent | 61f953a2c88047ccc5fb2de0b91e661503d0f06a (diff) | |
download | LibGui-319727b72bbc0d87d926c4585a88ea5c1e15e17f.tar.gz LibGui-319727b72bbc0d87d926c4585a88ea5c1e15e17f.tar.bz2 LibGui-319727b72bbc0d87d926c4585a88ea5c1e15e17f.zip |
Create InputResult for specifying whether mouse inputs are processed
This means that mouse events are propagated upwards the widget tree
until they are processed or the root panel is reached.
Code duplication in mouse handling was reduced by moving all logic
into a new MouseInputHandler helper class. (I'd obviously have them
directly in the screen classes if there was only one.)
16 files changed, 290 insertions, 243 deletions
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/SyncedGuiDescription.java b/src/main/java/io/github/cottonmc/cotton/gui/SyncedGuiDescription.java index b4d6f94..a7367cf 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/SyncedGuiDescription.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/SyncedGuiDescription.java @@ -297,52 +297,6 @@ public class SyncedGuiDescription extends ScreenHandler implements GuiDescriptio return inserted; } - - @Nullable - public WWidget doMouseUp(int x, int y, int state) { - if (rootPanel!=null) return rootPanel.onMouseUp(x, y, state); - return null; - } - - @Nullable - public WWidget doMouseDown(int x, int y, int button) { - if (rootPanel!=null) return rootPanel.onMouseDown(x, y, button); - return null; - } - - public void doMouseDrag(int x, int y, int button, double deltaX, double deltaY) { - if (rootPanel!=null) rootPanel.onMouseDrag(x, y, button, deltaX, deltaY); - } - - public void doClick(int x, int y, int button) { - if (focus!=null) { - int wx = focus.getAbsoluteX(); - int wy = focus.getAbsoluteY(); - - if (x>=wx && x<wx+focus.getWidth() && y>=wy && y<wy+focus.getHeight()) { - //Do nothing, focus will get the click soon - } else { - //Invalidate the component first - WWidget lastFocus = focus; - focus = null; - lastFocus.onFocusLost(); - } - } - - //if (rootPanel!=null) rootPanel.onClick(x, y, button); - } - - public void doCharType(char ch) { - if (focus!=null) focus.onCharTyped(ch); - } - - //public void doKeyPress(int key) { - // if (focus!=null) focus.onKeyPressed(key); - //} - - //public void doKeyRelease(int key) { - // if (focus!=null) focus.onKeyReleased(key); - //} @Nullable @Override diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java index 055262e..5fdd521 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonClientScreen.java @@ -7,11 +7,14 @@ import net.minecraft.text.Style; import net.minecraft.text.Text; import io.github.cottonmc.cotton.gui.GuiDescription; +import io.github.cottonmc.cotton.gui.impl.client.CottonScreenImpl; +import io.github.cottonmc.cotton.gui.impl.client.MouseInputHandler; import io.github.cottonmc.cotton.gui.widget.WPanel; import io.github.cottonmc.cotton.gui.widget.WWidget; +import org.jetbrains.annotations.Nullable; import org.lwjgl.opengl.GL11; -public class CottonClientScreen extends Screen implements TextHoverRendererScreen { +public class CottonClientScreen extends Screen implements TextHoverRendererScreen, CottonScreenImpl { protected GuiDescription description; protected int left = 0; protected int top = 0; @@ -30,6 +33,7 @@ public class CottonClientScreen extends Screen implements TextHoverRendererScree */ protected int titleY; + @Nullable protected WWidget lastResponder = null; public CottonClientScreen(GuiDescription description) { @@ -63,6 +67,17 @@ public class CottonClientScreen extends Screen implements TextHoverRendererScree this.client.keyboard.setRepeatEvents(false); } + @Nullable + @Override + public WWidget getLastResponder() { + return lastResponder; + } + + @Override + public void setLastResponder(@Nullable WWidget lastResponder) { + this.lastResponder = lastResponder; + } + /** * Repositions the root panel. * @@ -157,68 +172,46 @@ public class CottonClientScreen extends Screen implements TextHoverRendererScree } } - boolean result = super.mouseClicked(mouseX, mouseY, mouseButton); + super.mouseClicked(mouseX, mouseY, mouseButton); int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; - if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return result; - if (lastResponder==null) { - lastResponder = description.getRootPanel().hit(containerX, containerY); - if (lastResponder!=null) lastResponder.onMouseDown(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton); - } else { - //This is a drag instead - } - return result; - + if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return true; + MouseInputHandler.onMouseDown(description, this, containerX, containerY, mouseButton); + + return true; } @Override public boolean mouseReleased(double mouseX, double mouseY, int mouseButton) { if (description.getRootPanel()==null) return super.mouseReleased(mouseX, mouseY, mouseButton); - boolean result = super.mouseReleased(mouseX, mouseY, mouseButton); + super.mouseReleased(mouseX, mouseY, mouseButton); int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; + MouseInputHandler.onMouseUp(description, this, containerX, containerY, mouseButton); - if (lastResponder!=null) { - lastResponder.onMouseUp(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton); - if (containerX>=0 && containerY>=0 && containerX<width && containerY<height) { - lastResponder.onClick(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton); - } - } else { - description.getRootPanel().onMouseUp(containerX, containerY, mouseButton); - } - - lastResponder = null; - return result; + return true; } @Override public boolean mouseDragged(double mouseX, double mouseY, int mouseButton, double deltaX, double deltaY) { if (description.getRootPanel()==null) return super.mouseDragged(mouseX, mouseY, mouseButton, deltaX, deltaY); - boolean result = super.mouseDragged(mouseX, mouseY, mouseButton, deltaX, deltaY); + super.mouseDragged(mouseX, mouseY, mouseButton, deltaX, deltaY); int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; - - if (lastResponder!=null) { - lastResponder.onMouseDrag(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton, deltaX, deltaY); - return result; - } else { - if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return result; - description.getRootPanel().onMouseDrag(containerX, containerY, mouseButton, deltaX, deltaY); - } - return result; + MouseInputHandler.onMouseDrag(description, this, containerX, containerY, mouseButton, deltaX, deltaY); + + return true; } @Override public boolean mouseScrolled(double mouseX, double mouseY, double amount) { if (description.getRootPanel()==null) return super.mouseScrolled(mouseX, mouseY, amount); - WPanel root = description.getRootPanel(); int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; - - WWidget child = root.hit(containerX, containerY); - child.onMouseScroll(containerX - child.getAbsoluteX(), containerY - child.getAbsoluteY(), amount); + MouseInputHandler.onMouseScroll(description, containerX, containerY, amount); + return true; } @@ -226,12 +219,9 @@ public class CottonClientScreen extends Screen implements TextHoverRendererScree public void mouseMoved(double mouseX, double mouseY) { if (description.getRootPanel()==null) return; - WPanel root = description.getRootPanel(); int containerX = (int)mouseX-left; int containerY = (int)mouseY-top; - - WWidget child = root.hit(containerX, containerY); - child.onMouseMove(containerX - child.getAbsoluteX(), containerY - child.getAbsoluteY()); + MouseInputHandler.onMouseMove(description, containerX, containerY); } @Override diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java index 5b36a66..b6ed959 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/client/CottonInventoryScreen.java @@ -9,8 +9,11 @@ import net.minecraft.text.Style; import net.minecraft.text.Text; import io.github.cottonmc.cotton.gui.SyncedGuiDescription; +import io.github.cottonmc.cotton.gui.impl.client.CottonScreenImpl; +import io.github.cottonmc.cotton.gui.impl.client.MouseInputHandler; import io.github.cottonmc.cotton.gui.widget.WPanel; import io.github.cottonmc.cotton.gui.widget.WWidget; +import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; import org.lwjgl.opengl.GL11; @@ -19,9 +22,9 @@ import org.lwjgl.opengl.GL11; * * @param <T> the description type */ -public class CottonInventoryScreen<T extends SyncedGuiDescription> extends HandledScreen<T> implements TextHoverRendererScreen { +public class CottonInventoryScreen<T extends SyncedGuiDescription> extends HandledScreen<T> implements TextHoverRendererScreen, CottonScreenImpl { protected SyncedGuiDescription description; - protected WWidget lastResponder = null; + @Nullable protected WWidget lastResponder = null; /** * Constructs a new screen without a title. @@ -77,6 +80,17 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl this.client.keyboard.setRepeatEvents(false); } + @Nullable + @Override + public WWidget getLastResponder() { + return lastResponder; + } + + @Override + public void setLastResponder(@Nullable WWidget lastResponder) { + this.lastResponder = lastResponder; + } + /** * Clears the heavyweight peers of this screen's GUI description. */ @@ -177,60 +191,40 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl int containerX = (int)mouseX-x; int containerY = (int)mouseY-y; if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return result; - if (lastResponder==null) { - lastResponder = description.doMouseDown(containerX, containerY, mouseButton); - } else { - //This is a drag instead - } - return result; + MouseInputHandler.onMouseDown(description, this, containerX, containerY, mouseButton); + + return true; } @Override public boolean mouseReleased(double mouseX, double mouseY, int mouseButton) { //Testing shows that STATE IS ACTUALLY BUTTON - boolean result = super.mouseReleased(mouseX, mouseY, mouseButton); + super.mouseReleased(mouseX, mouseY, mouseButton); int containerX = (int)mouseX-x; int containerY = (int)mouseY-y; - - if (lastResponder!=null) { - lastResponder.onMouseUp(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton); - if (containerX>=0 && containerY>=0 && containerX<width && containerY<height) { - lastResponder.onClick(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton); - } - } else { - description.doMouseUp(containerX, containerY, mouseButton); - } - - lastResponder = null; - return result; + MouseInputHandler.onMouseUp(description, this, containerX, containerY, mouseButton); + + return true; } @Override public boolean mouseDragged(double mouseX, double mouseY, int mouseButton, double deltaX, double deltaY) { - boolean result = super.mouseDragged(mouseX, mouseY, mouseButton, deltaX, deltaY); + super.mouseDragged(mouseX, mouseY, mouseButton, deltaX, deltaY); int containerX = (int)mouseX-x; int containerY = (int)mouseY-y; - - if (lastResponder!=null) { - lastResponder.onMouseDrag(containerX-lastResponder.getAbsoluteX(), containerY-lastResponder.getAbsoluteY(), mouseButton, deltaX, deltaY); - return result; - } else { - if (containerX<0 || containerY<0 || containerX>=width || containerY>=height) return result; - description.doMouseDrag(containerX, containerY, mouseButton, deltaX, deltaY); - } - return result; + MouseInputHandler.onMouseDrag(description, this, containerX, containerY, mouseButton, deltaX, deltaY); + + return true; } @Override public boolean mouseScrolled(double mouseX, double mouseY, double amount) { if (description.getRootPanel()==null) return super.mouseScrolled(mouseX, mouseY, amount); - - WPanel root = description.getRootPanel(); + int containerX = (int)mouseX-x; int containerY = (int)mouseY-y; - - WWidget child = root.hit(containerX, containerY); - child.onMouseScroll(containerX - child.getAbsoluteX(), containerY - child.getAbsoluteY(), amount); + MouseInputHandler.onMouseScroll(description, containerX, containerY, amount); + return true; } @@ -238,12 +232,9 @@ public class CottonInventoryScreen<T extends SyncedGuiDescription> extends Handl public void mouseMoved(double mouseX, double mouseY) { if (description.getRootPanel()==null) return; - WPanel root = description.getRootPanel(); int containerX = (int)mouseX-x; int containerY = (int)mouseY-y; - - WWidget child = root.hit(containerX, containerY); - child.onMouseMove(containerX - child.getAbsoluteX(), containerY - child.getAbsoluteY()); + MouseInputHandler.onMouseMove(description, containerX, containerY); } @Override diff --git a/src/main/java/io/github/cottonmc/cotton/gui/impl/client/CottonScreenImpl.java b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/CottonScreenImpl.java new file mode 100644 index 0000000..b99911b --- /dev/null +++ b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/CottonScreenImpl.java @@ -0,0 +1,15 @@ +package io.github.cottonmc.cotton.gui.impl.client; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import io.github.cottonmc.cotton.gui.widget.WWidget; +import org.jetbrains.annotations.Nullable; + +@Environment(EnvType.CLIENT) +public interface CottonScreenImpl { + @Nullable + WWidget getLastResponder(); + + void setLastResponder(@Nullable WWidget lastResponder); +} diff --git a/src/main/java/io/github/cottonmc/cotton/gui/impl/client/MouseInputHandler.java b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/MouseInputHandler.java new file mode 100644 index 0000000..45fc17f --- /dev/null +++ b/src/main/java/io/github/cottonmc/cotton/gui/impl/client/MouseInputHandler.java @@ -0,0 +1,114 @@ +package io.github.cottonmc.cotton.gui.impl.client; + +import net.minecraft.client.gui.screen.Screen; + +import io.github.cottonmc.cotton.gui.GuiDescription; +import io.github.cottonmc.cotton.gui.widget.WWidget; +import io.github.cottonmc.cotton.gui.widget.data.InputResult; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Function; + +/** + * The implementation for mouse inputs. + */ +public final class MouseInputHandler { + public static void onMouseDown(GuiDescription description, CottonScreenImpl screen, int containerX, int containerY, int mouseButton) { + if (screen.getLastResponder() == null) { + WWidget lastResponder = description.getRootPanel().hit(containerX, containerY); + screen.setLastResponder(lastResponder); + if (lastResponder != null) { + runTree( + lastResponder, + widget -> widget.onMouseDown(containerX - widget.getAbsoluteX(), containerY - widget.getAbsoluteY(), mouseButton) + ); + } + } else { + // This is a drag instead + } + } + + public static <S extends Screen & CottonScreenImpl> void onMouseUp(GuiDescription description, S screen, int containerX, int containerY, int mouseButton) { + WWidget lastResponder = screen.getLastResponder(); + + if (lastResponder != null) { + int width = screen.width; + int height = screen.height; + + runTree( + lastResponder, + widget -> widget.onMouseUp(containerX - widget.getAbsoluteX(), containerY - widget.getAbsoluteY(), mouseButton) + ); + + if (containerX >= 0 && containerY >= 0 && containerX < width && containerY < height) { + runTree( + lastResponder, + widget -> widget.onClick(containerX - widget.getAbsoluteX(), containerY - widget.getAbsoluteY(), mouseButton) + ); + } + } else { + runTree( + description.getRootPanel().hit(containerX, containerY), + widget -> widget.onMouseUp(containerX - widget.getAbsoluteX(), containerY - widget.getAbsoluteY(), mouseButton) + ); + } + + screen.setLastResponder(null); + } + + public static <S extends Screen & CottonScreenImpl> void onMouseDrag(GuiDescription description, S screen, int containerX, int containerY, int mouseButton, double deltaX, double deltaY) { + WWidget lastResponder = screen.getLastResponder(); + + if (lastResponder != null) { + lastResponder.onMouseDrag(containerX - lastResponder.getAbsoluteX(), containerY - lastResponder.getAbsoluteY(), mouseButton, deltaX, deltaY); + } else { + int width = screen.width; + int height = screen.height; + + if (containerX < 0 || containerY < 0 || containerX >= width || containerY >= height) return; + + runTree( + description.getRootPanel().hit(containerX, containerY), + widget -> widget.onMouseDrag(containerX - widget.getAbsoluteX(), containerY - widget.getAbsoluteY(), mouseButton, deltaX, deltaY) + ); + } + } + + public static void onMouseScroll(GuiDescription description, int containerX, int containerY, double amount) { + runTree( + description.getRootPanel().hit(containerX, containerY), + widget -> widget.onMouseScroll(containerX - widget.getAbsoluteX(), containerY - widget.getAbsoluteY(), amount) + ); + } + + public static void onMouseMove(GuiDescription description, int containerX, int containerY) { + runTree( + description.getRootPanel().hit(containerX, containerY), + widget -> widget.onMouseMove(containerX - widget.getAbsoluteX(), containerY - widget.getAbsoluteY()) + ); + } + + /** + * Traverses the {@code function} up the widget tree until it finds a {@link InputResult#PROCESSED} result. + * + * @param bottom the starting point for the traversal + * @param function the function to run + * @return the first widget to return {@link InputResult#PROCESSED}, or null if none found. + */ + @Nullable + private static WWidget runTree(WWidget bottom, Function<WWidget, InputResult> function) { + WWidget current = bottom; + + while (current != null) { + InputResult result = function.apply(current); + + if (result == InputResult.PROCESSED) { + break; + } else { + current = current.getParent(); + } + } + + return current; + } +} diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java index 6c422bc..bc9807c 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WAbstractSlider.java @@ -5,6 +5,7 @@ import net.fabricmc.api.Environment; import net.minecraft.util.math.MathHelper; import io.github.cottonmc.cotton.gui.widget.data.Axis; +import io.github.cottonmc.cotton.gui.widget.data.InputResult; import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; @@ -108,28 +109,33 @@ public abstract class WAbstractSlider extends WWidget { @Environment(EnvType.CLIENT) @Override - public WWidget onMouseDown(int x, int y, int button) { + public InputResult onMouseDown(int x, int y, int button) { // Check if cursor is inside or <=2px away from track if (isMouseInsideBounds(x, y)) { requestFocus(); + return InputResult.PROCESSED; } - return super.onMouseDown(x, y, button); + return InputResult.IGNORED; } @Environment(EnvType.CLIENT) @Override - public void onMouseDrag(int x, int y, int button) { + public InputResult onMouseDrag(int x, int y, int button, double deltaX, double deltaY) { if (isFocused()) { dragging = true; moveSlider(x, y); + return InputResult.PROCESSED; } + + return InputResult.IGNORED; } @Environment(EnvType.CLIENT) @Override - public void onClick(int x, int y, int button) { + public InputResult onClick(int x, int y, int button) { moveSlider(x, y); if (draggingFinishedListener != null) draggingFinishedListener.accept(value); + return InputResult.PROCESSED; } private void moveSlider(int x, int y) { @@ -160,15 +166,15 @@ public abstract class WAbstractSlider extends WWidget { @Environment(EnvType.CLIENT) @Override - public WWidget onMouseUp(int x, int y, int button) { + public InputResult onMouseUp(int x, int y, int button) { dragging = false; if (draggingFinishedListener != null) draggingFinishedListener.accept(value); - return super.onMouseUp(x, y, button); + return InputResult.PROCESSED; } @Environment(EnvType.CLIENT) @Override - public void onMouseScroll(int x, int y, double amount) { + public InputResult onMouseScroll(int x, int y, double amount) { if (direction == Direction.LEFT || direction == Direction.DOWN) { amount = -amount; } @@ -180,6 +186,8 @@ public abstract class WAbstractSlider extends WWidget { onValueChanged(value); pendingDraggingFinishedFromScrolling = true; } + + return InputResult.PROCESSED; } @Environment(EnvType.CLIENT) diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java index deee662..3b5e4de 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WButton.java @@ -1,5 +1,7 @@ package io.github.cottonmc.cotton.gui.widget; +import io.github.cottonmc.cotton.gui.widget.data.InputResult; + import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; @@ -120,14 +122,17 @@ public class WButton extends WWidget { @Environment(EnvType.CLIENT) @Override - public void onClick(int x, int y, int button) { + public InputResult onClick(int x, int y, int button) { super.onClick(x, y, button); if (enabled && isWithinBounds(x, y)) { MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F)); if (onClick!=null) onClick.run(); + return InputResult.PROCESSED; } + + return InputResult.IGNORED; } @Environment(EnvType.CLIENT) diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabel.java index 78133b5..2bf9600 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabel.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WLabel.java @@ -1,7 +1,5 @@ package io.github.cottonmc.cotton.gui.widget; -import io.github.cottonmc.cotton.gui.impl.client.LibGuiConfig; - import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; @@ -15,7 +13,9 @@ import net.minecraft.text.Text; import io.github.cottonmc.cotton.gui.client.LibGui; import io.github.cottonmc.cotton.gui.client.ScreenDrawing; import io.github.cottonmc.cotton.gui.client.TextHoverRendererScreen; +import io.github.cottonmc.cotton.gui.impl.client.LibGuiConfig; import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment; +import io.github.cottonmc.cotton.gui.widget.data.InputResult; import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment; import org.jetbrains.annotations.Nullable; @@ -113,14 +113,16 @@ public class WLabel extends WWidget { @Environment(EnvType.CLIENT) @Override - public void onClick(int x, int y, int button) { + public InputResult onClick(int x, int y, int button) { Style hoveredTextStyle = getTextStyleAt(x, y); if (hoveredTextStyle != null) { Screen screen = MinecraftClient.getInstance().currentScreen; if (screen != null) { - screen.handleTextClick(hoveredTextStyle); + return InputResult.of(screen.handleTextClick(hoveredTextStyle)); } } + + return InputResult.IGNORED; } /** diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java index 09d4ace..b472d45 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WPanel.java @@ -92,70 +92,6 @@ public abstract class WPanel extends WWidget { this.setSize(Math.max(this.getWidth(), pushRight), Math.max(this.getHeight(), pushDown)); } - @Environment(EnvType.CLIENT) - @Override - public WWidget onMouseUp(int x, int y, int button) { - if (children.isEmpty()) return super.onMouseUp(x, y, button); - for(int i=children.size()-1; i>=0; i--) { //Backwards so topmost widgets get priority - WWidget child = children.get(i); - if ( x>=child.getX() && - y>=child.getY() && - x<child.getX()+child.getWidth() && - y<child.getY()+child.getHeight()) { - return child.onMouseUp(x-child.getX(), y-child.getY(), button); - } - } - return super.onMouseUp(x, y, button); - } - - @Environment(EnvType.CLIENT) - @Override - public WWidget onMouseDown(int x, int y, int button) { - if (children.isEmpty()) return super.onMouseDown(x, y, button); - for(int i=children.size()-1; i>=0; i--) { //Backwards so topmost widgets get priority - WWidget child = children.get(i); - if ( x>=child.getX() && - y>=child.getY() && - x<child.getX()+child.getWidth() && - y<child.getY()+child.getHeight()) { - return child.onMouseDown(x-child.getX(), y-child.getY(), button); - } - } - return super.onMouseDown(x, y, button); - } - - @Environment(EnvType.CLIENT) - @Override - public void onMouseDrag(int x, int y, int button) { - if (children.isEmpty()) return; - for(int i=children.size()-1; i>=0; i--) { //Backwards so topmost widgets get priority - WWidget child = children.get(i); - if ( x>=child.getX() && - y>=child.getY() && - x<child.getX()+child.getWidth() && - y<child.getY()+child.getHeight()) { - child.onMouseDrag(x-child.getX(), y-child.getY(), button); - return; //Only send the message to the first valid recipient - } - } - super.onMouseDrag(x, y, button); - } - /* - @Override - public void onClick(int x, int y, int button) { - if (children.isEmpty()) return; - for(int i=children.size()-1; i>=0; i--) { //Backwards so topmost widgets get priority - WWidget child = children.get(i); - if ( x>=child.getX() && - y>=child.getY() && - x<child.getX()+child.getWidth() && - y<child.getY()+child.getHeight()) { - child.onClick(x-child.getX(), y-child.getY(), button); - return; //Only send the message to the first valid recipient - } - } - }*/ - /** * Finds the most specific child node at this location. */ diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WScrollBar.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WScrollBar.java index 1f97f48..c08e141 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WScrollBar.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WScrollBar.java @@ -7,6 +7,7 @@ import net.minecraft.client.util.math.MatrixStack; import io.github.cottonmc.cotton.gui.client.LibGui; import io.github.cottonmc.cotton.gui.client.ScreenDrawing; import io.github.cottonmc.cotton.gui.widget.data.Axis; +import io.github.cottonmc.cotton.gui.widget.data.InputResult; public class WScrollBar extends WWidget { protected Axis axis = Axis.HORIZONTAL; @@ -166,7 +167,7 @@ public class WScrollBar extends WWidget { } @Override - public WWidget onMouseDown(int x, int y, int button) { + public InputResult onMouseDown(int x, int y, int button) { //TODO: Clicking before or after the handle should jump instead of scrolling requestFocus(); @@ -178,23 +179,24 @@ public class WScrollBar extends WWidget { anchorValue = value; } sliding = true; - return this; + return InputResult.PROCESSED; } @Environment(EnvType.CLIENT) @Override - public void onMouseDrag(int x, int y, int button) { + public InputResult onMouseDrag(int x, int y, int button, double deltaX, double deltaY) { adjustSlider(x, y); + return InputResult.PROCESSED; } @Environment(EnvType.CLIENT) @Override - public WWidget onMouseUp(int x, int y, int button) { + public InputResult onMouseUp(int x, int y, int button) { //TODO: Clicking before or after the handle should jump instead of scrolling anchor = -1; anchorValue = -1; sliding = false; - return this; + return InputResult.PROCESSED; } @Override @@ -216,8 +218,9 @@ public class WScrollBar extends WWidget { @Environment(EnvType.CLIENT) @Override - public void onMouseScroll(int x, int y, double amount) { + public InputResult onMouseScroll(int x, int y, double amount) { setValue(getValue() + (int) -amount); + return InputResult.PROCESSED; } public int getValue() { diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WTabPanel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WTabPanel.java index 48a5e59..2ba08be 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WTabPanel.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WTabPanel.java @@ -1,7 +1,5 @@ package io.github.cottonmc.cotton.gui.widget; -import io.github.cottonmc.cotton.gui.impl.LibGuiCommon; - import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; @@ -15,8 +13,10 @@ import net.minecraft.util.Identifier; import io.github.cottonmc.cotton.gui.client.BackgroundPainter; import io.github.cottonmc.cotton.gui.client.LibGui; import io.github.cottonmc.cotton.gui.client.ScreenDrawing; +import io.github.cottonmc.cotton.gui.impl.LibGuiCommon; import io.github.cottonmc.cotton.gui.widget.data.Axis; import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment; +import io.github.cottonmc.cotton.gui.widget.data.InputResult; import io.github.cottonmc.cotton.gui.widget.icon.Icon; import org.jetbrains.annotations.Nullable; @@ -288,7 +288,7 @@ public class WTabPanel extends WPanel { @Environment(EnvType.CLIENT) @Override - public void onClick(int x, int y, int button) { + public InputResult onClick(int x, int y, int button) { super.onClick(x, y, button); MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F)); @@ -299,6 +299,7 @@ public class WTabPanel extends WPanel { mainPanel.setSelectedCard(data.getWidget()); WTabPanel.this.layout(); + return InputResult.PROCESSED; } @Environment(EnvType.CLIENT) diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WText.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WText.java index 4ce4440..cf3d9ec 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WText.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WText.java @@ -14,6 +14,7 @@ import io.github.cottonmc.cotton.gui.client.LibGui; import io.github.cottonmc.cotton.gui.client.ScreenDrawing; import io.github.cottonmc.cotton.gui.client.TextHoverRendererScreen; import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment; +import io.github.cottonmc.cotton.gui.widget.data.InputResult; import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment; import org.jetbrains.annotations.Nullable; @@ -125,13 +126,16 @@ public class WText extends WWidget { @Environment(EnvType.CLIENT) @Override - public void onClick(int x, int y, int button) { - if (button != 0) return; // only left clicks + public InputResult onClick(int x, int y, int button) { + if (button != 0) return InputResult.IGNORED; // only left clicks Style hoveredTextStyle = getTextStyleAt(x, y); if (hoveredTextStyle != null) { - MinecraftClient.getInstance().currentScreen.handleTextClick(hoveredTextStyle); + boolean processed = MinecraftClient.getInstance().currentScreen.handleTextClick(hoveredTextStyle); + return InputResult.of(processed); } + + return InputResult.IGNORED; } /** diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WTextField.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WTextField.java index e4f36de..c9fd92e 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WTextField.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WTextField.java @@ -17,6 +17,7 @@ import net.minecraft.util.math.MathHelper; import io.github.cottonmc.cotton.gui.client.BackgroundPainter; import io.github.cottonmc.cotton.gui.client.ScreenDrawing; +import io.github.cottonmc.cotton.gui.widget.data.InputResult; import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; import org.lwjgl.opengl.GL11; @@ -538,9 +539,10 @@ public class WTextField extends WWidget { @Environment(EnvType.CLIENT) @Override - public void onClick(int x, int y, int button) { + public InputResult onClick(int x, int y, int button) { requestFocus(); cursor = getCaretPos(this.text, x-OFFSET_X_TEXT); + return InputResult.PROCESSED; } @Environment(EnvType.CLIENT) diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java index c74f131..8953f4d 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WToggleButton.java @@ -1,7 +1,5 @@ package io.github.cottonmc.cotton.gui.widget; -import io.github.cottonmc.cotton.gui.impl.LibGuiCommon; - import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; @@ -13,6 +11,8 @@ import net.minecraft.util.Identifier; import io.github.cottonmc.cotton.gui.client.LibGui; import io.github.cottonmc.cotton.gui.client.ScreenDrawing; +import io.github.cottonmc.cotton.gui.impl.LibGuiCommon; +import io.github.cottonmc.cotton.gui.widget.data.InputResult; import io.github.cottonmc.cotton.gui.widget.data.Texture; import org.jetbrains.annotations.Nullable; @@ -125,13 +125,12 @@ public class WToggleButton extends WWidget { @Environment(EnvType.CLIENT) @Override - public void onClick(int x, int y, int button) { - super.onClick(x, y, button); - + public InputResult onClick(int x, int y, int button) { MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F)); this.isOn = !this.isOn; onToggle(this.isOn); + return InputResult.PROCESSED; } @Override diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java index cd3c31b..9507983 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WWidget.java @@ -1,5 +1,7 @@ package io.github.cottonmc.cotton.gui.widget; +import io.github.cottonmc.cotton.gui.widget.data.InputResult; + import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; @@ -150,41 +152,31 @@ public class WWidget { /** * Notifies this widget that the mouse has been pressed while inside its bounds + * * @param x The X coordinate of the event, in widget-space (0 is the left edge of this widget) * @param y The Y coordinate of the event, in widget-space (0 is the top edge of this widget) * @param button The mouse button that was used. Button numbering is consistent with LWJGL Mouse (0=left, 1=right, 2=mousewheel click) + * @return {@link InputResult#PROCESSED} if the event is handled, {@link InputResult#IGNORED} otherwise. */ @Environment(EnvType.CLIENT) - public WWidget onMouseDown(int x, int y, int button) { - return this; + public InputResult onMouseDown(int x, int y, int button) { + return InputResult.IGNORED; } /** * Notifies this widget that the mouse has been moved while pressed and inside its bounds. * - * <p>The default implementation calls {@link #onMouseDrag(int, int, int)} for backwards compatibility. - * * @param x The X coordinate of the event, in widget-space (0 is the left edge of this widget) * @param y The Y coordinate of the event, in widget-space (0 is the top edge of this widget) * @param button The mouse button that was used. Button numbering is consistent with LWJGL Mouse (0=left, 1=right, 2=mousewheel click) * @param deltaX The amount of dragging on the X axis * @param deltaY The amount of dragging on the Y axis - * + * @return {@link InputResult#PROCESSED} if the event is handled, {@link InputResult#IGNORED} otherwise. * @since 1.5.0 */ @Environment(EnvType.CLIENT) - public void onMouseDrag(int x, int y, int button, double deltaX, double deltaY) { - onMouseDrag(x, y, button); - } - - /** - * Notifies this widget that the mouse has been moved while pressed and inside its bounds - * @param x The X coordinate of the event, in widget-space (0 is the left edge of this widget) - * @param y The Y coordinate of the event, in widget-space (0 is the top edge of this widget) - * @param button The mouse button that was used. Button numbering is consistent with LWJGL Mouse (0=left, 1=right, 2=mousewheel click) - */ - @Environment(EnvType.CLIENT) - public void onMouseDrag(int x, int y, int button) { + public InputResult onMouseDrag(int x, int y, int button, double deltaX, double deltaY) { + return InputResult.IGNORED; } /** @@ -192,30 +184,37 @@ public class WWidget { * @param x The X coordinate of the event, in widget-space (0 is the left edge of this widget) * @param y The Y coordinate of the event, in widget-space (0 is the top edge of this widget) * @param button The mouse button that was used. Button numbering is consistent with LWJGL Mouse (0=left, 1=right, 2=mousewheel click) + * @return {@link InputResult#PROCESSED} if the event is handled, {@link InputResult#IGNORED} otherwise. */ @Environment(EnvType.CLIENT) - public WWidget onMouseUp(int x, int y, int button) { - return this; + public InputResult onMouseUp(int x, int y, int button) { + return InputResult.IGNORED; } /** * Notifies this widget that the mouse has been pressed and released, both while inside its bounds. + * * @param x The X coordinate of the event, in widget-space (0 is the left edge of this widget) * @param y The Y coordinate of the event, in widget-space (0 is the top edge of this widget) * @param button The mouse button that was used. Button numbering is consistent with LWJGL Mouse (0=left, 1=right, 2=mousewheel click) + * @return {@link InputResult#PROCESSED} if the event is handled, {@link InputResult#IGNORED} otherwise. */ @Environment(EnvType.CLIENT) - public void onClick(int x, int y, int button) { + public InputResult onClick(int x, int y, int button) { + return InputResult.IGNORED; } /** * Notifies this widget that the mouse has been scrolled inside its bounds. + * * @param x The X coordinate of the event, in widget-space (0 is the left edge of this widget) * @param y The Y coordinate of the event, in widget-space (0 is the top edge of this widget) * @param amount The scrolled amount. Positive values are up and negative values are down. + * @return {@link InputResult#PROCESSED} if the event is handled, {@link InputResult#IGNORED} otherwise. */ @Environment(EnvType.CLIENT) - public void onMouseScroll(int x, int y, double amount) { + public InputResult onMouseScroll(int x, int y, double amount) { + return InputResult.IGNORED; } /** @@ -223,10 +222,12 @@ public class WWidget { * * @param x The X coordinate of the event, in widget-space (0 is the left edge of this widget) * @param y The Y coordinate of the event, in widget-space (0 is the top edge of this widget) + * @return {@link InputResult#PROCESSED} if the event is handled, {@link InputResult#IGNORED} otherwise. * @since 1.5.0 */ @Environment(EnvType.CLIENT) - public void onMouseMove(int x, int y) { + public InputResult onMouseMove(int x, int y) { + return InputResult.IGNORED; } /** diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/data/InputResult.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/data/InputResult.java new file mode 100644 index 0000000..97e8215 --- /dev/null +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/data/InputResult.java @@ -0,0 +1,22 @@ +package io.github.cottonmc.cotton.gui.widget.data; + +/** + * Specifies whether an input event was ignored or processed. + * Used for mouse input events. + * + * @since 4.0.0 + */ +public enum InputResult { + PROCESSED, + IGNORED; + + /** + * Gets the corresponding input result for a {@code processed} boolean. + * + * @param processed whether an input event was processed + * @return {@link #PROCESSED} if true, {@link #IGNORED} otherwise + */ + public static InputResult of(boolean processed) { + return processed ? PROCESSED : IGNORED; + } +} |