1
0
forked from Clones/Controlify

🐛 Fix unable to create newlines and spaces in signs in mixed input mode (close #151)

Refactor `NavigationHelper` to `HoldRepeatHelper`
This commit is contained in:
Xander
2023-10-25 17:08:43 +01:00
parent d0b8f912f1
commit 36fadf1445
8 changed files with 88 additions and 32 deletions

View File

@ -3,12 +3,12 @@ package dev.isxander.controlify.compatibility.yacl;
import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.screenop.ScreenProcessor;
import dev.isxander.controlify.screenop.ComponentProcessor;
import dev.isxander.controlify.utils.NavigationHelper;
import dev.isxander.controlify.utils.HoldRepeatHelper;
import dev.isxander.yacl3.gui.controllers.slider.SliderControllerElement;
public class SliderControllerElementComponentProcessor implements ComponentProcessor {
private final SliderControllerElement slider;
private final NavigationHelper navigationHelper = new NavigationHelper(15, 3);
private final HoldRepeatHelper holdRepeatHelper = new HoldRepeatHelper(15, 3);
public SliderControllerElementComponentProcessor(SliderControllerElement element) {
this.slider = element;
@ -21,23 +21,23 @@ public class SliderControllerElementComponentProcessor implements ComponentProce
var right = controller.bindings().CYCLE_OPT_FORWARD.held();
var rightPrev = controller.bindings().CYCLE_OPT_FORWARD.prevHeld();
boolean repeatEventAvailable = navigationHelper.canNavigate();
boolean repeatEventAvailable = holdRepeatHelper.canNavigate();
if (left && (repeatEventAvailable || !leftPrev)) {
slider.incrementValue(-1);
if (!leftPrev)
navigationHelper.reset();
holdRepeatHelper.reset();
} else if (right && (repeatEventAvailable || !rightPrev)) {
slider.incrementValue(1);
if (!rightPrev)
navigationHelper.reset();
holdRepeatHelper.reset();
} else {
return false;
}
navigationHelper.onNavigate();
holdRepeatHelper.onNavigate();
return true;
}

View File

@ -1,7 +1,6 @@
package dev.isxander.controlify.ingame;
import dev.isxander.controlify.Controlify;
import dev.isxander.controlify.InputMode;
import dev.isxander.controlify.api.ingameinput.LookInputModifier;
import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.api.event.ControlifyEvents;
@ -11,7 +10,7 @@ import dev.isxander.controlify.gui.screen.RadialMenuScreen;
import dev.isxander.controlify.server.ServerPolicies;
import dev.isxander.controlify.utils.Animator;
import dev.isxander.controlify.utils.Easings;
import dev.isxander.controlify.utils.NavigationHelper;
import dev.isxander.controlify.utils.HoldRepeatHelper;
import net.minecraft.client.CameraType;
import net.minecraft.client.Minecraft;
import net.minecraft.client.Screenshot;
@ -39,12 +38,12 @@ public class InGameInputHandler {
private boolean shouldShowPlayerList;
private final NavigationHelper dropRepeatHelper;
private final HoldRepeatHelper dropRepeatHelper;
public InGameInputHandler(Controller<?, ?> controller) {
this.controller = controller;
this.minecraft = Minecraft.getInstance();
this.dropRepeatHelper = new NavigationHelper(20, 1);
this.dropRepeatHelper = new HoldRepeatHelper(20, 1);
}
public void inputTick() {

View File

@ -0,0 +1,19 @@
package dev.isxander.controlify.mixins.feature.screenop.vanilla;
import dev.isxander.controlify.screenop.ScreenProcessor;
import dev.isxander.controlify.screenop.ScreenProcessorProvider;
import dev.isxander.controlify.screenop.compat.vanilla.AbstractSignEditScreenProcessor;
import net.minecraft.client.gui.screens.inventory.AbstractSignEditScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@Mixin(AbstractSignEditScreen.class)
public class AbstractSignEditScreenMixin implements ScreenProcessorProvider {
@Unique private final AbstractSignEditScreenProcessor screenProcessor =
new AbstractSignEditScreenProcessor((AbstractSignEditScreen) (Object) this);
@Override
public ScreenProcessor<?> screenProcessor() {
return screenProcessor;
}
}

View File

@ -8,14 +8,13 @@ import dev.isxander.controlify.controller.gamepad.GamepadState;
import dev.isxander.controlify.mixins.feature.screenop.ScreenAccessor;
import dev.isxander.controlify.mixins.feature.screenop.vanilla.TabNavigationBarAccessor;
import dev.isxander.controlify.sound.ControlifySounds;
import dev.isxander.controlify.utils.NavigationHelper;
import dev.isxander.controlify.utils.HoldRepeatHelper;
import dev.isxander.controlify.virtualmouse.VirtualMouseBehaviour;
import dev.isxander.controlify.virtualmouse.VirtualMouseHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ComponentPath;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.components.tabs.Tab;
import net.minecraft.client.gui.components.tabs.TabNavigationBar;
@ -31,7 +30,7 @@ import java.util.*;
public class ScreenProcessor<T extends Screen> {
public final T screen;
protected final NavigationHelper navigationHelper = new NavigationHelper(10, 3);
protected final HoldRepeatHelper holdRepeatHelper = new HoldRepeatHelper(10, 3);
protected static final Minecraft minecraft = Minecraft.getInstance();
public ScreenProcessor(T screen) {
@ -88,7 +87,7 @@ public class ScreenProcessor<T extends Screen> {
var accessor = (ScreenAccessor) screen;
boolean repeatEventAvailable = navigationHelper.canNavigate();
boolean repeatEventAvailable = holdRepeatHelper.canNavigate();
var bindings = controller.bindings();
@ -97,43 +96,43 @@ public class ScreenProcessor<T extends Screen> {
event = accessor.invokeCreateArrowEvent(ScreenDirection.RIGHT);
if (!bindings.GUI_NAVI_RIGHT.prevHeld())
navigationHelper.reset();
holdRepeatHelper.reset();
} else if (bindings.GUI_NAVI_LEFT.held() && (repeatEventAvailable || !bindings.GUI_NAVI_LEFT.prevHeld())) {
event = accessor.invokeCreateArrowEvent(ScreenDirection.LEFT);
if (!bindings.GUI_NAVI_LEFT.prevHeld())
navigationHelper.reset();
holdRepeatHelper.reset();
} else if (bindings.GUI_NAVI_UP.held() && (repeatEventAvailable || !bindings.GUI_NAVI_UP.prevHeld())) {
event = accessor.invokeCreateArrowEvent(ScreenDirection.UP);
if (!bindings.GUI_NAVI_UP.prevHeld())
navigationHelper.reset();
holdRepeatHelper.reset();
} else if (bindings.GUI_NAVI_DOWN.held() && (repeatEventAvailable || !bindings.GUI_NAVI_DOWN.prevHeld())) {
event = accessor.invokeCreateArrowEvent(ScreenDirection.DOWN);
if (!bindings.GUI_NAVI_DOWN.prevHeld())
navigationHelper.reset();
holdRepeatHelper.reset();
} else if (controller.state() instanceof GamepadState state && controller.prevState() instanceof GamepadState prevState) {
if (state.gamepadButtons().dpadRight() && (repeatEventAvailable || !prevState.gamepadButtons().dpadRight())) {
event = accessor.invokeCreateArrowEvent(ScreenDirection.RIGHT);
if (!prevState.gamepadButtons().dpadRight())
navigationHelper.reset();
holdRepeatHelper.reset();
} else if (state.gamepadButtons().dpadLeft() && (repeatEventAvailable || !prevState.gamepadButtons().dpadLeft())) {
event = accessor.invokeCreateArrowEvent(ScreenDirection.LEFT);
if (!prevState.gamepadButtons().dpadLeft())
navigationHelper.reset();
holdRepeatHelper.reset();
} else if (state.gamepadButtons().dpadUp() && (repeatEventAvailable || !prevState.gamepadButtons().dpadUp())) {
event = accessor.invokeCreateArrowEvent(ScreenDirection.UP);
if (!prevState.gamepadButtons().dpadUp())
navigationHelper.reset();
holdRepeatHelper.reset();
} else if (state.gamepadButtons().dpadDown() && (repeatEventAvailable || !prevState.gamepadButtons().dpadDown())) {
event = accessor.invokeCreateArrowEvent(ScreenDirection.DOWN);
if (!prevState.gamepadButtons().dpadDown())
navigationHelper.reset();
holdRepeatHelper.reset();
}
}
@ -142,7 +141,7 @@ public class ScreenProcessor<T extends Screen> {
if (path != null) {
accessor.invokeChangeFocus(path);
navigationHelper.onNavigate();
holdRepeatHelper.onNavigate();
if (Controlify.instance().config().globalSettings().uiSounds)
minecraft.getSoundManager().play(SimpleSoundInstance.forUI(ControlifySounds.SCREEN_FOCUS_CHANGE, 1.0F));
@ -235,7 +234,7 @@ public class ScreenProcessor<T extends Screen> {
ComponentPath path = screen.nextFocusPath(accessor.invokeCreateArrowEvent(ScreenDirection.DOWN));
if (path != null) {
accessor.invokeChangeFocus(path);
navigationHelper.clearDelay();
holdRepeatHelper.clearDelay();
}
}
}

View File

@ -3,14 +3,14 @@ package dev.isxander.controlify.screenop.compat;
import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.screenop.ComponentProcessor;
import dev.isxander.controlify.screenop.ScreenProcessor;
import dev.isxander.controlify.utils.NavigationHelper;
import dev.isxander.controlify.utils.HoldRepeatHelper;
/**
* A component processor that handles incrementing and decrementing a slider.
* This uses {@link dev.isxander.controlify.bindings.ControllerBindings#CYCLE_OPT_FORWARD} and {@link dev.isxander.controlify.bindings.ControllerBindings#CYCLE_OPT_BACKWARD} to increment and decrement the slider.
*/
public abstract class AbstractSliderComponentProcessor implements ComponentProcessor {
private final NavigationHelper navigationHelper = new NavigationHelper(15, 3);
private final HoldRepeatHelper holdRepeatHelper = new HoldRepeatHelper(15, 3);
@Override
public boolean overrideControllerNavigation(ScreenProcessor<?> screen, Controller<?, ?> controller) {
@ -19,23 +19,23 @@ public abstract class AbstractSliderComponentProcessor implements ComponentProce
var right = controller.bindings().CYCLE_OPT_FORWARD.held();
var rightPrev = controller.bindings().CYCLE_OPT_FORWARD.prevHeld();
boolean repeatEventAvailable = navigationHelper.canNavigate();
boolean repeatEventAvailable = holdRepeatHelper.canNavigate();
if (left && (repeatEventAvailable || !leftPrev)) {
incrementSlider(true);
if (!leftPrev)
navigationHelper.reset();
holdRepeatHelper.reset();
} else if (right && (repeatEventAvailable || !rightPrev)) {
incrementSlider(false);
if (!rightPrev)
navigationHelper.reset();
holdRepeatHelper.reset();
} else {
return false;
}
navigationHelper.onNavigate();
holdRepeatHelper.onNavigate();
return true;
}

View File

@ -0,0 +1,38 @@
package dev.isxander.controlify.screenop.compat.vanilla;
import dev.isxander.controlify.Controlify;
import dev.isxander.controlify.InputMode;
import dev.isxander.controlify.api.buttonguide.ButtonGuideApi;
import dev.isxander.controlify.api.buttonguide.ButtonGuidePredicate;
import dev.isxander.controlify.api.buttonguide.ButtonRenderPosition;
import dev.isxander.controlify.screenop.ScreenProcessor;
import net.minecraft.client.gui.components.AbstractButton;
import net.minecraft.client.gui.screens.inventory.AbstractSignEditScreen;
import net.minecraft.network.chat.CommonComponents;
public class AbstractSignEditScreenProcessor extends ScreenProcessor<AbstractSignEditScreen> {
public AbstractSignEditScreenProcessor(AbstractSignEditScreen screen) {
super(screen);
}
@Override
protected void setInitialFocus() {
if (Controlify.instance().currentInputMode() == InputMode.MIXED)
holdRepeatHelper.clearDelay();
else
super.setInitialFocus();
}
@Override
public void onWidgetRebuild() {
super.onWidgetRebuild();
getWidget(CommonComponents.GUI_DONE).ifPresent(doneButton ->
ButtonGuideApi.addGuideToButtonBuiltin(
(AbstractButton) doneButton,
bindings -> bindings.GUI_BACK,
ButtonRenderPosition.TEXT,
ButtonGuidePredicate.ALWAYS
));
}
}

View File

@ -2,13 +2,13 @@ package dev.isxander.controlify.utils;
import dev.isxander.controlify.api.bind.ControllerBinding;
public class NavigationHelper {
public class HoldRepeatHelper {
private final int initialDelay, repeatDelay;
private int currentDelay;
private boolean hasResetThisTick = false;
public NavigationHelper(int initialDelay, int repeatDelay) {
public HoldRepeatHelper(int initialDelay, int repeatDelay) {
this.initialDelay = initialDelay;
this.repeatDelay = repeatDelay;
this.currentDelay = 0;

View File

@ -66,6 +66,7 @@
"feature.screenop.vanilla.AbstractContainerEventHandlerMixin",
"feature.screenop.vanilla.AbstractContainerScreenMixin",
"feature.screenop.vanilla.AbstractSelectionListMixin",
"feature.screenop.vanilla.AbstractSignEditScreenMixin",
"feature.screenop.vanilla.AbstractSliderButtonMixin",
"feature.screenop.vanilla.ContainerObjectSelectionListEntryMixin",
"feature.screenop.vanilla.CreateWorldScreenMixin",