diff --git a/common-testmod/src/main/java/me/pandamods/test/client/screen/TestScreen.java b/common-testmod/src/main/java/me/pandamods/test/client/screen/TestScreen.java index 4675f25f..8fe17a2b 100644 --- a/common-testmod/src/main/java/me/pandamods/test/client/screen/TestScreen.java +++ b/common-testmod/src/main/java/me/pandamods/test/client/screen/TestScreen.java @@ -18,6 +18,7 @@ import me.pandamods.pandalib.client.screen.layouts.StackContainer; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; import net.minecraft.network.chat.Component; public class TestScreen extends BasePLScreen { @@ -31,9 +32,12 @@ protected void build(StackContainer rootComponent) { button -> System.out.println("Test click")) .width(200) .build()); - vanillaTestButton.mount(rootComponent); + EditBox editBox = new EditBox(Minecraft.getInstance().font, 0, 0, 200, 20, Component.literal("Test TextField")); + VanillaUIComponent vanillaTestTextField = VanillaUIComponent.of(editBox); + vanillaTestTextField.mount(rootComponent); + TextUIComponent textUIComponent = new TextUIComponent(Minecraft.getInstance().font, Component.literal("Test Text")); textUIComponent.mount(rootComponent); } diff --git a/common/src/main/java/me/pandamods/pandalib/client/screen/BasePLScreen.java b/common/src/main/java/me/pandamods/pandalib/client/screen/BasePLScreen.java index 17f53772..80380bcc 100644 --- a/common/src/main/java/me/pandamods/pandalib/client/screen/BasePLScreen.java +++ b/common/src/main/java/me/pandamods/pandalib/client/screen/BasePLScreen.java @@ -62,25 +62,19 @@ public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, doubl @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - FocusHandler focusHandler = this.rootComponent.getFocusHandler(); - if (focusHandler != null && focusHandler.isFocusing() && focusHandler.getFocusedComponent().keyPressed(keyCode, scanCode, modifiers)) - return true; + if (this.rootComponent.keyPressed(keyCode, scanCode, modifiers)) return true; return super.keyPressed(keyCode, scanCode, modifiers); } @Override public boolean keyReleased(int keyCode, int scanCode, int modifiers) { - FocusHandler focusHandler = this.rootComponent.getFocusHandler(); - if (focusHandler != null && focusHandler.isFocusing() && focusHandler.getFocusedComponent().keyReleased(keyCode, scanCode, modifiers)) - return true; + if (this.rootComponent.keyReleased(keyCode, scanCode, modifiers)) return true; return super.keyReleased(keyCode, scanCode, modifiers); } @Override public boolean charTyped(char codePoint, int modifiers) { - FocusHandler focusHandler = this.rootComponent.getFocusHandler(); - if (focusHandler != null && focusHandler.isFocusing() && focusHandler.getFocusedComponent().charTyped(codePoint, modifiers)) - return true; + if (this.rootComponent.charTyped(codePoint, modifiers)) return true; return super.charTyped(codePoint, modifiers); } } diff --git a/common/src/main/java/me/pandamods/pandalib/client/screen/BaseParentUIComponent.java b/common/src/main/java/me/pandamods/pandalib/client/screen/BaseParentUIComponent.java index c7827929..032a0818 100644 --- a/common/src/main/java/me/pandamods/pandalib/client/screen/BaseParentUIComponent.java +++ b/common/src/main/java/me/pandamods/pandalib/client/screen/BaseParentUIComponent.java @@ -19,15 +19,16 @@ import org.jetbrains.annotations.Nullable; public abstract class BaseParentUIComponent extends BaseUIComponent implements ParentUIComponent { - private FocusHandler focusHandler = new FocusHandler(this); + protected FocusHandler focusHandler = new FocusHandler(this); @Override public void render(RenderContext context, int mouseX, int mouseY, float partialTicks) { Runnable renderChildren = () -> renderChildren(context, mouseX, mouseY, partialTicks); - if (this.isOverflowAllowed()) + if (this.isOverflowAllowed()) { renderChildren.run(); - else + }else { context.scissor(this.getX(), this.getY(), this.getX() + this.getWidth(), this.getY() + this.getHeight(), renderChildren); + } } protected void renderChildren(RenderContext context, int mouseX, int mouseY, float partialTicks) { @@ -53,12 +54,4 @@ public void updateChildState(UIComponent uiComponent) { protected abstract void addChild(UIComponent UIComponent); protected abstract void removeChild(UIComponent UIComponent); - - @Override - public @Nullable FocusHandler getFocusHandler() { - FocusHandler focusHandler = super.getFocusHandler(); - if (focusHandler == null) - focusHandler = this.focusHandler; - return focusHandler; - } } diff --git a/common/src/main/java/me/pandamods/pandalib/client/screen/BaseUIComponent.java b/common/src/main/java/me/pandamods/pandalib/client/screen/BaseUIComponent.java index 52b902d5..47109a70 100644 --- a/common/src/main/java/me/pandamods/pandalib/client/screen/BaseUIComponent.java +++ b/common/src/main/java/me/pandamods/pandalib/client/screen/BaseUIComponent.java @@ -14,7 +14,6 @@ import me.pandamods.pandalib.client.screen.core.ParentUIComponent; import me.pandamods.pandalib.client.screen.core.UIComponent; -import me.pandamods.pandalib.client.screen.utils.FocusHandler; import org.jetbrains.annotations.Nullable; public abstract class BaseUIComponent implements UIComponent { @@ -43,11 +42,6 @@ public void dismount() { mount(null); } - @Override - public @Nullable FocusHandler getFocusHandler() { - return this.hasParent() ? this.getParent().getFocusHandler() : null; - } - @Override public void setX(int x) { this.x = x; diff --git a/common/src/main/java/me/pandamods/pandalib/client/screen/components/VanillaUIComponent.java b/common/src/main/java/me/pandamods/pandalib/client/screen/components/VanillaUIComponent.java index d25d799f..12177d55 100644 --- a/common/src/main/java/me/pandamods/pandalib/client/screen/components/VanillaUIComponent.java +++ b/common/src/main/java/me/pandamods/pandalib/client/screen/components/VanillaUIComponent.java @@ -111,4 +111,14 @@ public boolean mouseReleased(double mouseX, double mouseY, int button) { public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) { return this.widget.mouseScrolled(mouseX, mouseY, scrollX, scrollY); } + + @Override + public void onFocusGained() { + this.widget.setFocused(true); + } + + @Override + public void onFocusLost() { + this.widget.setFocused(false); + } } diff --git a/common/src/main/java/me/pandamods/pandalib/client/screen/core/ParentUIComponent.java b/common/src/main/java/me/pandamods/pandalib/client/screen/core/ParentUIComponent.java index a6c0300f..ecca5a49 100644 --- a/common/src/main/java/me/pandamods/pandalib/client/screen/core/ParentUIComponent.java +++ b/common/src/main/java/me/pandamods/pandalib/client/screen/core/ParentUIComponent.java @@ -12,6 +12,8 @@ package me.pandamods.pandalib.client.screen.core; +import me.pandamods.pandalib.client.screen.utils.FocusHandler; + import java.util.List; public interface ParentUIComponent extends UIComponent { @@ -36,21 +38,16 @@ default UIComponent getChildAt(int x, int y) { return isInBoundingBox(x, y) ? this : null; } - @Override - default boolean keyPressed(int keyCode, int scanCode, int modifiers) { - return UIComponent.super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - default boolean keyReleased(int keyCode, int scanCode, int modifiers) { - return UIComponent.super.keyReleased(keyCode, scanCode, modifiers); - } - @Override default boolean mousePressed(double mouseX, double mouseY, int button) { for (UIComponent child : getChildren()) { if (!child.isInBoundingBox(getX() + mouseX, getY() + mouseY)) continue; - if (child.mousePressed(mouseX, mouseY, button)) return true; + if (child.mousePressed(mouseX, mouseY, button)) { + FocusHandler focusHandler = getFocusHandler(); + if (focusHandler != null) + focusHandler.focus(child); + return true; + } } return UIComponent.super.mousePressed(mouseX, mouseY, button); diff --git a/common/src/main/java/me/pandamods/pandalib/client/screen/core/UIComponent.java b/common/src/main/java/me/pandamods/pandalib/client/screen/core/UIComponent.java index 6bf4b07f..a9a00a25 100644 --- a/common/src/main/java/me/pandamods/pandalib/client/screen/core/UIComponent.java +++ b/common/src/main/java/me/pandamods/pandalib/client/screen/core/UIComponent.java @@ -12,9 +12,10 @@ package me.pandamods.pandalib.client.screen.core; +import me.pandamods.pandalib.client.screen.BasePLScreen; import me.pandamods.pandalib.client.screen.utils.FocusHandler; import me.pandamods.pandalib.client.screen.utils.RenderContext; -import org.jetbrains.annotations.Nullable; +import net.minecraft.client.Minecraft; public interface UIComponent { void render(RenderContext context, int mouseX, int mouseY, float partialTicks); @@ -28,13 +29,19 @@ default boolean hasParent() { void mount(ParentUIComponent parent); void dismount(); + default boolean isMounted() { + return this.hasParent(); + } + default ParentUIComponent root() { ParentUIComponent root = this.getParent(); while (root.hasParent()) root = root.getParent(); return root; } - @Nullable FocusHandler getFocusHandler(); + default FocusHandler getFocusHandler() { + return this.hasParent() ? this.getParent().getFocusHandler() : null; + } void setX(int x); void setY(int y); @@ -56,6 +63,7 @@ default void position(int x, int y) { setX(x); setY(y); } + default void size(int width, int height) { setWidth(width); setHeight(height); @@ -87,4 +95,7 @@ default boolean mouseReleased(double mouseX, double mouseY, int button) { default boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) { return false; } + + default void onFocusGained() {} + default void onFocusLost() {} } diff --git a/common/src/main/java/me/pandamods/pandalib/client/screen/utils/FocusHandler.java b/common/src/main/java/me/pandamods/pandalib/client/screen/utils/FocusHandler.java index e9b69ed8..0aace36c 100644 --- a/common/src/main/java/me/pandamods/pandalib/client/screen/utils/FocusHandler.java +++ b/common/src/main/java/me/pandamods/pandalib/client/screen/utils/FocusHandler.java @@ -12,30 +12,41 @@ package me.pandamods.pandalib.client.screen.utils; +import me.pandamods.pandalib.client.screen.BaseParentUIComponent; import me.pandamods.pandalib.client.screen.core.ParentUIComponent; import me.pandamods.pandalib.client.screen.core.UIComponent; -import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Nullable; public class FocusHandler { - protected final ParentUIComponent root; + private final ParentUIComponent root; - protected UIComponent focusedComponent; + @Nullable + protected UIComponent focused; public FocusHandler(ParentUIComponent root) { this.root = root; } - public void setFocused(UIComponent component) { - this.focusedComponent = component; + public void focus(UIComponent focused) { + if (this.focused != null) this.focused.onFocusLost(); + this.focused = focused; + if (this.focused != null) this.focused.onFocusGained(); + } + + public void clearFocus() { + focus(null); } @Nullable - public UIComponent getFocusedComponent() { - return focusedComponent; + public UIComponent getFocused() { + return focused; + } + + public boolean isFocused(UIComponent component) { + return focused == component; } - public boolean isFocusing() { - return getFocusedComponent() != null; + public ParentUIComponent getRoot() { + return root; } }