diff options
5 files changed, 100 insertions, 10 deletions
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/client/BackgroundPainter.java b/src/main/java/io/github/cottonmc/cotton/gui/client/BackgroundPainter.java index fa51754..f95d816 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/client/BackgroundPainter.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/client/BackgroundPainter.java @@ -47,6 +47,7 @@ public interface BackgroundPainter { WItemSlot slot = (WItemSlot)panel; for(int x = 0; x < slot.getWidth()/18; ++x) { for(int y = 0; y < slot.getHeight()/18; ++y) { + int index = x + y * (slot.getWidth() / 18); int lo = 0xB8000000; int bg = 0x4C000000; //this will cause a slightly discolored bottom border on vanilla backgrounds but it's necessary for color support, it shouldn't be *too* visible unless you're looking for it @@ -54,9 +55,25 @@ public interface BackgroundPainter { if (slot.isBigSlot()) { ScreenDrawing.drawBeveledPanel((x * 18) + left - 3, (y * 18) + top - 3, 26, 26, lo, bg, hi); + if (slot.getFocusedSlot() == index) { + int sx = (x * 18) + left - 3; + int sy = (y * 18) + top - 3; + ScreenDrawing.coloredRect(sx, sy, 26, 1, 0xFF_FFFFA0); + ScreenDrawing.coloredRect(sx, sy + 1, 1, 26 - 1, 0xFF_FFFFA0); + ScreenDrawing.coloredRect(sx + 26 - 1, sy + 1, 1, 26 - 1, 0xFF_FFFFA0); + ScreenDrawing.coloredRect(sx + 1, sy + 26 - 1, 26 - 1, 1, 0xFF_FFFFA0); + } } else { ScreenDrawing.drawBeveledPanel((x * 18) + left, (y * 18) + top, 16+2, 16+2, lo, bg, hi); + if (slot.getFocusedSlot() == index) { + int sx = (x * 18) + left; + int sy = (y * 18) + top; + ScreenDrawing.coloredRect(sx, sy, 18, 1, 0xFF_FFFFA0); + ScreenDrawing.coloredRect(sx, sy + 1, 1, 18 - 1, 0xFF_FFFFA0); + ScreenDrawing.coloredRect(sx + 18 - 1, sy + 1, 1, 18 - 1, 0xFF_FFFFA0); + ScreenDrawing.coloredRect(sx + 1, sy + 18 - 1, 18 - 1, 1, 0xFF_FFFFA0); + } } } } diff --git a/src/main/java/io/github/cottonmc/cotton/gui/impl/FocusHandler.java b/src/main/java/io/github/cottonmc/cotton/gui/impl/FocusHandler.java index df0ef32..61cffa6 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/impl/FocusHandler.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/impl/FocusHandler.java @@ -14,8 +14,7 @@ public final class FocusHandler { if (focus == null) { result = cycleFocus(host, lookForwards, host.getRootPanel(), null); } else { - WPanel parent = focus.getParent(); - result = cycleFocus(host, lookForwards, parent != null ? parent : host.getRootPanel(), focus); + result = cycleFocus(host, lookForwards, focus, null); } if (!result) { @@ -24,15 +23,18 @@ public final class FocusHandler { } } - private static boolean cycleFocus(GuiDescription host, boolean lookForwards, WPanel panel, WWidget pivot) { - WWidget next = panel.cycleFocus(lookForwards, pivot); + private static boolean cycleFocus(GuiDescription host, boolean lookForwards, WWidget widget, WWidget pivot) { + WWidget next = widget instanceof WPanel + ? ((WPanel) widget).cycleFocus(lookForwards, pivot) + : widget.cycleFocus(lookForwards); + if (next != null) { host.requestFocus(next); return true; } else { - WPanel parent = panel.getParent(); + WPanel parent = widget.getParent(); if (parent != null) { - return cycleFocus(host, lookForwards, parent, panel); + return cycleFocus(host, lookForwards, parent, widget); } } diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java index d173ae2..ec1bf9c 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WItemSlot.java @@ -8,8 +8,11 @@ import io.github.cottonmc.cotton.gui.ValidatedSlot; import io.github.cottonmc.cotton.gui.client.BackgroundPainter; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.inventory.Inventory; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.screen.slot.SlotActionType; import javax.annotation.Nullable; @@ -25,6 +28,7 @@ public class WItemSlot extends WWidget { private boolean big = false; private boolean insertingAllowed = true; private boolean takingAllowed = true; + private int focusedSlot = -1; public WItemSlot(Inventory inventory, int startIndex, int slotsWide, int slotsHigh, boolean big) { this.inventory = inventory; @@ -92,6 +96,11 @@ public class WItemSlot extends WWidget { return slotsHigh * 18; } + @Override + public boolean canFocus() { + return true; + } + public boolean isBigSlot() { return big; } @@ -166,6 +175,16 @@ public class WItemSlot extends WWidget { return this; } + /** + * Gets the currently focused slot index. + * + * @return the currently focused slot, or -1 if this widget isn't focused + * @since 2.0.0 + */ + public int getFocusedSlot() { + return focusedSlot; + } + @Override public void createPeers(GuiDescription c) { super.createPeers(c); @@ -185,6 +204,18 @@ public class WItemSlot extends WWidget { } } + @Environment(EnvType.CLIENT) + @Override + public void onKeyPressed(int ch, int key, int modifiers) { + if (isActivationKey(ch) && host instanceof ScreenHandler && focusedSlot >= 0) { + ScreenHandler handler = (ScreenHandler) host; + MinecraftClient client = MinecraftClient.getInstance(); + + ValidatedSlot peer = peers.get(focusedSlot); + client.interactionManager.clickSlot(handler.syncId, peer.id, 0, SlotActionType.PICKUP, client.player); + } + } + /** * Creates a slot peer for this slot widget. * @@ -228,4 +259,26 @@ public class WItemSlot extends WWidget { backgroundPainter.paintBackground(x, y, this); } } + + @Nullable + @Override + public WWidget cycleFocus(boolean lookForwards) { + if (focusedSlot < 0) { + focusedSlot = lookForwards ? 0 : (slotsWide * slotsHigh - 1); + return this; + } + + if (lookForwards) { + focusedSlot++; + if (focusedSlot >= slotsWide * slotsHigh) { + focusedSlot = -1; + return null; + } else { + return this; + } + } else { + focusedSlot--; + return focusedSlot >= 0 ? this : null; + } + } }
\ No newline at end of file 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 987248f..3002fc2 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 @@ -199,6 +199,12 @@ public abstract class WPanel extends WWidget { for(WWidget child : children) child.tick(); } + @Nullable + @Override + public WWidget cycleFocus(boolean lookForwards) { + return cycleFocus(lookForwards, null); + } + /** * Cycles the focus inside this panel. * @@ -253,10 +259,8 @@ public abstract class WPanel extends WWidget { @Nullable private WWidget checkFocusCycling(boolean lookForwards, WWidget child) { - if (child.canFocus()) { - return child; - } else if (child instanceof WPanel) { - return ((WPanel) child).cycleFocus(lookForwards, null); + if (child.canFocus() || child instanceof WPanel) { + return child.cycleFocus(lookForwards); } return null; 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 11387e2..7476c71 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 @@ -387,6 +387,20 @@ public class WWidget { public void tick() {} /** + * Cycles the focus inside this widget. + * + * <p>If this widget is not focusable, returns null. + * + * @param lookForwards whether this should cycle forwards (true) or backwards (false) + * @return the next focused widget, or null if should exit to the parent panel + * @since 2.0.0 + */ + @Nullable + public WWidget cycleFocus(boolean lookForwards) { + return canFocus() ? (isFocused() ? null : this) : null; + } + + /** * Tests if the provided key code is an activation key for widgets. * * <p>The activation keys are Enter, keypad Enter, and Space. |