Add chording and new button assignment system.

This commit is contained in:
LambdAurora
2020-01-02 00:31:00 +01:00
parent 1b5a0e470e
commit 647e03134f
13 changed files with 135 additions and 69 deletions

View File

@@ -47,8 +47,7 @@ import java.util.Map;
import java.util.Optional;
import static me.lambdaurora.lambdacontrols.controller.ButtonBinding.axis_as_button;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X;
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y;
import static org.lwjgl.glfw.GLFW.*;
/**
* Represents the LambdaControls' input handler.
@@ -135,15 +134,20 @@ public class LambdaInput
this.fetch_axe_input(client, state, true);
});
InputManager.update_bindings(client);
boolean allow_input = true;
if (client.currentScreen instanceof LambdaControlsControlsScreen && ((LambdaControlsControlsScreen) client.currentScreen).focused_binding != null)
allow_input = false;
if (allow_input)
InputManager.update_bindings(client);
if (this.ignore_next_a > 0)
this.ignore_next_a--;
if (client.currentScreen instanceof LambdaControlsControlsScreen && InputManager.STATES.entrySet().parallelStream().map(Map.Entry::getValue).allMatch(ButtonState::is_unpressed))
{
if (client.currentScreen instanceof LambdaControlsControlsScreen && InputManager.STATES.entrySet().parallelStream().map(Map.Entry::getValue).allMatch(ButtonState::is_unpressed)) {
LambdaControlsControlsScreen controls_screen = (LambdaControlsControlsScreen) client.currentScreen;
if (controls_screen.focused_binding != null) {
if (controls_screen.focused_binding != null && !controls_screen.waiting) {
int[] buttons = new int[controls_screen.current_buttons.size()];
for (int i = 0; i < controls_screen.current_buttons.size(); i++)
buttons[i] = controls_screen.current_buttons.get(i);
@@ -253,10 +257,19 @@ public class LambdaInput
private void handle_button(@NotNull MinecraftClient client, int button, int action, boolean state)
{
if (client.currentScreen instanceof LambdaControlsControlsScreen && action == 0) {
if (client.currentScreen instanceof LambdaControlsControlsScreen) {
LambdaControlsControlsScreen controls_screen = (LambdaControlsControlsScreen) client.currentScreen;
if (controls_screen.focused_binding != null) {
controls_screen.current_buttons.add(button);
if (action == 0 && !controls_screen.current_buttons.contains(button)) {
controls_screen.current_buttons.add(button);
int[] buttons = new int[controls_screen.current_buttons.size()];
for (int i = 0; i < controls_screen.current_buttons.size(); i++)
buttons[i] = controls_screen.current_buttons.get(i);
controls_screen.focused_binding.set_button(buttons);
controls_screen.waiting = false;
}
return;
}
}
@@ -335,47 +348,60 @@ public class LambdaInput
{
int as_button_state = value > 0.5F ? 1 : (value < -0.5F ? 2 : 0);
if (client.currentScreen instanceof LambdaControlsControlsScreen && as_button_state != 0
&& !(as_button_state == 2 && (axis == GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || axis == GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER ||
axis == ButtonBinding.controller2_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER) || axis == ButtonBinding.controller2_button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER)))) {
if (axis == GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || axis == GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER || axis == ButtonBinding.controller2_button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER) ||
axis == ButtonBinding.controller2_button(GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER))
if (as_button_state == 2)
as_button_state = 0;
{
boolean current_plus_state = as_button_state == 1;
boolean current_minus_state = as_button_state == 2;
ButtonState previous_plus_state = InputManager.STATES.getOrDefault(axis_as_button(axis, true), ButtonState.NONE);
ButtonState previous_minus_state = InputManager.STATES.getOrDefault(axis_as_button(axis, false), ButtonState.NONE);
if (current_plus_state != previous_plus_state.is_pressed()) {
InputManager.STATES.put(axis_as_button(axis, true), current_plus_state ? ButtonState.PRESS : ButtonState.RELEASE);
if (current_plus_state)
BUTTON_COOLDOWNS.put(axis_as_button(axis, true), 5);
} else if (current_plus_state) {
InputManager.STATES.put(axis_as_button(axis, true), ButtonState.REPEAT);
if (BUTTON_COOLDOWNS.getOrDefault(axis_as_button(axis, true), 0) == 0) {
BUTTON_COOLDOWNS.put(axis_as_button(axis, true), 5);
}
}
if (current_minus_state != previous_minus_state.is_pressed()) {
InputManager.STATES.put(axis_as_button(axis, false), current_minus_state ? ButtonState.PRESS : ButtonState.RELEASE);
if (current_minus_state)
BUTTON_COOLDOWNS.put(axis_as_button(axis, false), 5);
} else if (current_minus_state) {
InputManager.STATES.put(axis_as_button(axis, false), ButtonState.REPEAT);
if (BUTTON_COOLDOWNS.getOrDefault(axis_as_button(axis, false), 0) == 0) {
BUTTON_COOLDOWNS.put(axis_as_button(axis, false), 5);
}
}
}
if (client.currentScreen instanceof LambdaControlsControlsScreen) {
LambdaControlsControlsScreen controls_screen = (LambdaControlsControlsScreen) client.currentScreen;
if (controls_screen.focused_binding != null) {
controls_screen.current_buttons.add(axis_as_button(axis, as_button_state == 1));
if (as_button_state != 0 && !controls_screen.current_buttons.contains(axis_as_button(axis, as_button_state == 1))) {
controls_screen.current_buttons.add(axis_as_button(axis, as_button_state == 1));
int[] buttons = new int[controls_screen.current_buttons.size()];
for (int i = 0; i < controls_screen.current_buttons.size(); i++)
buttons[i] = controls_screen.current_buttons.get(i);
controls_screen.focused_binding.set_button(buttons);
controls_screen.waiting = false;
}
return;
}
}
double dead_zone = this.config.get_dead_zone();
if (client.currentScreen == null) {
{
boolean current_plus_state = as_button_state == 1;
boolean current_minus_state = as_button_state == 2;
ButtonState previous_plus_state = InputManager.STATES.getOrDefault(axis_as_button(axis, true), ButtonState.NONE);
ButtonState previous_minus_state = InputManager.STATES.getOrDefault(axis_as_button(axis, false), ButtonState.NONE);
if (current_plus_state != previous_plus_state.is_pressed()) {
InputManager.STATES.put(axis_as_button(axis, true), current_plus_state ? ButtonState.PRESS : ButtonState.RELEASE);
if (current_plus_state)
BUTTON_COOLDOWNS.put(axis_as_button(axis, true), 5);
} else if (current_plus_state) {
InputManager.STATES.put(axis_as_button(axis, true), ButtonState.REPEAT);
if (BUTTON_COOLDOWNS.getOrDefault(axis_as_button(axis, true), 0) == 0) {
BUTTON_COOLDOWNS.put(axis_as_button(axis, true), 5);
}
}
if (current_minus_state != previous_minus_state.is_pressed()) {
InputManager.STATES.put(axis_as_button(axis, false), current_minus_state ? ButtonState.PRESS : ButtonState.RELEASE);
if (current_minus_state)
BUTTON_COOLDOWNS.put(axis_as_button(axis, false), 5);
} else if (current_minus_state) {
InputManager.STATES.put(axis_as_button(axis, false), ButtonState.REPEAT);
if (BUTTON_COOLDOWNS.getOrDefault(axis_as_button(axis, false), 0) == 0) {
BUTTON_COOLDOWNS.put(axis_as_button(axis, false), 5);
}
}
}
// Handles the look direction.
this.handle_look(client, axis, (float) (abs_value / (1.0 - this.config.get_dead_zone())), state);
} else {

View File

@@ -24,8 +24,6 @@ import org.jetbrains.annotations.NotNull;
*/
public class LambdaControlsCompat
{
private static final String OKZOOMER_CLASS_PATH = "io.github.joaoh1.okzoomer.OkZoomer";
/**
* Initializes compatibility with other mods if needed.
*
@@ -33,7 +31,7 @@ public class LambdaControlsCompat
*/
public static void init(@NotNull LambdaControls mod)
{
if (FabricLoader.getInstance().isModLoaded("okzoomer") && LambdaReflection.does_class_exist(OKZOOMER_CLASS_PATH)) {
if (FabricLoader.getInstance().isModLoaded("okzoomer") && LambdaReflection.does_class_exist(OkZoomerCompat.OKZOOMER_CLASS_PATH)) {
mod.log("Adding okzoomer compatibility...");
new OkZoomerCompat().handle(mod);
}

View File

@@ -26,6 +26,8 @@ import org.lwjgl.glfw.GLFW;
*/
public class OkZoomerCompat implements CompatHandler
{
public static final String OKZOOMER_CLASS_PATH = "io.github.joaoh1.okzoomer.OkZoomer";
@Override
public void handle(@NotNull LambdaControls mod)
{

View File

@@ -140,7 +140,7 @@ public class ButtonBinding implements Nameable
*/
public boolean is_not_bound()
{
return this.button[0] == -1;
return this.button.length == 0 || this.button[0] == -1;
}
/**

View File

@@ -9,10 +9,12 @@
package me.lambdaurora.lambdacontrols.gui;
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.LambdaControls;
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
import me.lambdaurora.spruceui.AbstractIconButtonWidget;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.resource.language.I18n;
import org.aperlambda.lambdacommon.utils.Pair;
import org.jetbrains.annotations.NotNull;
/**
@@ -21,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
public class ControllerButtonWidget extends AbstractIconButtonWidget
{
private ButtonBinding binding;
private int icon_width;
public ControllerButtonWidget(int x, int y, int width, @NotNull ButtonBinding button_binding, @NotNull PressAction on_press)
{
@@ -30,12 +33,27 @@ public class ControllerButtonWidget extends AbstractIconButtonWidget
public void update()
{
this.setMessage(ButtonBinding.get_localized_button_name(binding.get_button()[0]));
int length = binding.get_button().length;
this.setMessage(this.binding.is_not_bound() ? I18n.translate("lambdacontrols.not_bound") :
(length > 0 ? ButtonBinding.get_localized_button_name(binding.get_button()[0]) : "<>"));
}
@Override
public String getMessage()
{
if (this.binding.get_button().length > 1)
return "";
return super.getMessage();
}
@Override
protected int render_icon(int mouse_x, int mouse_y, float delta, int x, int y)
{
return LambdaControls.draw_button(x, y, this.binding, MinecraftClient.getInstance()).get_value();
if (this.binding.get_button().length > 1) {
x += (this.width / 2 - this.icon_width / 2) - 4;
}
Pair<Integer, Integer> size = LambdaControls.draw_button(x, y, this.binding, MinecraftClient.getInstance());
this.icon_width = size.get_key();
return size.get_value();
}
}

View File

@@ -33,8 +33,9 @@ import java.util.List;
*/
public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Entry>
{
private final LambdaControlsControlsScreen gui;
private int field_2733;
private static final int[] UNBOUND = new int[0];
private final LambdaControlsControlsScreen gui;
private int field_2733;
public ControlsListWidget(@NotNull LambdaControlsControlsScreen gui, @NotNull MinecraftClient client)
{
@@ -75,6 +76,7 @@ public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Ent
private final String binding_name;
private final ControllerButtonWidget edit_button;
private final ButtonWidget reset_button;
private final ButtonWidget unbound_button;
ButtonBindingEntry(@NotNull ButtonBinding binding)
{
@@ -83,6 +85,7 @@ public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Ent
this.edit_button = new ControllerButtonWidget(0, 0, 110, this.binding, btn -> {
gui.focused_binding = binding;
gui.current_buttons.clear();
gui.waiting = true;
})
{
protected String getNarrationMessage()
@@ -98,6 +101,17 @@ public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Ent
return I18n.translate("narrator.controls.reset", binding_name);
}
};
this.unbound_button = new ButtonWidget(0, 0, 50, 20, I18n.translate("lambdacontrols.menu.unbound"),
btn -> {
gui.mod.config.set_button_binding(binding, UNBOUND);
gui.focused_binding = null;
})
{
protected String getNarrationMessage()
{
return I18n.translate("lambdacontrols.narrator.unbound", binding_name);
}
};
}
@Override
@@ -115,10 +129,13 @@ public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Ent
float var10002 = (float) (x + 70 - ControlsListWidget.this.field_2733);
int var10003 = y + height / 2;
text_renderer.draw(binding_name, var10002, (float) (var10003 - 9 / 2), 16777215);
this.reset_button.x = x + 190;
this.reset_button.y = y;
this.reset_button.x = this.unbound_button.x = x + 190;
this.reset_button.y = this.unbound_button.y = y;
this.reset_button.active = !this.binding.is_default();
this.reset_button.render(mouse_x, mouse_y, delta);
if (focused)
this.unbound_button.render(mouse_x, mouse_y, delta);
else
this.reset_button.render(mouse_x, mouse_y, delta);
this.edit_button.x = x + 75;
this.edit_button.y = y;
this.edit_button.update();
@@ -134,17 +151,19 @@ public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Ent
this.edit_button.render(mouse_x, mouse_y, delta);
}
public boolean mouseClicked(double mouseX, double mouseY, int button)
public boolean mouseClicked(double mouse_x, double mouse_y, int button)
{
if (this.edit_button.mouseClicked(mouseX, mouseY, button))
boolean focused = gui.focused_binding == this.binding;
if (this.edit_button.mouseClicked(mouse_x, mouse_y, button))
return true;
else
return this.reset_button.mouseClicked(mouseX, mouseY, button);
return focused ? this.unbound_button.mouseClicked(mouse_x, mouse_y, button) : this.reset_button.mouseClicked(mouse_x, mouse_y, button);
}
public boolean mouseReleased(double mouseX, double mouseY, int button)
public boolean mouseReleased(double mouse_x, double mouse_y, int button)
{
return this.edit_button.mouseReleased(mouseX, mouseY, button) || this.reset_button.mouseReleased(mouseX, mouseY, button);
return this.edit_button.mouseReleased(mouse_x, mouse_y, button) || this.reset_button.mouseReleased(mouse_x, mouse_y, button)
|| this.unbound_button.mouseReleased(mouse_x, mouse_y, button);
}
}

View File

@@ -36,6 +36,7 @@ public class LambdaControlsControlsScreen extends Screen
private ControlsListWidget bindings_list_widget;
private ButtonWidget reset_button;
public ButtonBinding focused_binding;
public boolean waiting = false;
public List<Integer> current_buttons = new ArrayList<>();
public LambdaControlsControlsScreen(@NotNull Screen parent, boolean hide_settings)

View File

@@ -9,10 +9,10 @@
package me.lambdaurora.lambdacontrols.gui;
import me.lambdaurora.lambdacontrols.HudSide;
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.ControlsMode;
import me.lambdaurora.lambdacontrols.HudSide;
import me.lambdaurora.lambdacontrols.LambdaControls;
import me.lambdaurora.lambdacontrols.controller.ButtonBinding;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.util.hit.HitResult;
@@ -29,8 +29,8 @@ public class LambdaControlsHud extends DrawableHelper
{
private final MinecraftClient client;
private final LambdaControls mod;
private int width_bottom = 0;
private int width_top = 0;
private int width_bottom = 0;
private int width_top = 0;
public LambdaControlsHud(@NotNull MinecraftClient client, @NotNull LambdaControls mod)
{

View File

@@ -21,7 +21,6 @@ import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen;
import net.minecraft.client.gui.widget.ButtonListWidget;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.options.BooleanOption;
import net.minecraft.client.options.CyclingOption;
import net.minecraft.client.options.GameOptions;
import net.minecraft.client.options.Option;

View File

@@ -12,18 +12,12 @@ package me.lambdaurora.lambdacontrols.mixin;
import me.lambdaurora.lambdacontrols.ControlsMode;
import me.lambdaurora.lambdacontrols.LambdaControls;
import me.lambdaurora.lambdacontrols.gui.LambdaControlsControlsScreen;
import me.lambdaurora.lambdacontrols.gui.LambdaControlsSettingsScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.SettingsScreen;
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.options.GameOptions;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

View File

@@ -92,6 +92,9 @@
"lambdacontrols.menu.title.controller_controls": "Controller controls",
"lambdacontrols.menu.title.general": "General options",
"lambdacontrols.menu.title.hud": "HUD options",
"lambdacontrols.menu.unbound": "Unbound",
"lambdacontrols.narrator.unbound": "Unbound %s",
"lambdacontrols.not_bound": "Not bound",
"lambdacontrols.tooltip.auto_switch_mode": "Sets whether the controls mode should be switched automatically to Controller if a controller is connected.",
"lambdacontrols.tooltip.controller2": "Defines a second controller to use, which allow Joy-Cons support for example.",
"lambdacontrols.tooltip.controller_type": "Changes the controller type to displays the correct buttons.",

View File

@@ -92,6 +92,9 @@
"lambdacontrols.menu.title.controller_controls": "Contrôles de la manette",
"lambdacontrols.menu.title.general": "Options générales",
"lambdacontrols.menu.title.hud": "Options du HUD",
"lambdacontrols.menu.unbound": "Délier",
"lambdacontrols.narrator.unbound": "Délier %s",
"lambdacontrols.not_bound": "Non défini",
"lambdacontrols.tooltip.auto_switch_mode": "Détermine si le mode de contrôle doit automatiquement changer sur Manette si une manette est connectée et inversement.",
"lambdacontrols.tooltip.controller2": "Défini une deuxième manette, utile dans le cas d'utilisation de Joy-Cons.",
"lambdacontrols.tooltip.controller_type": "Le type de contrôle n'influe que sur les boutons affichés.",

View File

@@ -92,6 +92,9 @@
"lambdacontrols.menu.title.controller_controls": "Contrôles de la manette",
"lambdacontrols.menu.title.general": "Options générales",
"lambdacontrols.menu.title.hud": "Options du HUD",
"lambdacontrols.menu.unbound": "Délier",
"lambdacontrols.narrator.unbound": "Délier %s",
"lambdacontrols.not_bound": "Non défini",
"lambdacontrols.tooltip.auto_switch_mode": "Détermine si le mode de contrôle doit automatiquement changer sur Manette si une manette est connectée et inversement.",
"lambdacontrols.tooltip.controller2": "Défini une deuxième manette, utile dans le cas d'utilisation de Joy-Cons.",
"lambdacontrols.tooltip.controller_type": "Le type de contrôle n'influe que sur les boutons affichés.",