WIP broken stuff.

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

View File

@@ -1,12 +1,20 @@
plugins { plugins {
id 'java-library' id 'java-library'
id 'maven-publish' id 'maven-publish'
id 'com.github.johnrengelman.shadow' version '6.1.0'
id 'org.cadixdev.licenser' version '0.5.0'
} }
allprojects { allprojects {
apply plugin: 'java-library'
group = project.maven_group group = project.maven_group
version = project.mod_version 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 { repositories {
mavenLocal() mavenLocal()
mavenCentral() mavenCentral()
@@ -16,8 +24,21 @@ allprojects {
dependencies { dependencies {
} }
tasks.withType(JavaCompile) { java {
options.encoding = "UTF-8" 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 { 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()
}
}*/

View File

@@ -1,14 +1,24 @@
import net.fabricmc.loom.task.RemapJarTask
plugins { plugins {
id 'fabric-loom' version '0.4-SNAPSHOT' id 'fabric-loom' version '0.6-SNAPSHOT'
id 'java-library' id 'java-library'
id 'maven-publish' 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" 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 { minecraft {
} }
@@ -20,6 +30,7 @@ repositories {
repositories { repositories {
maven { url = "https://jitpack.io" } maven { url = "https://jitpack.io" }
} }
maven { url "https://maven.shedaniel.me/" }
} }
configurations { configurations {
@@ -43,17 +54,12 @@ dependencies {
// Compatibility mods // Compatibility mods
modImplementation "com.github.joaoh1:okzoomer:e13183c59b" modImplementation "com.github.joaoh1:okzoomer:e13183c59b"
modImplementation "me.shedaniel:RoughlyEnoughItems:5.2.3" modImplementation "me.shedaniel:RoughlyEnoughItems:5.10.184"
api project(":core") api project(":core")
shadowInternal project(":core") shadow project(":core")
shadow("org.aperlambda:lambdajcommon:1.8.1") { shadow "com.electronwill.night-config:core:3.6.3"
// Minecraft already has all that google crap. shadow "com.electronwill.night-config:toml:3.6.3"
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"
} }
processResources { processResources {
@@ -80,23 +86,21 @@ jar {
from "../LICENSE" from "../LICENSE"
} }
task shadowJar(type: Jar) { license {
archiveClassifier.set("dev") header file('HEADER')
include '**/*.java'
}
from sourceSets.main.output shadowJar {
dependsOn jar
configurations = [project.configurations.shadow]
archiveClassifier.set('dev')
from { exclude 'META-INF/maven/**'
configurations.shadowInternal.filter { exclude 'com/google/**'
it.getName().contains("lambdacontrols") exclude 'javax/**'
}.collect { exclude 'org/**'
it.isDirectory() ? it : zipTree(it) relocate 'com.electronwill.nightconfig', 'dev.lambdaurora.lambdacontrols.shadow.nightconfig'
}
}
from {
configurations.shadow.collect {
it.isDirectory() ? it : zipTree(it)
}
}
} }
task shadowRemapJar(type: RemapJarTask) { task shadowRemapJar(type: RemapJarTask) {

View File

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

View File

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

View File

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

View File

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

View File

@@ -35,77 +35,76 @@ import static org.lwjgl.glfw.GLFW.*;
* @version 1.5.0 * @version 1.5.0
* @since 1.0.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 MOVEMENT_CATEGORY;
public static final ButtonCategory GAMEPLAY_CATEGORY; public static final ButtonCategory GAMEPLAY_CATEGORY;
public static final ButtonCategory INVENTORY_CATEGORY; public static final ButtonCategory INVENTORY_CATEGORY;
public static final ButtonCategory MULTIPLAYER_CATEGORY; public static final ButtonCategory MULTIPLAYER_CATEGORY;
public static final ButtonCategory MISC_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 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 BACK = new Builder("back").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, false))
.action(MovementHandler.HANDLER).onlyInGame().register(); .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 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 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 FORWARD = new Builder("forward").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_Y, true))
.action(MovementHandler.HANDLER).onlyInGame().register(); .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(); .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(); .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 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 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 LEFT = new Builder("left").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, false))
.action(MovementHandler.HANDLER).onlyInGame().register(); .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 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 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 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 RIGHT = new Builder("right").buttons(axisAsButton(GLFW_GAMEPAD_AXIS_LEFT_X, true))
.action(MovementHandler.HANDLER).onlyInGame().register(); .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(); .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(); .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(); .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(); .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(); .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 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 SNEAK = new Builder("sneak").buttons(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB)
.actions(InputHandlers::handleToggleSneak).onlyInGame().cooldown().register(); .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 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 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 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(); .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(); .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 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[] button;
private int[] defaultButton; private final int[] defaultButton;
private String key; private final String key;
private KeyBinding mcKeyBinding = null; private final Text text;
private KeyBinding mcKeyBinding = null;
protected PairPredicate<MinecraftClient, ButtonBinding> filter; protected PairPredicate<MinecraftClient, ButtonBinding> filter;
private List<PressAction> actions = new ArrayList<>(Collections.singletonList(PressAction.DEFAULT_ACTION)); private List<PressAction> actions = new ArrayList<>(Collections.singletonList(PressAction.DEFAULT_ACTION));
private boolean hasCooldown; private boolean hasCooldown;
private int cooldown = 0; private int cooldown = 0;
boolean pressed = false; boolean pressed = false;
public ButtonBinding(@NotNull String key, int[] defaultButton, @NotNull List<PressAction> actions, PairPredicate<MinecraftClient, ButtonBinding> filter, boolean hasCooldown) public ButtonBinding(@NotNull String key, int[] defaultButton, @NotNull List<PressAction> actions, PairPredicate<MinecraftClient, ButtonBinding> filter, boolean hasCooldown) {
{
this.setButton(this.defaultButton = defaultButton); this.setButton(this.defaultButton = defaultButton);
this.key = key; this.key = key;
this.text = new TranslatableText(this.key);
this.filter = filter; this.filter = filter;
this.actions.addAll(actions); this.actions.addAll(actions);
this.hasCooldown = hasCooldown; 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); this(key, defaultButton, Collections.emptyList(), Predicates.pairAlwaysTrue(), hasCooldown);
} }
@@ -114,8 +113,7 @@ public class ButtonBinding implements Nameable
* *
* @return The bound button. * @return The bound button.
*/ */
public int[] getButton() public int[] getButton() {
{
return this.button; return this.button;
} }
@@ -124,8 +122,7 @@ public class ButtonBinding implements Nameable
* *
* @param button The bound button. * @param button The bound button.
*/ */
public void setButton(int[] button) public void setButton(int[] button) {
{
this.button = button; this.button = button;
if (InputManager.hasBinding(this)) if (InputManager.hasBinding(this))
@@ -138,8 +135,7 @@ public class ButtonBinding implements Nameable
* @param button The button to check. * @param button The button to check.
* @return True if the bound button is the specified button, else false. * @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); return InputManager.areButtonsEquivalent(button, this.button);
} }
@@ -148,8 +144,7 @@ public class ButtonBinding implements Nameable
* *
* @return True if the button is down, else false. * @return True if the button is down, else false.
*/ */
public boolean isButtonDown() public boolean isButtonDown() {
{
return this.pressed; return this.pressed;
} }
@@ -158,8 +153,7 @@ public class ButtonBinding implements Nameable
* *
* @return True if this button binding is bound, else false. * @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; return this.button.length == 0 || this.button[0] == -1;
} }
@@ -168,8 +162,7 @@ public class ButtonBinding implements Nameable
* *
* @return The default button. * @return The default button.
*/ */
public int[] getDefaultButton() public int[] getDefaultButton() {
{
return this.defaultButton; return this.defaultButton;
} }
@@ -178,8 +171,7 @@ public class ButtonBinding implements Nameable
* *
* @return True if the assigned button is the default button, else false. * @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); 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. * @return The button code.
*/ */
public @NotNull public @NotNull
String getButtonCode() String getButtonCode() {
{
return Arrays.stream(this.button) return Arrays.stream(this.button)
.mapToObj(btn -> Integer.valueOf(btn).toString()) .mapToObj(btn -> Integer.valueOf(btn).toString())
.collect(Collectors.joining("+")); .collect(Collectors.joining("+"));
@@ -201,8 +192,7 @@ public class ButtonBinding implements Nameable
* *
* @param keyBinding The optional key binding. * @param keyBinding The optional key binding.
*/ */
public void setKeyBinding(@Nullable KeyBinding keyBinding) public void setKeyBinding(@Nullable KeyBinding keyBinding) {
{
this.mcKeyBinding = keyBinding; this.mcKeyBinding = keyBinding;
} }
@@ -212,16 +202,14 @@ public class ButtonBinding implements Nameable
* @param client The client instance. * @param client The client instance.
* @return True if the button binding is available, else false. * @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); return this.filter.test(client, this);
} }
/** /**
* Updates the button binding cooldown. * Updates the button binding cooldown.
*/ */
public void update() public void update() {
{
if (this.hasCooldown && this.cooldown > 0) if (this.hasCooldown && this.cooldown > 0)
this.cooldown--; this.cooldown--;
} }
@@ -230,10 +218,9 @@ public class ButtonBinding implements Nameable
* Handles the button binding. * Handles the button binding.
* *
* @param client The client instance. * @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) if (state == ButtonState.REPEAT && this.hasCooldown && this.cooldown != 0)
return; return;
if (this.hasCooldown && state.isPressed()) { if (this.hasCooldown && state.isPressed()) {
@@ -247,8 +234,7 @@ public class ButtonBinding implements Nameable
} }
@Override @Override
public @NotNull String getName() public @NotNull String getName() {
{
return this.key; return this.key;
} }
@@ -257,24 +243,25 @@ public class ButtonBinding implements Nameable
* *
* @return The translation key. * @return The translation key.
*/ */
public @NotNull String getTranslationKey() public @NotNull String getTranslationKey() {
{
return "lambdacontrols.action." + this.getName(); return "lambdacontrols.action." + this.getName();
} }
public @NotNull Text getText() {
return this.text;
}
/** /**
* Returns the key binding equivalent of this button binding. * Returns the key binding equivalent of this button binding.
* *
* @return The key binding equivalent. * @return The key binding equivalent.
*/ */
public @NotNull Optional<KeyBinding> asKeyBinding() public @NotNull Optional<KeyBinding> asKeyBinding() {
{
return Optional.ofNullable(this.mcKeyBinding); return Optional.ofNullable(this.mcKeyBinding);
} }
@Override @Override
public String toString() public String toString() {
{
return "ButtonBinding{id=\"" + this.key + "\"," return "ButtonBinding{id=\"" + this.key + "\","
+ "hasCooldown=" + this.hasCooldown + "hasCooldown=" + this.hasCooldown
+ "}"; + "}";
@@ -283,12 +270,11 @@ public class ButtonBinding implements Nameable
/** /**
* Returns the specified axis as a button. * 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. * @param positive True if the axis part is positive, else false.
* @return The axis as a button. * @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; return positive ? 100 + axis : 200 + axis;
} }
@@ -298,8 +284,7 @@ public class ButtonBinding implements Nameable
* @param button The button. * @param button The button.
* @return True if the button is an axis, else false. * @return True if the button is an axis, else false.
*/ */
public static boolean isAxis(int button) public static boolean isAxis(int button) {
{
button %= 500; button %= 500;
return button >= 100; return button >= 100;
} }
@@ -310,13 +295,11 @@ public class ButtonBinding implements Nameable
* @param button The raw button code. * @param button The raw button code.
* @return The second Joycon's button code. * @return The second Joycon's button code.
*/ */
public static int controller2Button(int button) public static int controller2Button(int button) {
{
return 500 + button; return 500 + button;
} }
public static void init(@NotNull GameOptions options) public static void init(@NotNull GameOptions options) {
{
ATTACK.mcKeyBinding = options.keyAttack; ATTACK.mcKeyBinding = options.keyAttack;
BACK.mcKeyBinding = options.keyBack; BACK.mcKeyBinding = options.keyBack;
CHAT.mcKeyBinding = options.keyChat; CHAT.mcKeyBinding = options.keyChat;
@@ -343,8 +326,7 @@ public class ButtonBinding implements Nameable
* @param button The button. * @param button The button.
* @return The localized name of 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) { switch (button % 500) {
case -1: case -1:
return new TranslatableText("key.keyboard.unknown"); return new TranslatableText("key.keyboard.unknown");
@@ -440,8 +422,7 @@ public class ButtonBinding implements Nameable
* @return The builder instance * @return The builder instance
* @since 1.5.0 * @since 1.5.0
*/ */
public static Builder builder(@NotNull Identifier identifier) public static Builder builder(@NotNull Identifier identifier) {
{
return new Builder(identifier); return new Builder(identifier);
} }
@@ -452,8 +433,7 @@ public class ButtonBinding implements Nameable
* @return The builder instance. * @return The builder instance.
* @since 1.5.0 * @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); return new Builder(identifier);
} }
@@ -465,34 +445,30 @@ public class ButtonBinding implements Nameable
* @version 1.5.0 * @version 1.5.0
* @since 1.1.0 * @since 1.1.0
*/ */
public static class Builder public static class Builder {
{ private final String key;
private final String key; private int[] buttons = new int[0];
private int[] buttons = new int[0]; private List<PressAction> actions = new ArrayList<>();
private List<PressAction> actions = new ArrayList<>(); private PairPredicate<MinecraftClient, ButtonBinding> filter = Predicates.pairAlwaysTrue();
private PairPredicate<MinecraftClient, ButtonBinding> filter = Predicates.pairAlwaysTrue(); private boolean cooldown = false;
private boolean cooldown = false; private ButtonCategory category = null;
private ButtonCategory category = null; private KeyBinding mcBinding = null;
private KeyBinding mcBinding = null;
/** /**
* This constructor shouldn't be used for other mods. * This constructor shouldn't be used for other mods.
* *
* @param key The key with format {@code "<namespace>.<name>"}. * @param key The key with format {@code "<namespace>.<name>"}.
*/ */
public Builder(@NotNull String key) public Builder(@NotNull String key) {
{
this.key = key; this.key = key;
this.unbound(); this.unbound();
} }
public Builder(@NotNull Identifier identifier) public Builder(@NotNull Identifier identifier) {
{
this(identifier.getNamespace() + "." + identifier.getName()); 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())); this(new Identifier(identifier.toString()));
} }
@@ -502,8 +478,7 @@ public class ButtonBinding implements Nameable
* @param buttons The default buttons. * @param buttons The default buttons.
* @return The builder instance. * @return The builder instance.
*/ */
public Builder buttons(int... buttons) public Builder buttons(int... buttons) {
{
this.buttons = buttons; this.buttons = buttons;
return this; return this;
} }
@@ -513,8 +488,7 @@ public class ButtonBinding implements Nameable
* *
* @return The builder instance. * @return The builder instance.
*/ */
public Builder unbound() public Builder unbound() {
{
return this.buttons(-1); return this.buttons(-1);
} }
@@ -524,8 +498,7 @@ public class ButtonBinding implements Nameable
* @param actions The actions to add. * @param actions The actions to add.
* @return The builder instance. * @return The builder instance.
*/ */
public Builder actions(@NotNull PressAction... actions) public Builder actions(@NotNull PressAction... actions) {
{
this.actions.addAll(Arrays.asList(actions)); this.actions.addAll(Arrays.asList(actions));
return this; return this;
} }
@@ -536,8 +509,7 @@ public class ButtonBinding implements Nameable
* @param action The action to add. * @param action The action to add.
* @return The builder instance. * @return The builder instance.
*/ */
public Builder action(@NotNull PressAction action) public Builder action(@NotNull PressAction action) {
{
this.actions.add(action); this.actions.add(action);
return this; return this;
} }
@@ -548,8 +520,7 @@ public class ButtonBinding implements Nameable
* @param filter The filter. * @param filter The filter.
* @return The builder instance. * @return The builder instance.
*/ */
public Builder filter(@NotNull PairPredicate<MinecraftClient, ButtonBinding> filter) public Builder filter(@NotNull PairPredicate<MinecraftClient, ButtonBinding> filter) {
{
this.filter = filter; this.filter = filter;
return this; return this;
} }
@@ -561,8 +532,7 @@ public class ButtonBinding implements Nameable
* @see #filter(PairPredicate) * @see #filter(PairPredicate)
* @see InputHandlers#inGame(MinecraftClient, ButtonBinding) * @see InputHandlers#inGame(MinecraftClient, ButtonBinding)
*/ */
public Builder onlyInGame() public Builder onlyInGame() {
{
return this.filter(InputHandlers::inGame); return this.filter(InputHandlers::inGame);
} }
@@ -573,8 +543,7 @@ public class ButtonBinding implements Nameable
* @see #filter(PairPredicate) * @see #filter(PairPredicate)
* @see InputHandlers#inInventory(MinecraftClient, ButtonBinding) * @see InputHandlers#inInventory(MinecraftClient, ButtonBinding)
*/ */
public Builder onlyInInventory() public Builder onlyInInventory() {
{
return this.filter(InputHandlers::inInventory); 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. * @param cooldown True if the {@link ButtonBinding} has a cooldown, else false.
* @return The builder instance. * @return The builder instance.
*/ */
public Builder cooldown(boolean cooldown) public Builder cooldown(boolean cooldown) {
{
this.cooldown = cooldown; this.cooldown = cooldown;
return this; return this;
} }
@@ -596,8 +564,7 @@ public class ButtonBinding implements Nameable
* @return The builder instance. * @return The builder instance.
* @since 1.5.0 * @since 1.5.0
*/ */
public Builder cooldown() public Builder cooldown() {
{
return this.cooldown(true); return this.cooldown(true);
} }
@@ -607,8 +574,7 @@ public class ButtonBinding implements Nameable
* @param category The category. * @param category The category.
* @return The builder instance. * @return The builder instance.
*/ */
public Builder category(@Nullable ButtonCategory category) public Builder category(@Nullable ButtonCategory category) {
{
this.category = category; this.category = category;
return this; return this;
} }
@@ -619,8 +585,7 @@ public class ButtonBinding implements Nameable
* @param binding The keybinding to link. * @param binding The keybinding to link.
* @return The builder instance. * @return The builder instance.
*/ */
public Builder linkKeybind(@Nullable KeyBinding binding) public Builder linkKeybind(@Nullable KeyBinding binding) {
{
this.mcBinding = binding; this.mcBinding = binding;
return this; return this;
} }
@@ -630,8 +595,7 @@ public class ButtonBinding implements Nameable
* *
* @return The built {@link ButtonBinding}. * @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); ButtonBinding binding = new ButtonBinding(this.key, this.buttons, this.actions, this.filter, this.cooldown);
if (this.category != null) if (this.category != null)
this.category.registerBinding(binding); this.category.registerBinding(binding);
@@ -646,8 +610,7 @@ public class ButtonBinding implements Nameable
* @return The built {@link ButtonBinding}. * @return The built {@link ButtonBinding}.
* @see #build() * @see #build()
*/ */
public ButtonBinding register() public ButtonBinding register() {
{
return InputManager.registerBinding(this.build()); return InputManager.registerBinding(this.build());
} }
} }

View File

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

View File

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

View File

@@ -13,19 +13,19 @@ import me.lambdaurora.lambdacontrols.ControlsMode;
import me.lambdaurora.lambdacontrols.LambdaControls; import me.lambdaurora.lambdacontrols.LambdaControls;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient; import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.controller.Controller; import me.lambdaurora.lambdacontrols.client.controller.Controller;
import me.lambdaurora.spruceui.SpruceButtonWidget; import me.lambdaurora.lambdacontrols.client.gui.widget.ControllerControlsWidget;
import me.lambdaurora.spruceui.SpruceLabelWidget; import me.lambdaurora.spruceui.Position;
import me.lambdaurora.spruceui.SpruceTexts; import me.lambdaurora.spruceui.SpruceTexts;
import me.lambdaurora.spruceui.Tooltip;
import me.lambdaurora.spruceui.option.*; 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.fabricmc.fabric.api.network.ClientSidePacketRegistry;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.Screen; 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.gui.widget.ButtonWidget;
import net.minecraft.client.options.Option;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
@@ -38,50 +38,57 @@ import org.lwjgl.glfw.GLFW;
/** /**
* Represents the LambdaControls settings screen. * Represents the LambdaControls settings screen.
*/ */
public class LambdaControlsSettingsScreen extends Screen public class LambdaControlsSettingsScreen extends SpruceScreen {
{ public static final String GAMEPAD_TOOL_URL = "https://generalarcade.com/gamepadtool/";
public static final String GAMEPAD_TOOL_URL = "https://generalarcade.com/gamepadtool/"; final LambdaControlsClient mod;
final LambdaControlsClient mod; private final Screen parent;
private final Screen parent;
private final boolean hideControls;
// General options // General options
private final Option autoSwitchModeOption; private final SpruceOption inputModeOption;
private final Option rotationSpeedOption; private final SpruceOption autoSwitchModeOption;
private final Option mouseSpeedOption; private final SpruceOption rotationSpeedOption;
private final Option resetOption; private final SpruceOption mouseSpeedOption;
private final SpruceOption resetOption;
// Gameplay options // Gameplay options
private final Option autoJumpOption; private final SpruceOption autoJumpOption;
private final Option fastBlockPlacingOption; private final SpruceOption fastBlockPlacingOption;
private final Option frontBlockPlacingOption; private final SpruceOption frontBlockPlacingOption;
private final Option verticalReacharoundOption; private final SpruceOption verticalReacharoundOption;
private final Option flyDriftingOption; private final SpruceOption flyDriftingOption;
private final Option flyVerticalDriftingOption; private final SpruceOption flyVerticalDriftingOption;
// Controller options // Controller options
private final Option controllerOption; private final SpruceOption controllerOption;
private final Option secondControllerOption; private final SpruceOption secondControllerOption;
private final Option controllerTypeOption; private final SpruceOption controllerTypeOption;
private final Option deadZoneOption; private final SpruceOption deadZoneOption;
private final Option invertsRightXAxis; private final SpruceOption invertsRightXAxis;
private final Option invertsRightYAxis; private final SpruceOption invertsRightYAxis;
private final Option unfocusedInputOption; private final SpruceOption unfocusedInputOption;
private final Option virtualMouseOption; private final SpruceOption virtualMouseOption;
private final Option virtualMouseSkinOption; private final SpruceOption virtualMouseSkinOption;
// Hud options // Hud options
private final Option hudEnableOption; private final SpruceOption hudEnableOption;
private final Option hudSideOption; private final SpruceOption hudSideOption;
private final MutableText controllerMappingsUrlText = new LiteralText("(") private final MutableText controllerMappingsUrlText = new LiteralText("(")
.append(new LiteralText(GAMEPAD_TOOL_URL).formatted(Formatting.GOLD)) .append(new LiteralText(GAMEPAD_TOOL_URL).formatted(Formatting.GOLD))
.append("),"); .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")); super(new TranslatableText("lambdacontrols.title.settings"));
this.mod = LambdaControlsClient.get(); this.mod = LambdaControlsClient.get();
this.parent = parent; this.parent = parent;
this.hideControls = hideControls;
// General options // 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.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.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, 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()))), }, option -> option.getDisplayText(new LiteralText(String.valueOf(option.get()))),
new TranslatableText("lambdacontrols.tooltip.mouse_speed")); new TranslatableText("lambdacontrols.tooltip.mouse_speed"));
this.resetOption = new SpruceResetOption(btn -> { this.resetOption = SpruceSimpleActionOption.reset(btn -> {
this.mod.config.reset(); this.mod.config.reset();
MinecraftClient client = MinecraftClient.getInstance(); MinecraftClient client = MinecraftClient.getInstance();
this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
}); });
// Gameplay options // Gameplay options
this.autoJumpOption = SpruceBooleanOption.fromVanilla("options.autoJump", Option.AUTO_JUMP, null, true); this.autoJumpOption = new SpruceCheckboxBooleanOption("options.autoJump",
this.fastBlockPlacingOption = new SpruceBooleanOption("lambdacontrols.menu.fast_block_placing", this.mod.config::hasFastBlockPlacing, () -> 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.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.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.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.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); this.mod.config::setFlyVerticalDrifting, new TranslatableText("lambdacontrols.tooltip.fly_drifting_vertical"), true);
// Controller options // Controller options
this.controllerOption = new SpruceCyclingOption("lambdacontrols.menu.controller", amount -> { this.controllerOption = new SpruceCyclingOption("lambdacontrols.menu.controller", amount -> {
@@ -191,30 +201,26 @@ public class LambdaControlsSettingsScreen extends Screen
} }
@Override @Override
public void removed() public void removed() {
{
this.mod.config.save(); this.mod.config.save();
super.removed(); super.removed();
} }
@Override @Override
public void onClose() public void onClose() {
{
this.mod.config.save(); this.mod.config.save();
super.onClose(); super.onClose();
} }
private int getTextHeight() private int getTextHeight() {
{
return (5 + this.textRenderer.fontHeight) * 3 + 5; return (5 + this.textRenderer.fontHeight) * 3 + 5;
} }
@Override @Override
protected void init() protected void init() {
{
super.init(); super.init();
int buttonHeight = 20; /*int buttonHeight = 20;
SpruceButtonWidget controlsModeBtn = new SpruceButtonWidget(this.width / 2 - 155, 18, this.hideControls ? 310 : 150, buttonHeight, 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())), new TranslatableText("lambdacontrols.menu.controls_mode").append(": ").append(new TranslatableText(this.mod.config.getControlsMode().getTranslationKey())),
btn -> { btn -> {
ControlsMode next = this.mod.config.getControlsMode().next(); ControlsMode next = this.mod.config.getControlsMode().next();
@@ -227,7 +233,7 @@ public class LambdaControlsSettingsScreen extends Screen
} }
}); });
controlsModeBtn.setTooltip(new TranslatableText("lambdacontrols.tooltip.controls_mode")); controlsModeBtn.setTooltip(new TranslatableText("lambdacontrols.tooltip.controls_mode"));
this.addButton(controlsModeBtn); this.addChild(controlsModeBtn);
if (!this.hideControls) if (!this.hideControls)
this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, 18, 150, buttonHeight, new TranslatableText("options.controls"), this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, 18, 150, buttonHeight, new TranslatableText("options.controls"),
btn -> { btn -> {
@@ -237,18 +243,18 @@ public class LambdaControlsSettingsScreen extends Screen
this.client.openScreen(new ControlsOptionsScreen(this, this.client.options)); 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 // General options
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.general", true, null)); this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.general", true, null));
this.list.addOptionEntry(this.rotationSpeedOption, this.mouseSpeedOption); this.list.addOptionEntry(this.rotationSpeedOption, this.mouseSpeedOption);
this.list.addSingleOptionEntry(this.autoSwitchModeOption); this.list.addSingleOptionEntry(this.autoSwitchModeOption);
// Gameplay options // Gameplay options
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.gameplay", true, null)); 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.addOptionEntry(this.frontBlockPlacingOption, this.verticalReacharoundOption);
this.list.addSingleOptionEntry(this.flyDriftingOption); this.list.addSingleOptionEntry(this.flyDriftingOption);
this.list.addSingleOptionEntry(this.flyVerticalDriftingOption); 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 // Controller options
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.controller", true, null)); this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.controller", true, null));
this.list.addSingleOptionEntry(this.controllerOption); 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.invertsRightXAxis, this.invertsRightYAxis);
this.list.addOptionEntry(this.unfocusedInputOption, this.virtualMouseOption); this.list.addOptionEntry(this.unfocusedInputOption, this.virtualMouseOption);
this.list.addSingleOptionEntry(this.virtualMouseSkinOption); this.list.addSingleOptionEntry(this.virtualMouseSkinOption);
this.list.addSingleOptionEntry(new ReloadControllerMappingsOption()); this.list.addSingleOptionEntry(ReloadControllerMappingsOption.newOption(null));
this.list.addSingleOptionEntry(new SpruceSimpleActionOption("lambdacontrols.menu.mappings.open_input_str", this.list.addSingleOptionEntry(SpruceSimpleActionOption.of("lambdacontrols.menu.mappings.open_input_str",
btn -> this.client.openScreen(new MappingsStringInputScreen(this)))); btn -> this.client.openScreen(new MappingsStringInputScreen(this))));
// HUD options // HUD options
this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.hud", true, null)); this.list.addSingleOptionEntry(new SpruceSeparatorOption("lambdacontrols.menu.title.hud", true, null));
this.list.addOptionEntry(this.hudEnableOption, this.hudSideOption); 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); label -> Util.getOperatingSystem().open(GAMEPAD_TOOL_URL), true);
this.gamepadToolUrlLabel.setTooltip(new TranslatableText("chat.link.open")); 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.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, buttonHeight, SpruceTexts.GUI_DONE, this.addButton(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, SpruceTexts.GUI_DONE,
btn -> this.client.openScreen(this.parent))); 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 @Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) public void renderTitle(MatrixStack matrices, int mouseX, int mouseY, float delta) {
{
this.renderBackground(matrices);
this.list.render(matrices, mouseX, mouseY, delta);
super.render(matrices, mouseX, mouseY, delta);
drawCenteredString(matrices, this.textRenderer, I18n.translate("lambdacontrols.menu.title"), this.width / 2, 8, 16777215); 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); 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); drawCenteredString(matrices, this.textRenderer, I18n.translate("lambdacontrols.controller.mappings.3", Formatting.GREEN.toString(), Formatting.RESET.toString()), this.width / 2, this.height - 29 - (5 + this.textRenderer.fontHeight), 10526880);
Tooltip.renderAll(matrices);
} }
} }

View File

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

View File

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

View File

@@ -12,7 +12,6 @@ package me.lambdaurora.lambdacontrols.client.gui;
import me.lambdaurora.lambdacontrols.client.HudSide; import me.lambdaurora.lambdacontrols.client.HudSide;
import me.lambdaurora.lambdacontrols.client.LambdaControlsClient; import me.lambdaurora.lambdacontrols.client.LambdaControlsClient;
import me.lambdaurora.lambdacontrols.client.util.KeyBindingAccessor; 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.ChatScreen;
import net.minecraft.client.gui.screen.GameMenuScreen; import net.minecraft.client.gui.screen.GameMenuScreen;
import net.minecraft.client.gui.screen.Screen; 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.client.gui.widget.TexturedButtonWidget;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.util.Arm; import net.minecraft.util.Arm;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos; 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 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 LambdaControlsClient mod;
private SpruceTexturedButtonWidget jumpButton; private SpruceTexturedButtonWidget jumpButton;
private SpruceTexturedButtonWidget flyButton; private SpruceTexturedButtonWidget flyButton;
@@ -85,7 +89,7 @@ public class TouchscreenOverlay extends Screen
* Updates the forward button ticks cooldown. * Updates the forward button ticks cooldown.
* *
* @param state The button state. * @param state The button state.
*/ *
private void updateForwardButtonsState(boolean state) private void updateForwardButtonsState(boolean state)
{ {
if (state) if (state)
@@ -96,7 +100,7 @@ public class TouchscreenOverlay extends Screen
/** /**
* Updates the jump buttons. * Updates the jump buttons.
*/ *
private void updateJumpButtons() private void updateJumpButtons()
{ {
if (this.client == null) if (this.client == null)
@@ -125,7 +129,7 @@ public class TouchscreenOverlay extends Screen
* *
* @param btn The pressed button. * @param btn The pressed button.
* @param state The state of the jump button. * @param state The state of the jump button.
*/ *
private void handleJump(ButtonWidget btn, boolean state) private void handleJump(ButtonWidget btn, boolean state)
{ {
((KeyBindingAccessor) this.client.options.keyJump).lambdacontrols_handlePressState(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); 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); return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
} }*/
} }

View File

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

View File

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

View File

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

View File

@@ -9,7 +9,7 @@
package me.lambdaurora.lambdacontrols.client.mixin; 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 me.lambdaurora.lambdacontrols.client.gui.LambdaControlsSettingsScreen;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.options.ControlsOptionsScreen; 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)) @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) private AbstractButtonWidget onInit(ControlsOptionsScreen screen, AbstractButtonWidget btn)
{ {
if (this.parent instanceof ControllerControlsScreen) /*if (this.parent instanceof ControllerControlsWidget)
return this.addButton(btn); return this.addButton(btn);
else else*/
return this.addButton(new ButtonWidget(btn.x, btn.y, btn.getWidth(), ((AbstractButtonWidgetAccessor) btn).getHeight(), new TranslatableText("menu.options"), 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)))); b -> this.client.openScreen(new LambdaControlsSettingsScreen(this, true))));
} }

View File

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

View File

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

View File

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

View File

@@ -3,17 +3,17 @@ org.gradle.jvmargs=-Xmx1G
# Fabric Properties # Fabric Properties
# check these on https://fabricmc.net/use # check these on https://fabricmc.net/use
minecraft_version=1.16.2 minecraft_version=1.16.5
yarn_mappings=1.16.2+build.25 yarn_mappings=1.16.5+build.5
loader_version=0.9.1+build.205 loader_version=0.11.3
# Mod Properties # Mod Properties
mod_version = 1.5.0 mod_version = 1.6.0
maven_group = me.lambdaurora.lambdacontrols maven_group = me.lambdaurora.lambdacontrols
archives_base_name = lambdacontrols archives_base_name = lambdacontrols
# Dependencies # Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api # 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 fabric_version=0.32.0+1.16
spruceui_version=1.6.4 spruceui_version=2.0.4-1.16
modmenu_version=1.14.6+build.31 modmenu_version=1.14.6+build.31

Binary file not shown.

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists 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 zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

2
gradlew vendored
View File

@@ -130,7 +130,7 @@ fi
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"` JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath

21
gradlew.bat vendored
View File

@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init if "%ERRORLEVEL%" == "0" goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 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_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -64,21 +64,6 @@ echo location of your Java installation.
goto fail 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 :execute
@rem Setup the command line @rem Setup the command line
@@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @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 :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell

View File

@@ -1,6 +1,5 @@
pluginManagement { pluginManagement {
repositories { repositories {
jcenter()
maven { maven {
name = 'Fabric' name = 'Fabric'
url = 'https://maven.fabricmc.net/' url = 'https://maven.fabricmc.net/'