WIP broken stuff.

This commit is contained in:
LambdAurora
2021-03-15 17:20:16 +01:00
parent deccb758ea
commit 0532913d69
26 changed files with 1023 additions and 936 deletions

View File

@@ -1,14 +1,24 @@
import net.fabricmc.loom.task.RemapJarTask
plugins {
id 'fabric-loom' version '0.4-SNAPSHOT'
id 'fabric-loom' version '0.6-SNAPSHOT'
id 'java-library'
id 'maven-publish'
id 'com.github.johnrengelman.shadow'
id 'org.cadixdev.licenser'
}
version = "${project.mod_version}+${project.minecraft_version}"
import net.fabricmc.loom.task.RemapJarTask
version = "${project.mod_version}+${getMCVersionString()}"
archivesBaseName = project.archives_base_name + "-fabric"
def getMCVersionString() {
if (project.minecraft_version.matches("\\d\\dw\\d\\d[a-z]")) {
return project.minecraft_version
}
int lastDot = project.minecraft_version.lastIndexOf('.')
return project.minecraft_version.substring(0, lastDot)
}
minecraft {
}
@@ -20,6 +30,7 @@ repositories {
repositories {
maven { url = "https://jitpack.io" }
}
maven { url "https://maven.shedaniel.me/" }
}
configurations {
@@ -43,17 +54,12 @@ dependencies {
// Compatibility mods
modImplementation "com.github.joaoh1:okzoomer:e13183c59b"
modImplementation "me.shedaniel:RoughlyEnoughItems:5.2.3"
modImplementation "me.shedaniel:RoughlyEnoughItems:5.10.184"
api project(":core")
shadowInternal project(":core")
shadow("org.aperlambda:lambdajcommon:1.8.1") {
// Minecraft already has all that google crap.
exclude group: 'com.google.code.gson'
exclude group: 'com.google.guava'
}
shadow "com.electronwill.night-config:core:3.5.3"
shadow "com.electronwill.night-config:toml:3.5.3"
shadow project(":core")
shadow "com.electronwill.night-config:core:3.6.3"
shadow "com.electronwill.night-config:toml:3.6.3"
}
processResources {
@@ -80,23 +86,21 @@ jar {
from "../LICENSE"
}
task shadowJar(type: Jar) {
archiveClassifier.set("dev")
license {
header file('HEADER')
include '**/*.java'
}
from sourceSets.main.output
shadowJar {
dependsOn jar
configurations = [project.configurations.shadow]
archiveClassifier.set('dev')
from {
configurations.shadowInternal.filter {
it.getName().contains("lambdacontrols")
}.collect {
it.isDirectory() ? it : zipTree(it)
}
}
from {
configurations.shadow.collect {
it.isDirectory() ? it : zipTree(it)
}
}
exclude 'META-INF/maven/**'
exclude 'com/google/**'
exclude 'javax/**'
exclude 'org/**'
relocate 'com.electronwill.nightconfig', 'dev.lambdaurora.lambdacontrols.shadow.nightconfig'
}
task shadowRemapJar(type: RemapJarTask) {

View File

@@ -29,7 +29,7 @@ import java.util.Optional;
* Represents the LambdaControls mod.
*
* @author LambdAurora
* @version 1.5.0
* @version 1.6.0
* @since 1.0.0
*/
public class LambdaControls implements ModInitializer
@@ -51,7 +51,7 @@ public class LambdaControls implements ModInitializer
ServerSidePacketRegistry.INSTANCE.register(HELLO_CHANNEL,
(context, attachedData) -> {
String version = attachedData.readString(16);
String version = attachedData.readString(32);
ControlsMode.byId(attachedData.readString(32))
.ifPresent(controlsMode -> context.getTaskQueue()
.execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.getPlayer(), controlsMode)));
@@ -117,7 +117,7 @@ public class LambdaControls implements ModInitializer
if ((container = FabricLoader.getInstance().getModContainer(LambdaControlsConstants.NAMESPACE)).isPresent()) {
version = container.get().getMetadata().getVersion().getFriendlyString();
}
return new PacketByteBuf(Unpooled.buffer()).writeString(version, 16).writeString(controlsMode.getName(), 32);
return new PacketByteBuf(Unpooled.buffer()).writeString(version, 32).writeString(controlsMode.getName(), 32);
}
/**

View File

@@ -18,7 +18,6 @@ import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.client.controller.Controller;
import me.lambdaurora.lambdacontrols.client.controller.InputManager;
import me.lambdaurora.lambdacontrols.client.gui.LambdaControlsHud;
import me.lambdaurora.lambdacontrols.client.gui.RingScreen;
import me.lambdaurora.lambdacontrols.client.gui.TouchscreenOverlay;
import me.lambdaurora.lambdacontrols.client.ring.KeyBindingRingAction;
import me.lambdaurora.lambdacontrols.client.ring.LambdaRing;
@@ -140,9 +139,9 @@ public class LambdaControlsClient extends LambdaControls implements ClientModIni
*/
public void onTick(@NotNull MinecraftClient client)
{
this.input.onTick(client);
this.input.tick(client);
if (this.config.getControlsMode() == ControlsMode.CONTROLLER && (client.isWindowFocused() || this.config.hasUnfocusedInput()))
this.input.onControllerTick(client);
this.input.tickController(client);
/*if (BINDING_RING.wasPressed()) {
client.openScreen(new RingScreen());

View File

@@ -31,62 +31,59 @@ import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y;
/**
* Represents LambdaControls configuration.
*/
public class LambdaControlsConfig
{
public class LambdaControlsConfig {
// General
private static final ControlsMode DEFAULT_CONTROLS_MODE = ControlsMode.DEFAULT;
private static final boolean DEFAULT_AUTO_SWITCH_MODE = false;
private static final boolean DEFAULT_DEBUG = false;
private static final ControlsMode DEFAULT_CONTROLS_MODE = ControlsMode.DEFAULT;
private static final boolean DEFAULT_AUTO_SWITCH_MODE = false;
private static final boolean DEFAULT_DEBUG = false;
// HUD
private static final boolean DEFAULT_HUD_ENABLE = true;
private static final HudSide DEFAULT_HUD_SIDE = HudSide.LEFT;
private static final boolean DEFAULT_HUD_ENABLE = true;
private static final HudSide DEFAULT_HUD_SIDE = HudSide.LEFT;
// Gameplay
private static final boolean DEFAULT_FAST_BLOCK_INTERACTION = true;
private static final boolean DEFAULT_FLY_DRIFTING = false;
private static final boolean DEFAULT_FLY_VERTICAL_DRIFTING = true;
private static final boolean DEFAULT_HORIZONTAL_REACHAROUND = false;
private static final boolean DEFAULT_VERTICAL_REACHAROUND = false;
private static final boolean DEFAULT_REACHAROUND_OUTLINE = true;
private static final int[] DEFAULT_REACHAROUND_OUTLINE_COLOR = new int[]{255, 255, 255, 102};
private static final boolean DEFAULT_FAST_BLOCK_INTERACTION = true;
private static final boolean DEFAULT_FLY_DRIFTING = false;
private static final boolean DEFAULT_FLY_VERTICAL_DRIFTING = true;
private static final boolean DEFAULT_HORIZONTAL_REACHAROUND = false;
private static final boolean DEFAULT_VERTICAL_REACHAROUND = false;
private static final boolean DEFAULT_REACHAROUND_OUTLINE = true;
private static final int[] DEFAULT_REACHAROUND_OUTLINE_COLOR = new int[]{255, 255, 255, 102};
// Controller
private static final ControllerType DEFAULT_CONTROLLER_TYPE = ControllerType.DEFAULT;
private static final double DEFAULT_DEAD_ZONE = 0.25;
private static final double DEFAULT_ROTATION_SPEED = 40.0;
private static final double DEFAULT_MOUSE_SPEED = 25.0;
private static final boolean DEFAULT_UNFOCUSED_INPUT = false;
private static final boolean DEFAULT_VIRTUAL_MOUSE = false;
private static final VirtualMouseSkin DEFAULT_VIRTUAL_MOUSE_SKIN = VirtualMouseSkin.DEFAULT_LIGHT;
private static final ControllerType DEFAULT_CONTROLLER_TYPE = ControllerType.DEFAULT;
private static final double DEFAULT_DEAD_ZONE = 0.25;
private static final double DEFAULT_ROTATION_SPEED = 40.0;
private static final double DEFAULT_MOUSE_SPEED = 25.0;
private static final boolean DEFAULT_UNFOCUSED_INPUT = false;
private static final boolean DEFAULT_VIRTUAL_MOUSE = false;
private static final VirtualMouseSkin DEFAULT_VIRTUAL_MOUSE_SKIN = VirtualMouseSkin.DEFAULT_LIGHT;
private static final Pattern BUTTON_BINDING_PATTERN = Pattern.compile("(-?\\d+)\\+?");
protected final FileConfig config = FileConfig.builder("config/lambdacontrols.toml").concurrent().defaultResource("/config.toml").build();
private final LambdaControlsClient mod;
private ControlsMode controlsMode;
private ControllerType controllerType;
protected final FileConfig config = FileConfig.builder("config/lambdacontrols.toml").concurrent().defaultResource("/config.toml").build();
private final LambdaControlsClient mod;
private ControlsMode controlsMode;
private ControllerType controllerType;
// Gameplay.
private boolean shouldRenderReacharoundOutline;
private int[] reacharoundOutlineColor;
private boolean shouldRenderReacharoundOutline;
private int[] reacharoundOutlineColor;
// Controller settings
private double deadZone;
private double rotationSpeed;
private double mouseSpeed;
private boolean unfocusedInput;
private boolean virtualMouse;
private VirtualMouseSkin virtualMouseSkin;
private double deadZone;
private double rotationSpeed;
private double mouseSpeed;
private boolean unfocusedInput;
private boolean virtualMouse;
private VirtualMouseSkin virtualMouseSkin;
// HUD settings.
private boolean hudEnable;
private HudSide hudSide;
private boolean hudEnable;
private HudSide hudSide;
public LambdaControlsConfig(@NotNull LambdaControlsClient mod)
{
public LambdaControlsConfig(@NotNull LambdaControlsClient mod) {
this.mod = mod;
}
/**
* Loads the configuration
*/
public void load()
{
public void load() {
this.config.load();
this.checkAndFix();
this.mod.log("Configuration loaded.");
@@ -117,8 +114,7 @@ public class LambdaControlsConfig
/**
* Saves the configuration.
*/
public void save()
{
public void save() {
this.config.set("controller.dead_zone", this.deadZone);
this.config.set("controller.rotation_speed", this.rotationSpeed);
this.config.set("controller.mouse_speed", this.mouseSpeed);
@@ -128,8 +124,7 @@ public class LambdaControlsConfig
this.mod.log("Configuration saved.");
}
public void checkAndFix()
{
public void checkAndFix() {
InputManager.streamBindings().forEach(binding -> {
String path = "controller.controls." + binding.getName();
Object raw = this.config.getRaw(path);
@@ -158,8 +153,7 @@ public class LambdaControlsConfig
this.renamed("controller.controls.tab_right", "controller.controls.tab_next");
}
private void renamed(String oldPath, String newPath)
{
private void renamed(String oldPath, String newPath) {
if (!this.config.contains(oldPath))
return;
Object raw = this.config.getRaw(oldPath);
@@ -170,8 +164,7 @@ public class LambdaControlsConfig
/**
* Resets the configuration to default values.
*/
public void reset()
{
public void reset() {
// General
this.setControlsMode(DEFAULT_CONTROLS_MODE);
this.setAutoSwitchMode(DEFAULT_AUTO_SWITCH_MODE);
@@ -204,8 +197,7 @@ public class LambdaControlsConfig
*
* @return The controls mode.
*/
public @NotNull ControlsMode getControlsMode()
{
public @NotNull ControlsMode getControlsMode() {
return this.controlsMode;
}
@@ -214,8 +206,7 @@ public class LambdaControlsConfig
*
* @param controlsMode The controls mode.
*/
public void setControlsMode(@NotNull ControlsMode controlsMode)
{
public void setControlsMode(@NotNull ControlsMode controlsMode) {
this.controlsMode = controlsMode;
this.config.set("controls", controlsMode.getName());
}
@@ -225,8 +216,7 @@ public class LambdaControlsConfig
*
* @return True if the auto switch mode is enabled, else false.
*/
public boolean hasAutoSwitchMode()
{
public boolean hasAutoSwitchMode() {
return this.config.getOrElse("auto_switch_mode", DEFAULT_AUTO_SWITCH_MODE);
}
@@ -235,8 +225,7 @@ public class LambdaControlsConfig
*
* @param autoSwitchMode True if the auto switch mode is enabled, else false.
*/
public void setAutoSwitchMode(boolean autoSwitchMode)
{
public void setAutoSwitchMode(boolean autoSwitchMode) {
this.config.set("auto_switch_mode", autoSwitchMode);
}
@@ -245,8 +234,7 @@ public class LambdaControlsConfig
*
* @return True if debug is enabled, else false.
*/
public boolean hasDebug()
{
public boolean hasDebug() {
return this.config.getOrElse("debug", DEFAULT_DEBUG);
}
@@ -255,8 +243,7 @@ public class LambdaControlsConfig
*
* @param debug True if debug is enabled, else false.
*/
protected void setDebug(boolean debug)
{
protected void setDebug(boolean debug) {
this.config.set("debug", debug);
}
@@ -269,8 +256,7 @@ public class LambdaControlsConfig
*
* @return True if the HUD is enabled, else false.
*/
public boolean isHudEnabled()
{
public boolean isHudEnabled() {
return this.hudEnable;
}
@@ -279,8 +265,7 @@ public class LambdaControlsConfig
*
* @param enable True if the HUD is enabled, else false.
*/
public void setHudEnabled(boolean enable)
{
public void setHudEnabled(boolean enable) {
this.hudEnable = enable;
this.config.set("hud.enable", this.hudEnable);
}
@@ -290,8 +275,7 @@ public class LambdaControlsConfig
*
* @return The HUD side.
*/
public @NotNull HudSide getHudSide()
{
public @NotNull HudSide getHudSide() {
return this.hudSide;
}
@@ -300,8 +284,7 @@ public class LambdaControlsConfig
*
* @param hudSide The HUD side.
*/
public void setHudSide(@NotNull HudSide hudSide)
{
public void setHudSide(@NotNull HudSide hudSide) {
this.hudSide = hudSide;
this.config.set("hud.side", hudSide.getName());
}
@@ -315,8 +298,7 @@ public class LambdaControlsConfig
*
* @return True if fast block placing is enabled, else false.
*/
public boolean hasFastBlockPlacing()
{
public boolean hasFastBlockPlacing() {
return LambdaControlsFeature.FAST_BLOCK_PLACING.isEnabled();
}
@@ -325,8 +307,7 @@ public class LambdaControlsConfig
*
* @param enable True if fast block placing is enabled, else false.
*/
public void setFastBlockPlacing(boolean enable)
{
public void setFastBlockPlacing(boolean enable) {
LambdaControlsFeature.FAST_BLOCK_PLACING.setEnabled(enable);
this.config.set("gameplay.fast_block_placing", enable);
}
@@ -336,8 +317,7 @@ public class LambdaControlsConfig
*
* @return True if fly drifting is enabled, else false.
*/
public boolean hasFlyDrifting()
{
public boolean hasFlyDrifting() {
return this.config.getOrElse("gameplay.fly.drifting", DEFAULT_FLY_DRIFTING);
}
@@ -346,8 +326,7 @@ public class LambdaControlsConfig
*
* @param flyDrifting True if fly drifting is enabled, else false.
*/
public void setFlyDrifting(boolean flyDrifting)
{
public void setFlyDrifting(boolean flyDrifting) {
this.config.set("gameplay.fly.drifting", flyDrifting);
}
@@ -356,8 +335,7 @@ public class LambdaControlsConfig
*
* @return True if vertical fly drifting is enabled, else false.
*/
public boolean hasFlyVerticalDrifting()
{
public boolean hasFlyVerticalDrifting() {
return this.config.getOrElse("gameplay.fly.vertical_drifting", DEFAULT_FLY_VERTICAL_DRIFTING);
}
@@ -366,8 +344,7 @@ public class LambdaControlsConfig
*
* @param flyDrifting True if vertical fly drifting is enabled, else false.
*/
public void setFlyVerticalDrifting(boolean flyDrifting)
{
public void setFlyVerticalDrifting(boolean flyDrifting) {
this.config.set("gameplay.fly.vertical_drifting", flyDrifting);
}
@@ -376,8 +353,7 @@ public class LambdaControlsConfig
*
* @return True if front block placing is enabled, else false.
*/
public boolean hasFrontBlockPlacing()
{
public boolean hasFrontBlockPlacing() {
return LambdaControlsFeature.HORIZONTAL_REACHAROUND.isEnabled();
}
@@ -386,8 +362,7 @@ public class LambdaControlsConfig
*
* @param enable True if front block placing is enabled, else false.
*/
public void setFrontBlockPlacing(boolean enable)
{
public void setFrontBlockPlacing(boolean enable) {
LambdaControlsFeature.HORIZONTAL_REACHAROUND.setEnabled(enable);
this.config.set("gameplay.reacharound.horizontal", enable);
}
@@ -397,8 +372,7 @@ public class LambdaControlsConfig
*
* @return True if vertical reacharound is enabled, else false.
*/
public boolean hasVerticalReacharound()
{
public boolean hasVerticalReacharound() {
return LambdaControlsFeature.VERTICAL_REACHAROUND.isEnabled();
}
@@ -407,8 +381,7 @@ public class LambdaControlsConfig
*
* @param enable True if vertical reacharound is enabled, else false.
*/
public void setVerticalReacharound(boolean enable)
{
public void setVerticalReacharound(boolean enable) {
LambdaControlsFeature.VERTICAL_REACHAROUND.setEnabled(enable);
this.config.set("gameplay.reacharound.vertical", enable);
}
@@ -418,8 +391,7 @@ public class LambdaControlsConfig
*
* @return True if front block placing outline is enabled, else false.
*/
public boolean shouldRenderReacharoundOutline()
{
public boolean shouldRenderReacharoundOutline() {
return this.shouldRenderReacharoundOutline;
}
@@ -428,8 +400,7 @@ public class LambdaControlsConfig
*
* @param render True if front block placing outline is enabled, else false.
*/
public void setRenderReacharoundOutline(boolean render)
{
public void setRenderReacharoundOutline(boolean render) {
this.config.set("gameplay.reacharound.outline", this.shouldRenderReacharoundOutline = render);
}
@@ -440,8 +411,7 @@ public class LambdaControlsConfig
*
* @return The color as a RGBA integer array.
*/
public int[] getReacharoundOutlineColor()
{
public int[] getReacharoundOutlineColor() {
return this.reacharoundOutlineColor;
}
@@ -454,8 +424,7 @@ public class LambdaControlsConfig
*
* @return The used controller.
*/
public @NotNull Controller getController()
{
public @NotNull Controller getController() {
Object raw = this.config.getRaw("controller.id");
if (raw instanceof Number) {
return Controller.byId((Integer) raw);
@@ -470,8 +439,7 @@ public class LambdaControlsConfig
*
* @param controller The used controller.
*/
public void setController(@NotNull Controller controller)
{
public void setController(@NotNull Controller controller) {
this.config.set("controller.id", controller.getId());
}
@@ -480,8 +448,7 @@ public class LambdaControlsConfig
*
* @return The second controller.
*/
public @NotNull Optional<Controller> getSecondController()
{
public @NotNull Optional<Controller> getSecondController() {
Object raw = this.config.getRaw("controller.id2");
if (raw instanceof Number) {
if ((int) raw == -1)
@@ -498,8 +465,7 @@ public class LambdaControlsConfig
*
* @param controller The second controller.
*/
public void setSecondController(@Nullable Controller controller)
{
public void setSecondController(@Nullable Controller controller) {
this.config.set("controller.id2", controller == null ? -1 : controller.getId());
}
@@ -508,8 +474,7 @@ public class LambdaControlsConfig
*
* @return The controller's type.
*/
public @NotNull ControllerType getControllerType()
{
public @NotNull ControllerType getControllerType() {
return this.controllerType;
}
@@ -518,8 +483,7 @@ public class LambdaControlsConfig
*
* @param controllerType The controller's type.
*/
public void setControllerType(@NotNull ControllerType controllerType)
{
public void setControllerType(@NotNull ControllerType controllerType) {
this.controllerType = controllerType;
this.config.set("controller.type", controllerType.getName());
}
@@ -529,8 +493,7 @@ public class LambdaControlsConfig
*
* @return The controller's dead zone value.
*/
public double getDeadZone()
{
public double getDeadZone() {
return this.deadZone;
}
@@ -539,8 +502,7 @@ public class LambdaControlsConfig
*
* @param deadZone The new controller's dead zone value.
*/
public void setDeadZone(double deadZone)
{
public void setDeadZone(double deadZone) {
this.deadZone = deadZone;
}
@@ -549,8 +511,7 @@ public class LambdaControlsConfig
*
* @return The rotation speed.
*/
public double getRotationSpeed()
{
public double getRotationSpeed() {
return this.rotationSpeed;
}
@@ -559,8 +520,7 @@ public class LambdaControlsConfig
*
* @param rotationSpeed The rotation speed.
*/
public void setRotationSpeed(double rotationSpeed)
{
public void setRotationSpeed(double rotationSpeed) {
this.rotationSpeed = rotationSpeed;
}
@@ -569,8 +529,7 @@ public class LambdaControlsConfig
*
* @return The mouse speed.
*/
public double getMouseSpeed()
{
public double getMouseSpeed() {
return this.mouseSpeed;
}
@@ -579,8 +538,7 @@ public class LambdaControlsConfig
*
* @param mouseSpeed The mouse speed.
*/
public void setMouseSpeed(double mouseSpeed)
{
public void setMouseSpeed(double mouseSpeed) {
this.mouseSpeed = mouseSpeed;
}
@@ -589,8 +547,7 @@ public class LambdaControlsConfig
*
* @return True if the right X axis is inverted, else false.
*/
public boolean doesInvertRightXAxis()
{
public boolean doesInvertRightXAxis() {
return this.config.getOrElse("controller.invert_right_x_axis", false);
}
@@ -599,8 +556,7 @@ public class LambdaControlsConfig
*
* @param invert True if the right X axis is inverted, else false.
*/
public void setInvertRightXAxis(boolean invert)
{
public void setInvertRightXAxis(boolean invert) {
this.config.set("controller.invert_right_x_axis", invert);
}
@@ -609,8 +565,7 @@ public class LambdaControlsConfig
*
* @return True if the right Y axis is inverted, else false.
*/
public boolean doesInvertRightYAxis()
{
public boolean doesInvertRightYAxis() {
return this.config.getOrElse("controller.invert_right_y_axis", false);
}
@@ -619,8 +574,7 @@ public class LambdaControlsConfig
*
* @param invert True if the right Y axis is inverted, else false.
*/
public void setInvertRightYAxis(boolean invert)
{
public void setInvertRightYAxis(boolean invert) {
this.config.set("controller.invert_right_y_axis", invert);
}
@@ -629,8 +583,7 @@ public class LambdaControlsConfig
*
* @return True if unfocused controller input is allowed, else false.
*/
public boolean hasUnfocusedInput()
{
public boolean hasUnfocusedInput() {
return this.unfocusedInput;
}
@@ -639,8 +592,7 @@ public class LambdaControlsConfig
*
* @param unfocusedInput True if unfocused controller input is allowed, else false.
*/
public void setUnfocusedInput(boolean unfocusedInput)
{
public void setUnfocusedInput(boolean unfocusedInput) {
this.unfocusedInput = unfocusedInput;
}
@@ -649,8 +601,7 @@ public class LambdaControlsConfig
*
* @return True if the mouse is virtual, else false.
*/
public boolean hasVirtualMouse()
{
public boolean hasVirtualMouse() {
return this.virtualMouse;
}
@@ -659,8 +610,7 @@ public class LambdaControlsConfig
*
* @param virtualMouse True if the mouse is virtual, else false.
*/
public void setVirtualMouse(boolean virtualMouse)
{
public void setVirtualMouse(boolean virtualMouse) {
this.virtualMouse = virtualMouse;
}
@@ -669,8 +619,7 @@ public class LambdaControlsConfig
*
* @return The virtual mouse skin.
*/
public VirtualMouseSkin getVirtualMouseSkin()
{
public VirtualMouseSkin getVirtualMouseSkin() {
return this.virtualMouseSkin;
}
@@ -679,8 +628,7 @@ public class LambdaControlsConfig
*
* @param skin The virtual mouse skin.
*/
public void setVirtualMouseSkin(VirtualMouseSkin skin)
{
public void setVirtualMouseSkin(VirtualMouseSkin skin) {
this.virtualMouseSkin = skin;
this.config.set("controller.virtual_mouse_skin", skin.getName());
}
@@ -690,8 +638,7 @@ public class LambdaControlsConfig
*
* @return The right X axis sign.
*/
public double getRightXAxisSign()
{
public double getRightXAxisSign() {
return this.doesInvertRightXAxis() ? -1.0 : 1.0;
}
@@ -700,8 +647,7 @@ public class LambdaControlsConfig
*
* @return The right Y axis sign.
*/
public double getRightYAxisSign()
{
public double getRightYAxisSign() {
return this.doesInvertRightYAxis() ? -1.0 : 1.0;
}
@@ -710,8 +656,7 @@ public class LambdaControlsConfig
*
* @param button The button binding.
*/
public void loadButtonBinding(@NotNull ButtonBinding button)
{
public void loadButtonBinding(@NotNull ButtonBinding button) {
button.setButton(button.getDefaultButton());
String code = this.config.getOrElse("controller.controls." + button.getName(), button.getButtonCode());
@@ -741,8 +686,7 @@ public class LambdaControlsConfig
}
}
private boolean checkValidity(@NotNull ButtonBinding binding, @NotNull String input, String group)
{
private boolean checkValidity(@NotNull ButtonBinding binding, @NotNull String input, String group) {
if (group == null) {
this.mod.warn("Malformed config value \"" + input + "\" for binding \"" + binding.getName() + "\".");
this.config.set("controller.controls." + binding.getName(), binding.getButtonCode());
@@ -755,37 +699,32 @@ public class LambdaControlsConfig
* Sets the button binding in configuration.
*
* @param binding The button binding.
* @param button The button.
* @param button The button.
*/
public void setButtonBinding(@NotNull ButtonBinding binding, int[] button)
{
public void setButtonBinding(@NotNull ButtonBinding binding, int[] button) {
binding.setButton(button);
this.config.set("controller.controls." + binding.getName(), binding.getButtonCode());
}
public boolean isBackButton(int btn, boolean isBtn, int state)
{
public boolean isBackButton(int btn, boolean isBtn, int state) {
if (!isBtn && state == 0)
return false;
return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, false) == ButtonBinding.axisAsButton(btn, state == 1);
}
public boolean isForwardButton(int btn, boolean isBtn, int state)
{
public boolean isForwardButton(int btn, boolean isBtn, int state) {
if (!isBtn && state == 0)
return false;
return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, true) == ButtonBinding.axisAsButton(btn, state == 1);
}
public boolean isLeftButton(int btn, boolean isBtn, int state)
{
public boolean isLeftButton(int btn, boolean isBtn, int state) {
if (!isBtn && state == 0)
return false;
return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, false) == ButtonBinding.axisAsButton(btn, state == 1);
}
public boolean isRightButton(int btn, boolean isBtn, int state)
{
public boolean isRightButton(int btn, boolean isBtn, int state) {
if (!isBtn && state == 0)
return false;
return ButtonBinding.axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, true) == ButtonBinding.axisAsButton(btn, state == 1);
@@ -797,8 +736,7 @@ public class LambdaControlsConfig
* @param axis The axis index.
* @return True if the axis is used for movements, else false.
*/
public boolean isMovementAxis(int axis)
{
public boolean isMovementAxis(int axis) {
return axis == GLFW_GAMEPAD_AXIS_LEFT_Y || axis == GLFW_GAMEPAD_AXIS_LEFT_X;
}
@@ -808,8 +746,7 @@ public class LambdaControlsConfig
* @param hex The hexadecimal color.
* @return The color instance, null if invalid.
*/
private static int[] parseColor(String hex)
{
private static int[] parseColor(String hex) {
hex = hex.replace("#", "");
switch (hex.length()) {
case 6:

View File

@@ -14,14 +14,20 @@ import me.lambdaurora.lambdacontrols.client.compat.LambdaControlsCompat;
import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.client.controller.Controller;
import me.lambdaurora.lambdacontrols.client.controller.InputManager;
import me.lambdaurora.lambdacontrols.client.gui.ControllerControlsScreen;
import me.lambdaurora.lambdacontrols.client.gui.TouchscreenOverlay;
import me.lambdaurora.lambdacontrols.client.gui.widget.ControllerControlsWidget;
import me.lambdaurora.lambdacontrols.client.mixin.AdvancementsScreenAccessor;
import me.lambdaurora.lambdacontrols.client.mixin.CreativeInventoryScreenAccessor;
import me.lambdaurora.lambdacontrols.client.mixin.EntryListWidgetAccessor;
import me.lambdaurora.lambdacontrols.client.util.HandledScreenAccessor;
import me.lambdaurora.lambdacontrols.client.util.MouseAccessor;
import me.lambdaurora.spruceui.SpruceLabelWidget;
import me.lambdaurora.spruceui.navigation.NavigationDirection;
import me.lambdaurora.spruceui.screen.SpruceScreen;
import me.lambdaurora.spruceui.widget.AbstractSprucePressableButtonWidget;
import me.lambdaurora.spruceui.widget.SpruceElement;
import me.lambdaurora.spruceui.widget.SpruceLabelWidget;
import me.lambdaurora.spruceui.widget.SpruceWidget;
import me.lambdaurora.spruceui.widget.container.SpruceParentWidget;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.ParentElement;
@@ -67,25 +73,25 @@ import static org.lwjgl.glfw.GLFW.*;
* @version 1.4.3
* @since 1.0.0
*/
public class LambdaInput
{
private static final Map<Integer, Integer> BUTTON_COOLDOWNS = new HashMap<>();
private final LambdaControlsConfig config;
public class LambdaInput {
private static final Map<Integer, Integer> BUTTON_COOLDOWNS = new HashMap<>();
private final LambdaControlsConfig config;
// Cooldowns
private int actionGuiCooldown = 0;
private boolean ignoreNextARelease = false;
private double targetYaw = 0.0;
private double targetPitch = 0.0;
private float prevXAxis = 0.F;
private float prevYAxis = 0.F;
private int targetMouseX = 0;
private int targetMouseY = 0;
private float mouseSpeedX = 0.F;
private float mouseSpeedY = 0.F;
private int inventoryInteractionCooldown = 0;
private int actionGuiCooldown = 0;
private boolean ignoreNextARelease = false;
private double targetYaw = 0.0;
private double targetPitch = 0.0;
private float prevXAxis = 0.F;
private float prevYAxis = 0.F;
private int targetMouseX = 0;
private int targetMouseY = 0;
private float mouseSpeedX = 0.F;
private float mouseSpeedY = 0.F;
private int inventoryInteractionCooldown = 0;
public LambdaInput(@NotNull LambdaControlsClient mod)
{
private ControllerControlsWidget controlsInput = null;
public LambdaInput(@NotNull LambdaControlsClient mod) {
this.config = mod.config;
}
@@ -94,8 +100,7 @@ public class LambdaInput
*
* @param client The client instance.
*/
public void onTick(@NotNull MinecraftClient client)
{
public void tick(@NotNull MinecraftClient client) {
this.targetYaw = 0.F;
this.targetPitch = 0.F;
@@ -119,8 +124,7 @@ public class LambdaInput
*
* @param client The client instance.
*/
public void onControllerTick(@NotNull MinecraftClient client)
{
public void tickController(@NotNull MinecraftClient client) {
BUTTON_COOLDOWNS.entrySet().stream().filter(entry -> entry.getValue() > 0).forEach(entry -> BUTTON_COOLDOWNS.put(entry.getKey(), entry.getValue() - 1));
// Decreases the cooldown for GUI actions.
if (this.actionGuiCooldown > 0)
@@ -143,20 +147,21 @@ public class LambdaInput
boolean allowInput = true;
if (client.currentScreen instanceof ControllerControlsScreen && ((ControllerControlsScreen) client.currentScreen).focusedBinding != null)
if (this.controlsInput != null && this.controlsInput.focusedBinding != null)
allowInput = false;
if (allowInput)
InputManager.updateBindings(client);
if (client.currentScreen instanceof ControllerControlsScreen && InputManager.STATES.entrySet().parallelStream().map(Map.Entry::getValue).allMatch(ButtonState::isUnpressed)) {
ControllerControlsScreen screen = (ControllerControlsScreen) client.currentScreen;
if (screen.focusedBinding != null && !screen.waiting) {
int[] buttons = new int[screen.currentButtons.size()];
for (int i = 0; i < screen.currentButtons.size(); i++)
buttons[i] = screen.currentButtons.get(i);
screen.focusedBinding.setButton(buttons);
screen.focusedBinding = null;
if (this.controlsInput != null
&& InputManager.STATES.entrySet().parallelStream().map(Map.Entry::getValue).allMatch(ButtonState::isUnpressed)) {
if (this.controlsInput.focusedBinding != null && !this.controlsInput.waiting) {
int[] buttons = new int[this.controlsInput.currentButtons.size()];
for (int i = 0; i < this.controlsInput.currentButtons.size(); i++)
buttons[i] = this.controlsInput.currentButtons.get(i);
this.controlsInput.focusedBinding.setButton(buttons);
this.controlsInput.focusedBinding = null;
this.controlsInput = null;
}
}
@@ -170,8 +175,7 @@ public class LambdaInput
* @param client The client instance.
* @param screen The screen to render.
*/
public void onPreRenderScreen(@NotNull MinecraftClient client, @NotNull Screen screen)
{
public void onPreRenderScreen(@NotNull MinecraftClient client, @NotNull Screen screen) {
if (!isScreenInteractive(screen)) {
INPUT_MANAGER.updateMousePosition(client);
}
@@ -182,8 +186,7 @@ public class LambdaInput
*
* @param client The client instance.
*/
public void onRender(float tickDelta, @NotNull MinecraftClient client)
{
public void onRender(float tickDelta, @NotNull MinecraftClient client) {
if (!(client.currentScreen == null || client.currentScreen instanceof TouchscreenOverlay))
return;
@@ -206,12 +209,11 @@ public class LambdaInput
/**
* This method is called when a Screen is opened.
*
* @param client The client instance.
* @param windowWidth The window width.
* @param client The client instance.
* @param windowWidth The window width.
* @param windowHeight The window height.
*/
public void onScreenOpen(@NotNull MinecraftClient client, int windowWidth, int windowHeight)
{
public void onScreenOpen(@NotNull MinecraftClient client, int windowWidth, int windowHeight) {
if (client.currentScreen == null) {
this.mouseSpeedX = this.mouseSpeedY = 0.0F;
INPUT_MANAGER.resetMousePosition(windowWidth, windowHeight);
@@ -222,8 +224,15 @@ public class LambdaInput
this.inventoryInteractionCooldown = 5;
}
private void fetchButtonInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon)
{
public void beginControlsInput(ControllerControlsWidget widget) {
this.controlsInput = widget;
if (widget != null) {
this.controlsInput.currentButtons.clear();
this.controlsInput.waiting = true;
}
}
private void fetchButtonInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) {
ByteBuffer buffer = gamepadState.buttons();
for (int i = 0; i < buffer.limit(); i++) {
int btn = leftJoycon ? ButtonBinding.controller2Button(i) : i;
@@ -248,8 +257,7 @@ public class LambdaInput
}
}
private void fetchAxeInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon)
{
private void fetchAxeInput(@NotNull MinecraftClient client, @NotNull GLFWGamepadState gamepadState, boolean leftJoycon) {
FloatBuffer buffer = gamepadState.axes();
for (int i = 0; i < buffer.limit(); i++) {
int axis = leftJoycon ? ButtonBinding.controller2Button(i) : i;
@@ -264,23 +272,19 @@ public class LambdaInput
}
}
private void handleButton(@NotNull MinecraftClient client, int button, int action, boolean state)
{
if (client.currentScreen instanceof ControllerControlsScreen) {
ControllerControlsScreen screen = (ControllerControlsScreen) client.currentScreen;
if (screen.focusedBinding != null) {
if (action == 0 && !screen.currentButtons.contains(button)) {
screen.currentButtons.add(button);
private void handleButton(@NotNull MinecraftClient client, int button, int action, boolean state) {
if (this.controlsInput != null && this.controlsInput.focusedBinding != null) {
if (action == 0 && !this.controlsInput.currentButtons.contains(button)) {
this.controlsInput.currentButtons.add(button);
int[] buttons = new int[screen.currentButtons.size()];
for (int i = 0; i < screen.currentButtons.size(); i++)
buttons[i] = screen.currentButtons.get(i);
screen.focusedBinding.setButton(buttons);
int[] buttons = new int[this.controlsInput.currentButtons.size()];
for (int i = 0; i < this.controlsInput.currentButtons.size(); i++)
buttons[i] = this.controlsInput.currentButtons.get(i);
this.controlsInput.focusedBinding.setButton(buttons);
screen.waiting = false;
}
return;
this.controlsInput.waiting = false;
}
return;
}
if (action == 0 || action == 2) {
@@ -289,9 +293,9 @@ public class LambdaInput
|| button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT || button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT)) {
if (this.actionGuiCooldown == 0) {
if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP) {
this.changeFocus(client.currentScreen, false);
this.changeFocus(client.currentScreen, NavigationDirection.UP);
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN) {
this.changeFocus(client.currentScreen, true);
this.changeFocus(client.currentScreen, NavigationDirection.DOWN);
} else if (button == GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT) {
this.handleLeftRight(client.currentScreen, false);
} else {
@@ -355,8 +359,7 @@ public class LambdaInput
* @param button The button pressed.
* @return True if an inventory interaction was done.
*/
private boolean handleInventory(@NotNull MinecraftClient client, int button)
{
private boolean handleInventory(@NotNull MinecraftClient client, int button) {
if (!(client.currentScreen instanceof HandledScreen))
return false;
@@ -417,8 +420,7 @@ public class LambdaInput
* @param screen The current screen.
* @return True if successful, else false.
*/
public boolean tryGoBack(@NotNull Screen screen)
{
public boolean tryGoBack(@NotNull Screen screen) {
ImmutableSet<String> set = ImmutableSet.of("gui.back", "gui.done", "gui.cancel", "gui.toTitle", "gui.toMenu");
return screen.children().stream().filter(element -> element instanceof AbstractPressableButtonWidget)
.map(element -> (AbstractPressableButtonWidget) element)
@@ -432,8 +434,7 @@ public class LambdaInput
});
}
private void handleAxe(@NotNull MinecraftClient client, int axis, float value, float absValue, int state)
{
private void handleAxe(@NotNull MinecraftClient client, int axis, float value, float absValue, int state) {
int asButtonState = value > 0.5F ? 1 : (value < -0.5F ? 2 : 0);
if (axis == GLFW_GAMEPAD_AXIS_LEFT_TRIGGER || axis == GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER || axis == ButtonBinding.controller2Button(GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER) ||
@@ -483,22 +484,19 @@ public class LambdaInput
double deadZone = this.config.getDeadZone();
if (client.currentScreen instanceof ControllerControlsScreen) {
ControllerControlsScreen screen = (ControllerControlsScreen) client.currentScreen;
if (screen.focusedBinding != null) {
if (asButtonState != 0 && !screen.currentButtons.contains(axisAsButton(axis, asButtonState == 1))) {
if (this.controlsInput != null && this.controlsInput.focusedBinding != null) {
if (asButtonState != 0 && !this.controlsInput.currentButtons.contains(axisAsButton(axis, asButtonState == 1))) {
screen.currentButtons.add(axisAsButton(axis, asButtonState == 1));
this.controlsInput.currentButtons.add(axisAsButton(axis, asButtonState == 1));
int[] buttons = new int[screen.currentButtons.size()];
for (int i = 0; i < screen.currentButtons.size(); i++)
buttons[i] = screen.currentButtons.get(i);
screen.focusedBinding.setButton(buttons);
int[] buttons = new int[this.controlsInput.currentButtons.size()];
for (int i = 0; i < this.controlsInput.currentButtons.size(); i++)
buttons[i] = this.controlsInput.currentButtons.get(i);
this.controlsInput.focusedBinding.setButton(buttons);
screen.waiting = false;
}
return;
this.controlsInput.waiting = false;
}
return;
} else if (client.currentScreen instanceof CreativeInventoryScreen) {
if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) {
CreativeInventoryScreen screen = (CreativeInventoryScreen) client.currentScreen;
@@ -530,9 +528,9 @@ public class LambdaInput
if (this.actionGuiCooldown == 0 && this.config.isMovementAxis(axis) && isScreenInteractive(client.currentScreen)) {
if (this.config.isForwardButton(axis, false, asButtonState)) {
allowMouseControl = this.changeFocus(client.currentScreen, false);
allowMouseControl = this.changeFocus(client.currentScreen, NavigationDirection.UP);
} else if (this.config.isBackButton(axis, false, asButtonState)) {
allowMouseControl = this.changeFocus(client.currentScreen, true);
allowMouseControl = this.changeFocus(client.currentScreen, NavigationDirection.DOWN);
} else if (this.config.isLeftButton(axis, false, asButtonState)) {
allowMouseControl = this.handleLeftRight(client.currentScreen, false);
} else if (this.config.isRightButton(axis, false, asButtonState)) {
@@ -590,13 +588,17 @@ public class LambdaInput
}
}
private boolean handleAButton(@NotNull Screen screen, @NotNull Element focused)
{
private boolean handleAButton(@NotNull Screen screen, @NotNull Element focused) {
if (focused instanceof AbstractPressableButtonWidget) {
AbstractPressableButtonWidget widget = (AbstractPressableButtonWidget) focused;
widget.playDownSound(MinecraftClient.getInstance().getSoundManager());
widget.onPress();
return true;
} else if (focused instanceof AbstractSprucePressableButtonWidget) {
AbstractSprucePressableButtonWidget widget = (AbstractSprucePressableButtonWidget) focused;
widget.playDownSound();
widget.onPress();
return true;
} else if (focused instanceof SpruceLabelWidget) {
((SpruceLabelWidget) focused).onPress();
return true;
@@ -611,6 +613,10 @@ public class LambdaInput
((MultiplayerScreen) screen).select(entry);
((MultiplayerScreen) screen).connect();
}
} else if (focused instanceof SpruceParentWidget) {
Element childFocused = ((SpruceParentWidget<?>) focused).getFocused();
if (childFocused != null)
return this.handleAButton(screen, childFocused);
} else if (focused instanceof ParentElement) {
Element childFocused = ((ParentElement) focused).getFocused();
if (childFocused != null)
@@ -623,19 +629,27 @@ public class LambdaInput
* Handles the left and right buttons.
*
* @param screen The current screen.
* @param right True if the right button is pressed, else false.
* @param right True if the right button is pressed, else false.
*/
private boolean handleLeftRight(@NotNull Screen screen, boolean right)
{
private boolean handleLeftRight(@NotNull Screen screen, boolean right) {
if (screen instanceof SpruceScreen) {
((SpruceScreen) screen).onNavigation(right ? NavigationDirection.RIGHT : NavigationDirection.LEFT, false);
this.actionGuiCooldown = 5;
return false;
}
Element focused = screen.getFocused();
if (focused != null)
if (this.handleRightLeftElement(focused, right))
return this.changeFocus(screen, right);
return this.changeFocus(screen, right ? NavigationDirection.RIGHT : NavigationDirection.LEFT);
return true;
}
private boolean handleRightLeftElement(@NotNull Element element, boolean right)
{
private boolean handleRightLeftElement(@NotNull Element element, boolean right) {
if (element instanceof SpruceElement) {
if (((SpruceElement) element).requiresCursor())
return true;
return !((SpruceElement) element).onNavigation(right ? NavigationDirection.RIGHT : NavigationDirection.LEFT, false);
}
if (element instanceof SliderWidget) {
SliderWidget slider = (SliderWidget) element;
slider.keyPressed(right ? 262 : 263, 0, 0);
@@ -658,12 +672,11 @@ public class LambdaInput
* Handles the look direction input.
*
* @param client The client instance.
* @param axis The axis to change.
* @param value The value of the look.
* @param state The state.
* @param axis The axis to change.
* @param value The value of the look.
* @param state The state.
*/
public void handleLook(@NotNull MinecraftClient client, int axis, float value, int state)
{
public void handleLook(@NotNull MinecraftClient client, int axis, float value, int state) {
// Handles the look direction.
if (client.player != null) {
double powValue = Math.pow(value, 2.0);
@@ -684,10 +697,15 @@ public class LambdaInput
}
}
private boolean changeFocus(@NotNull Screen screen, boolean down)
{
if (!screen.changeFocus(down)) {
if (screen.changeFocus(down)) {
private boolean changeFocus(@NotNull Screen screen, NavigationDirection direction) {
if (screen instanceof SpruceScreen) {
if (((SpruceScreen) screen).onNavigation(direction, false)) {
this.actionGuiCooldown = 5;
}
return false;
}
if (!screen.changeFocus(direction.isLookingForward())) {
if (screen.changeFocus(direction.isLookingForward())) {
this.actionGuiCooldown = 5;
return false;
}
@@ -698,14 +716,14 @@ public class LambdaInput
}
}
public static boolean isScreenInteractive(@NotNull Screen screen)
{
return !(screen instanceof AdvancementsScreen || screen instanceof HandledScreen || screen instanceof PackScreen || LambdaControlsCompat.requireMouseOnScreen(screen));
public static boolean isScreenInteractive(@NotNull Screen screen) {
return !(screen instanceof AdvancementsScreen || screen instanceof HandledScreen || screen instanceof PackScreen
|| (screen instanceof SpruceScreen && ((SpruceScreen) screen).requiresCursor())
|| LambdaControlsCompat.requireMouseOnScreen(screen));
}
// Inspired from https://github.com/MrCrayfish/Controllable/blob/1.14.X/src/main/java/com/mrcrayfish/controllable/client/ControllerInput.java#L686.
private void moveMouseToClosestSlot(@NotNull MinecraftClient client, @Nullable Screen screen)
{
private void moveMouseToClosestSlot(@NotNull MinecraftClient client, @Nullable Screen screen) {
// Makes the mouse attracted to slots. This helps with selecting items when using a controller.
if (screen instanceof HandledScreen) {
HandledScreen inventoryScreen = (HandledScreen) screen;

View File

@@ -35,77 +35,76 @@ import static org.lwjgl.glfw.GLFW.*;
* @version 1.5.0
* @since 1.0.0
*/
public class ButtonBinding implements Nameable
{
public class ButtonBinding implements Nameable {
public static final ButtonCategory MOVEMENT_CATEGORY;
public static final ButtonCategory GAMEPLAY_CATEGORY;
public static final ButtonCategory INVENTORY_CATEGORY;
public static final ButtonCategory MULTIPLAYER_CATEGORY;
public static final ButtonCategory MISC_CATEGORY;
public static final ButtonBinding ATTACK = new Builder("attack").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true)).onlyInGame().register();
public static final ButtonBinding BACK = new Builder("back").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, false))
public static final ButtonBinding ATTACK = new Builder("attack").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, true)).onlyInGame().register();
public static final ButtonBinding BACK = new Builder("back").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, false))
.action(MovementHandler.HANDLER).onlyInGame().register();
public static final ButtonBinding CHAT = new Builder("chat").buttons(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT).onlyInGame().cooldown().register();
public static final ButtonBinding DROP_ITEM = new Builder("drop_item").buttons(GLFW_GAMEPAD_BUTTON_B).onlyInGame().cooldown().register();
public static final ButtonBinding FORWARD = new Builder("forward").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, true))
public static final ButtonBinding CHAT = new Builder("chat").buttons(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT).onlyInGame().cooldown().register();
public static final ButtonBinding DROP_ITEM = new Builder("drop_item").buttons(GLFW_GAMEPAD_BUTTON_B).onlyInGame().cooldown().register();
public static final ButtonBinding FORWARD = new Builder("forward").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, true))
.action(MovementHandler.HANDLER).onlyInGame().register();
public static final ButtonBinding HOTBAR_LEFT = new Builder("hotbar_left").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)
public static final ButtonBinding HOTBAR_LEFT = new Builder("hotbar_left").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)
.action(InputHandlers.handleHotbar(false)).onlyInGame().cooldown().register();
public static final ButtonBinding HOTBAR_RIGHT = new Builder("hotbar_right").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER)
public static final ButtonBinding HOTBAR_RIGHT = new Builder("hotbar_right").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER)
.action(InputHandlers.handleHotbar(true)).onlyInGame().cooldown().register();
public static final ButtonBinding INVENTORY = new Builder("inventory").buttons(GLFW_GAMEPAD_BUTTON_Y).onlyInGame().cooldown().register();
public static final ButtonBinding JUMP = new Builder("jump").buttons(GLFW_GAMEPAD_BUTTON_A).onlyInGame().register();
public static final ButtonBinding LEFT = new Builder("left").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, false))
public static final ButtonBinding INVENTORY = new Builder("inventory").buttons(GLFW_GAMEPAD_BUTTON_Y).onlyInGame().cooldown().register();
public static final ButtonBinding JUMP = new Builder("jump").buttons(GLFW_GAMEPAD_BUTTON_A).onlyInGame().register();
public static final ButtonBinding LEFT = new Builder("left").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, false))
.action(MovementHandler.HANDLER).onlyInGame().register();
public static final ButtonBinding PAUSE_GAME = new Builder("pause_game").buttons(GLFW_GAMEPAD_BUTTON_START).action(InputHandlers::handlePauseGame).cooldown().register();
public static final ButtonBinding PICK_BLOCK = new Builder("pick_block").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT).onlyInGame().cooldown().register();
public static final ButtonBinding PLAYER_LIST = new Builder("player_list").buttons(GLFW_GAMEPAD_BUTTON_BACK).onlyInGame().register();
public static final ButtonBinding RIGHT = new Builder("right").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, true))
public static final ButtonBinding PAUSE_GAME = new Builder("pause_game").buttons(GLFW_GAMEPAD_BUTTON_START).action(InputHandlers::handlePauseGame).cooldown().register();
public static final ButtonBinding PICK_BLOCK = new Builder("pick_block").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT).onlyInGame().cooldown().register();
public static final ButtonBinding PLAYER_LIST = new Builder("player_list").buttons(GLFW_GAMEPAD_BUTTON_BACK).onlyInGame().register();
public static final ButtonBinding RIGHT = new Builder("right").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, true))
.action(MovementHandler.HANDLER).onlyInGame().register();
public static final ButtonBinding SCREENSHOT = new Builder("screenshot").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_A)
public static final ButtonBinding SCREENSHOT = new Builder("screenshot").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_A)
.action(InputHandlers::handleScreenshot).cooldown().register();
public static final ButtonBinding SLOT_DOWN = new Builder("slot_down").buttons(GLFW_GAMEPAD_BUTTON_DPAD_DOWN)
public static final ButtonBinding SLOT_DOWN = new Builder("slot_down").buttons(GLFW_GAMEPAD_BUTTON_DPAD_DOWN)
.action(InputHandlers.handleInventorySlotPad(1)).onlyInInventory().cooldown().register();
public static final ButtonBinding SLOT_LEFT = new Builder("slot_left").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT)
public static final ButtonBinding SLOT_LEFT = new Builder("slot_left").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT)
.action(InputHandlers.handleInventorySlotPad(3)).onlyInInventory().cooldown().register();
public static final ButtonBinding SLOT_RIGHT = new Builder("slot_right").buttons(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT)
public static final ButtonBinding SLOT_RIGHT = new Builder("slot_right").buttons(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT)
.action(InputHandlers.handleInventorySlotPad(2)).onlyInInventory().cooldown().register();
public static final ButtonBinding SLOT_UP = new Builder("slot_up").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP)
public static final ButtonBinding SLOT_UP = new Builder("slot_up").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP)
.action(InputHandlers.handleInventorySlotPad(0)).onlyInInventory().cooldown().register();
public static final ButtonBinding SMOOTH_CAMERA = new Builder("toggle_smooth_camera").onlyInGame().cooldown().register();
public static final ButtonBinding SNEAK = new Builder("sneak").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB)
public static final ButtonBinding SMOOTH_CAMERA = new Builder("toggle_smooth_camera").onlyInGame().cooldown().register();
public static final ButtonBinding SNEAK = new Builder("sneak").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB)
.actions(InputHandlers::handleToggleSneak).onlyInGame().cooldown().register();
public static final ButtonBinding SPRINT = new Builder("sprint").buttons(GLFW_GAMEPAD_BUTTON_LEFT_THUMB).onlyInGame().register();
public static final ButtonBinding SWAP_HANDS = new Builder("swap_hands").buttons(GLFW_GAMEPAD_BUTTON_X).onlyInGame().cooldown().register();
public static final ButtonBinding TAB_LEFT = new Builder("tab_back").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)
public static final ButtonBinding SPRINT = new Builder("sprint").buttons(GLFW_GAMEPAD_BUTTON_LEFT_THUMB).onlyInGame().register();
public static final ButtonBinding SWAP_HANDS = new Builder("swap_hands").buttons(GLFW_GAMEPAD_BUTTON_X).onlyInGame().cooldown().register();
public static final ButtonBinding TAB_LEFT = new Builder("tab_back").buttons(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)
.action(InputHandlers.handleHotbar(false)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements)).cooldown().register();
public static final ButtonBinding TAB_RIGHT = new Builder("tab_next").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER)
public static final ButtonBinding TAB_RIGHT = new Builder("tab_next").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER)
.action(InputHandlers.handleHotbar(true)).filter(Predicates.or(InputHandlers::inInventory, InputHandlers::inAdvancements)).cooldown().register();
public static final ButtonBinding TOGGLE_PERSPECTIVE = new Builder("toggle_perspective").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_Y).cooldown().register();
public static final ButtonBinding USE = new Builder("use").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true)).register();
public static final ButtonBinding USE = new Builder("use").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, true)).register();
private int[] button;
private int[] defaultButton;
private String key;
private KeyBinding mcKeyBinding = null;
private int[] button;
private final int[] defaultButton;
private final String key;
private final Text text;
private KeyBinding mcKeyBinding = null;
protected PairPredicate<MinecraftClient, ButtonBinding> filter;
private List<PressAction> actions = new ArrayList<>(Collections.singletonList(PressAction.DEFAULT_ACTION));
private boolean hasCooldown;
private int cooldown = 0;
private List<PressAction> actions = new ArrayList<>(Collections.singletonList(PressAction.DEFAULT_ACTION));
private boolean hasCooldown;
private int cooldown = 0;
boolean pressed = false;
public ButtonBinding(@NotNull String key, int[] defaultButton, @NotNull List<PressAction> actions, PairPredicate<MinecraftClient, ButtonBinding> filter, boolean hasCooldown)
{
public ButtonBinding(@NotNull String key, int[] defaultButton, @NotNull List<PressAction> actions, PairPredicate<MinecraftClient, ButtonBinding> filter, boolean hasCooldown) {
this.setButton(this.defaultButton = defaultButton);
this.key = key;
this.text = new TranslatableText(this.key);
this.filter = filter;
this.actions.addAll(actions);
this.hasCooldown = hasCooldown;
}
public ButtonBinding(@NotNull String key, int[] defaultButton, boolean hasCooldown)
{
public ButtonBinding(@NotNull String key, int[] defaultButton, boolean hasCooldown) {
this(key, defaultButton, Collections.emptyList(), Predicates.pairAlwaysTrue(), hasCooldown);
}
@@ -114,8 +113,7 @@ public class ButtonBinding implements Nameable
*
* @return The bound button.
*/
public int[] getButton()
{
public int[] getButton() {
return this.button;
}
@@ -124,8 +122,7 @@ public class ButtonBinding implements Nameable
*
* @param button The bound button.
*/
public void setButton(int[] button)
{
public void setButton(int[] button) {
this.button = button;
if (InputManager.hasBinding(this))
@@ -138,8 +135,7 @@ public class ButtonBinding implements Nameable
* @param button The button to check.
* @return True if the bound button is the specified button, else false.
*/
public boolean isButton(int[] button)
{
public boolean isButton(int[] button) {
return InputManager.areButtonsEquivalent(button, this.button);
}
@@ -148,8 +144,7 @@ public class ButtonBinding implements Nameable
*
* @return True if the button is down, else false.
*/
public boolean isButtonDown()
{
public boolean isButtonDown() {
return this.pressed;
}
@@ -158,8 +153,7 @@ public class ButtonBinding implements Nameable
*
* @return True if this button binding is bound, else false.
*/
public boolean isNotBound()
{
public boolean isNotBound() {
return this.button.length == 0 || this.button[0] == -1;
}
@@ -168,8 +162,7 @@ public class ButtonBinding implements Nameable
*
* @return The default button.
*/
public int[] getDefaultButton()
{
public int[] getDefaultButton() {
return this.defaultButton;
}
@@ -178,8 +171,7 @@ public class ButtonBinding implements Nameable
*
* @return True if the assigned button is the default button, else false.
*/
public boolean isDefault()
{
public boolean isDefault() {
return this.button.length == this.defaultButton.length && InputManager.areButtonsEquivalent(this.button, this.defaultButton);
}
@@ -189,8 +181,7 @@ public class ButtonBinding implements Nameable
* @return The button code.
*/
public @NotNull
String getButtonCode()
{
String getButtonCode() {
return Arrays.stream(this.button)
.mapToObj(btn -> Integer.valueOf(btn).toString())
.collect(Collectors.joining("+"));
@@ -201,8 +192,7 @@ public class ButtonBinding implements Nameable
*
* @param keyBinding The optional key binding.
*/
public void setKeyBinding(@Nullable KeyBinding keyBinding)
{
public void setKeyBinding(@Nullable KeyBinding keyBinding) {
this.mcKeyBinding = keyBinding;
}
@@ -212,16 +202,14 @@ public class ButtonBinding implements Nameable
* @param client The client instance.
* @return True if the button binding is available, else false.
*/
public boolean isAvailable(@NotNull MinecraftClient client)
{
public boolean isAvailable(@NotNull MinecraftClient client) {
return this.filter.test(client, this);
}
/**
* Updates the button binding cooldown.
*/
public void update()
{
public void update() {
if (this.hasCooldown && this.cooldown > 0)
this.cooldown--;
}
@@ -230,10 +218,9 @@ public class ButtonBinding implements Nameable
* Handles the button binding.
*
* @param client The client instance.
* @param state The state.
* @param state The state.
*/
public void handle(@NotNull MinecraftClient client, float value, @NotNull ButtonState state)
{
public void handle(@NotNull MinecraftClient client, float value, @NotNull ButtonState state) {
if (state == ButtonState.REPEAT && this.hasCooldown && this.cooldown != 0)
return;
if (this.hasCooldown && state.isPressed()) {
@@ -247,8 +234,7 @@ public class ButtonBinding implements Nameable
}
@Override
public @NotNull String getName()
{
public @NotNull String getName() {
return this.key;
}
@@ -257,24 +243,25 @@ public class ButtonBinding implements Nameable
*
* @return The translation key.
*/
public @NotNull String getTranslationKey()
{
public @NotNull String getTranslationKey() {
return "lambdacontrols.action." + this.getName();
}
public @NotNull Text getText() {
return this.text;
}
/**
* Returns the key binding equivalent of this button binding.
*
* @return The key binding equivalent.
*/
public @NotNull Optional<KeyBinding> asKeyBinding()
{
public @NotNull Optional<KeyBinding> asKeyBinding() {
return Optional.ofNullable(this.mcKeyBinding);
}
@Override
public String toString()
{
public String toString() {
return "ButtonBinding{id=\"" + this.key + "\","
+ "hasCooldown=" + this.hasCooldown
+ "}";
@@ -283,12 +270,11 @@ public class ButtonBinding implements Nameable
/**
* Returns the specified axis as a button.
*
* @param axis The axis.
* @param axis The axis.
* @param positive True if the axis part is positive, else false.
* @return The axis as a button.
*/
public static int axisAsButton(int axis, boolean positive)
{
public static int axisAsButton(int axis, boolean positive) {
return positive ? 100 + axis : 200 + axis;
}
@@ -298,8 +284,7 @@ public class ButtonBinding implements Nameable
* @param button The button.
* @return True if the button is an axis, else false.
*/
public static boolean isAxis(int button)
{
public static boolean isAxis(int button) {
button %= 500;
return button >= 100;
}
@@ -310,13 +295,11 @@ public class ButtonBinding implements Nameable
* @param button The raw button code.
* @return The second Joycon's button code.
*/
public static int controller2Button(int button)
{
public static int controller2Button(int button) {
return 500 + button;
}
public static void init(@NotNull GameOptions options)
{
public static void init(@NotNull GameOptions options) {
ATTACK.mcKeyBinding = options.keyAttack;
BACK.mcKeyBinding = options.keyBack;
CHAT.mcKeyBinding = options.keyChat;
@@ -343,8 +326,7 @@ public class ButtonBinding implements Nameable
* @param button The button.
* @return The localized name of the button.
*/
public static @NotNull Text getLocalizedButtonName(int button)
{
public static @NotNull Text getLocalizedButtonName(int button) {
switch (button % 500) {
case -1:
return new TranslatableText("key.keyboard.unknown");
@@ -440,8 +422,7 @@ public class ButtonBinding implements Nameable
* @return The builder instance
* @since 1.5.0
*/
public static Builder builder(@NotNull Identifier identifier)
{
public static Builder builder(@NotNull Identifier identifier) {
return new Builder(identifier);
}
@@ -452,8 +433,7 @@ public class ButtonBinding implements Nameable
* @return The builder instance.
* @since 1.5.0
*/
public static Builder builder(@NotNull net.minecraft.util.Identifier identifier)
{
public static Builder builder(@NotNull net.minecraft.util.Identifier identifier) {
return new Builder(identifier);
}
@@ -465,34 +445,30 @@ public class ButtonBinding implements Nameable
* @version 1.5.0
* @since 1.1.0
*/
public static class Builder
{
private final String key;
private int[] buttons = new int[0];
private List<PressAction> actions = new ArrayList<>();
private PairPredicate<MinecraftClient, ButtonBinding> filter = Predicates.pairAlwaysTrue();
private boolean cooldown = false;
private ButtonCategory category = null;
private KeyBinding mcBinding = null;
public static class Builder {
private final String key;
private int[] buttons = new int[0];
private List<PressAction> actions = new ArrayList<>();
private PairPredicate<MinecraftClient, ButtonBinding> filter = Predicates.pairAlwaysTrue();
private boolean cooldown = false;
private ButtonCategory category = null;
private KeyBinding mcBinding = null;
/**
* This constructor shouldn't be used for other mods.
*
* @param key The key with format {@code "<namespace>.<name>"}.
*/
public Builder(@NotNull String key)
{
public Builder(@NotNull String key) {
this.key = key;
this.unbound();
}
public Builder(@NotNull Identifier identifier)
{
public Builder(@NotNull Identifier identifier) {
this(identifier.getNamespace() + "." + identifier.getName());
}
public Builder(@NotNull net.minecraft.util.Identifier identifier)
{
public Builder(@NotNull net.minecraft.util.Identifier identifier) {
this(new Identifier(identifier.toString()));
}
@@ -502,8 +478,7 @@ public class ButtonBinding implements Nameable
* @param buttons The default buttons.
* @return The builder instance.
*/
public Builder buttons(int... buttons)
{
public Builder buttons(int... buttons) {
this.buttons = buttons;
return this;
}
@@ -513,8 +488,7 @@ public class ButtonBinding implements Nameable
*
* @return The builder instance.
*/
public Builder unbound()
{
public Builder unbound() {
return this.buttons(-1);
}
@@ -524,8 +498,7 @@ public class ButtonBinding implements Nameable
* @param actions The actions to add.
* @return The builder instance.
*/
public Builder actions(@NotNull PressAction... actions)
{
public Builder actions(@NotNull PressAction... actions) {
this.actions.addAll(Arrays.asList(actions));
return this;
}
@@ -536,8 +509,7 @@ public class ButtonBinding implements Nameable
* @param action The action to add.
* @return The builder instance.
*/
public Builder action(@NotNull PressAction action)
{
public Builder action(@NotNull PressAction action) {
this.actions.add(action);
return this;
}
@@ -548,8 +520,7 @@ public class ButtonBinding implements Nameable
* @param filter The filter.
* @return The builder instance.
*/
public Builder filter(@NotNull PairPredicate<MinecraftClient, ButtonBinding> filter)
{
public Builder filter(@NotNull PairPredicate<MinecraftClient, ButtonBinding> filter) {
this.filter = filter;
return this;
}
@@ -561,8 +532,7 @@ public class ButtonBinding implements Nameable
* @see #filter(PairPredicate)
* @see InputHandlers#inGame(MinecraftClient, ButtonBinding)
*/
public Builder onlyInGame()
{
public Builder onlyInGame() {
return this.filter(InputHandlers::inGame);
}
@@ -573,8 +543,7 @@ public class ButtonBinding implements Nameable
* @see #filter(PairPredicate)
* @see InputHandlers#inInventory(MinecraftClient, ButtonBinding)
*/
public Builder onlyInInventory()
{
public Builder onlyInInventory() {
return this.filter(InputHandlers::inInventory);
}
@@ -584,8 +553,7 @@ public class ButtonBinding implements Nameable
* @param cooldown True if the {@link ButtonBinding} has a cooldown, else false.
* @return The builder instance.
*/
public Builder cooldown(boolean cooldown)
{
public Builder cooldown(boolean cooldown) {
this.cooldown = cooldown;
return this;
}
@@ -596,8 +564,7 @@ public class ButtonBinding implements Nameable
* @return The builder instance.
* @since 1.5.0
*/
public Builder cooldown()
{
public Builder cooldown() {
return this.cooldown(true);
}
@@ -607,8 +574,7 @@ public class ButtonBinding implements Nameable
* @param category The category.
* @return The builder instance.
*/
public Builder category(@Nullable ButtonCategory category)
{
public Builder category(@Nullable ButtonCategory category) {
this.category = category;
return this;
}
@@ -619,8 +585,7 @@ public class ButtonBinding implements Nameable
* @param binding The keybinding to link.
* @return The builder instance.
*/
public Builder linkKeybind(@Nullable KeyBinding binding)
{
public Builder linkKeybind(@Nullable KeyBinding binding) {
this.mcBinding = binding;
return this;
}
@@ -630,8 +595,7 @@ public class ButtonBinding implements Nameable
*
* @return The built {@link ButtonBinding}.
*/
public ButtonBinding build()
{
public ButtonBinding build() {
ButtonBinding binding = new ButtonBinding(this.key, this.buttons, this.actions, this.filter, this.cooldown);
if (this.category != null)
this.category.registerBinding(binding);
@@ -646,8 +610,7 @@ public class ButtonBinding implements Nameable
* @return The built {@link ButtonBinding}.
* @see #build()
*/
public ButtonBinding register()
{
public ButtonBinding register() {
return InputManager.registerBinding(this.build());
}
}

View File

@@ -1,88 +0,0 @@
/*
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of LambdaControls.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package me.lambdaurora.lambdacontrols.client.gui;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.client.controller.InputManager;
import me.lambdaurora.spruceui.SpruceButtonWidget;
import me.lambdaurora.spruceui.SpruceTexts;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.TranslatableText;
import org.aperlambda.lambdacommon.utils.function.Predicates;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Represents the controls screen.
*/
public class ControllerControlsScreen extends Screen
{
private final Screen parent;
final LambdaControlsClient mod;
private final boolean hideSettings;
private ControlsListWidget bindingsListWidget;
private ButtonWidget resetButton;
public ButtonBinding focusedBinding;
public boolean waiting = false;
public List<Integer> currentButtons = new ArrayList<>();
public ControllerControlsScreen(@NotNull Screen parent, boolean hideSettings)
{
super(new TranslatableText("lambdacontrols.menu.title.controller_controls"));
this.parent = parent;
this.mod = LambdaControlsClient.get();
this.hideSettings = hideSettings;
}
@Override
public void removed()
{
this.mod.config.save();
super.removed();
}
@Override
protected void init()
{
this.addButton(new SpruceButtonWidget(this.width / 2 - 155, 18, this.hideSettings ? 310 : 150, 20,
new TranslatableText("lambdacontrols.menu.keyboard_controls"),
btn -> this.client.openScreen(new ControlsOptionsScreen(this, this.client.options))));
if (!this.hideSettings)
this.addButton(new SpruceButtonWidget(this.width / 2 - 155 + 160, 18, 150, 20,
SpruceTexts.MENU_OPTIONS,
btn -> this.client.openScreen(new LambdaControlsSettingsScreen(this, true))));
this.bindingsListWidget = new ControlsListWidget(this, this.client);
this.children.add(this.bindingsListWidget);
this.resetButton = this.addButton(new ButtonWidget(this.width / 2 - 155, this.height - 29, 150, 20,
SpruceTexts.CONTROLS_RESET_ALL,
btn -> InputManager.streamBindings().collect(Collectors.toSet()).forEach(binding -> this.mod.config.setButtonBinding(binding, binding.getDefaultButton()))));
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20,
SpruceTexts.GUI_DONE,
btn -> this.client.openScreen(this.parent)));
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta)
{
this.renderBackground(matrices);
this.bindingsListWidget.render(matrices, mouseX, mouseY, delta);
drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 8, 16777215);
this.resetButton.active = InputManager.streamBindings().anyMatch(Predicates.not(ButtonBinding::isDefault));
super.render(matrices, mouseX, mouseY, delta);
}
}

View File

@@ -1,214 +0,0 @@
/*
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of LambdaControls.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package me.lambdaurora.lambdacontrols.client.gui;
import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.client.controller.ButtonCategory;
import me.lambdaurora.lambdacontrols.client.controller.InputManager;
import me.lambdaurora.spruceui.SpruceTexts;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.ElementListWidget;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText;
import net.minecraft.text.MutableText;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Formatting;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Represents a control list widget.
*/
public class ControlsListWidget extends ElementListWidget<ControlsListWidget.Entry>
{
private static final int[] UNBOUND = new int[]{-1};
private final ControllerControlsScreen gui;
private int field_2733;
public ControlsListWidget(@NotNull ControllerControlsScreen gui, @NotNull MinecraftClient client)
{
super(client, gui.width + 45, gui.height, 43, gui.height - 32, 24);
this.gui = gui;
InputManager.streamCategories()
.sorted(Comparator.comparingInt(ButtonCategory::getPriority))
.forEach(category -> {
this.addEntry(new CategoryEntry(category));
category.getBindings().forEach(binding -> {
int i = client.textRenderer.getWidth(I18n.translate(binding.getTranslationKey()));
if (i > this.field_2733) {
this.field_2733 = i;
}
this.addEntry(new ControlsListWidget.ButtonBindingEntry(binding));
});
});
}
@Override
protected int getScrollbarPositionX()
{
return super.getScrollbarPositionX() + 15;
}
@Override
public int getRowWidth()
{
return super.getRowWidth() + 32;
}
public class ButtonBindingEntry extends Entry
{
private final ButtonBinding binding;
private final String bindingName;
private final ControllerButtonWidget editButton;
private final ButtonWidget resetButton;
private final ButtonWidget unboundButton;
ButtonBindingEntry(@NotNull ButtonBinding binding)
{
this.binding = binding;
this.bindingName = I18n.translate(this.binding.getTranslationKey());
this.editButton = new ControllerButtonWidget(0, 0, 110, this.binding, btn -> {
gui.focusedBinding = binding;
gui.currentButtons.clear();
gui.waiting = true;
})
{
protected MutableText getNarrationMessage()
{
return binding.isNotBound() ? new TranslatableText("narrator.controls.unbound", bindingName) : new TranslatableText("narrator.controls.bound", bindingName, super.getNarrationMessage());
}
};
this.resetButton = new ButtonWidget(0, 0, 50, 20, new TranslatableText("controls.reset"),
btn -> gui.mod.config.setButtonBinding(binding, binding.getDefaultButton()))
{
protected MutableText getNarrationMessage()
{
return new TranslatableText("narrator.controls.reset", bindingName);
}
};
this.unboundButton = new ButtonWidget(0, 0, 50, 20, SpruceTexts.OPTIONS_GENERIC_UNBOUND,
btn -> {
gui.mod.config.setButtonBinding(binding, UNBOUND);
gui.focusedBinding = null;
})
{
protected MutableText getNarrationMessage()
{
return new TranslatableText("lambdacontrols.narrator.unbound", bindingName);
}
};
}
@Override
public List<? extends Element> children()
{
return Collections.unmodifiableList(Arrays.asList(this.editButton, this.resetButton));
}
@Override
public void render(MatrixStack matrices, int index, int y, int x, int width, int height, int mouseX, int mouseY, boolean hovering, float delta)
{
boolean focused = gui.focusedBinding == this.binding;
TextRenderer textRenderer = ControlsListWidget.this.client.textRenderer;
String bindingName = this.bindingName;
float var10002 = (float) (x + 70 - ControlsListWidget.this.field_2733);
int var10003 = y + height / 2;
textRenderer.draw(matrices, bindingName, var10002, (float) (var10003 - 9 / 2), 16777215);
this.resetButton.x = this.unboundButton.x = x + 190;
this.resetButton.y = this.unboundButton.y = y;
this.resetButton.active = !this.binding.isDefault();
if (focused)
this.unboundButton.render(matrices, mouseX, mouseY, delta);
else
this.resetButton.render(matrices, mouseX, mouseY, delta);
this.editButton.x = x + 75;
this.editButton.y = y;
this.editButton.update();
if (focused) {
MutableText text = new LiteralText("> ").formatted(Formatting.WHITE);
text.append(this.editButton.getMessage().copy().formatted(Formatting.YELLOW));
this.editButton.setMessage(text.append(new LiteralText(" <").formatted(Formatting.WHITE)));
} else if (!this.binding.isNotBound() && InputManager.hasDuplicatedBindings(this.binding)) {
MutableText text = this.editButton.getMessage().copy();
this.editButton.setMessage(text.formatted(Formatting.RED));
} else if (this.binding.isNotBound()) {
MutableText text = this.editButton.getMessage().copy();
this.editButton.setMessage(text.formatted(Formatting.GOLD));
}
this.editButton.render(matrices, mouseX, mouseY, delta);
}
public boolean mouseClicked(double mouseX, double mouseY, int button)
{
boolean focused = gui.focusedBinding == this.binding;
if (this.editButton.mouseClicked(mouseX, mouseY, button))
return true;
else
return focused ? this.unboundButton.mouseClicked(mouseX, mouseY, button) : this.resetButton.mouseClicked(mouseX, mouseY, button);
}
public boolean mouseReleased(double mouseX, double mouseY, int button)
{
return this.editButton.mouseReleased(mouseX, mouseY, button) || this.resetButton.mouseReleased(mouseX, mouseY, button)
|| this.unboundButton.mouseReleased(mouseX, mouseY, button);
}
}
public class CategoryEntry extends Entry
{
private final String name;
private final int nameWidth;
public CategoryEntry(@NotNull ButtonCategory category)
{
this.name = category.getTranslatedName();
this.nameWidth = ControlsListWidget.this.client.textRenderer.getWidth(this.name);
}
@Override
public void render(MatrixStack matrices, int index, int y, int x, int width, int height, int mouseX, int mouseY, boolean hovering, float delta)
{
ControlsListWidget.this.client.textRenderer.draw(matrices, this.name, (float) (ControlsListWidget.this.client.currentScreen.width / 2 - this.nameWidth / 2),
(float) ((y + height) - 9 - 1), 16777215);
}
@Override
public boolean changeFocus(boolean bl)
{
return false;
}
@Override
public List<? extends Element> children()
{
return Collections.emptyList();
}
}
@Environment(EnvType.CLIENT)
public abstract static class Entry extends ElementListWidget.Entry<Entry>
{
}
}

View File

@@ -13,19 +13,19 @@ import me.lambdaurora.lambdacontrols.ControlsMode;
import me.lambdaurora.lambdacontrols.LambdaControls;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.controller.Controller;
import me.lambdaurora.spruceui.SpruceButtonWidget;
import me.lambdaurora.spruceui.SpruceLabelWidget;
import me.lambdaurora.lambdacontrols.client.gui.widget.ControllerControlsWidget;
import me.lambdaurora.spruceui.Position;
import me.lambdaurora.spruceui.SpruceTexts;
import me.lambdaurora.spruceui.Tooltip;
import me.lambdaurora.spruceui.option.*;
import me.lambdaurora.spruceui.screen.SpruceScreen;
import me.lambdaurora.spruceui.widget.SpruceLabelWidget;
import me.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
import me.lambdaurora.spruceui.widget.container.SpruceOptionListWidget;
import me.lambdaurora.spruceui.widget.container.tabbed.SpruceTabbedWidget;
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawableHelper;
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.Option;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText;
@@ -38,50 +38,57 @@ import org.lwjgl.glfw.GLFW;
/**
* Represents the LambdaControls settings screen.
*/
public class LambdaControlsSettingsScreen extends Screen
{
public static final String GAMEPAD_TOOL_URL = "https://generalarcade.com/gamepadtool/";
final LambdaControlsClient mod;
private final Screen parent;
private final boolean hideControls;
public class LambdaControlsSettingsScreen extends SpruceScreen {
public static final String GAMEPAD_TOOL_URL = "https://generalarcade.com/gamepadtool/";
final LambdaControlsClient mod;
private final Screen parent;
// General options
private final Option autoSwitchModeOption;
private final Option rotationSpeedOption;
private final Option mouseSpeedOption;
private final Option resetOption;
private final SpruceOption inputModeOption;
private final SpruceOption autoSwitchModeOption;
private final SpruceOption rotationSpeedOption;
private final SpruceOption mouseSpeedOption;
private final SpruceOption resetOption;
// Gameplay options
private final Option autoJumpOption;
private final Option fastBlockPlacingOption;
private final Option frontBlockPlacingOption;
private final Option verticalReacharoundOption;
private final Option flyDriftingOption;
private final Option flyVerticalDriftingOption;
private final SpruceOption autoJumpOption;
private final SpruceOption fastBlockPlacingOption;
private final SpruceOption frontBlockPlacingOption;
private final SpruceOption verticalReacharoundOption;
private final SpruceOption flyDriftingOption;
private final SpruceOption flyVerticalDriftingOption;
// Controller options
private final Option controllerOption;
private final Option secondControllerOption;
private final Option controllerTypeOption;
private final Option deadZoneOption;
private final Option invertsRightXAxis;
private final Option invertsRightYAxis;
private final Option unfocusedInputOption;
private final Option virtualMouseOption;
private final Option virtualMouseSkinOption;
private final SpruceOption controllerOption;
private final SpruceOption secondControllerOption;
private final SpruceOption controllerTypeOption;
private final SpruceOption deadZoneOption;
private final SpruceOption invertsRightXAxis;
private final SpruceOption invertsRightYAxis;
private final SpruceOption unfocusedInputOption;
private final SpruceOption virtualMouseOption;
private final SpruceOption virtualMouseSkinOption;
// Hud options
private final Option hudEnableOption;
private final Option hudSideOption;
private final MutableText controllerMappingsUrlText = new LiteralText("(")
private final SpruceOption hudEnableOption;
private final SpruceOption hudSideOption;
private final MutableText controllerMappingsUrlText = new LiteralText("(")
.append(new LiteralText(GAMEPAD_TOOL_URL).formatted(Formatting.GOLD))
.append("),");
private ButtonListWidget list;
private SpruceLabelWidget gamepadToolUrlLabel;
private SpruceLabelWidget gamepadToolUrlLabel;
public LambdaControlsSettingsScreen(Screen parent, boolean hideControls)
{
public LambdaControlsSettingsScreen(Screen parent, boolean hideControls) {
super(new TranslatableText("lambdacontrols.title.settings"));
this.mod = LambdaControlsClient.get();
this.parent = parent;
this.hideControls = hideControls;
// General options
this.inputModeOption = new SpruceCyclingOption("lambdacontrols.menu.controls_mode",
amount -> {
ControlsMode next = this.mod.config.getControlsMode().next();
this.mod.config.setControlsMode(next);
this.mod.config.save();
if (this.client.player != null) {
ClientSidePacketRegistry.INSTANCE.sendToServer(LambdaControls.CONTROLS_MODE_CHANNEL, this.mod.makeControlsModeBuffer(next));
}
}, option -> option.getDisplayText(new TranslatableText(this.mod.config.getControlsMode().getTranslationKey())),
new TranslatableText("lambdacontrols.tooltip.controls_mode"));
this.autoSwitchModeOption = new SpruceBooleanOption("lambdacontrols.menu.auto_switch_mode", this.mod.config::hasAutoSwitchMode,
this.mod.config::setAutoSwitchMode, new TranslatableText("lambdacontrols.tooltip.auto_switch_mode"), true);
this.rotationSpeedOption = new SpruceDoubleOption("lambdacontrols.menu.rotation_speed", 0.0, 100.0, 0.5F, this.mod.config::getRotationSpeed,
@@ -98,22 +105,25 @@ public class LambdaControlsSettingsScreen extends Screen
}
}, option -> option.getDisplayText(new LiteralText(String.valueOf(option.get()))),
new TranslatableText("lambdacontrols.tooltip.mouse_speed"));
this.resetOption = new SpruceResetOption(btn -> {
this.resetOption = SpruceSimpleActionOption.reset(btn -> {
this.mod.config.reset();
MinecraftClient client = MinecraftClient.getInstance();
this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
});
// Gameplay options
this.autoJumpOption = SpruceBooleanOption.fromVanilla("options.autoJump", Option.AUTO_JUMP, null, true);
this.fastBlockPlacingOption = new SpruceBooleanOption("lambdacontrols.menu.fast_block_placing", this.mod.config::hasFastBlockPlacing,
this.autoJumpOption = new SpruceCheckboxBooleanOption("options.autoJump",
() -> this.client.options.autoJump,
newValue -> this.client.options.autoJump = newValue,
null, true);
this.fastBlockPlacingOption = new SpruceCheckboxBooleanOption("lambdacontrols.menu.fast_block_placing", this.mod.config::hasFastBlockPlacing,
this.mod.config::setFastBlockPlacing, new TranslatableText("lambdacontrols.tooltip.fast_block_placing"), true);
this.frontBlockPlacingOption = new SpruceBooleanOption("lambdacontrols.menu.reacharound.horizontal", this.mod.config::hasFrontBlockPlacing,
this.frontBlockPlacingOption = new SpruceCheckboxBooleanOption("lambdacontrols.menu.reacharound.horizontal", this.mod.config::hasFrontBlockPlacing,
this.mod.config::setFrontBlockPlacing, new TranslatableText("lambdacontrols.tooltip.reacharound.horizontal"), true);
this.verticalReacharoundOption = new SpruceBooleanOption("lambdacontrols.menu.reacharound.vertical", this.mod.config::hasVerticalReacharound,
this.verticalReacharoundOption = new SpruceCheckboxBooleanOption("lambdacontrols.menu.reacharound.vertical", this.mod.config::hasVerticalReacharound,
this.mod.config::setVerticalReacharound, new TranslatableText("lambdacontrols.tooltip.reacharound.vertical"), true);
this.flyDriftingOption = new SpruceBooleanOption("lambdacontrols.menu.fly_drifting", this.mod.config::hasFlyDrifting,
this.flyDriftingOption = new SpruceCheckboxBooleanOption("lambdacontrols.menu.fly_drifting", this.mod.config::hasFlyDrifting,
this.mod.config::setFlyDrifting, new TranslatableText("lambdacontrols.tooltip.fly_drifting"), true);
this.flyVerticalDriftingOption = new SpruceBooleanOption("lambdacontrols.menu.fly_drifting_vertical", this.mod.config::hasFlyVerticalDrifting,
this.flyVerticalDriftingOption = new SpruceCheckboxBooleanOption("lambdacontrols.menu.fly_drifting_vertical", this.mod.config::hasFlyVerticalDrifting,
this.mod.config::setFlyVerticalDrifting, new TranslatableText("lambdacontrols.tooltip.fly_drifting_vertical"), true);
// Controller options
this.controllerOption = new SpruceCyclingOption("lambdacontrols.menu.controller", amount -> {
@@ -191,30 +201,26 @@ public class LambdaControlsSettingsScreen extends Screen
}
@Override
public void removed()
{
public void removed() {
this.mod.config.save();
super.removed();
}
@Override
public void onClose()
{
public void onClose() {
this.mod.config.save();
super.onClose();
}
private int getTextHeight()
{
private int getTextHeight() {
return (5 + this.textRenderer.fontHeight) * 3 + 5;
}
@Override
protected void init()
{
protected void init() {
super.init();
int buttonHeight = 20;
SpruceButtonWidget controlsModeBtn = new SpruceButtonWidget(this.width / 2 - 155, 18, this.hideControls ? 310 : 150, buttonHeight,
/*int buttonHeight = 20;
SpruceButtonWidget controlsModeBtn = new SpruceButtonWidget(Position.of(this.width / 2 - 155, 18), this.hideControls ? 310 : 150, buttonHeight,
new TranslatableText("lambdacontrols.menu.controls_mode").append(": ").append(new TranslatableText(this.mod.config.getControlsMode().getTranslationKey())),
btn -> {
ControlsMode next = this.mod.config.getControlsMode().next();
@@ -227,7 +233,7 @@ public class LambdaControlsSettingsScreen extends Screen
}
});
controlsModeBtn.setTooltip(new TranslatableText("lambdacontrols.tooltip.controls_mode"));
this.addButton(controlsModeBtn);
this.addChild(controlsModeBtn);
if (!this.hideControls)
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, 18, 150, buttonHeight, new TranslatableText("options.controls"),
btn -> {
@@ -237,18 +243,18 @@ public class LambdaControlsSettingsScreen extends Screen
this.client.openScreen(new ControlsOptionsScreen(this, this.client.options));
}));
this.list = new ButtonListWidget(this.client, this.width, this.height, 43, this.height - 29 - this.getTextHeight(), 25);
this.list = new SpruceOptionListWidget(Position.of(this, 0, 43), this.width, this.height - 29 - this.getTextHeight() - 43);
// General options
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.general", true, null));
this.list.addOptionEntry(this.rotationSpeedOption, this.mouseSpeedOption);
this.list.addSingleOptionEntry(this.autoSwitchModeOption);
// Gameplay options
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.gameplay", true, null));
this.list.addOptionEntry(this.autoJumpOption, this.fastBlockPlacingOption);
//this.list.addOptionEntry(this.autoJumpOption, this.fastBlockPlacingOption);
this.list.addOptionEntry(this.frontBlockPlacingOption, this.verticalReacharoundOption);
this.list.addSingleOptionEntry(this.flyDriftingOption);
this.list.addSingleOptionEntry(this.flyVerticalDriftingOption);
this.list.addOptionEntry(Option.SNEAK_TOGGLED, Option.SPRINT_TOGGLED);
//this.list.addOptionEntry(Option.SNEAK_TOGGLED, Option.SPRINT_TOGGLED);
// Controller options
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.controller", true, null));
this.list.addSingleOptionEntry(this.controllerOption);
@@ -257,35 +263,95 @@ public class LambdaControlsSettingsScreen extends Screen
this.list.addOptionEntry(this.invertsRightXAxis, this.invertsRightYAxis);
this.list.addOptionEntry(this.unfocusedInputOption, this.virtualMouseOption);
this.list.addSingleOptionEntry(this.virtualMouseSkinOption);
this.list.addSingleOptionEntry(new ReloadControllerMappingsOption());
this.list.addSingleOptionEntry(new SpruceSimpleActionOption("lambdacontrols.menu.mappings.open_input_str",
this.list.addSingleOptionEntry(ReloadControllerMappingsOption.newOption(null));
this.list.addSingleOptionEntry(SpruceSimpleActionOption.of("lambdacontrols.menu.mappings.open_input_str",
btn -> this.client.openScreen(new MappingsStringInputScreen(this))));
// HUD options
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.hud", true, null));
this.list.addOptionEntry(this.hudEnableOption, this.hudSideOption);
this.children.add(this.list);
this.addChild(this.list);*/
this.gamepadToolUrlLabel = new SpruceLabelWidget(this.width / 2, this.height - 29 - (5 + this.textRenderer.fontHeight) * 2, this.controllerMappingsUrlText, this.width,
this.buildTabs();
this.gamepadToolUrlLabel = new SpruceLabelWidget(Position.of(this.width / 2, this.height - 29 - (5 + this.textRenderer.fontHeight) * 2), this.controllerMappingsUrlText, this.width,
label -> Util.getOperatingSystem().open(GAMEPAD_TOOL_URL), true);
this.gamepadToolUrlLabel.setTooltip(new TranslatableText("chat.link.open"));
this.children.add(this.gamepadToolUrlLabel);
this.addChild(this.gamepadToolUrlLabel);
this.addButton(this.resetOption.createButton(this.client.options, this.width / 2 - 155, this.height - 29, 150));
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, buttonHeight, SpruceTexts.GUI_DONE,
this.addChild(this.resetOption.createWidget(Position.of(this.width / 2 - 155, this.height - 29), 150));
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, SpruceTexts.GUI_DONE,
btn -> this.client.openScreen(this.parent)));
}
public void buildTabs() {
SpruceTabbedWidget tabs = new SpruceTabbedWidget(Position.of(0, 24), this.width, this.height - 32 - 24,
null,
Math.max(100, this.width / 8), 0);
this.addChild(tabs);
tabs.addSeparatorEntry(new TranslatableText("lambdacontrols.menu.separator.general"));
tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.general"), null,
this::buildGeneralTab);
tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.gameplay"), null,
this::buildGameplayTab);
tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.hud"), null,
this::buildHudTab);
tabs.addSeparatorEntry(new TranslatableText("options.controls"));
tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.controller_controls"), null,
this::buildControllerControlsTab);
tabs.addSeparatorEntry(new TranslatableText("lambdacontrols.menu.separator.controller"));
tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.controller"), null,
this::buildControllerTab);
tabs.addTabEntry(new TranslatableText("lambdacontrols.menu.title.mappings.string"), null,
this::buildMappingsStringEditorTab);
}
public SpruceOptionListWidget buildGeneralTab(int width, int height) {
SpruceOptionListWidget list = new SpruceOptionListWidget(Position.origin(), width, height);
list.addSingleOptionEntry(this.inputModeOption);
list.addSingleOptionEntry(this.autoSwitchModeOption);
return list;
}
public SpruceOptionListWidget buildGameplayTab(int width, int height) {
SpruceOptionListWidget list = new SpruceOptionListWidget(Position.origin(), width, height);
list.addSingleOptionEntry(this.fastBlockPlacingOption);
list.addSingleOptionEntry(this.frontBlockPlacingOption);
list.addSingleOptionEntry(this.verticalReacharoundOption);
list.addSingleOptionEntry(this.flyDriftingOption);
list.addSingleOptionEntry(this.flyVerticalDriftingOption);
list.addSingleOptionEntry(this.autoJumpOption);
return list;
}
public SpruceOptionListWidget buildHudTab(int width, int height) {
SpruceOptionListWidget list = new SpruceOptionListWidget(Position.origin(), width, height);
list.addSingleOptionEntry(this.hudEnableOption);
list.addSingleOptionEntry(this.hudSideOption);
return list;
}
public ControllerControlsWidget buildControllerControlsTab(int width, int height) {
return new ControllerControlsWidget(Position.origin(), width, height);
}
public SpruceOptionListWidget buildControllerTab(int width, int height) {
SpruceOptionListWidget list = new SpruceOptionListWidget(Position.origin(), width, height);
list.addSingleOptionEntry(this.controllerOption);
list.addSingleOptionEntry(this.secondControllerOption);
return list;
}
public SpruceContainerWidget buildMappingsStringEditorTab(int width, int height) {
return new MappingsStringInputWidget(Position.origin(), width, height);
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta)
{
this.renderBackground(matrices);
this.list.render(matrices, mouseX, mouseY, delta);
super.render(matrices, mouseX, mouseY, delta);
public void renderTitle(MatrixStack matrices, int mouseX, int mouseY, float delta) {
drawCenteredString(matrices, this.textRenderer, I18n.translate("lambdacontrols.menu.title"), this.width / 2, 8, 16777215);
drawCenteredString(matrices, this.textRenderer, I18n.translate("lambdacontrols.controller.mappings.1", Formatting.GREEN.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.textRenderer.fontHeight) * 3, 10526880);
this.gamepadToolUrlLabel.render(matrices, mouseX, mouseY, delta);
drawCenteredString(matrices, this.textRenderer, I18n.translate("lambdacontrols.controller.mappings.3", Formatting.GREEN.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.textRenderer.fontHeight), 10526880);
Tooltip.renderAll(matrices);
}
}

View File

@@ -11,11 +11,15 @@ package me.lambdaurora.lambdacontrols.client.gui;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.controller.Controller;
import me.lambdaurora.spruceui.SpruceTextAreaWidget;
import me.lambdaurora.spruceui.Position;
import me.lambdaurora.spruceui.SpruceTexts;
import me.lambdaurora.spruceui.option.SpruceOption;
import me.lambdaurora.spruceui.screen.SpruceScreen;
import me.lambdaurora.spruceui.widget.SpruceButtonWidget;
import me.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
import me.lambdaurora.spruceui.widget.text.SpruceTextAreaWidget;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.options.Option;
import net.minecraft.client.toast.SystemToast;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText;
@@ -33,44 +37,34 @@ import java.nio.file.Files;
* @version 1.4.3
* @since 1.4.3
*/
public class MappingsStringInputScreen extends Screen
{
private final Screen parent;
private final Option reloadMappingsOption;
private String mappings;
private SpruceTextAreaWidget textArea;
public class MappingsStringInputWidget extends SpruceContainerWidget {
private final SpruceOption reloadMappingsOption;
private String mappings;
private SpruceTextAreaWidget textArea;
protected MappingsStringInputScreen(@Nullable Screen parent)
{
super(new TranslatableText("lambdacontrols.menu.title.mappings.string"));
this.parent = parent;
protected MappingsStringInputWidget(Position position, int width, int height) {
super(position, width, height);
//super(new TranslatableText("lambdacontrols.menu.title.mappings.string"));
this.reloadMappingsOption = new ReloadControllerMappingsOption(btn -> {
this.reloadMappingsOption = ReloadControllerMappingsOption.newOption(btn -> {
this.writeMappings();
});
this.init();
}
@Override
public void removed()
{
public void removed() {
this.writeMappings();
Controller.updateMappings();
super.removed();
}
@Override
public void onClose()
{
public void onClose() {
this.removed();
super.onClose();
}
public void writeMappings()
{
public void writeMappings() {
if (this.textArea != null) {
this.mappings = this.textArea.getText();
System.out.println(this.mappings);
try {
FileWriter fw = new FileWriter(LambdaControlsClient.MAPPINGS_FILE, false);
fw.write(this.mappings);
@@ -84,11 +78,7 @@ public class MappingsStringInputScreen extends Screen
}
}
@Override
protected void init()
{
super.init();
protected void init() {
if (this.textArea != null) {
this.mappings = this.textArea.getText();
}
@@ -106,23 +96,17 @@ public class MappingsStringInputScreen extends Screen
}
}
int textFieldWidth = (int) (this.width * (3.0 / 4.0));
this.textArea = new SpruceTextAreaWidget(this.textRenderer, this.width / 2 - textFieldWidth / 2, 50, textFieldWidth, this.height - 100, new LiteralText(mappings));
int textFieldWidth = (int) (this.width * (5.0 / 6.0));
this.textArea = new SpruceTextAreaWidget(Position.of(this, this.width / 2 - textFieldWidth / 2, 0), this.client.textRenderer, textFieldWidth, this.height - 50, new LiteralText(mappings));
this.textArea.setText(mappings);
// Display as many lines as possible
this.textArea.setDisplayedLines(this.textArea.getInnerHeight() / this.textRenderer.fontHeight);
this.addButton(this.textArea);
this.textArea.setDisplayedLines(this.textArea.getInnerHeight() / this.client.textRenderer.fontHeight);
this.addChild(this.textArea);
this.addButton(this.reloadMappingsOption.createButton(this.client.options, this.width / 2 - 155, this.height - 29, 150));
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, SpruceTexts.GUI_DONE,
(buttonWidget) -> this.client.openScreen(this.parent)));
this.addChild(this.reloadMappingsOption.createWidget(Position.of(this.width / 2 - 155, this.height - 29), 310));
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta)
{
this.renderBackground(matrices);
super.render(matrices, mouseX, mouseY, delta);
/*public void renderTitle(MatrixStack matrices, int mouseX, int mouseY, float delta) {
drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 8, 16777215);
}
}*/
}

View File

@@ -11,8 +11,8 @@ package me.lambdaurora.lambdacontrols.client.gui;
import me.lambdaurora.lambdacontrols.client.controller.Controller;
import me.lambdaurora.spruceui.option.SpruceSimpleActionOption;
import me.lambdaurora.spruceui.widget.SpruceButtonWidget;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.toast.SystemToast;
import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText;
@@ -23,18 +23,11 @@ import java.util.function.Consumer;
/**
* Represents the option to reload the controller mappings.
*/
public class ReloadControllerMappingsOption extends SpruceSimpleActionOption
{
public class ReloadControllerMappingsOption {
private static final String KEY = "lambdacontrols.menu.reload_controller_mappings";
public ReloadControllerMappingsOption()
{
this(null);
}
public ReloadControllerMappingsOption(@Nullable Consumer<AbstractButtonWidget> before)
{
super(KEY, btn -> {
public static SpruceSimpleActionOption newOption(@Nullable Consumer<SpruceButtonWidget> before) {
return SpruceSimpleActionOption.of(KEY, btn -> {
MinecraftClient client = MinecraftClient.getInstance();
if (before != null)
before.accept(btn);

View File

@@ -12,7 +12,6 @@ package me.lambdaurora.lambdacontrols.client.gui;
import me.lambdaurora.lambdacontrols.client.HudSide;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor;
import me.lambdaurora.spruceui.SpruceTexturedButtonWidget;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.screen.GameMenuScreen;
import net.minecraft.client.gui.screen.Screen;
@@ -21,6 +20,7 @@ import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TexturedButtonWidget;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.util.Arm;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
@@ -36,7 +36,11 @@ import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y;
*/
public class TouchscreenOverlay extends Screen
{
public static final Identifier WIDGETS_LOCATION = new Identifier("lambdacontrols", "textures/gui/widgets.png");
public TouchscreenOverlay(@NotNull LambdaControlsClient mod)
{
super(new LiteralText("Touchscreen overlay"));
}
/*public static final Identifier WIDGETS_LOCATION = new Identifier("lambdacontrols", "textures/gui/widgets.png");
private LambdaControlsClient mod;
private SpruceTexturedButtonWidget jumpButton;
private SpruceTexturedButtonWidget flyButton;
@@ -85,7 +89,7 @@ public class TouchscreenOverlay extends Screen
* Updates the forward button ticks cooldown.
*
* @param state The button state.
*/
*
private void updateForwardButtonsState(boolean state)
{
if (state)
@@ -96,7 +100,7 @@ public class TouchscreenOverlay extends Screen
/**
* Updates the jump buttons.
*/
*
private void updateJumpButtons()
{
if (this.client == null)
@@ -125,7 +129,7 @@ public class TouchscreenOverlay extends Screen
*
* @param btn The pressed button.
* @param state The state of the jump button.
*/
*
private void handleJump(ButtonWidget btn, boolean state)
{
((KeyBindingAccessor) this.client.options.keyJump).lambdacontrols_handlePressState(state);
@@ -293,5 +297,5 @@ public class TouchscreenOverlay extends Screen
this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 1);
}
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
}
}*/
}

View File

@@ -7,11 +7,13 @@
* see the LICENSE file.
*/
package me.lambdaurora.lambdacontrols.client.gui;
package me.lambdaurora.lambdacontrols.client.gui.widget;
import me.lambdaurora.lambdacontrols.LambdaControls;
import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import me.lambdaurora.spruceui.AbstractIconButtonWidget;
import me.lambdaurora.lambdacontrols.client.gui.LambdaControlsRenderer;
import me.lambdaurora.spruceui.Position;
import me.lambdaurora.spruceui.SpruceTexts;
import me.lambdaurora.spruceui.widget.AbstractSpruceIconButtonWidget;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText;
@@ -22,39 +24,35 @@ import org.jetbrains.annotations.NotNull;
/**
* Represents a controller button widget.
*/
public class ControllerButtonWidget extends AbstractIconButtonWidget
{
public class ControllerButtonWidget extends AbstractSpruceIconButtonWidget {
private ButtonBinding binding;
private int iconWidth;
private int iconWidth;
public ControllerButtonWidget(int x, int y, int width, @NotNull ButtonBinding binding, @NotNull PressAction action)
{
super(x, y, width, 20, ButtonBinding.getLocalizedButtonName(binding.getButton()[0]), action);
public ControllerButtonWidget(Position position, int width, @NotNull ButtonBinding binding, @NotNull PressAction action) {
super(position, width, 20, ButtonBinding.getLocalizedButtonName(binding.getButton()[0]), action);
this.binding = binding;
}
public void update()
{
public void update() {
int length = binding.getButton().length;
this.setMessage(this.binding.isNotBound() ? LambdaControls.NOT_BOUND_TEXT :
this.setMessage(this.binding.isNotBound() ? SpruceTexts.NOT_BOUND.copy() :
(length > 0 ? ButtonBinding.getLocalizedButtonName(binding.getButton()[0]) : new LiteralText("<>")));
}
@Override
public Text getMessage()
{
public Text getMessage() {
if (this.binding.getButton().length > 1)
return LiteralText.EMPTY;
return super.getMessage();
}
@Override
protected int renderIcon(MatrixStack matrices, int mouseX, int mouseY, float delta, int x, int y)
{
protected int renderIcon(MatrixStack matrices, int mouseX, int mouseY, float delta) {
int x = this.getX();
if (this.binding.getButton().length > 1) {
x += (this.width / 2 - this.iconWidth / 2) - 4;
}
Pair<Integer, Integer> size = LambdaControlsRenderer.drawButton(matrices, x, y, this.binding, MinecraftClient.getInstance());
Pair<Integer, Integer> size = LambdaControlsRenderer.drawButton(matrices, x, this.getY(), this.binding, MinecraftClient.getInstance());
this.iconWidth = size.key;
return size.value;
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of LambdaControls.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package me.lambdaurora.lambdacontrols.client.gui.widget;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.client.controller.InputManager;
import me.lambdaurora.spruceui.Position;
import me.lambdaurora.spruceui.SpruceTexts;
import me.lambdaurora.spruceui.widget.SpruceButtonWidget;
import me.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.TranslatableText;
import org.aperlambda.lambdacommon.utils.function.Predicates;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Represents the controls screen.
*/
public class ControllerControlsWidget extends SpruceContainerWidget {
final LambdaControlsClient mod;
private ControlsListWidget bindingsListWidget;
private SpruceButtonWidget resetButton;
public ButtonBinding focusedBinding;
public boolean waiting = false;
public List<Integer> currentButtons = new ArrayList<>();
public ControllerControlsWidget(Position position, int width, int height) {
super(position, width, height);
this.mod = LambdaControlsClient.get();
this.init();
}
protected void init() {
this.addChild(new SpruceButtonWidget(Position.of(this, this.width / 2 - 155, 18), 310, 20,
new TranslatableText("lambdacontrols.menu.keyboard_controls"),
btn -> this.client.openScreen(new ControlsOptionsScreen(null, this.client.options))));
this.bindingsListWidget = new ControlsListWidget(Position.of(this, 0, 43), this.width, this.height - 43 - 43, this);
this.addChild(this.bindingsListWidget);
this.addChild(this.resetButton = new SpruceButtonWidget(Position.of(this, this.width / 2 - 155, this.height - 29), 150, 20,
SpruceTexts.CONTROLS_RESET_ALL,
btn -> InputManager.streamBindings().collect(Collectors.toSet()).forEach(binding -> this.mod.config.setButtonBinding(binding, binding.getDefaultButton()))));
}
@Override
public void renderWidget(MatrixStack matrices, int mouseX, int mouseY, float delta) {
drawCenteredText(matrices, this.client.textRenderer, new TranslatableText("lambdacontrols.menu.title.controller_controls"), this.width / 2, 8, 16777215);
this.resetButton.setActive(InputManager.streamBindings().anyMatch(Predicates.not(ButtonBinding::isDefault)));
super.renderWidget(matrices, mouseX, mouseY, delta);
}
}

View File

@@ -0,0 +1,373 @@
/*
* Copyright © 2020 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of LambdaControls.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package me.lambdaurora.lambdacontrols.client.gui.widget;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.controller.ButtonBinding;
import me.lambdaurora.lambdacontrols.client.controller.ButtonCategory;
import me.lambdaurora.lambdacontrols.client.controller.InputManager;
import me.lambdaurora.spruceui.Position;
import me.lambdaurora.spruceui.SpruceTexts;
import me.lambdaurora.spruceui.navigation.NavigationDirection;
import me.lambdaurora.spruceui.navigation.NavigationUtils;
import me.lambdaurora.spruceui.widget.SpruceButtonWidget;
import me.lambdaurora.spruceui.widget.SpruceSeparatorWidget;
import me.lambdaurora.spruceui.widget.SpruceWidget;
import me.lambdaurora.spruceui.widget.container.SpruceEntryListWidget;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Formatting;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW;
import java.util.*;
/**
* Represents a control list widget.
*/
public class ControlsListWidget extends SpruceEntryListWidget<ControlsListWidget.Entry> {
private static final int[] UNBOUND = new int[]{-1};
private final ControllerControlsWidget gui;
protected int lastIndex = 0;
private final int maxTextLength;
public ControlsListWidget(Position position, int width, int height, ControllerControlsWidget gui) {
super(position, width, height, 4, ControlsListWidget.Entry.class);
this.gui = gui;
this.maxTextLength = InputManager.streamBindings().mapToInt(binding -> this.client.textRenderer.getWidth(binding.getText())).max().orElse(0);
InputManager.streamCategories()
.sorted(Comparator.comparingInt(ButtonCategory::getPriority))
.forEach(category -> {
this.addEntry(new CategoryEntry(this, category));
category.getBindings().forEach(binding -> {
this.addEntry(new ControlsListWidget.ButtonBindingEntry(this, binding));
});
});
this.setAllowOutsideHorizontalNavigation(true);
}
private int getRowWidth() {
return this.getWidth() - 6 - this.getRowLeft() * 2;
}
public int getRowLeft() {
int baseWidth = 220 + 32;
return this.getWidth() / 2 - baseWidth / 2 + 72 - this.maxTextLength;
}
public class ButtonBindingEntry extends Entry {
private final List<SpruceWidget> children = new ArrayList<>();
private @Nullable SpruceWidget focused;
private final ButtonBinding binding;
private final String bindingName;
private final ControllerButtonWidget editButton;
private final SpruceButtonWidget resetButton;
private final SpruceButtonWidget unbindButton;
ButtonBindingEntry(@NotNull ControlsListWidget parent, @NotNull ButtonBinding binding) {
super(parent);
this.binding = binding;
this.bindingName = I18n.translate(this.binding.getTranslationKey());
this.editButton = new ControllerButtonWidget(Position.of(this, this.getWidth() - 55 - 110, 0), 110, this.binding, btn -> {
gui.focusedBinding = binding;
LambdaControlsClient.get().input.beginControlsInput(gui);
}) {
protected Optional<Text> getNarrationMessage() {
return Optional.of(binding.isNotBound() ? new TranslatableText("narrator.controls.unbound", bindingName) : new TranslatableText("narrator.controls.bound", bindingName, super.getNarrationMessage()));
}
};
this.children.add(editButton);
this.resetButton = new SpruceButtonWidget(Position.of(this, this.getWidth() - 50, 0), 50, 20, new TranslatableText("controls.reset"),
btn -> LambdaControlsClient.get().config.setButtonBinding(binding, binding.getDefaultButton())) {
protected Optional<Text> getNarrationMessage() {
return Optional.of(new TranslatableText("narrator.controls.reset", bindingName));
}
};
this.children.add(this.resetButton);
this.unbindButton = new SpruceButtonWidget(Position.of(this, this.getWidth() - 50, 0), 50, 20, SpruceTexts.GUI_UNBIND,
btn -> {
LambdaControlsClient.get().config.setButtonBinding(binding, UNBOUND);
gui.focusedBinding = null;
LambdaControlsClient.get().input.beginControlsInput(null);
}) {
protected Optional<Text> getNarrationMessage() {
return Optional.of(new TranslatableText("lambdacontrols.narrator.unbound", bindingName));
}
};
this.children.add(this.unbindButton);
}
public List<SpruceWidget> children() {
return this.children;
}
public @Nullable SpruceWidget getFocused() {
return this.focused;
}
public void setFocused(@Nullable SpruceWidget focused) {
if (this.focused == focused)
return;
if (this.focused != null)
this.focused.setFocused(false);
this.focused = focused;
}
@Override
public int getHeight() {
return this.children.stream().mapToInt(SpruceWidget::getHeight).reduce(Integer::max).orElse(0) + 4;
}
public Optional<SpruceWidget> hoveredElement(double mouseX, double mouseY) {
Iterator<SpruceWidget> it = this.children().iterator();
SpruceWidget element;
do {
if (!it.hasNext()) {
return Optional.empty();
}
element = it.next();
} while (!element.isMouseOver(mouseX, mouseY));
return Optional.of(element);
}
/* Input */
@Override
protected boolean onMouseClick(double mouseX, double mouseY, int button) {
Iterator<SpruceWidget> it = this.children().iterator();
SpruceWidget element;
do {
if (!it.hasNext()) {
return false;
}
element = it.next();
} while (!element.mouseClicked(mouseX, mouseY, button));
this.setFocused(element);
if (button == GLFW.GLFW_MOUSE_BUTTON_1)
this.dragging = true;
return true;
}
@Override
protected boolean onMouseRelease(double mouseX, double mouseY, int button) {
this.dragging = false;
return this.hoveredElement(mouseX, mouseY).filter(element -> element.mouseReleased(mouseX, mouseY, button)).isPresent();
}
@Override
protected boolean onMouseDrag(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
return this.getFocused() != null && this.dragging && button == GLFW.GLFW_MOUSE_BUTTON_1
&& this.getFocused().mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
}
@Override
protected boolean onKeyPress(int keyCode, int scanCode, int modifiers) {
return this.focused != null && this.focused.keyPressed(keyCode, scanCode, modifiers);
}
/* Navigation */
@Override
public void setFocused(boolean focused) {
super.setFocused(focused);
if (!focused) {
this.setFocused(null);
}
}
@Override
public boolean onNavigation(@NotNull NavigationDirection direction, boolean tab) {
if (this.requiresCursor()) return false;
if (!tab && direction.isVertical()) {
if (this.isFocused()) {
this.setFocused(null);
return false;
}
int lastIndex = this.parent.lastIndex;
if (lastIndex >= this.children.size())
lastIndex = this.children.size() - 1;
if (!this.children.get(lastIndex).onNavigation(direction, tab))
return false;
this.setFocused(this.children.get(lastIndex));
return true;
}
boolean result = NavigationUtils.tryNavigate(direction, tab, this.children, this.focused, this::setFocused, true);
if (result) {
this.setFocused(true);
if (direction.isHorizontal() && this.getFocused() != null) {
this.parent.lastIndex = this.children.indexOf(this.getFocused());
}
}
return result;
}
/* @Override
public void render(MatrixStack matrices, int index, int y, int x, int width, int height, int mouseX, int mouseY, boolean hovering, float delta)
{
220+32
boolean focused = gui.focusedBinding == this.binding;
TextRenderer textRenderer = ControlsListWidget.this.client.textRenderer;
String bindingName = this.bindingName;
float var10002 = (float) (x + 70 - ControlsListWidget.this.field_2733);
int var10003 = y + height / 2;
textRenderer.draw(matrices, bindingName, var10002, (float) (var10003 - 9 / 2), 16777215);
this.resetButton.x = this.unboundButton.x = x + 190;
this.resetButton.y = this.unboundButton.y = y;
this.resetButton.active = !this.binding.isDefault();
if (focused)
this.unboundButton.render(matrices, mouseX, mouseY, delta);
else
this.resetButton.render(matrices, mouseX, mouseY, delta);
this.editButton.x = x + 75;
this.editButton.y = y;
this.editButton.update();
if (focused) {
MutableText text = new LiteralText("> ").formatted(Formatting.WHITE);
text.append(this.editButton.getMessage().copy().formatted(Formatting.YELLOW));
this.editButton.setMessage(text.append(new LiteralText(" <").formatted(Formatting.WHITE)));
} else if (!this.binding.isNotBound() && InputManager.hasDuplicatedBindings(this.binding)) {
MutableText text = this.editButton.getMessage().copy();
this.editButton.setMessage(text.formatted(Formatting.RED));
} else if (this.binding.isNotBound()) {
MutableText text = this.editButton.getMessage().copy();
this.editButton.setMessage(text.formatted(Formatting.GOLD));
}
this.editButton.render(matrices, mouseX, mouseY, delta);
}*/
/*public boolean mouseClicked(double mouseX, double mouseY, int button) {
boolean focused = gui.focusedBinding == this.binding;
if (this.editButton.mouseClicked(mouseX, mouseY, button))
return true;
else
return focused ? this.unboundButton.mouseClicked(mouseX, mouseY, button) : this.resetButton.mouseClicked(mouseX, mouseY, button);
}
public boolean mouseReleased(double mouseX, double mouseY, int button) {
return this.editButton.mouseReleased(mouseX, mouseY, button) || this.resetButton.mouseReleased(mouseX, mouseY, button)
|| this.unboundButton.mouseReleased(mouseX, mouseY, button);
}*/
/* Rendering */
@Override
protected void renderWidget(MatrixStack matrices, int mouseX, int mouseY, float delta) {
boolean focused = gui.focusedBinding == this.binding;
TextRenderer textRenderer = ControlsListWidget.this.client.textRenderer;
String bindingName = this.bindingName;
int height = this.getHeight();
//float textX = (float) (this.getX() + 70 - ControlsListWidget.this.maxTextLength);
int textY = this.getY() + height / 2;
textRenderer.draw(matrices, bindingName, this.getX(), (float) (textY - 9 / 2), 16777215);
this.resetButton.setVisible(!focused);
this.unbindButton.setVisible(focused);
this.resetButton.setActive(!this.binding.isDefault());
this.editButton.update();
if (focused) {
MutableText text = new LiteralText("> ").formatted(Formatting.WHITE);
text.append(this.editButton.getMessage().copy().formatted(Formatting.YELLOW));
this.editButton.setMessage(text.append(new LiteralText(" <").formatted(Formatting.WHITE)));
} else if (!this.binding.isNotBound() && InputManager.hasDuplicatedBindings(this.binding)) {
MutableText text = this.editButton.getMessage().copy();
this.editButton.setMessage(text.formatted(Formatting.RED));
} else if (this.binding.isNotBound()) {
MutableText text = this.editButton.getMessage().copy();
this.editButton.setMessage(text.formatted(Formatting.GOLD));
}
this.children.forEach(widget -> widget.render(matrices, mouseX, mouseY, delta));
}
}
public static class CategoryEntry extends Entry {
private final SpruceSeparatorWidget separatorWidget;
protected CategoryEntry(ControlsListWidget parent, ButtonCategory category) {
super(parent);
this.separatorWidget = new SpruceSeparatorWidget(Position.of(this, 0, 0), this.getWidth(), new LiteralText(category.getTranslatedName())) {
@Override
public int getWidth() {
return CategoryEntry.this.getWidth();
}
};
}
public SpruceSeparatorWidget getSeparatorWidget() {
return this.separatorWidget;
}
@Override
public int getHeight() {
return this.separatorWidget.getHeight() + 4;
}
/* Navigation */
@Override
public boolean onNavigation(@NotNull NavigationDirection direction, boolean tab) {
return this.separatorWidget.onNavigation(direction, tab);
}
/* Rendering */
@Override
protected void renderWidget(MatrixStack matrices, int mouseX, int mouseY, float delta) {
this.separatorWidget.render(matrices, mouseX, mouseY, delta);
}
@Override
public String toString() {
return "SpruceTabbedWidget$SeparatorEntry{" +
"position=" + this.getPosition() +
", width=" + this.getWidth() +
", height=" + this.getHeight() +
'}';
}
}
@Environment(EnvType.CLIENT)
public abstract static class Entry extends SpruceEntryListWidget.Entry {
protected final ControlsListWidget parent;
protected Entry(ControlsListWidget parent) {
this.parent = parent;
this.position.setRelativeX(this.parent.getRowLeft());
}
@Override
public int getWidth() {
return this.parent.getRowWidth();
}
}
}

View File

@@ -9,7 +9,7 @@
package me.lambdaurora.lambdacontrols.client.mixin;
import me.lambdaurora.lambdacontrols.client.gui.ControllerControlsScreen;
import me.lambdaurora.lambdacontrols.client.gui.widget.ControllerControlsWidget;
import me.lambdaurora.lambdacontrols.client.gui.LambdaControlsSettingsScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen;
@@ -37,9 +37,9 @@ public class ControlsOptionsScreenMixin extends GameOptionsScreen
@Redirect(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/options/ControlsOptionsScreen;addButton(Lnet/minecraft/client/gui/widget/AbstractButtonWidget;)Lnet/minecraft/client/gui/widget/AbstractButtonWidget;", ordinal = 1))
private AbstractButtonWidget onInit(ControlsOptionsScreen screen, AbstractButtonWidget btn)
{
if (this.parent instanceof ControllerControlsScreen)
/*if (this.parent instanceof ControllerControlsWidget)
return this.addButton(btn);
else
else*/
return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).getHeight(), new TranslatableText("menu.options"),
b -> this.client.openScreen(new LambdaControlsSettingsScreen(this, true))));
}

View File

@@ -105,13 +105,13 @@ public abstract class MinecraftClientMixin
this.lambdacontrols_lastTargetSide = side;
}
// Removed front placing sprinting as way too cheaty.
/* else if (this.player.isSprinting()) {
else if (this.player.isSprinting()) {
hitResult = LambdaControlsClient.get().reacharound.getLastReacharoundResult();
if (hitResult != null) {
if (cooldown > 0)
this.itemUseCooldown = 0;
}
} */
}
this.lambdacontrols_lastPos = this.player.getPos();
}

View File

@@ -11,7 +11,8 @@ package me.lambdaurora.lambdacontrols.client.mixin;
import me.lambdaurora.lambdacontrols.ControlsMode;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.gui.ControllerControlsScreen;
import me.lambdaurora.lambdacontrols.client.gui.LambdaControlsSettingsScreen;
import me.lambdaurora.lambdacontrols.client.gui.widget.ControllerControlsWidget;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.options.OptionsScreen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
@@ -37,7 +38,7 @@ public class OptionsScreenMixin extends Screen
{
if (LambdaControlsClient.get().config.getControlsMode() == ControlsMode.CONTROLLER) {
return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).getHeight(), btn.getMessage(),
b -> this.client.openScreen(new ControllerControlsScreen(this, false))));
b -> this.client.openScreen(new LambdaControlsSettingsScreen(this, false))));
} else {
return this.addButton(btn);
}

View File

@@ -99,6 +99,8 @@
"lambdacontrols.menu.reacharound.vertical": "Vertical Reacharound",
"lambdacontrols.menu.reload_controller_mappings": "Reload Controller Mappings",
"lambdacontrols.menu.rotation_speed": "Rotation Speed",
"lambdacontrols.menu.separator.controller": "Controller",
"lambdacontrols.menu.separator.general": "General",
"lambdacontrols.menu.title": "LambdaControls - Settings",
"lambdacontrols.menu.title.controller": "Controller Options",
"lambdacontrols.menu.title.controller_controls": "Controller Controls",