diff --git a/gradle.properties b/gradle.properties index f3b2f7b..da53e0c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Done to increase the memory available to Gradle. -org.gradle.jvmargs=-Xmx2G +org.gradle.jvmargs=-Xmx4G org.gradle.parallel=true org.gradle.warning.mode=all @@ -11,7 +11,7 @@ maven.group = com.thecsdev # Mod properties mod.id = tcdcommons -mod.version = 5.5.6 +mod.version = 5.6.0-beta.1 mod.name = TCDCommons API mod.description = TheCSDev's personal Minecraft modding library. mod.author = TheCSDev @@ -22,14 +22,14 @@ mod.link.sources = https://thecsdev.com/fwd/tcdcommons-sources/ mod.link.issues = https://thecsdev.com/fwd/tcdcommons-issues/ # 'pack.mcmeta' properties -pack.format = 88 +pack.format = 97.1 # Minecraft properties -minecraft.version = 26.2 +minecraft.version = 26.3 # Fabric properties -fabric.loader_version = 0.19.2 -fabric.api_version = 0.152.1+26.2 +fabric.loader_version = 0.19.5 +fabric.api_version = 0.160.5+26.3 # fabric.mod.json properties fabric.json.entrypoints.main = com.thecsdev.commonmc.fabric.TCDCommonsFabric @@ -37,8 +37,8 @@ fabric.api_version = 0.152.1+26.2 fabric.json.entrypoints.server = com.thecsdev.commonmc.fabric.TCDCommonsFabric fabric.json.depends.java = >=25 - fabric.json.depends.minecraft = ~26.2 - fabric.json.depends.fabricloader = >=0.18.5 + fabric.json.depends.minecraft = >=26.3- <26.4 + fabric.json.depends.fabricloader = >=0.19.5 fabric.json.depends.fabric-api = * # Neo-Forge properties @@ -47,4 +47,4 @@ neoforge.version = 26.2.0.1-beta # neoforge.mods.toml properties net.toml.loaderVersion = [4,) neo.toml.dependencies.neoforge = [26.2.0.1-beta,) - neo.toml.dependencies.minecraft = [26.2, 26.3) + neo.toml.dependencies.minecraft = [26.3-, 26.4) diff --git a/src/main/java/com/thecsdev/common/math/TMath.java b/src/main/java/com/thecsdev/common/math/TMath.java index 63df55c..bd1985f 100644 --- a/src/main/java/com/thecsdev/common/math/TMath.java +++ b/src/main/java/com/thecsdev/common/math/TMath.java @@ -9,36 +9,6 @@ public final class TMath // ================================================== private TMath() {} // ================================================== - /** - * Clamps a {@code int} value to the given {@code min/max} range. - * @param value the value to clamp - * @param min The minimum value. - * @param max The maximum value. - * @return {@code min} if {@code value < min}, {@code max} if {@code value > max}, otherwise {@code value}. - */ - @Deprecated(forRemoval = true) - public static final int clampi(int value, int min, int max) { return Math.max(min, Math.min(max, value)); } - - /** - * Clamps a {@code float} value to the given {@code min/max} range. - * @param value the value to clamp - * @param min The minimum value. - * @param max The maximum value. - * @return {@code min} if {@code value < min}, {@code max} if {@code value > max}, otherwise {@code value}. - */ - @Deprecated(forRemoval = true) - public static final float clampf(float value, float min, float max) { return Math.max(min, Math.min(max, value)); } - - /** - * Clamps a {@code double} value to the given {@code min/max} range. - * @param value the value to clamp - * @param min The minimum value. - * @param max The maximum value. - * @return {@code min} if {@code value < min}, {@code max} if {@code value > max}, otherwise {@code value}. - */ - @Deprecated(forRemoval = true) - public static final double clampd(double value, double min, double max) { return Math.max(min, Math.min(max, value)); } - // -------------------------------------------------- /** * Clamps a {@code float} value to the range [0.0f, 1.0f]. * @param value the value to clamp diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/ctxmenu/TContextMenu.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/ctxmenu/TContextMenu.java index 1f1b00d..9759a19 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/ctxmenu/TContextMenu.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/ctxmenu/TContextMenu.java @@ -38,7 +38,7 @@ import static com.thecsdev.commonmc.api.client.gui.util.TInputContext.InputType.MOUSE_PRESS; import static java.lang.Math.max; import static java.lang.Math.min; -import static org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE; +import static org.lwjgl.sdl.SDLScancode.SDL_SCANCODE_ESCAPE; /** * A {@link TContextMenu} is a specialized {@link TElement} that represents a context menu @@ -63,10 +63,10 @@ public TContextMenu() focusableProperty().set(true, TContextMenu.class); //in order to have child context menus be visible, we need not clip descendants clipsDescendantsProperty().set(false, TContextMenu.class); - clipsDescendantsProperty().addFilter(__ -> false, TContextMenu.class); + clipsDescendantsProperty().addFilter(_ -> false, TContextMenu.class); //handle being assigned to a new screen - screenProperty().addChangeListener((p, o, n) -> { + screenProperty().addChangeListener((_, _, n) -> { //ignore removals from screens (aka screen becoming null) if(n == null) return; //remove other dropdown elements "branches". there cannot be more than one @@ -82,7 +82,7 @@ public TContextMenu() }); //ensure the parent is always a screen or another context menu - parentProperty().addChangeListener((p, o, n) -> { + parentProperty().addChangeListener((_, _, n) -> { if(n == null) return; if(!(n instanceof TScreen) && !(n instanceof TContextMenu)) { n.remove(this); //restore to stable state - caution: re-invokes this change listener @@ -93,13 +93,13 @@ public TContextMenu() //tracking the root context menu element (this has to be placed last) this.rootContextMenu.setReadOnly(true, TContextMenu.class); this.rootContextMenu.setOwner(PropertyAccessor.class, TContextMenu.class); - this.rootContextMenu.addChangeListener((p, o, n) -> { + this.rootContextMenu.addChangeListener((_, _, n) -> { //propagate the new root context menu to all child context menus for(final var child : this) if(child instanceof TContextMenu childMenu) setRootCtxMenuValue(childMenu, n); }); - parentProperty().addChangeListener((p, o, n) -> { + parentProperty().addChangeListener((_, _, _) -> { //find the root context menu and set it @NotNull TContextMenu root = this; @Nullable TElement next = this; @@ -139,7 +139,7 @@ public TContextMenu() //close this dropdown if a key press happens without focus //to this dropdown or one of its (grand/)children case KEY_PRESS: { - if(!isFocusAncestor() || context.getKeyCode() == GLFW_KEY_ESCAPE) + if(!isFocusAncestor() || context.getScanCode() == SDL_SCANCODE_ESCAPE) return remove(); else break; } @@ -299,7 +299,7 @@ public final Builder addButton( btn.setBounds(0, 0, this.client.font.width(text) + (TButtonWidget.LBL_PAD_X * 2), 15); btn.eClicked.addListener(onClick); //on-click goes first, as is may rely on btn#getClient() btn.eClicked.addListener( //then remove, which also clears the screen/client property value - __ -> btn.getParentMenu().rootContextMenuProperty().get().remove()); + _ -> btn.getParentMenu().rootContextMenuProperty().get().remove()); this.entries.add(btn); return this; } @@ -319,7 +319,7 @@ public final Builder addContextMenu( btn.getLabel().setText(text); btn.getLabel().textAlignmentProperty().set(CompassDirection.WEST, Builder.class); btn.setBounds(0, 0, this.client.font.width(text) + (TButtonWidget.LBL_PAD_X * 2), 15); - btn.eClicked.addListener(__ -> { + btn.eClicked.addListener(_ -> { //add the context menu final var menu = Objects.requireNonNull(menuBuilder.apply(btn), "Context menu Supplier returned 'null'"); btn.getParentMenu().add(menu); diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TTextureElement.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TTextureElement.java index 62e97fa..cc947ee 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TTextureElement.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/misc/TTextureElement.java @@ -1,6 +1,6 @@ package com.thecsdev.commonmc.api.client.gui.misc; -import com.mojang.blaze3d.pipeline.RenderPipeline; +import com.mojang.renderpearl.api.pipeline.RenderPipeline; import com.thecsdev.common.properties.IntegerProperty; import com.thecsdev.common.properties.NotNullProperty; import com.thecsdev.common.util.annotations.Virtual; @@ -8,12 +8,12 @@ import com.thecsdev.commonmc.api.client.gui.render.TGuiGraphics; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import static net.minecraft.client.renderer.RenderPipelines.GUI_TEXTURED; -import static net.minecraft.client.renderer.texture.TextureManager.INTENTIONAL_MISSING_TEXTURE; /** * A {@link TElement} whose sole purpose is to render a sprite/texture. @@ -25,7 +25,7 @@ // TTextureElement IMPLEMENTATION // ================================================== ================================================== private final NotNullProperty renderPipeline = new NotNullProperty<>(GUI_TEXTURED); - private final NotNullProperty texture = new NotNullProperty<>(INTENTIONAL_MISSING_TEXTURE); + private final NotNullProperty texture = new NotNullProperty<>(MissingTextureAtlasSprite.getLocation()); private final NotNullProperty mode = new NotNullProperty<>(Mode.TEXTURE); private final IntegerProperty color = new IntegerProperty(0xFFFFFFFF); // ================================================== diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/panel/TPanelElement.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/panel/TPanelElement.java index 6a88aa7..af82604 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/panel/TPanelElement.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/panel/TPanelElement.java @@ -11,7 +11,10 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import org.jetbrains.annotations.NotNull; -import org.lwjgl.glfw.GLFW; + +import static org.lwjgl.sdl.SDLMouse.SDL_BUTTON_LEFT; +import static org.lwjgl.sdl.SDLMouse.SDL_BUTTON_MIDDLE; +import static org.lwjgl.sdl.SDLScancode.*; /** * A panel element primarily featuring functionality like scrolling. @@ -38,7 +41,7 @@ public TPanelElement() //clamp01 the scroll amount this.scrollAmount.addFilter(Point2d::clamp01, TPanelElement.class); - this.scrollAmount.addChangeListener((p, o, n) -> { + this.scrollAmount.addChangeListener((_, _, _) -> { final var ccb = getContentBounds(); final var ncb = computeContentBoundsFromScrollAmount(); moveChildren(ncb.x - ccb.x, ncb.y - ccb.y); @@ -84,7 +87,7 @@ public TPanelElement() switch(context.getInputType()) { //mouse press should result in focus, so we return true here - case MOUSE_PRESS: return (context.getMouseButton() == 0 || context.getMouseButton() == 2) && isFocusable(); + case MOUSE_PRESS: return (context.getMouseButton() == SDL_BUTTON_LEFT || context.getMouseButton() == SDL_BUTTON_MIDDLE) && isFocusable(); //mouse scroll should result in scrolling case MOUSE_SCROLL: { final int ss = this.scrollSensitivity.getI(); @@ -117,11 +120,11 @@ public TPanelElement() final int s = this.scrollSensitivity.getI(); int dX = 0, dY = 0; //noinspection DataFlowIssue - switch(context.getKeyCode()) { - case GLFW.GLFW_KEY_UP: dY += s; break; - case GLFW.GLFW_KEY_DOWN: dY -= s; break; - case GLFW.GLFW_KEY_LEFT: dX += s; break; - case GLFW.GLFW_KEY_RIGHT: dX -= s; break; + switch(context.getScanCode()) { + case SDL_SCANCODE_UP: dY += s; break; + case SDL_SCANCODE_DOWN: dY -= s; break; + case SDL_SCANCODE_LEFT: dX += s; break; + case SDL_SCANCODE_RIGHT: dX -= s; break; default: break; } if(dX != 0 || dY != 0) { scroll(dX, dY); return true; } @@ -141,8 +144,7 @@ public TPanelElement() */ private final Bounds2i computeContentBoundsFromScrollAmount() { - //Point2d - constructor: new Point2d(double x, double y) - fields: .x .y (doubles) - //Bounds2i fields: .x .y .width .height .endX .endY (integers) + //prerequisites final Bounds2i bb = getBounds(); //current rectangle of this element (viewport) final Bounds2i cbb = getContentBounds(); //current rectangle encapsulating all children bounding boxes final Point2d sa = this.scrollAmount.get(); @@ -183,11 +185,10 @@ private final Bounds2i computeContentBoundsFromScrollAmount() */ private final Point2d computeScrollAmountFromContentBounds() { - //Point2d - constructor: new Point2d(double x, double y) - fields: .x .y (doubles) - //Bounds2i fields: .x .y .width .height .endX .endY (integers) + //prerequisites final Bounds2i bb = getBounds(); //rectangle of this element (viewport) final Bounds2i cbb = getContentBounds(); //rectangle encapsulating all children bounding boxes - final int sp = this.scrollPadding.getI(); // NEW: Scroll Padding + final int sp = this.scrollPadding.getI(); //scroll padding // 1. Calculate the effective maximum scrollable distance (delta) // The scrollable range is reduced by 2 * sp. @@ -201,21 +202,8 @@ private final Point2d computeScrollAmountFromContentBounds() final double offsetX = (bb.x + sp) - cbb.x; final double offsetY = (bb.y + sp) - cbb.y; - double scrollAmountX; - if (maxScrollX > 0) { - // sa = Offset / MaxScroll. - scrollAmountX = offsetX / maxScrollX; - } else { - // Content fits or is smaller than viewport, so scroll is 0. - scrollAmountX = 0.0; - } - - double scrollAmountY; - if (maxScrollY > 0) { - scrollAmountY = offsetY / maxScrollY; - } else { - scrollAmountY = 0.0; - } + double scrollAmountX = (maxScrollX > 0) ? (offsetX / maxScrollX) : 0.0; + double scrollAmountY = (maxScrollY > 0) ? (offsetY / maxScrollY) : 0.0; // The scroll amount should be between 0 and 1. // We ensure this using Math.min/max, just in case of floating point inaccuracies or external manipulation. diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/panel/window/TWindowElement.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/panel/window/TWindowElement.java index 4ad602a..3967d3a 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/panel/window/TWindowElement.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/panel/window/TWindowElement.java @@ -22,6 +22,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static org.lwjgl.sdl.SDLMouse.SDL_BUTTON_LEFT; + /** * {@link TElement} implementation that has the visual appearance to that of a "window", * featuring a title-bar that has a title label and control buttons like [X]. @@ -140,11 +142,11 @@ public TWindowElement() return switch(context.getInputType()) { //LMB mouse press returns true, so drag input can be handled - case MOUSE_PRESS -> context.getMouseButton() == 0; + case MOUSE_PRESS -> context.getMouseButton() == SDL_BUTTON_LEFT; //mouse release stops the drag, so clear the drag values case MOUSE_RELEASE -> { //FIXME - Releasing another button causes this to yield false. This is an issue in the input system. - if(context.getMouseButton() != 0) yield false; + if(context.getMouseButton() != SDL_BUTTON_LEFT) yield false; this.dragDeltaX = this.dragDeltaY = 0; TGuiUtils.keepElementWithinBounds(this, getParent().getBounds()); yield true; diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphics.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphics.java index 7ffa8a2..e3449a8 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphics.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphics.java @@ -1,8 +1,8 @@ package com.thecsdev.commonmc.api.client.gui.render; -import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.platform.cursor.CursorType; +import com.mojang.renderpearl.api.pipeline.RenderPipeline; import com.thecsdev.common.util.annotations.Virtual; import com.thecsdev.commonmc.api.client.gui.TElement; import com.thecsdev.commonmc.api.client.gui.screen.TScreen; @@ -15,7 +15,7 @@ import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.render.GuiRenderer; import net.minecraft.client.gui.screens.inventory.InventoryScreen; -import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; import net.minecraft.data.AtlasIds; import net.minecraft.resources.Identifier; import net.minecraft.world.entity.Entity; @@ -159,7 +159,7 @@ protected TGuiGraphics(GuiGraphicsExtractor drawContext, int mouseX, int mouseY, * @param color The sprite's ARGB color. */ public @Virtual void drawMissingNo(int x, int y, int width, int height, int color) { - drawGuiSprite(TextureManager.INTENTIONAL_MISSING_TEXTURE, x, y, width, height, color); + drawGuiSprite(MissingTextureAtlasSprite.getLocation(), x, y, width, height, color); } /** diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphicsDefault.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphicsDefault.java index 8df81e5..3e11db7 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphicsDefault.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/render/TGuiGraphicsDefault.java @@ -1,6 +1,6 @@ package com.thecsdev.commonmc.api.client.gui.render; -import com.mojang.blaze3d.pipeline.RenderPipeline; +import com.mojang.renderpearl.api.pipeline.RenderPipeline; import com.thecsdev.commonmc.resource.TSprites; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenPlus.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenPlus.java index 7c0908e..5cdfe03 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenPlus.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenPlus.java @@ -14,7 +14,7 @@ import java.util.Objects; import java.util.function.Predicate; -import static org.lwjgl.glfw.GLFW.*; +import static org.lwjgl.sdl.SDLScancode.*; /** * Same as {@link TScreen}, but with some extra features such as arrow-key @@ -42,11 +42,11 @@ public TScreenPlus() {} if(context.getInputType() == TInputContext.InputType.KEY_PRESS) { //obtain the direction based on the pressed key-code - final CompassDirection direction = switch(context.getKeyCode()) { - case GLFW_KEY_UP -> CompassDirection.NORTH; - case GLFW_KEY_DOWN -> CompassDirection.SOUTH; - case GLFW_KEY_LEFT -> CompassDirection.WEST; - case GLFW_KEY_RIGHT -> CompassDirection.EAST; + final CompassDirection direction = switch(context.getScanCode()) { + case SDL_SCANCODE_UP -> CompassDirection.NORTH; + case SDL_SCANCODE_DOWN -> CompassDirection.SOUTH; + case SDL_SCANCODE_LEFT -> CompassDirection.WEST; + case SDL_SCANCODE_RIGHT -> CompassDirection.EAST; case null, default -> null; }; if(direction == null) return false; @@ -144,8 +144,8 @@ public TScreenPlus() {} //multiplying the cross-axis by a weight (e.g., 4) makes the cursor strongly //prefer jumping in a straight line rather than making wild diagonal jumps. long distSq = switch(direction) { - case NORTH, SOUTH -> (dX * dX * 4) + (dY * dY); // Penalize X variance - case EAST, WEST -> (dX * dX) + (dY * dY * 4); // Penalize Y variance + case NORTH, SOUTH -> (dX * dX * 4) + (dY * dY); //penalize X variance + case EAST, WEST -> (dX * dX) + (dY * dY * 4); //penalize Y variance default -> (dX * dX) + (dY * dY); }; diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java index e84bd92..9d36350 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TScreenWrapper.java @@ -13,7 +13,6 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.input.CharacterEvent; import net.minecraft.client.input.KeyEvent; import net.minecraft.client.input.MouseButtonEvent; import net.minecraft.network.chat.Component; @@ -26,9 +25,10 @@ import static com.thecsdev.commonmc.TCDCommons.LOGGER; import static com.thecsdev.commonmc.TCDCommonsConfig.FLAG_DEV_ENV; -import static com.thecsdev.commonmc.api.client.gui.util.TGuiUtils.isShiftDown; +import static com.thecsdev.commonmc.api.client.gui.util.TGuiUtils.*; import static java.lang.System.nanoTime; -import static org.lwjgl.glfw.GLFW.*; +import static org.lwjgl.sdl.SDLMouse.SDL_BUTTON_RIGHT; +import static org.lwjgl.sdl.SDLScancode.*; /** * The {@link TScreenWrapper} serves as an adapter for the {@link TScreen} @@ -142,24 +142,29 @@ protected TScreenWrapper(@NotNull T target) { // ================================================== public final @Override boolean keyPressed(@NotNull KeyEvent e) { if(super.keyPressed(e)) return true; - else return sendInput(TInputContext.ofKeyPress(e.key(), e.scancode(), e.modifiers())); + else if(sendInput(TInputContext.ofKeyPress(e.keycode(), e.input(), e.modifiers()))) return true; + else { + //FIXME - REPLACE THIS BAND-AID CODE WITH PROPER SDL 'TYPING' HANDLING + final var typedChar = getCharFromSdlScancode(e.input(), isShiftDown(), isCapsLockOn(), isNumLockOn()); + return typedChar != 0 && sendInput(TInputContext.ofCharType(typedChar, 0)); + } } public final @Override boolean keyReleased(@NotNull KeyEvent e) { if(super.keyReleased(e)) return true; - else return sendInput(TInputContext.ofKeyRelease(e.key(), e.scancode(), e.modifiers())); + else return sendInput(TInputContext.ofKeyRelease(e.keycode(), e.input(), e.modifiers())); } - public final @Override boolean charTyped(@NotNull CharacterEvent e) { + /*public final @Override boolean charTyped(@NotNull CharacterEvent e) { -- they changed something here if(super.charTyped(e)) return true; else return sendInput(TInputContext.ofCharType((char) e.codepoint(), 0)); - } + }*/ // -------------------------------------------------- public final @Override boolean mouseClicked(@NotNull MouseButtonEvent e, boolean doubled) { if(super.mouseClicked(e, doubled)) return true; - else return sendInput(TInputContext.ofMousePress(e.x(), e.y(), e.button())); + else return sendInput(TInputContext.ofMousePress(e.x(), e.y(), e.button(), e.modifiers())); } public final @Override boolean mouseReleased(@NotNull MouseButtonEvent e) { if(super.mouseReleased(e)) return true; - else return sendInput(TInputContext.ofMouseRelease(e.x(), e.y(), e.button())); + else return sendInput(TInputContext.ofMouseRelease(e.x(), e.y(), e.button(), e.modifiers())); } public final @Override void mouseMoved(double mouseX, double mouseY) { super.mouseMoved(mouseX, mouseY); @@ -183,6 +188,7 @@ protected TScreenWrapper(@NotNull T target) { //FIXME - Extremely high priority. I urgently need a "set in stone" input handling contract. // I keep finding myself needing to tweak input handling. I need standardization. @ApiStatus.Internal + @SuppressWarnings("DataFlowIssue") final boolean sendInput(TInputContext context) { //calculate hovered element for mouse-related inputs @@ -276,8 +282,7 @@ else if(this.target.findChild(child -> child.inputCallback(TInputContext.InputDi if(context.getInputType() == TInputContext.InputType.KEY_PRESS) { //handle tab-navigation - //noinspection DataFlowIssue - if(context.getKeyCode() == GLFW_KEY_TAB) + if(context.getScanCode() == SDL_SCANCODE_TAB) { //prepare for navigation final var forward = !isShiftDown(); @@ -298,20 +303,20 @@ else if(this.target.findChild(child -> child.inputCallback(TInputContext.InputDi return true; } //handle context menu key - else if(context.getKeyCode() == GLFW_KEY_MENU) { + else if(context.getScanCode() == SDL_SCANCODE_APPLICATION) { //attempt to show the context menu of the focused element final @Nullable var focused = this.target.focused.get(); if(focused != null && focused.showContextMenu() != null) return true; //return ONLY IF successful, no returning false! } //handle closing on escape - else if(context.getKeyCode() == GLFW_KEY_ESCAPE) { onClose(); return true; } + else if(context.getScanCode() == SDL_SCANCODE_ESCAPE) { onClose(); return true; } } //additional mouse-press logic else if(context.getInputType() == TInputContext.InputType.MOUSE_PRESS) { //noinspection DataFlowIssue - handle right-clicking for opening context-menus - if(context.getMouseButton() == 1) { + if(context.getMouseButton() == SDL_BUTTON_RIGHT) { //attempt to show the context menu of the hovered element final @Nullable var hovered = this.target.hovered.get(); if(hovered != null && hovered.showContextMenu() != null) @@ -342,4 +347,93 @@ private static final TElement sendInputBubbleMain(TInputContext context, @Nullab return element; } // ================================================== + /** + * Band-Aid method that helps {@link #keyPressed(KeyEvent)} emit "character typed" events.
+ * FIXME - Implement proper typing handling functionality. + * @param sdlScanCode Pressed key SDL scan-code. + * @param isShiftDown Is shift key down? + * @param isCapsLockOn Is CapsLock turned on? + * @param isNumLockOn Is NumLock turned on? + * @return {@link Character} from SDL scan-code, or {@code 0} is character is not printable. + * @implNote Supports English keyboard layout only, which is problematic. + */ + @Deprecated + @SuppressWarnings("DeprecatedIsStillUsed") + public static final char getCharFromSdlScancode( + int sdlScanCode, + boolean isShiftDown, boolean isCapsLockOn, boolean isNumLockOn) + { + //handle [A to Z] keys + if(sdlScanCode >= SDL_SCANCODE_A && sdlScanCode <= SDL_SCANCODE_Z) { + final var isUppercase = isShiftDown ^ isCapsLockOn; + final var baseChar = (char) ('a' + (sdlScanCode - 4)); + return isUppercase ? Character.toUpperCase(baseChar) : baseChar; + } + + //handle number keys [1 to 0] + if(sdlScanCode >= SDL_SCANCODE_1 && sdlScanCode <= SDL_SCANCODE_0) { + if(isShiftDown) { + switch(sdlScanCode) { + case SDL_SCANCODE_1: return '!'; + case SDL_SCANCODE_2: return '@'; + case SDL_SCANCODE_3: return '#'; + case SDL_SCANCODE_4: return '$'; + case SDL_SCANCODE_5: return '%'; + case SDL_SCANCODE_6: return '^'; + case SDL_SCANCODE_7: return '&'; + case SDL_SCANCODE_8: return '*'; + case SDL_SCANCODE_9: return '('; + case SDL_SCANCODE_0: return ')'; + } + } else { + if(sdlScanCode == SDL_SCANCODE_0) return '0'; + return (char) ('1' + (sdlScanCode - SDL_SCANCODE_1)); + } + } + + //punctuation and miscellaneous keys + return switch(sdlScanCode) + { + //general punctuation keys + case SDL_SCANCODE_SPACE -> ' '; + case SDL_SCANCODE_MINUS -> isShiftDown ? '_' : '-'; + case SDL_SCANCODE_EQUALS -> isShiftDown ? '+' : '='; + case SDL_SCANCODE_LEFTBRACKET -> isShiftDown ? '{' : '['; + case SDL_SCANCODE_RIGHTBRACKET -> isShiftDown ? '}' : ']'; + case SDL_SCANCODE_BACKSLASH -> isShiftDown ? '|' : '\\'; + case SDL_SCANCODE_SEMICOLON -> isShiftDown ? ':' : ';'; + case SDL_SCANCODE_APOSTROPHE -> isShiftDown ? '"' : '\''; + case SDL_SCANCODE_GRAVE -> isShiftDown ? '~' : '`'; //the key below 'Esc' + case SDL_SCANCODE_COMMA -> isShiftDown ? '<' : ','; + case SDL_SCANCODE_PERIOD -> isShiftDown ? '>' : '.'; + case SDL_SCANCODE_SLASH -> isShiftDown ? '?' : '/'; + + //numpad keys + case SDL_SCANCODE_KP_DIVIDE -> '/'; + case SDL_SCANCODE_KP_MULTIPLY -> '*'; + case SDL_SCANCODE_KP_MINUS -> '-'; + case SDL_SCANCODE_KP_PLUS -> '+'; + case SDL_SCANCODE_KP_ENTER -> '\n'; + case SDL_SCANCODE_KP_1 -> isNumLockOn ? '1' : (char) 0; + case SDL_SCANCODE_KP_2 -> isNumLockOn ? '2' : (char) 0; + case SDL_SCANCODE_KP_3 -> isNumLockOn ? '3' : (char) 0; + case SDL_SCANCODE_KP_4 -> isNumLockOn ? '4' : (char) 0; + case SDL_SCANCODE_KP_5 -> isNumLockOn ? '5' : (char) 0; + case SDL_SCANCODE_KP_6 -> isNumLockOn ? '6' : (char) 0; + case SDL_SCANCODE_KP_7 -> isNumLockOn ? '7' : (char) 0; + case SDL_SCANCODE_KP_8 -> isNumLockOn ? '8' : (char) 0; + case SDL_SCANCODE_KP_9 -> isNumLockOn ? '9' : (char) 0; + case SDL_SCANCODE_KP_0 -> isNumLockOn ? '0' : (char) 0; + case SDL_SCANCODE_KP_PERIOD -> isNumLockOn ? '.' : (char) 0; + case SDL_SCANCODE_KP_EQUALS -> '='; + + //control characters + //case SDL_SCANCODE_RETURN -> '\n'; + //case SDL_SCANCODE_BACKSPACE -> '\b'; + //case SDL_SCANCODE_TAB -> '\t'; + + default -> 0; //non-printable keys (F1 to F12, delete, arrows, etc.) + }; + } + // ================================================== } diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TTextDialogScreen.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TTextDialogScreen.java index a04099b..f8034af 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TTextDialogScreen.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/TTextDialogScreen.java @@ -132,7 +132,7 @@ public WindowElement() { (bb_panel.width / 2) - 20, 15); btn_done.getLabel().setText(translatable("gui.done")); btn_done.getLabel().textScaleProperty().set(0.8, WindowElement.class); - btn_done.eClicked.addListener(__ -> TTextDialogScreen.this.close()); + btn_done.eClicked.addListener(_ -> TTextDialogScreen.this.close()); body.add(btn_done); //the 'Copy to clipboard' button @@ -142,7 +142,7 @@ public WindowElement() { btn_copy.getLabel().setText(gui(TSprites.gui_icon_clipboard())); btn_copy.eClicked.addListener(btn -> Objects.requireNonNull(btn.getClient(), "Missing 'client' instance") .keyboardHandler.setClipboard(el_label.getText().getString())); - btn_copy.tooltipProperty().set(__ -> TTooltip.of(translatable("chat.copy")), WindowElement.class); + btn_copy.tooltipProperty().set(_ -> TTooltip.of(translatable("chat.copy")), WindowElement.class); body.add(btn_copy); //context menu @@ -151,7 +151,7 @@ public WindowElement() { return new TContextMenu.Builder(client) .addButton( gui(TSprites.gui_icon_clipboard()).append(" ").append(translatable("chat.copy")), - ___ -> client.keyboardHandler.setClipboard(el_label.getText().getString())) + _ -> client.keyboardHandler.setClipboard(el_label.getText().getString())) .build(); }, WindowElement.class); } diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/promise/TFileChooserScreen.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/promise/TFileChooserScreen.java index a50aff7..c4e3655 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/promise/TFileChooserScreen.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/screen/promise/TFileChooserScreen.java @@ -1,5 +1,6 @@ package com.thecsdev.commonmc.api.client.gui.screen.promise; +import com.mojang.blaze3d.Blaze3D; import com.sun.jna.Platform; import com.sun.jna.platform.win32.KnownFolders; import com.sun.jna.platform.win32.Shell32Util; @@ -27,7 +28,6 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; -import net.minecraft.util.Util; import org.apache.commons.io.FilenameUtils; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -53,7 +53,9 @@ import static java.nio.file.Files.readAttributes; import static org.apache.commons.io.FilenameUtils.isExtension; import static org.apache.commons.io.FilenameUtils.removeExtension; -import static org.lwjgl.glfw.GLFW.*; +import static org.lwjgl.sdl.SDLMouse.SDL_BUTTON_X1; +import static org.lwjgl.sdl.SDLMouse.SDL_BUTTON_X2; +import static org.lwjgl.sdl.SDLScancode.SDL_SCANCODE_F5; /** * {@link TScreen} implementation that provides a user-friendly interface for selecting @@ -130,8 +132,8 @@ public final void refresh() { //handle refreshing (F5) if(context.getInputType() == TInputContext.InputType.KEY_RELEASE) { - assert (context.getKeyCode() != null); - if(context.getKeyCode() == GLFW_KEY_F5) { + assert (context.getScanCode() != null); + if(context.getScanCode() == SDL_SCANCODE_F5) { refresh(); return true; } @@ -140,10 +142,10 @@ public final void refresh() { //handle mouse navigation if(context.getInputType() == TInputContext.InputType.MOUSE_RELEASE) { assert (context.getMouseButton() != null); - if(context.getMouseButton() == GLFW_MOUSE_BUTTON_4) { + if(context.getMouseButton() == SDL_BUTTON_X1) { this.controller.navigateBack(); return true; - } else if(context.getMouseButton() == GLFW_MOUSE_BUTTON_5) { + } else if(context.getMouseButton() == SDL_BUTTON_X2) { this.controller.navigateForward(); return true; } @@ -909,7 +911,7 @@ public final void submitForm() return; case EXPLORE: if(input.isEmpty() || !Files.exists(choice)) return; - Util.getPlatform().openUri(choice.toUri()); + Blaze3D.openUri(choice.toUri()); return; default: break; @@ -937,7 +939,8 @@ public final void submitForm() private static final Function CONTEXT_MENU = (fee) -> { //create the builder instance - final var builder = new TContextMenu.Builder(Objects.requireNonNull(fee.getClient())); + final var client = Objects.requireNonNull(fee.getClient()); + final var builder = new TContextMenu.Builder(client); //file "Select" / "Open" switch(fee.controller.getMode()) { @@ -959,10 +962,10 @@ public final void submitForm() _ -> fee.openInAppCallback()); builder.addContextMenu( gui(TSprites.gui_icon_fsFolder()).append(" ").append(TLanguage.gui_fileChooser_ctxmenu_openWith()), - _ -> new TContextMenu.Builder(fee.getClient()) + _ -> new TContextMenu.Builder(client) .addButton( gui(TSprites.gui_icon_fsFile()).append(" ").append(TLanguage.gui_fileChooser_ctxmenu_openWith_assocApp()), - _ -> Util.getPlatform().openUri(fee.path.toUri())) + _ -> Blaze3D.openUri(fee.path.toUri())) .build()); //build and return @@ -1053,7 +1056,7 @@ else return switch (FilenameUtils.getExtension(filename(this.path))) { /** * Opens the {@link #path} with the default external application. */ - private final void openInAppCallback() { Util.getPlatform().openUri(this.path.toUri()); } + private final void openInAppCallback() { Blaze3D.openUri(this.path.toUri()); } protected final @Override void focusGainedCallback() { TFileChooserScreen.this.findChild(el -> el instanceof ActionPanel, true) diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/util/TGuiUtils.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/util/TGuiUtils.java index 82042cb..7ccc861 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/util/TGuiUtils.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/util/TGuiUtils.java @@ -19,13 +19,16 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.lwjgl.glfw.GLFW; +import org.lwjgl.sdl.SDLScancode; import java.util.ArrayList; import java.util.Objects; import java.util.Random; -import static org.lwjgl.glfw.GLFW.*; +import static org.lwjgl.sdl.SDLKeyboard.SDL_GetModState; +import static org.lwjgl.sdl.SDLKeycode.SDL_KMOD_CAPS; +import static org.lwjgl.sdl.SDLKeycode.SDL_KMOD_NUM; +import static org.lwjgl.sdl.SDLScancode.*; /** * {@link TCDCommons} API's GUI-related utility methods. @@ -82,30 +85,41 @@ public static final Bounds2i getScreenBounds() { } // ================================================== /** - * Returns {@code true} is a given key is currently held down - * for the current game window. - * @param keyCode The {@link GLFW} key code. + * Returns {@code true} is a given key is currently held down. + * @param scanCode The key's scan-code from {@link SDLScancode}. */ - public static final boolean isKeyDown(int keyCode) { - return InputConstants.isKeyDown(Minecraft.getInstance().getWindow(), keyCode); + public static final boolean isKeyDown(int scanCode) { + return InputConstants.isKeyDown(scanCode); } /** - * Returns {@code true} is either the left or right control key is currently held down - * for the current game window. + * Returns {@code true} is either the left or right control key is currently held down. * @see #isKeyDown(int) */ public static final boolean isCtrlDown() { - return isKeyDown(GLFW_KEY_LEFT_CONTROL) || isKeyDown(GLFW_KEY_RIGHT_CONTROL); + return isKeyDown(SDL_SCANCODE_LCTRL) || isKeyDown(SDL_SCANCODE_RCTRL); } /** - * Returns {@code true} is either the left or right shift key is currently held down - * for the current game window. + * Returns {@code true} is either the left or right shift key is currently held down. * @see #isKeyDown(int) */ public static final boolean isShiftDown() { - return isKeyDown(GLFW_KEY_LEFT_SHIFT) || isKeyDown(GLFW_KEY_RIGHT_SHIFT); + return isKeyDown(SDL_SCANCODE_LSHIFT) || isKeyDown(SDL_SCANCODE_RSHIFT); + } + // -------------------------------------------------- + /** + * Returns {@code true} if the "caps lock" state is "on". + */ + public static final boolean isCapsLockOn() { + return (SDL_GetModState() & SDL_KMOD_CAPS) != 0; + } + + /** + * Returns {@code true} if the "num lock" state is "on". + */ + public static final boolean isNumLockOn() { + return (SDL_GetModState() & SDL_KMOD_NUM) != 0; } // ================================================== /** @@ -308,7 +322,7 @@ public static final void keepElementWithinBounds( Objects.requireNonNull(target); Objects.requireNonNull(bounds); - //calculate the detla x and delta y + //calculate the data x and delta y final var bb = target.getBounds(); int dX = 0, dY = 0; if(bb.endY > bounds.endY) dY = bounds.endY - bb.endY; diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/util/TInputContext.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/util/TInputContext.java index 6438abd..8b277af 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/util/TInputContext.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/util/TInputContext.java @@ -65,7 +65,7 @@ public final boolean isMouse() { } // ================================================== private final InputType inputType; - private final @Nullable Integer keyCode, scanCode, keyModifiers; + private final @Nullable Integer keyCode, scanCode, nodifiers; private final @Nullable Character character; private final @Nullable Double mouseX, mouseY; private final @Nullable Integer mouseButton; @@ -74,7 +74,7 @@ public final boolean isMouse() { // ================================================== private TInputContext( InputType inputType, - @Nullable Integer keyCode, @Nullable Integer scanCode, @Nullable Integer keyModifiers, + @Nullable Integer keyCode, @Nullable Integer scanCode, @Nullable Integer modifiers, @Nullable Character character, @Nullable Double mouseX, @Nullable Double mouseY, @Nullable Integer mouseButton, @Nullable Double scrollX, @Nullable Double scrollY, @@ -83,7 +83,7 @@ private TInputContext( this.inputType = Objects.requireNonNull(inputType); this.keyCode = keyCode; this.scanCode = scanCode; - this.keyModifiers = keyModifiers; + this.nodifiers = modifiers; this.character = character; this.mouseX = mouseX; this.mouseY = mouseY; @@ -96,7 +96,7 @@ private TInputContext( // ================================================== public final @Override int hashCode() { - return Objects.hash(this.inputType, this.keyCode, this.scanCode, this.keyModifiers, + return Objects.hash(this.inputType, this.keyCode, this.scanCode, this.nodifiers, this.character, this.mouseX, this.mouseY, this.mouseButton, this.scrollX, this.scrollY, this.mouseDeltaX, this.mouseDeltaY); } @@ -107,7 +107,7 @@ private TInputContext( return Objects.equals(this.inputType, other.inputType) && Objects.equals(this.keyCode, other.keyCode) && Objects.equals(this.scanCode, other.scanCode) && - Objects.equals(this.keyModifiers, other.keyModifiers) && + Objects.equals(this.nodifiers, other.nodifiers) && Objects.equals(this.character, other.character) && Objects.equals(this.mouseX, other.mouseX) && Objects.equals(this.mouseY, other.mouseY) && @@ -154,16 +154,29 @@ public static final TInputContext ofCharType(char character, int modifiers) { * @param mouseY Mouse Y position. * @param button The pressed mouse button. */ + @Deprecated(forRemoval = true) public static final TInputContext ofMousePress(double mouseX, double mouseY, int button) { return new TInputContext(InputType.MOUSE_PRESS, null, null, null, null, mouseX, mouseY, button, null, null, null, null); } + /** + * Creates and returns a {@link TInputContext} for {@link InputType#MOUSE_PRESS}. + * @param mouseX Mouse X position. + * @param mouseY Mouse Y position. + * @param button The pressed mouse button. + * @param modifiers Mouse button modifiers. + */ + public static final TInputContext ofMousePress(double mouseX, double mouseY, int button, int modifiers) { + return new TInputContext(InputType.MOUSE_PRESS, null, null, modifiers, null, mouseX, mouseY, button, null, null, null, null); + } + /** * Creates and returns a {@link TInputContext} for {@link InputType#MOUSE_RELEASE}. * @param mouseX Mouse X position. * @param mouseY Mouse Y position. * @param button The pressed mouse button. */ + @Deprecated(forRemoval = true) public static final TInputContext ofMouseRelease(double mouseX, double mouseY, int button) { return new TInputContext(InputType.MOUSE_RELEASE, null, null, null, null, mouseX, mouseY, button, null, null, null, null); } @@ -172,6 +185,17 @@ public static final TInputContext ofMouseRelease(double mouseX, double mouseY, i * Creates and returns a {@link TInputContext} for {@link InputType#MOUSE_RELEASE}. * @param mouseX Mouse X position. * @param mouseY Mouse Y position. + * @param button The pressed mouse button. + * @param modifiers Mouse button modifiers. + */ + public static final TInputContext ofMouseRelease(double mouseX, double mouseY, int button, int modifiers) { + return new TInputContext(InputType.MOUSE_RELEASE, null, null, modifiers, null, mouseX, mouseY, button, null, null, null, null); + } + + /** + * Creates and returns a {@link TInputContext} for {@link InputType#MOUSE_MOVE}. + * @param mouseX Mouse X position. + * @param mouseY Mouse Y position. */ public static final TInputContext ofMouseMove(double mouseX, double mouseY) { return new TInputContext(InputType.MOUSE_MOVE, null, null, null, null, mouseX, mouseY, null, null, null, null, null); @@ -217,12 +241,21 @@ public static final TInputContext ofMouseDrag(double mouseX, double mouseY, int */ public final @Nullable Integer getScanCode() { return this.scanCode; } + /** + * {@link Deprecated} because this method was renamed to {@link #getModifiers()}. + * Please use {@link #getModifiers()} instead. + */ + @Deprecated(forRemoval = true) + public final @Nullable Integer getKeyModifiers() { return this.nodifiers; } + /** * @see InputType#KEY_PRESS * @see InputType#KEY_RELEASE * @see InputType#CHAR_TYPE + * @see InputType#MOUSE_PRESS + * @see InputType#MOUSE_RELEASE */ - public final @Nullable Integer getKeyModifiers() { return this.keyModifiers; } + public final @Nullable Integer getModifiers() { return this.nodifiers; } /** * @see InputType#CHAR_TYPE diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/TClickableWidget.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/TClickableWidget.java index 5240650..565f83f 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/TClickableWidget.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/TClickableWidget.java @@ -16,9 +16,10 @@ import java.util.function.Consumer; -import static com.mojang.blaze3d.platform.InputConstants.KEY_NUMPADENTER; -import static com.mojang.blaze3d.platform.InputConstants.KEY_RETURN; import static com.thecsdev.commonmc.api.client.gui.util.TGuiUtils.playGuiButtonClickSound; +import static org.lwjgl.sdl.SDLMouse.SDL_BUTTON_LEFT; +import static org.lwjgl.sdl.SDLScancode.SDL_SCANCODE_KP_ENTER; +import static org.lwjgl.sdl.SDLScancode.SDL_SCANCODE_RETURN; /** * A {@link TElement} that can be clicked via mouse or keyboard inputs. @@ -102,24 +103,24 @@ public TClickableWidget() { { //mouse-based inputs case MOUSE_PRESS: - if(context.getMouseButton() != 0) break; //only accept LMB + if(context.getMouseButton() != SDL_BUTTON_LEFT) break; //only accept LMB return true; case MOUSE_RELEASE: - if(context.getMouseButton() != 0) break; //only accept LMB + if(context.getMouseButton() != SDL_BUTTON_LEFT) break; //only accept LMB if(isHovered()) click(); //just like in standardized GUI frameworks return true; //key-based inputs case KEY_PRESS: { - final int kc = context.getKeyCode(); - if(!(kc == KEY_RETURN || kc == KEY_NUMPADENTER)) break; + final int sc = context.getScanCode(); + if(!(sc == SDL_SCANCODE_RETURN || sc == SDL_SCANCODE_KP_ENTER)) break; this.pressed.set(true, TClickableWidget.class); click(); return true; } case KEY_RELEASE: { - final int kc = context.getKeyCode(); - if(!(kc == KEY_RETURN || kc == KEY_NUMPADENTER)) break; + final int sc = context.getScanCode(); + if(!(sc == SDL_SCANCODE_RETURN || sc == SDL_SCANCODE_KP_ENTER)) break; this.pressed.set(false, TClickableWidget.class); return true; } diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/TSliderWidget.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/TSliderWidget.java index c0366ab..41bfa21 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/TSliderWidget.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/TSliderWidget.java @@ -16,7 +16,8 @@ import static com.thecsdev.commonmc.api.client.gui.util.TGuiUtils.playGuiButtonClickSound; import static com.thecsdev.commonmc.api.client.gui.util.TInputContext.InputType.*; import static java.lang.Math.*; -import static org.lwjgl.glfw.GLFW.*; +import static org.lwjgl.sdl.SDLMouse.SDL_BUTTON_LEFT; +import static org.lwjgl.sdl.SDLScancode.*; /** * A GUI slider that lets a user select a value by moving a handle along a track. @@ -41,7 +42,7 @@ { //original click sound mechanism doesn't work properly here super.eClicked.removeListener(ONCLICK_SOUND); //so we remove it - pressedProperty().addChangeListener((p, o, n) -> { + pressedProperty().addChangeListener((_, _, n) -> { if(!n) playGuiButtonClickSound(); //this one works better here }); @@ -49,7 +50,7 @@ this.value.addFilter(Point2d::clamp01, TSliderWidget.class); //updates to the value need to be reflected on the knob bounds //(set value to handle to avoid stack overflow from cyclic dependency) - this.value.addChangeListener((p, o, n) -> this.knobBounds.getHandle().set(computeKnobFromValue())); + this.value.addChangeListener((_, _, _) -> this.knobBounds.getHandle().set(computeKnobFromValue())); //control the knob's bounds, such that it never leaves this slider this.knobBounds.addFilter(hbb -> { @@ -59,7 +60,7 @@ return new Bounds2i(clamp(hbb.x, sbb.x, sbb.endX - kbbW), clamp(hbb.y, sbb.y, sbb.endY - kbbH), kbbW, kbbH); }, TSliderWidget.class); //when the knob bounds update during click and drag, update the value of the slider - this.knobBounds.addChangeListener((p, o, n) -> { + this.knobBounds.addChangeListener((_, o, n) -> { //do not handle if not pressed or if resized if(!pressedProperty().getZ() || !o.hasSameSize(n)) return; //else set value @@ -67,7 +68,7 @@ }); //size changes also update the knob bounds size - final IChangeListener cl_rkbq = (p, o, n) -> refreshKnobQuietly(); + final IChangeListener cl_rkbq = (_, _, _) -> refreshKnobQuietly(); boundsProperty().addChangeListener((IChangeListener) cl_rkbq); this.knobSize .addChangeListener((IChangeListener) cl_rkbq); refreshKnobQuietly(); @@ -184,7 +185,7 @@ else if(phase != TInputContext.InputDiscoveryPhase.MAIN || !isFocusable()) //handle click and dragging //(must return true for both drag and mouse press) - if(context.getInputType() == MOUSE_DRAG && pressedProperty().getZ() && context.getMouseButton() == 0) { + if(context.getInputType() == MOUSE_DRAG && pressedProperty().getZ() && context.getMouseButton() == SDL_BUTTON_LEFT) { //move knob to cursor position final var kbb = this.knobBounds.get(); final int w2 = kbb.width / 2, h2 = kbb.height / 2; @@ -200,11 +201,11 @@ else if(context.getInputType() == KEY_PRESS) { final double sensitivity = 0.05; double dX = 0, dY = 0; - switch(context.getKeyCode()) { - case GLFW_KEY_LEFT: dX -= sensitivity; break; - case GLFW_KEY_RIGHT: dX += sensitivity; break; - case GLFW_KEY_UP: dY -= sensitivity; break; - case GLFW_KEY_DOWN: dY += sensitivity; break; + switch(context.getScanCode()) { + case SDL_SCANCODE_LEFT: dX -= sensitivity; break; + case SDL_SCANCODE_RIGHT: dX += sensitivity; break; + case SDL_SCANCODE_UP: dY -= sensitivity; break; + case SDL_SCANCODE_DOWN: dY += sensitivity; break; default: break; } if(dX != 0 || dY != 0) { diff --git a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/text/TSimpleTextFieldWidget.java b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/text/TSimpleTextFieldWidget.java index faaeeb2..693f1ad 100644 --- a/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/text/TSimpleTextFieldWidget.java +++ b/src/main/java/com/thecsdev/commonmc/api/client/gui/widget/text/TSimpleTextFieldWidget.java @@ -22,7 +22,7 @@ import static com.thecsdev.commonmc.api.client.gui.panel.TPanelElement.COLOR_OUTLINE; import static com.thecsdev.commonmc.api.client.gui.panel.TPanelElement.COLOR_OUTLINE_FOCUSED; -import static org.lwjgl.glfw.GLFW.GLFW_KEY_BACKSPACE; +import static org.lwjgl.sdl.SDLScancode.SDL_SCANCODE_BACKSPACE; /** * Text input widget where the user may type in text. Very minimal and @@ -53,17 +53,17 @@ public TSimpleTextFieldWidget() this.lbl_placeholder.textColorProperty().set(0x55FFFFFF, TSimpleTextFieldWidget.class); //change listeners - boundsProperty().addChangeListener((p, o, n) -> refreshAlignment()); - this.font.addChangeListener((p, o, n) -> { + boundsProperty().addChangeListener((_, _, _) -> refreshAlignment()); + this.font.addChangeListener((_, _, n) -> { this.lbl_placeholder.fontProperty().set(n, TSimpleTextFieldWidget.class); this.lbl_text.fontProperty().set(n, TSimpleTextFieldWidget.class); refreshAlignment(); }); - this.placeholder.addChangeListener((p, o, n) -> { + this.placeholder.addChangeListener((_, _, n) -> { this.lbl_placeholder.setText(n); refreshAlignment(); }); - this.text.addChangeListener((p, o, n) -> { + this.text.addChangeListener((_, _, n) -> { this.lbl_text.setText(Component.literal(n)); this.lbl_placeholder.visibleProperty().set(n.isEmpty(), TSimpleTextFieldWidget.class); refreshAlignment(); @@ -160,9 +160,9 @@ else if(phase != TInputContext.InputDiscoveryPhase.MAIN || !isFocused()) //handle based on input type final boolean typed = switch(context.getInputType()) { - //on click, handle to cath focus + //on click, handle to catch focus case CHAR_TYPE -> inputText(context.getCharacter().toString()); - case KEY_PRESS -> context.getKeyCode() == GLFW_KEY_BACKSPACE && inputBackspace(1); + case KEY_PRESS -> context.getScanCode() == SDL_SCANCODE_BACKSPACE && inputBackspace(1); default -> false; }; if(typed) TGuiUtils.playGuiTypingSound(); diff --git a/src/main/java/com/thecsdev/commonmc/client/gui/screen/TTestScreen.java b/src/main/java/com/thecsdev/commonmc/client/gui/screen/TTestScreen.java index 5d7b471..22b28de 100644 --- a/src/main/java/com/thecsdev/commonmc/client/gui/screen/TTestScreen.java +++ b/src/main/java/com/thecsdev/commonmc/client/gui/screen/TTestScreen.java @@ -14,6 +14,7 @@ import com.thecsdev.commonmc.api.client.gui.widget.stats.TBlockStatsWidget; import com.thecsdev.commonmc.api.client.gui.widget.stats.TEntityStatsWidget; import com.thecsdev.commonmc.api.client.gui.widget.stats.TItemStatsWidget; +import com.thecsdev.commonmc.api.client.gui.widget.text.TSimpleTextFieldWidget; import com.thecsdev.commonmc.api.stats.RandomStatsProvider; import com.thecsdev.commonmc.resource.TComponent; import net.fabricmc.api.EnvType; @@ -107,6 +108,12 @@ else if(throwable != null) btn_tog1.toggledProperty().set(n, TTestScreen.class)); panel.add(btn_tog2); + //test text input field + final var in_text = new TSimpleTextFieldWidget(); + in_text.setBounds(10, 100, 200, 20); + in_text.placeholderProperty().set(Component.literal("Type here..."), TTestScreen.class); + panel.add(in_text); + //test statistics initEnityStats(panel); initItemStats(panel); diff --git a/src/main/java/com/thecsdev/commonmc/resource/TComponent.java b/src/main/java/com/thecsdev/commonmc/resource/TComponent.java index c0c3e09..c1b5b34 100644 --- a/src/main/java/com/thecsdev/commonmc/resource/TComponent.java +++ b/src/main/java/com/thecsdev/commonmc/resource/TComponent.java @@ -1,6 +1,6 @@ package com.thecsdev.commonmc.resource; -import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; import net.minecraft.data.AtlasIds; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -27,7 +27,7 @@ public final class TComponent private TComponent() {} // ================================================== public static final MutableComponent air() { return literal("").append(object(new AtlasSprite(AtlasIds.GUI, Identifier.fromNamespaceAndPath(MOD_ID, "air")))); } - public static final MutableComponent missingNo() { return literal("").append(object(new AtlasSprite(AtlasSprite.DEFAULT_ATLAS, TextureManager.INTENTIONAL_MISSING_TEXTURE))); } + public static final MutableComponent missingNo() { return literal("").append(object(new AtlasSprite(AtlasSprite.DEFAULT_ATLAS, MissingTextureAtlasSprite.getLocation()))); } // -------------------------------------------------- public static final MutableComponent head(@NotNull UUID uuid) { return literal("").append(object(new PlayerSprite(ResolvableProfile.createUnresolved(uuid), true))); } public static final MutableComponent head(@NotNull String username) { return literal("").append(object(new PlayerSprite(ResolvableProfile.createUnresolved(username), true))); } diff --git a/src/main/java/com/thecsdev/commonmc/world/sandbox/DynamicRegistryAccess.java b/src/main/java/com/thecsdev/commonmc/world/sandbox/DynamicRegistryAccess.java index 49f0cdd..bbfc112 100644 --- a/src/main/java/com/thecsdev/commonmc/world/sandbox/DynamicRegistryAccess.java +++ b/src/main/java/com/thecsdev/commonmc/world/sandbox/DynamicRegistryAccess.java @@ -109,11 +109,15 @@ public GenericBootstrapContext(@NotNull WritableRegistry registry) { return (HolderGetter) this.registry.createRegistrationLookup(); } // -------------------------------------------------- - public @Override @NotNull Holder.Reference register(@NonNull ResourceKey key, T value, @NonNull Lifecycle lifecycle) { + public @Override @NotNull Holder.Reference register(@NonNull ResourceKey key, @NonNull T value) { Registry.register(this.registry, key, value); return Holder.Reference.createStandAlone(this.registry, key); } // ================================================== + public @Override @NonNull Stream> listContextElements(@NonNull ResourceKey> key) { + return ((HolderLookup.RegistryLookup) this.lookup(key)).listElements(); + } + // ================================================== } // ================================================== ================================================== } diff --git a/src/main/java/com/thecsdev/commonmc/world/sandbox/SandboxLevel.java b/src/main/java/com/thecsdev/commonmc/world/sandbox/SandboxLevel.java index 821e752..cfdd201 100644 --- a/src/main/java/com/thecsdev/commonmc/world/sandbox/SandboxLevel.java +++ b/src/main/java/com/thecsdev/commonmc/world/sandbox/SandboxLevel.java @@ -16,6 +16,7 @@ import net.minecraft.world.TickRateManager; import net.minecraft.world.attribute.EnvironmentAttributeMap; import net.minecraft.world.attribute.EnvironmentAttributeSystem; +import net.minecraft.world.clock.ClockInstance; import net.minecraft.world.clock.ClockManager; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; @@ -23,7 +24,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.flag.FeatureFlags; -import net.minecraft.world.item.alchemy.PotionBrewing; import net.minecraft.world.item.crafting.RecipeAccess; import net.minecraft.world.level.CardinalLighting; import net.minecraft.world.level.ExplosionDamageCalculator; @@ -31,7 +31,6 @@ import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biomes; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.FuelValues; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.chunk.ChunkSource; @@ -96,13 +95,17 @@ public void onTrackingStart(Entity object) {} public void onTrackingEnd(Entity object) {} public void onSectionChange(Entity object) {} }); - protected @NotNull ClockManager clockManager = _ -> 0; + protected @NotNull ClockInstance clockInstance = new ClockInstance() { + public final @Override long totalTicks() { return 0; } + public final @Override float partialTick() { return 0; } + public final @Override float rate() { return 0; } + public final @Override boolean isPaused() { return true; } + }; + protected @NotNull ClockManager clockManager = _ -> this.clockInstance; protected @NotNull List dragonParts = new ArrayList<>(); protected @NotNull TickRateManager tickRateManager = new TickRateManager(); protected @NotNull Scoreboard scoreboard = new Scoreboard(); protected @NotNull RecipeAccess recipeAccess = new SandboxLevelRecipes(); - protected @NotNull PotionBrewing potionBrewing = new PotionBrewing.Builder(FEATURES).build(); - protected @NotNull FuelValues fuelValues = new FuelValues.Builder(registryAccess(), FEATURES).build(); protected @NotNull ChunkSource chunkSource = new SandboxLevelChunks(this); protected @NotNull List players = new ArrayList<>(); protected @NotNull WorldBorder worldBorder = new WorldBorder(); @@ -138,8 +141,6 @@ public SandboxLevel(WritableLevelData properties, ResourceKey registryRef protected @Virtual @Override LevelEntityGetter getEntities() { return this.entityManager.getEntityGetter(); } public @Virtual @Override ClockManager clockManager() { return this.clockManager; } public @Virtual @Override EnvironmentAttributeSystem environmentAttributes() { return ENV_ATTR_SYS; } - public @Virtual @Override PotionBrewing potionBrewing() { return this.potionBrewing; } - public @Virtual @Override FuelValues fuelValues() { return this.fuelValues; } public @Virtual @Override ChunkSource getChunkSource() { return this.chunkSource; } public @Virtual @Override void levelEvent(@Nullable Entity source, int eventId, BlockPos position, int data) {} public @Virtual @Override void gameEvent(Holder event, Vec3 emitterPosition, GameEvent.Context emitter) {}