From bded92f51853cc31a97d011c0d90d426110501ec Mon Sep 17 00:00:00 2001 From: isXander Date: Fri, 5 May 2023 19:25:49 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9E=95=20Allow=20to=20unbind=20bindings=20wi?= =?UTF-8?q?th=20Right=20Stick=20Press?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bindings/ControllerBindings.java | 8 +- .../config/gui/AbstractBindController.java | 141 ++++++++++++++++++ .../config/gui/GamepadBindController.java | 117 ++------------- .../config/gui/JoystickBindController.java | 138 ++--------------- .../assets/controlify/lang/en_us.json | 1 + 5 files changed, 170 insertions(+), 235 deletions(-) create mode 100644 src/main/java/dev/isxander/controlify/config/gui/AbstractBindController.java diff --git a/src/main/java/dev/isxander/controlify/bindings/ControllerBindings.java b/src/main/java/dev/isxander/controlify/bindings/ControllerBindings.java index 90a90e6..490375b 100644 --- a/src/main/java/dev/isxander/controlify/bindings/ControllerBindings.java +++ b/src/main/java/dev/isxander/controlify/bindings/ControllerBindings.java @@ -63,7 +63,8 @@ public class ControllerBindings { VMOUSE_ESCAPE, VMOUSE_SHIFT, VMOUSE_TOGGLE, GUI_NAVI_UP, GUI_NAVI_DOWN, GUI_NAVI_LEFT, GUI_NAVI_RIGHT, - CYCLE_OPT_FORWARD, CYCLE_OPT_BACKWARD; + CYCLE_OPT_FORWARD, CYCLE_OPT_BACKWARD, + CLEAR_BINDING; private final Map registry = new LinkedHashMap<>(); @@ -331,6 +332,11 @@ public class ControllerBindings { .defaultBind(GamepadBinds.RIGHT_STICK_LEFT) .category(GUI_CATEGORY) .build()); + register(CLEAR_BINDING = ControllerBindingBuilder.create(controller) + .identifier("controlify", "clear_binding") + .defaultBind(GamepadBinds.RIGHT_STICK_PRESS) + .category(GUI_CATEGORY) + .build()); for (var constructor : CUSTOM_BINDS.values()) { register(constructor.apply(this)); diff --git a/src/main/java/dev/isxander/controlify/config/gui/AbstractBindController.java b/src/main/java/dev/isxander/controlify/config/gui/AbstractBindController.java new file mode 100644 index 0000000..4aaf6ef --- /dev/null +++ b/src/main/java/dev/isxander/controlify/config/gui/AbstractBindController.java @@ -0,0 +1,141 @@ +package dev.isxander.controlify.config.gui; + +import com.mojang.blaze3d.vertex.PoseStack; +import dev.isxander.controlify.api.event.ControlifyEvents; +import dev.isxander.controlify.bindings.EmptyBind; +import dev.isxander.controlify.bindings.IBind; +import dev.isxander.controlify.controller.ControllerState; +import dev.isxander.controlify.screenop.ComponentProcessor; +import dev.isxander.controlify.screenop.ScreenProcessor; +import dev.isxander.yacl.api.Controller; +import dev.isxander.yacl.api.Option; +import dev.isxander.yacl.api.utils.Dimension; +import dev.isxander.yacl.gui.YACLScreen; +import dev.isxander.yacl.gui.controllers.ControllerWidget; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import org.lwjgl.glfw.GLFW; + +import java.util.Optional; + +public abstract class AbstractBindController implements Controller> { + private final Option> option; + public final dev.isxander.controlify.controller.Controller controller; + + public AbstractBindController(Option> option, dev.isxander.controlify.controller.Controller controller) { + this.option = option; + this.controller = controller; + } + + @Override + public Option> option() { + return this.option; + } + + @Override + public Component formatValue() { + return Component.empty(); + } + + @Override + public abstract AbstractBindControllerElement provideWidget(YACLScreen yaclScreen, Dimension dimension); + + public abstract static class AbstractBindControllerElement extends ControllerWidget> implements ComponentProcessor, ControlifyEvents.ControllerStateUpdate { + private boolean awaitingControllerInput = false; + private boolean justTookInput = false; + private final Component awaitingText = Component.translatable("controlify.gui.bind_input_awaiting").withStyle(ChatFormatting.ITALIC); + + public AbstractBindControllerElement(AbstractBindController control, YACLScreen screen, Dimension dim) { + super(control, screen, dim); + } + + @Override + protected void drawValueText(PoseStack matrices, int mouseX, int mouseY, float delta) { + if (awaitingControllerInput) { + textRenderer.drawShadow(matrices, awaitingText, getDimension().xLimit() - textRenderer.width(awaitingText) - getXPadding(), getDimension().centerY() - textRenderer.lineHeight / 2f, 0xFFFFFF); + } else { + var bind = control.option().pendingValue(); + bind.draw(matrices, getDimension().xLimit() - bind.drawSize().width(), getDimension().centerY()); + } + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (isFocused() && keyCode == GLFW.GLFW_KEY_ENTER && !awaitingControllerInput) { + awaitingControllerInput = true; + ControllerBindHandler.setBindListener(this); + return true; + } + + return false; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (getDimension().isPointInside((int)mouseX, (int)mouseY)) { + awaitingControllerInput = true; + ControllerBindHandler.setBindListener(this); + return true; + } + + return false; + } + + @Override + public boolean overrideControllerButtons(ScreenProcessor screen, dev.isxander.controlify.controller.Controller controller) { + if (controller != control.controller) return true; + + if (controller.bindings().CLEAR_BINDING.justPressed()) { + control.option().requestSet(new EmptyBind<>()); + return true; + } + + if (controller.bindings().GUI_PRESS.justPressed() && !awaitingControllerInput) { + ControllerBindHandler.setBindListener(this); + return awaitingControllerInput = true; + } + + if (justTookInput) { + justTookInput = false; + return true; + } + + return false; + } + + @Override + public void onControllerStateUpdate(dev.isxander.controlify.controller.Controller controller) { + if (controller != control.controller) return; + + if (!awaitingControllerInput) return; + + Optional> pressedBind = getPressedBind(); + if (pressedBind.isPresent()) { + control.option().requestSet(pressedBind.get()); + awaitingControllerInput = false; + justTookInput = true; + ControllerBindHandler.clearBindListener(); + } + } + + @Override + public boolean overrideControllerNavigation(ScreenProcessor screen, dev.isxander.controlify.controller.Controller controller) { + return awaitingControllerInput || justTookInput; + } + + @Override + protected int getHoveredControlWidth() { + return getUnhoveredControlWidth(); + } + + @Override + protected int getUnhoveredControlWidth() { + if (awaitingControllerInput) + return textRenderer.width(awaitingText); + + return control.option().pendingValue().drawSize().width(); + } + + public abstract Optional> getPressedBind(); + } +} diff --git a/src/main/java/dev/isxander/controlify/config/gui/GamepadBindController.java b/src/main/java/dev/isxander/controlify/config/gui/GamepadBindController.java index 965805f..e8eecc6 100644 --- a/src/main/java/dev/isxander/controlify/config/gui/GamepadBindController.java +++ b/src/main/java/dev/isxander/controlify/config/gui/GamepadBindController.java @@ -1,142 +1,43 @@ package dev.isxander.controlify.config.gui; -import com.mojang.blaze3d.vertex.PoseStack; -import dev.isxander.controlify.api.event.ControlifyEvents; import dev.isxander.controlify.bindings.GamepadBind; import dev.isxander.controlify.bindings.GamepadBinds; import dev.isxander.controlify.bindings.IBind; import dev.isxander.controlify.controller.gamepad.GamepadController; import dev.isxander.controlify.controller.gamepad.GamepadState; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.yacl.api.Controller; import dev.isxander.yacl.api.Option; import dev.isxander.yacl.api.utils.Dimension; -import dev.isxander.yacl.gui.AbstractWidget; import dev.isxander.yacl.gui.YACLScreen; -import dev.isxander.yacl.gui.controllers.ControllerWidget; -import net.minecraft.ChatFormatting; -import net.minecraft.network.chat.Component; -import org.lwjgl.glfw.GLFW; -public class GamepadBindController implements Controller> { - private final Option> option; - private final GamepadController controller; +import java.util.Optional; +public class GamepadBindController extends AbstractBindController { public GamepadBindController(Option> option, GamepadController controller) { - this.option = option; - this.controller = controller; + super(option, controller); } @Override - public Option> option() { - return this.option; - } - - @Override - public Component formatValue() { - return Component.empty(); - } - - @Override - public AbstractWidget provideWidget(YACLScreen yaclScreen, Dimension dimension) { + public AbstractBindControllerElement provideWidget(YACLScreen yaclScreen, Dimension dimension) { return new BindButtonWidget(this, yaclScreen, dimension); } - public static class BindButtonWidget extends ControllerWidget implements ComponentProcessor, ControlifyEvents.ControllerStateUpdate { - private boolean awaitingControllerInput = false; - private boolean justTookInput = false; - private final Component awaitingText = Component.translatable("controlify.gui.bind_input_awaiting").withStyle(ChatFormatting.ITALIC); - + public static class BindButtonWidget extends AbstractBindControllerElement { public BindButtonWidget(GamepadBindController control, YACLScreen screen, Dimension dim) { super(control, screen, dim); } @Override - protected void drawValueText(PoseStack matrices, int mouseX, int mouseY, float delta) { - if (awaitingControllerInput) { - textRenderer.drawShadow(matrices, awaitingText, getDimension().xLimit() - textRenderer.width(awaitingText) - getXPadding(), getDimension().centerY() - textRenderer.lineHeight / 2f, 0xFFFFFF); - } else { - var bind = control.option().pendingValue(); - bind.draw(matrices, getDimension().xLimit() - bind.drawSize().width(), getDimension().centerY()); - } - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (isFocused() && keyCode == GLFW.GLFW_KEY_ENTER && !awaitingControllerInput) { - awaitingControllerInput = true; - ControllerBindHandler.setBindListener(this); - return true; - } - - return false; - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (getDimension().isPointInside((int)mouseX, (int)mouseY)) { - awaitingControllerInput = true; - ControllerBindHandler.setBindListener(this); - return true; - } - - return false; - } - - @Override - public boolean overrideControllerButtons(ScreenProcessor screen, dev.isxander.controlify.controller.Controller controller) { - if (controller != control.controller) return true; - - if (controller.bindings().GUI_PRESS.justPressed() && !awaitingControllerInput) { - ControllerBindHandler.setBindListener(this); - return awaitingControllerInput = true; - } - - if (justTookInput) { - justTookInput = false; - return true; - } - - return false; - } - - @Override - public void onControllerStateUpdate(dev.isxander.controlify.controller.Controller controller) { - if (controller != control.controller) return; - - if (!awaitingControllerInput) return; - - var gamepad = control.controller; + public Optional> getPressedBind() { + var gamepad = (GamepadController) control.controller; for (var bindType : GamepadBinds.values()) { GamepadBind bind = bindType.forGamepad(gamepad); if (bind.held(gamepad.state()) && !bind.held(gamepad.prevState())) { - control.option().requestSet(bind); - awaitingControllerInput = false; - justTookInput = true; - ControllerBindHandler.clearBindListener(); - return; + return Optional.of(bind); } } - } - @Override - public boolean overrideControllerNavigation(ScreenProcessor screen, dev.isxander.controlify.controller.Controller controller) { - return awaitingControllerInput || justTookInput; - } - - @Override - protected int getHoveredControlWidth() { - return getUnhoveredControlWidth(); - } - - @Override - protected int getUnhoveredControlWidth() { - if (awaitingControllerInput) - return textRenderer.width(awaitingText); - - return control.option().pendingValue().drawSize().width(); + return Optional.empty(); } } } diff --git a/src/main/java/dev/isxander/controlify/config/gui/JoystickBindController.java b/src/main/java/dev/isxander/controlify/config/gui/JoystickBindController.java index 7489b3c..f477055 100644 --- a/src/main/java/dev/isxander/controlify/config/gui/JoystickBindController.java +++ b/src/main/java/dev/isxander/controlify/config/gui/JoystickBindController.java @@ -1,124 +1,38 @@ package dev.isxander.controlify.config.gui; -import com.mojang.blaze3d.vertex.PoseStack; -import dev.isxander.controlify.api.event.ControlifyEvents; import dev.isxander.controlify.bindings.*; import dev.isxander.controlify.controller.joystick.JoystickController; -import dev.isxander.controlify.controller.joystick.SingleJoystickController; import dev.isxander.controlify.controller.joystick.JoystickState; -import dev.isxander.controlify.screenop.ComponentProcessor; -import dev.isxander.controlify.screenop.ScreenProcessor; -import dev.isxander.yacl.api.Controller; import dev.isxander.yacl.api.Option; import dev.isxander.yacl.api.utils.Dimension; -import dev.isxander.yacl.gui.AbstractWidget; import dev.isxander.yacl.gui.YACLScreen; -import dev.isxander.yacl.gui.controllers.ControllerWidget; -import net.minecraft.ChatFormatting; -import net.minecraft.network.chat.Component; -import org.lwjgl.glfw.GLFW; -public class JoystickBindController implements Controller> { - private final Option> option; - private final JoystickController controller; +import java.util.Optional; +public class JoystickBindController extends AbstractBindController { public JoystickBindController(Option> option, JoystickController controller) { - this.option = option; - this.controller = controller; + super(option, controller); } - @Override - public Option> option() { - return this.option; - } - - @Override - public Component formatValue() { - return Component.empty(); - } - - @Override - public AbstractWidget provideWidget(YACLScreen yaclScreen, Dimension dimension) { + public AbstractBindControllerElement provideWidget(YACLScreen yaclScreen, Dimension dimension) { return new BindButtonWidget(this, yaclScreen, dimension); } - public static class BindButtonWidget extends ControllerWidget implements ComponentProcessor, ControlifyEvents.ControllerStateUpdate { - private boolean awaitingControllerInput = false; - private boolean justTookInput = false; - private final Component awaitingText = Component.translatable("controlify.gui.bind_input_awaiting").withStyle(ChatFormatting.ITALIC); - + public static class BindButtonWidget extends AbstractBindControllerElement { public BindButtonWidget(JoystickBindController control, YACLScreen screen, Dimension dim) { super(control, screen, dim); } @Override - protected void drawValueText(PoseStack matrices, int mouseX, int mouseY, float delta) { - if (awaitingControllerInput) { - textRenderer.drawShadow(matrices, awaitingText, getDimension().xLimit() - textRenderer.width(awaitingText) - getXPadding(), getDimension().centerY() - textRenderer.lineHeight / 2f, 0xFFFFFF); - } else { - var bind = control.option().pendingValue(); - bind.draw(matrices, getDimension().xLimit() - bind.drawSize().width(), getDimension().centerY()); - } - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (isFocused() && keyCode == GLFW.GLFW_KEY_ENTER && !awaitingControllerInput) { - awaitingControllerInput = true; - ControllerBindHandler.setBindListener(this); - return true; - } - - return false; - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (getDimension().isPointInside((int)mouseX, (int)mouseY)) { - awaitingControllerInput = true; - ControllerBindHandler.setBindListener(this); - return true; - } - - return false; - } - - @Override - public boolean overrideControllerButtons(ScreenProcessor screen, dev.isxander.controlify.controller.Controller controller) { - if (controller != control.controller) return true; - - if (justTookInput) { - justTookInput = false; - return true; - } - - if (controller.bindings().GUI_PRESS.justPressed() && !awaitingControllerInput) { - awaitingControllerInput = true; - ControllerBindHandler.setBindListener(this); - return true; - } - - return awaitingControllerInput; - } - - @Override - public void onControllerStateUpdate(dev.isxander.controlify.controller.Controller controller) { - if (controller != control.controller) return; - - if (!awaitingControllerInput) return; - - var joystick = control.controller; + public Optional> getPressedBind() { + var joystick = (JoystickController) control.controller; var state = joystick.state(); var prevState = joystick.prevState(); for (int i = 0; i < Math.min(state.buttons().size(), prevState.buttons().size()); i++) { if (state.buttons().get(i) && !prevState.buttons().get(i)) { - control.option().requestSet(new JoystickButtonBind(joystick, i)); - awaitingControllerInput = false; - justTookInput = true; - ControllerBindHandler.clearBindListener(); - return; + return Optional.of(new JoystickButtonBind(joystick, i)); } } @@ -129,17 +43,9 @@ public class JoystickBindController implements Controller> if (Math.abs(prevAxis) < activationThreshold) { if (axis > activationThreshold) { - control.option().requestSet(new JoystickAxisBind(joystick, i, JoystickAxisBind.AxisDirection.POSITIVE)); - awaitingControllerInput = false; - justTookInput = true; - ControllerBindHandler.clearBindListener(); - return; + return Optional.of(new JoystickAxisBind(joystick, i, JoystickAxisBind.AxisDirection.POSITIVE)); } else if (axis < -activationThreshold) { - control.option().requestSet(new JoystickAxisBind(joystick, i, JoystickAxisBind.AxisDirection.NEGATIVE)); - awaitingControllerInput = false; - justTookInput = true; - ControllerBindHandler.clearBindListener(); - return; + return Optional.of(new JoystickAxisBind(joystick, i, JoystickAxisBind.AxisDirection.NEGATIVE)); } } } @@ -149,31 +55,11 @@ public class JoystickBindController implements Controller> var prevHat = prevState.hats().get(i); if (prevHat.isCentered() && !hat.isCentered()) { - control.option().requestSet(new JoystickHatBind(joystick, i, hat)); - awaitingControllerInput = false; - justTookInput = true; - ControllerBindHandler.clearBindListener(); - return; + return Optional.of(new JoystickHatBind(joystick, i, hat)); } } - } - @Override - public boolean overrideControllerNavigation(ScreenProcessor screen, dev.isxander.controlify.controller.Controller controller) { - return awaitingControllerInput || justTookInput; - } - - @Override - protected int getHoveredControlWidth() { - return getUnhoveredControlWidth(); - } - - @Override - protected int getUnhoveredControlWidth() { - if (awaitingControllerInput) - return textRenderer.width(awaitingText); - - return control.option().pendingValue().drawSize().width(); + return Optional.empty(); } } } diff --git a/src/main/resources/assets/controlify/lang/en_us.json b/src/main/resources/assets/controlify/lang/en_us.json index f03991d..c751e0b 100644 --- a/src/main/resources/assets/controlify/lang/en_us.json +++ b/src/main/resources/assets/controlify/lang/en_us.json @@ -178,6 +178,7 @@ "controlify.binding.controlify.gui_navi_right": "GUI Navi Right", "controlify.binding.controlify.cycle_opt_forward": "Cycle Option Forward", "controlify.binding.controlify.cycle_opt_backward": "Cycle Option Backward", + "controlify.binding.controlify.clear_binding": "Clear Binding", "controlify.binding_category.gui": "GUI", "controlify.binding_category.vmouse": "Virtual Mouse",