From 0532913d696804a054d8cfe4b6968b52843157e9 Mon Sep 17 00:00:00 2001 From: LambdAurora Date: Mon, 15 Mar 2021 17:20:16 +0100 Subject: [PATCH] WIP broken stuff. --- build.gradle | 46 +-- fabric/build.gradle | 60 +-- .../lambdacontrols/LambdaControls.java | 6 +- .../client/LambdaControlsClient.java | 5 +- .../client/LambdaControlsConfig.java | 257 +++++------- .../lambdacontrols/client/LambdaInput.java | 222 ++++++----- .../client/controller/ButtonBinding.java | 219 +++++----- .../client/gui/ControllerControlsScreen.java | 88 ----- .../client/gui/ControlsListWidget.java | 214 ---------- .../gui/LambdaControlsSettingsScreen.java | 218 ++++++---- ...en.java => MappingsStringInputWidget.java} | 70 ++-- .../gui/ReloadControllerMappingsOption.java | 15 +- .../client/gui/TouchscreenOverlay.java | 16 +- .../{ => widget}/ControllerButtonWidget.java | 32 +- .../gui/widget/ControllerControlsWidget.java | 63 +++ .../client/gui/widget/ControlsListWidget.java | 373 ++++++++++++++++++ .../mixin/ControlsOptionsScreenMixin.java | 6 +- .../client/mixin/MinecraftClientMixin.java | 4 +- .../client/mixin/OptionsScreenMixin.java | 5 +- .../assets/lambdacontrols/lang/en_us.json | 2 + gradle.properties | 12 +- gradle/wrapper/gradle-wrapper.jar | Bin 58910 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 2 +- gradlew.bat | 21 +- settings.gradle | 1 - 26 files changed, 1023 insertions(+), 936 deletions(-) delete mode 100644 fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerControlsScreen.java delete mode 100644 fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControlsListWidget.java rename fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/{MappingsStringInputScreen.java => MappingsStringInputWidget.java} (60%) rename fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/{ => widget}/ControllerButtonWidget.java (59%) create mode 100644 fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/widget/ControllerControlsWidget.java create mode 100644 fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/widget/ControlsListWidget.java diff --git a/build.gradle b/build.gradle index 3a61131..271be4d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,20 @@ plugins { id 'java-library' id 'maven-publish' + id 'com.github.johnrengelman.shadow' version '6.1.0' + id 'org.cadixdev.licenser' version '0.5.0' } allprojects { + apply plugin: 'java-library' + group = project.maven_group version = project.mod_version + // This field defines the Java version your mod target. + // The Minecraft launcher currently installs Java 8 for users, so your mod probably wants to target Java 8 too. + def targetJavaVersion = 8 + repositories { mavenLocal() mavenCentral() @@ -16,8 +24,21 @@ allprojects { dependencies { } - tasks.withType(JavaCompile) { - options.encoding = "UTF-8" + java { + sourceCompatibility = JavaVersion.toVersion(targetJavaVersion) + targetCompatibility = JavaVersion.toVersion(targetJavaVersion) + + withSourcesJar() + } + + tasks.withType(JavaCompile).configureEach { + it.options.encoding = "UTF-8" + + if (JavaVersion.current().isJava9Compatible()) { + if (JavaVersion.current().isJava9Compatible()) { + it.options.release = targetJavaVersion + } + } } publishing { @@ -34,24 +55,3 @@ allprojects { } } } - -/* -// configure the maven publication -publishing { - publications { - mavenJava(MavenPublication) { - // add all the jars that should be included when publishing to maven - artifact(remapJar) { - builtBy remapJar - } - artifact(sourcesJar) { - builtBy remapSourcesJar - } - } - } - - // select the repositories you want to publish to - repositories { - mavenLocal() - } -}*/ diff --git a/fabric/build.gradle b/fabric/build.gradle index e48dc38..963c07d 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -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) { diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java index 2ee910f..f20c45f 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/LambdaControls.java @@ -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); } /** diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsClient.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsClient.java index 372670a..3f5a360 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsClient.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsClient.java @@ -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()); diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java index d619d15..b988a06 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaControlsConfig.java @@ -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 getSecondController() - { + public @NotNull Optional 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: diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaInput.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaInput.java index fdcd041..7d5d22c 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaInput.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/LambdaInput.java @@ -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 BUTTON_COOLDOWNS = new HashMap<>(); - private final LambdaControlsConfig config; +public class LambdaInput { + private static final Map 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 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; diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java index 9dbd021..9a87c31 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/controller/ButtonBinding.java @@ -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 filter; - private List actions = new ArrayList<>(Collections.singletonList(PressAction.DEFAULT_ACTION)); - private boolean hasCooldown; - private int cooldown = 0; + private List 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 actions, PairPredicate filter, boolean hasCooldown) - { + public ButtonBinding(@NotNull String key, int[] defaultButton, @NotNull List actions, PairPredicate 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 asKeyBinding() - { + public @NotNull Optional 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 actions = new ArrayList<>(); - private PairPredicate 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 actions = new ArrayList<>(); + private PairPredicate 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 "."}. */ - 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 filter) - { + public Builder filter(@NotNull PairPredicate 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()); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerControlsScreen.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerControlsScreen.java deleted file mode 100644 index 79d8be0..0000000 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerControlsScreen.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright © 2020 LambdAurora - * - * 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 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); - } -} diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControlsListWidget.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControlsListWidget.java deleted file mode 100644 index 390b3bf..0000000 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControlsListWidget.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright © 2020 LambdAurora - * - * 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 -{ - 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 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 children() - { - return Collections.emptyList(); - } - } - - @Environment(EnvType.CLIENT) - public abstract static class Entry extends ElementListWidget.Entry - { - } -} diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsSettingsScreen.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsSettingsScreen.java index a60092d..6cbc5ed 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsSettingsScreen.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/LambdaControlsSettingsScreen.java @@ -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); } } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/MappingsStringInputScreen.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/MappingsStringInputWidget.java similarity index 60% rename from fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/MappingsStringInputScreen.java rename to fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/MappingsStringInputWidget.java index 1db8456..24d2e1a 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/MappingsStringInputScreen.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/MappingsStringInputWidget.java @@ -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); - } + }*/ } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ReloadControllerMappingsOption.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ReloadControllerMappingsOption.java index bbbf662..7380ce0 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ReloadControllerMappingsOption.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ReloadControllerMappingsOption.java @@ -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 before) - { - super(KEY, btn -> { + public static SpruceSimpleActionOption newOption(@Nullable Consumer before) { + return SpruceSimpleActionOption.of(KEY, btn -> { MinecraftClient client = MinecraftClient.getInstance(); if (before != null) before.accept(btn); diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/TouchscreenOverlay.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/TouchscreenOverlay.java index 941a4ac..3f288ee 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/TouchscreenOverlay.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/TouchscreenOverlay.java @@ -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); - } + }*/ } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerButtonWidget.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/widget/ControllerButtonWidget.java similarity index 59% rename from fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerButtonWidget.java rename to fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/widget/ControllerButtonWidget.java index a1ecb4b..f5a6f2a 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/ControllerButtonWidget.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/widget/ControllerButtonWidget.java @@ -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 size = LambdaControlsRenderer.drawButton(matrices, x, y, this.binding, MinecraftClient.getInstance()); + Pair size = LambdaControlsRenderer.drawButton(matrices, x, this.getY(), this.binding, MinecraftClient.getInstance()); this.iconWidth = size.key; return size.value; } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/widget/ControllerControlsWidget.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/widget/ControllerControlsWidget.java new file mode 100644 index 0000000..38c111c --- /dev/null +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/widget/ControllerControlsWidget.java @@ -0,0 +1,63 @@ +/* + * Copyright © 2020 LambdAurora + * + * 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 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); + } +} diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/widget/ControlsListWidget.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/widget/ControlsListWidget.java new file mode 100644 index 0000000..d1dc6d7 --- /dev/null +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/gui/widget/ControlsListWidget.java @@ -0,0 +1,373 @@ +/* + * Copyright © 2020 LambdAurora + * + * 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 { + 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 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 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 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 getNarrationMessage() { + return Optional.of(new TranslatableText("lambdacontrols.narrator.unbound", bindingName)); + } + }; + this.children.add(this.unbindButton); + } + + public List 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 hoveredElement(double mouseX, double mouseY) { + Iterator 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 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(); + } + } +} diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ControlsOptionsScreenMixin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ControlsOptionsScreenMixin.java index 75f9e75..cefeded 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ControlsOptionsScreenMixin.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/ControlsOptionsScreenMixin.java @@ -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)))); } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/MinecraftClientMixin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/MinecraftClientMixin.java index c2312ac..daf8766 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/MinecraftClientMixin.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/MinecraftClientMixin.java @@ -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(); } diff --git a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/OptionsScreenMixin.java b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/OptionsScreenMixin.java index a33ace9..dc97a70 100644 --- a/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/OptionsScreenMixin.java +++ b/fabric/src/main/java/me/lambdaurora/lambdacontrols/client/mixin/OptionsScreenMixin.java @@ -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); } diff --git a/fabric/src/main/resources/assets/lambdacontrols/lang/en_us.json b/fabric/src/main/resources/assets/lambdacontrols/lang/en_us.json index 1b48dd6..07dbd65 100644 --- a/fabric/src/main/resources/assets/lambdacontrols/lang/en_us.json +++ b/fabric/src/main/resources/assets/lambdacontrols/lang/en_us.json @@ -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", diff --git a/gradle.properties b/gradle.properties index 64d09a3..5ef23db 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,17 +3,17 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use -minecraft_version=1.16.2 -yarn_mappings=1.16.2+build.25 -loader_version=0.9.1+build.205 +minecraft_version=1.16.5 +yarn_mappings=1.16.5+build.5 +loader_version=0.11.3 # Mod Properties -mod_version = 1.5.0 +mod_version = 1.6.0 maven_group = me.lambdaurora.lambdacontrols archives_base_name = lambdacontrols # Dependencies # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api -fabric_version=0.17.2+build.396-1.16 -spruceui_version=1.6.4 +fabric_version=0.32.0+1.16 +spruceui_version=2.0.4-1.16 modmenu_version=1.14.6+build.31 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 62d4c053550b91381bbd28b1afc82d634bf73a8a..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f 100644 GIT binary patch delta 6656 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 Yte!%o?r4GTrVtxD61Ym!|5fq-1K$0e!T1w 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 622ab64..2a56324 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index fbd7c51..4f906e0 100644 --- a/gradlew +++ b/gradlew @@ -130,7 +130,7 @@ fi if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath diff --git a/gradlew.bat b/gradlew.bat index a9f778a..ac1b06f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -54,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -64,21 +64,6 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line @@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/settings.gradle b/settings.gradle index 136fc93..55cf86a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,5 @@ pluginManagement { repositories { - jcenter() maven { name = 'Fabric' url = 'https://maven.fabricmc.net/'