forked from Clones/Controlify
sodium compat
This commit is contained in:
@ -28,6 +28,7 @@ repositories {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
maven("https://jitpack.io")
|
maven("https://jitpack.io")
|
||||||
|
maven("https://maven.flashyreese.me/snapshots")
|
||||||
}
|
}
|
||||||
|
|
||||||
loom {
|
loom {
|
||||||
@ -52,11 +53,16 @@ dependencies {
|
|||||||
annotationProcessor(libs.mixin.extras)
|
annotationProcessor(libs.mixin.extras)
|
||||||
include(libs.mixin.extras)
|
include(libs.mixin.extras)
|
||||||
|
|
||||||
|
// used to identify controller connections
|
||||||
implementation(libs.hid4java)
|
implementation(libs.hid4java)
|
||||||
include(libs.hid4java)
|
include(libs.hid4java)
|
||||||
|
|
||||||
|
// used to parse hiddb.json5
|
||||||
implementation(libs.quilt.json5)
|
implementation(libs.quilt.json5)
|
||||||
include(libs.quilt.json5)
|
include(libs.quilt.json5)
|
||||||
|
|
||||||
|
// sodium compat
|
||||||
|
modImplementation(libs.sodium)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
@ -16,6 +16,7 @@ yet_another_config_lib = "2.3.0+beta.2+update.1.19.4-SNAPSHOT"
|
|||||||
mod_menu = "6.1.0-alpha.1"
|
mod_menu = "6.1.0-alpha.1"
|
||||||
hid4java = "0.7.0"
|
hid4java = "0.7.0"
|
||||||
quilt_json5 = "1.0.3"
|
quilt_json5 = "1.0.3"
|
||||||
|
sodium = "0.4.10+build.209"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" }
|
minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" }
|
||||||
@ -27,6 +28,7 @@ yet_another_config_lib = { module = "dev.isxander:yet-another-config-lib", versi
|
|||||||
mod_menu = { module = "com.terraformersmc:modmenu", version.ref = "mod_menu" }
|
mod_menu = { module = "com.terraformersmc:modmenu", version.ref = "mod_menu" }
|
||||||
hid4java = { module = "org.hid4java:hid4java", version.ref = "hid4java" }
|
hid4java = { module = "org.hid4java:hid4java", version.ref = "hid4java" }
|
||||||
quilt_json5 = { module = "org.quiltmc:quilt-json5", version.ref = "quilt_json5" }
|
quilt_json5 = { module = "org.quiltmc:quilt-json5", version.ref = "quilt_json5" }
|
||||||
|
sodium = { module = "me.jellysquid.mods:sodium-fabric", version.ref = "sodium" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
loom = { id = "fabric-loom", version.ref = "loom" }
|
loom = { id = "fabric-loom", version.ref = "loom" }
|
||||||
|
@ -38,7 +38,7 @@ public class ControllerBindings<T extends ControllerState> {
|
|||||||
VMOUSE_ESCAPE, VMOUSE_SHIFT,
|
VMOUSE_ESCAPE, VMOUSE_SHIFT,
|
||||||
VMOUSE_TOGGLE,
|
VMOUSE_TOGGLE,
|
||||||
GUI_NAVI_UP, GUI_NAVI_DOWN, GUI_NAVI_LEFT, GUI_NAVI_RIGHT,
|
GUI_NAVI_UP, GUI_NAVI_DOWN, GUI_NAVI_LEFT, GUI_NAVI_RIGHT,
|
||||||
YACL_CYCLE_OPT_FORWARD, YACL_CYCLE_OPT_BACKWARD;
|
CYCLE_OPT_FORWARD, CYCLE_OPT_BACKWARD;
|
||||||
|
|
||||||
private final Map<ResourceLocation, ControllerBinding<T>> registry = new LinkedHashMap<>();
|
private final Map<ResourceLocation, ControllerBinding<T>> registry = new LinkedHashMap<>();
|
||||||
|
|
||||||
@ -92,8 +92,8 @@ public class ControllerBindings<T extends ControllerState> {
|
|||||||
register(GUI_NAVI_DOWN = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_BACKWARD, new ResourceLocation("controlify", "gui_navi_down")));
|
register(GUI_NAVI_DOWN = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_BACKWARD, new ResourceLocation("controlify", "gui_navi_down")));
|
||||||
register(GUI_NAVI_LEFT = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_LEFT, new ResourceLocation("controlify", "gui_navi_left")));
|
register(GUI_NAVI_LEFT = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_LEFT, new ResourceLocation("controlify", "gui_navi_left")));
|
||||||
register(GUI_NAVI_RIGHT = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_RIGHT, new ResourceLocation("controlify", "gui_navi_right")));
|
register(GUI_NAVI_RIGHT = new ControllerBinding<>(controller, GamepadBinds.LEFT_STICK_RIGHT, new ResourceLocation("controlify", "gui_navi_right")));
|
||||||
register(YACL_CYCLE_OPT_FORWARD = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_RIGHT, new ResourceLocation("controlify", "yacl_cycle_opt_forward")));
|
register(CYCLE_OPT_FORWARD = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_RIGHT, new ResourceLocation("controlify", "cycle_opt_forward")));
|
||||||
register(YACL_CYCLE_OPT_BACKWARD = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_LEFT, new ResourceLocation("controlify", "yacl_cycle_opt_backward")));
|
register(CYCLE_OPT_BACKWARD = new ControllerBinding<>(controller, GamepadBinds.RIGHT_STICK_LEFT, new ResourceLocation("controlify", "cycle_opt_backward")));
|
||||||
|
|
||||||
ControlifyEvents.CONTROLLER_BIND_REGISTRY.invoker().onRegisterControllerBinds(this, controller);
|
ControlifyEvents.CONTROLLER_BIND_REGISTRY.invoker().onRegisterControllerBinds(this, controller);
|
||||||
|
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package dev.isxander.controlify.compatibility.sodium;
|
||||||
|
|
||||||
|
import dev.isxander.controlify.controller.Controller;
|
||||||
|
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ScreenProcessor;
|
||||||
|
|
||||||
|
public class ButtonProcessor implements ComponentProcessor {
|
||||||
|
private final Runnable action;
|
||||||
|
|
||||||
|
public ButtonProcessor(Runnable action) {
|
||||||
|
this.action = action != null ? action : () -> {};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean overrideControllerButtons(ScreenProcessor<?> screen, Controller<?, ?> controller) {
|
||||||
|
if (controller.bindings().GUI_PRESS.justPressed()) {
|
||||||
|
action.run();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package dev.isxander.controlify.compatibility.sodium;
|
||||||
|
|
||||||
|
import dev.isxander.controlify.controller.Controller;
|
||||||
|
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ScreenProcessor;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class CycleControlProcessor implements ComponentProcessor {
|
||||||
|
private final Consumer<Boolean> cycleMethod;
|
||||||
|
|
||||||
|
public CycleControlProcessor(Consumer<Boolean> cycleMethod) {
|
||||||
|
this.cycleMethod = cycleMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean overrideControllerButtons(ScreenProcessor<?> screen, Controller<?, ?> controller) {
|
||||||
|
if (controller.bindings().CYCLE_OPT_FORWARD.justPressed() || controller.bindings().GUI_PRESS.justPressed()) {
|
||||||
|
cycleMethod.accept(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (controller.bindings().CYCLE_OPT_BACKWARD.justPressed()) {
|
||||||
|
cycleMethod.accept(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package dev.isxander.controlify.compatibility.sodium;
|
||||||
|
|
||||||
|
import dev.isxander.controlify.controller.Controller;
|
||||||
|
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ScreenProcessor;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class SliderControlProcessor implements ComponentProcessor {
|
||||||
|
private final Consumer<Boolean> cycleMethod;
|
||||||
|
private int ticksSinceIncrement = 0;
|
||||||
|
private boolean prevLeft, prevRight;
|
||||||
|
|
||||||
|
public SliderControlProcessor(Consumer<Boolean> cycleMethod) {
|
||||||
|
this.cycleMethod = cycleMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean overrideControllerButtons(ScreenProcessor<?> screen, Controller<?, ?> controller) {
|
||||||
|
ticksSinceIncrement++;
|
||||||
|
|
||||||
|
var left = controller.bindings().CYCLE_OPT_BACKWARD.held();
|
||||||
|
var right = controller.bindings().CYCLE_OPT_FORWARD.held();
|
||||||
|
|
||||||
|
if (left || right) {
|
||||||
|
if (ticksSinceIncrement > controller.config().screenRepeatNavigationDelay || left != prevLeft || right != prevRight) {
|
||||||
|
cycleMethod.accept(left);
|
||||||
|
ticksSinceIncrement = 0;
|
||||||
|
prevLeft = left;
|
||||||
|
prevRight = right;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.prevLeft = false;
|
||||||
|
this.prevRight = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package dev.isxander.controlify.compatibility.sodium;
|
||||||
|
|
||||||
|
import dev.isxander.controlify.controller.Controller;
|
||||||
|
import dev.isxander.controlify.mixins.compat.sodium.SodiumOptionsGUIAccessor;
|
||||||
|
import dev.isxander.controlify.screenop.ScreenProcessor;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.SodiumOptionsGUI;
|
||||||
|
|
||||||
|
public class SodiumGuiScreenProcessor extends ScreenProcessor<SodiumOptionsGUI> {
|
||||||
|
public SodiumGuiScreenProcessor(SodiumOptionsGUI screen) {
|
||||||
|
super(screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleComponentNavigation(Controller<?, ?> controller) {
|
||||||
|
super.handleComponentNavigation(controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleButtons(Controller<?, ?> controller) {
|
||||||
|
var accessor = (SodiumOptionsGUIAccessor) screen;
|
||||||
|
|
||||||
|
if (controller.bindings().GUI_NEXT_TAB.justPressed()) {
|
||||||
|
var currentIndex = accessor.getPages().indexOf(accessor.getCurrentPage());
|
||||||
|
var nextIndex = (currentIndex + 1) % accessor.getPages().size();
|
||||||
|
screen.setPage(accessor.getPages().get(nextIndex));
|
||||||
|
}
|
||||||
|
if (controller.bindings().GUI_PREV_TAB.justPressed()) {
|
||||||
|
var currentIndex = accessor.getPages().indexOf(accessor.getCurrentPage());
|
||||||
|
var nextIndex = (currentIndex - 1 + accessor.getPages().size()) % accessor.getPages().size();
|
||||||
|
screen.setPage(accessor.getPages().get(nextIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
super.handleButtons(controller);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package dev.isxander.controlify.compatibility.sodium;
|
||||||
|
|
||||||
|
import dev.isxander.controlify.controller.Controller;
|
||||||
|
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ScreenProcessor;
|
||||||
|
|
||||||
|
public class TickBoxControlProcessor implements ComponentProcessor {
|
||||||
|
private final Runnable toggleMethod;
|
||||||
|
|
||||||
|
public TickBoxControlProcessor(Runnable toggleMethod) {
|
||||||
|
this.toggleMethod = toggleMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean overrideControllerButtons(ScreenProcessor<?> screen, Controller<?, ?> controller) {
|
||||||
|
if (controller.bindings().GUI_PRESS.justPressed()) {
|
||||||
|
toggleMethod.run();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (controller.bindings().CYCLE_OPT_FORWARD.justPressed() || controller.bindings().CYCLE_OPT_BACKWARD.justPressed()) {
|
||||||
|
toggleMethod.run();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package dev.isxander.controlify.screenop.compat.yacl;
|
package dev.isxander.controlify.compatibility.yacl;
|
||||||
|
|
||||||
import dev.isxander.controlify.controller.Controller;
|
import dev.isxander.controlify.controller.Controller;
|
||||||
import dev.isxander.controlify.screenop.ScreenProcessor;
|
import dev.isxander.controlify.screenop.ScreenProcessor;
|
@ -1,4 +1,4 @@
|
|||||||
package dev.isxander.controlify.screenop.compat.yacl;
|
package dev.isxander.controlify.compatibility.yacl;
|
||||||
|
|
||||||
import dev.isxander.controlify.controller.Controller;
|
import dev.isxander.controlify.controller.Controller;
|
||||||
import dev.isxander.controlify.screenop.ScreenProcessor;
|
import dev.isxander.controlify.screenop.ScreenProcessor;
|
||||||
@ -18,8 +18,8 @@ public class SliderControllerElementComponentProcessor implements ComponentProce
|
|||||||
public boolean overrideControllerButtons(ScreenProcessor<?> screen, Controller<?, ?> controller) {
|
public boolean overrideControllerButtons(ScreenProcessor<?> screen, Controller<?, ?> controller) {
|
||||||
ticksSinceIncrement++;
|
ticksSinceIncrement++;
|
||||||
|
|
||||||
var left = controller.bindings().GUI_NAVI_LEFT.held();
|
var left = controller.bindings().CYCLE_OPT_BACKWARD.held();
|
||||||
var right = controller.bindings().GUI_NAVI_RIGHT.held();
|
var right = controller.bindings().CYCLE_OPT_FORWARD.held();
|
||||||
|
|
||||||
if (left || right) {
|
if (left || right) {
|
||||||
if (ticksSinceIncrement > controller.config().screenRepeatNavigationDelay || left != prevLeft || right != prevRight) {
|
if (ticksSinceIncrement > controller.config().screenRepeatNavigationDelay || left != prevLeft || right != prevRight) {
|
@ -1,4 +1,4 @@
|
|||||||
package dev.isxander.controlify.screenop.compat.yacl;
|
package dev.isxander.controlify.compatibility.yacl;
|
||||||
|
|
||||||
import dev.isxander.controlify.controller.Controller;
|
import dev.isxander.controlify.controller.Controller;
|
||||||
import dev.isxander.controlify.screenop.ScreenProcessor;
|
import dev.isxander.controlify.screenop.ScreenProcessor;
|
@ -0,0 +1,24 @@
|
|||||||
|
package dev.isxander.controlify.mixins.compat.sodium;
|
||||||
|
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.widgets.AbstractWidget;
|
||||||
|
import net.minecraft.client.gui.ComponentPath;
|
||||||
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||||
|
import net.minecraft.client.gui.navigation.FocusNavigationEvent;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
@Mixin(AbstractWidget.class)
|
||||||
|
public abstract class AbstractWidgetMixin implements GuiEventListener {
|
||||||
|
@Shadow protected abstract void drawRect(double x1, double y1, double x2, double y2, int color);
|
||||||
|
|
||||||
|
@Shadow protected abstract void playClickSound();
|
||||||
|
|
||||||
|
@Shadow public abstract boolean isFocused();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public ComponentPath nextFocusPath(FocusNavigationEvent focusNavigationEvent) {
|
||||||
|
return !this.isFocused() ? ComponentPath.leaf(this) : null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package dev.isxander.controlify.mixins.compat.sodium;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.options.Option;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.options.control.ControlElement;
|
||||||
|
import me.jellysquid.mods.sodium.client.util.Dim2i;
|
||||||
|
import net.minecraft.client.gui.ComponentPath;
|
||||||
|
import net.minecraft.client.gui.navigation.FocusNavigationEvent;
|
||||||
|
import net.minecraft.client.gui.navigation.ScreenRectangle;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(ControlElement.class)
|
||||||
|
public abstract class ControlElementMixin<T> extends AbstractWidgetMixin {
|
||||||
|
|
||||||
|
@Shadow @Final protected Option<T> option;
|
||||||
|
@Shadow @Final protected Dim2i dim;
|
||||||
|
|
||||||
|
@Inject(method = "render", at = @At("TAIL"))
|
||||||
|
private void renderFocusRect(PoseStack matrixStack, int mouseX, int mouseY, float delta, CallbackInfo ci) {
|
||||||
|
if (this.isFocused()) {
|
||||||
|
int x1 = this.dim.x();
|
||||||
|
int y1 = this.dim.y();
|
||||||
|
int x2 = this.dim.getLimitX();
|
||||||
|
int y2 = this.dim.getLimitY();
|
||||||
|
|
||||||
|
this.drawRect(x1, y1, x2, y1 + 1, -1);
|
||||||
|
this.drawRect(x1, y2 - 1, x2, y2, -1);
|
||||||
|
this.drawRect(x1, y1, x1 + 1, y2, -1);
|
||||||
|
this.drawRect(x2 - 1, y1, x2, y2, -1);;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ModifyExpressionValue(method = "render", at = @At(value = "FIELD", target = "Lme/jellysquid/mods/sodium/client/gui/options/control/ControlElement;hovered:Z", opcode = Opcodes.GETFIELD, ordinal = 0))
|
||||||
|
private boolean shouldShortenName(boolean hovered) {
|
||||||
|
return hovered || this.isFocused();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable ComponentPath nextFocusPath(FocusNavigationEvent focusNavigationEvent) {
|
||||||
|
if (!this.option.isAvailable())
|
||||||
|
return null;
|
||||||
|
return super.nextFocusPath(focusNavigationEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ScreenRectangle getRectangle() {
|
||||||
|
return new ScreenRectangle(this.dim.x(), this.dim.y(), this.dim.width(), this.dim.height());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package dev.isxander.controlify.mixins.compat.sodium;
|
||||||
|
|
||||||
|
import dev.isxander.controlify.compatibility.sodium.CycleControlProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
||||||
|
import org.spongepowered.asm.mixin.*;
|
||||||
|
|
||||||
|
@Pseudo
|
||||||
|
@Mixin(targets = "me.jellysquid.mods.sodium.client.gui.options.control.CyclingControl$CyclingControlElement")
|
||||||
|
public abstract class CycleControlElementMixin<T extends Enum<T>> extends ControlElementMixin<T> implements ComponentProcessorProvider {
|
||||||
|
@Shadow private int currentIndex;
|
||||||
|
@Final @Shadow private T[] allowedValues;
|
||||||
|
|
||||||
|
@Unique private final ComponentProcessor controlify$componentProcessor
|
||||||
|
= new CycleControlProcessor(this::cycle);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ComponentProcessor componentProcessor() {
|
||||||
|
return controlify$componentProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cycle(boolean backwards) {
|
||||||
|
if (backwards) {
|
||||||
|
this.currentIndex = (this.currentIndex - 1 + this.allowedValues.length) % this.allowedValues.length;
|
||||||
|
} else {
|
||||||
|
this.currentIndex = (this.option.getValue().ordinal() + 1) % this.allowedValues.length;
|
||||||
|
}
|
||||||
|
this.option.setValue(this.allowedValues[this.currentIndex]);
|
||||||
|
this.playClickSound();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package dev.isxander.controlify.mixins.compat.sodium;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import dev.isxander.controlify.compatibility.sodium.ButtonProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.widgets.FlatButtonWidget;
|
||||||
|
import me.jellysquid.mods.sodium.client.util.Dim2i;
|
||||||
|
import net.minecraft.client.gui.ComponentPath;
|
||||||
|
import net.minecraft.client.gui.navigation.FocusNavigationEvent;
|
||||||
|
import net.minecraft.client.gui.navigation.ScreenRectangle;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(FlatButtonWidget.class)
|
||||||
|
public abstract class FlatButtonWidgetMixin extends AbstractWidgetMixin implements ComponentProcessorProvider {
|
||||||
|
@Shadow @Final private Dim2i dim;
|
||||||
|
@Shadow private boolean visible;
|
||||||
|
@Shadow private boolean enabled;
|
||||||
|
@Shadow @Final private Runnable action;
|
||||||
|
|
||||||
|
@Unique private final ComponentProcessor controlify$componentProcessor
|
||||||
|
= new ButtonProcessor(() -> action.run());
|
||||||
|
|
||||||
|
@Inject(method = "render", at = @At("TAIL"))
|
||||||
|
private void renderFocusRect(PoseStack matrixStack, int mouseX, int mouseY, float delta, CallbackInfo ci) {
|
||||||
|
if (this.enabled && this.isFocused()) {
|
||||||
|
int x1 = this.dim.x();
|
||||||
|
int y1 = this.dim.y();
|
||||||
|
int x2 = this.dim.getLimitX();
|
||||||
|
int y2 = this.dim.getLimitY();
|
||||||
|
|
||||||
|
this.drawRect(x1, y1, x2, y1 + 1, -1);
|
||||||
|
this.drawRect(x1, y2 - 1, x2, y2, -1);
|
||||||
|
this.drawRect(x1, y1, x1 + 1, y2, -1);
|
||||||
|
this.drawRect(x2 - 1, y1, x2, y2, -1);;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable ComponentPath nextFocusPath(FocusNavigationEvent focusNavigationEvent) {
|
||||||
|
if (!visible || !enabled)
|
||||||
|
return null;
|
||||||
|
return super.nextFocusPath(focusNavigationEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ScreenRectangle getRectangle() {
|
||||||
|
return new ScreenRectangle(this.dim.x(), this.dim.y(), this.dim.width(), this.dim.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ComponentProcessor componentProcessor() {
|
||||||
|
return controlify$componentProcessor;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package dev.isxander.controlify.mixins.compat.sodium;
|
||||||
|
|
||||||
|
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||||
|
import dev.isxander.controlify.compatibility.sodium.SliderControlProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
||||||
|
@Mixin(targets = "me.jellysquid.mods.sodium.client.gui.options.control.SliderControl$Button")
|
||||||
|
public abstract class SliderControlElementMixin extends ControlElementMixin<Integer> implements ComponentProcessorProvider {
|
||||||
|
@Shadow public abstract int getIntValue();
|
||||||
|
@Shadow @Final private int interval;
|
||||||
|
@Shadow protected abstract void setValue(double d);
|
||||||
|
@Shadow public abstract double getThumbPositionForValue(int value);
|
||||||
|
|
||||||
|
@Unique private final ComponentProcessor controlify$componentProcessor
|
||||||
|
= new SliderControlProcessor(this::incrementSlider);
|
||||||
|
|
||||||
|
@ModifyExpressionValue(method = "render", at = @At(value = "FIELD", target = "Lme/jellysquid/mods/sodium/client/gui/options/control/SliderControl$Button;hovered:Z", opcode = Opcodes.GETFIELD))
|
||||||
|
private boolean shouldRenderSlider(boolean hovered) {
|
||||||
|
return hovered || this.isFocused();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ComponentProcessor componentProcessor() {
|
||||||
|
return controlify$componentProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void incrementSlider(boolean reverse) {
|
||||||
|
int inc = reverse ? -1 : 1;
|
||||||
|
this.setValue(this.getThumbPositionForValue(this.getIntValue() + inc * this.interval));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package dev.isxander.controlify.mixins.compat.sodium;
|
||||||
|
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.SodiumOptionsGUI;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.options.OptionPage;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mixin(SodiumOptionsGUI.class)
|
||||||
|
public interface SodiumOptionsGUIAccessor {
|
||||||
|
@Accessor
|
||||||
|
List<OptionPage> getPages();
|
||||||
|
|
||||||
|
@Accessor
|
||||||
|
OptionPage getCurrentPage();
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package dev.isxander.controlify.mixins.compat.sodium;
|
||||||
|
|
||||||
|
import dev.isxander.controlify.compatibility.sodium.SodiumGuiScreenProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ScreenProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ScreenProcessorProvider;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.SodiumOptionsGUI;
|
||||||
|
import me.jellysquid.mods.sodium.client.gui.options.control.ControlElement;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mixin(value = SodiumOptionsGUI.class, remap = false)
|
||||||
|
public abstract class SodiumOptionsGUIMixin extends Screen implements ScreenProcessorProvider {
|
||||||
|
@Shadow @Final private List<ControlElement<?>> controls;
|
||||||
|
|
||||||
|
@Unique private final SodiumGuiScreenProcessor controlify$screenProcessor
|
||||||
|
= new SodiumGuiScreenProcessor((SodiumOptionsGUI) (Object) this);
|
||||||
|
|
||||||
|
protected SodiumOptionsGUIMixin(Component title) {
|
||||||
|
super(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "rebuildGUIOptions", at = @At("RETURN"))
|
||||||
|
private void focusFirstButton(CallbackInfo ci) {
|
||||||
|
this.setInitialFocus(controls.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScreenProcessor<?> screenProcessor() {
|
||||||
|
return controlify$screenProcessor;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package dev.isxander.controlify.mixins.compat.sodium;
|
||||||
|
|
||||||
|
import dev.isxander.controlify.compatibility.sodium.TickBoxControlProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||||
|
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Pseudo;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
|
||||||
|
@Pseudo
|
||||||
|
@Mixin(targets = "me.jellysquid.mods.sodium.client.gui.options.control.TickBoxControl$TickBoxControlElement")
|
||||||
|
public abstract class TickBoxControlElementMixin extends ControlElementMixin<Boolean> implements ComponentProcessorProvider {
|
||||||
|
@Unique private final ComponentProcessor controlify$componentProcessor
|
||||||
|
= new TickBoxControlProcessor(this::toggle);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ComponentProcessor componentProcessor() {
|
||||||
|
return controlify$componentProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggle() {
|
||||||
|
this.option.setValue(!this.option.getValue());
|
||||||
|
this.playClickSound();
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
package dev.isxander.controlify.mixins.feature.screenop.yacl;
|
package dev.isxander.controlify.mixins.compat.yacl;
|
||||||
|
|
||||||
import dev.isxander.controlify.screenop.ComponentProcessor;
|
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||||
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
||||||
import dev.isxander.controlify.screenop.compat.yacl.CyclingControllerElementComponentProcessor;
|
import dev.isxander.controlify.compatibility.yacl.CyclingControllerElementComponentProcessor;
|
||||||
import dev.isxander.yacl.gui.controllers.cycling.CyclingControllerElement;
|
import dev.isxander.yacl.gui.controllers.cycling.CyclingControllerElement;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
@ -1,8 +1,8 @@
|
|||||||
package dev.isxander.controlify.mixins.feature.screenop.yacl;
|
package dev.isxander.controlify.mixins.compat.yacl;
|
||||||
|
|
||||||
import dev.isxander.controlify.screenop.ComponentProcessor;
|
import dev.isxander.controlify.screenop.ComponentProcessor;
|
||||||
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
import dev.isxander.controlify.screenop.ComponentProcessorProvider;
|
||||||
import dev.isxander.controlify.screenop.compat.yacl.SliderControllerElementComponentProcessor;
|
import dev.isxander.controlify.compatibility.yacl.SliderControllerElementComponentProcessor;
|
||||||
import dev.isxander.yacl.gui.controllers.slider.SliderControllerElement;
|
import dev.isxander.yacl.gui.controllers.slider.SliderControllerElement;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
@ -1,8 +1,8 @@
|
|||||||
package dev.isxander.controlify.mixins.feature.screenop.yacl;
|
package dev.isxander.controlify.mixins.compat.yacl;
|
||||||
|
|
||||||
import dev.isxander.controlify.screenop.ScreenProcessor;
|
import dev.isxander.controlify.screenop.ScreenProcessor;
|
||||||
import dev.isxander.controlify.screenop.ScreenProcessorProvider;
|
import dev.isxander.controlify.screenop.ScreenProcessorProvider;
|
||||||
import dev.isxander.controlify.screenop.compat.yacl.YACLScreenProcessor;
|
import dev.isxander.controlify.compatibility.yacl.YACLScreenProcessor;
|
||||||
import dev.isxander.yacl.gui.YACLScreen;
|
import dev.isxander.yacl.gui.YACLScreen;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
@ -63,7 +63,6 @@ public class SliderComponentProcessor implements ComponentProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFocusGained(ScreenProcessor<?> screen, Controller<?, ?> controller) {
|
public void onFocusGained(ScreenProcessor<?> screen, Controller<?, ?> controller) {
|
||||||
System.out.println("navigated!");
|
|
||||||
this.canChangeValueSetter.accept(false);
|
this.canChangeValueSetter.accept(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,8 +115,8 @@
|
|||||||
"controlify.binding.controlify.gui_navi_up": "GUI Navi Up",
|
"controlify.binding.controlify.gui_navi_up": "GUI Navi Up",
|
||||||
"controlify.binding.controlify.gui_navi_left": "GUI Navi Left",
|
"controlify.binding.controlify.gui_navi_left": "GUI Navi Left",
|
||||||
"controlify.binding.controlify.gui_navi_right": "GUI Navi Right",
|
"controlify.binding.controlify.gui_navi_right": "GUI Navi Right",
|
||||||
"controlify.binding.controlify.yacl_cycle_opt_forward": "YACL Cycle Option Forward",
|
"controlify.binding.controlify.cycle_opt_forward": "Cycle Option Forward",
|
||||||
"controlify.binding.controlify.yacl_cycle_opt_backward": "YACL Cycle Option Backward",
|
"controlify.binding.controlify.cycle_opt_backward": "Cycle Option Backward",
|
||||||
|
|
||||||
"controlify.guide.inventory": "Open Inventory",
|
"controlify.guide.inventory": "Open Inventory",
|
||||||
"controlify.guide.swim_up": "Swim Up",
|
"controlify.guide.swim_up": "Swim Up",
|
||||||
|
@ -4,9 +4,17 @@
|
|||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
|
"compat.sodium.ControlElementMixin",
|
||||||
|
"compat.sodium.CycleControlElementMixin",
|
||||||
|
"compat.sodium.FlatButtonWidgetMixin",
|
||||||
|
"compat.sodium.SliderControlElementMixin",
|
||||||
|
"compat.sodium.TickBoxControlElementMixin",
|
||||||
"core.GLXMixin"
|
"core.GLXMixin"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
|
"compat.sodium.AbstractWidgetMixin",
|
||||||
|
"compat.sodium.SodiumOptionsGUIAccessor",
|
||||||
|
"compat.sodium.SodiumOptionsGUIMixin",
|
||||||
"core.ClientPacketListenerMixin",
|
"core.ClientPacketListenerMixin",
|
||||||
"core.KeyboardHandlerMixin",
|
"core.KeyboardHandlerMixin",
|
||||||
"core.MinecraftMixin",
|
"core.MinecraftMixin",
|
||||||
@ -32,9 +40,9 @@
|
|||||||
"feature.screenop.vanilla.SelectWorldScreenMixin",
|
"feature.screenop.vanilla.SelectWorldScreenMixin",
|
||||||
"feature.screenop.vanilla.ServerSelectionListEntryMixin",
|
"feature.screenop.vanilla.ServerSelectionListEntryMixin",
|
||||||
"feature.screenop.vanilla.WorldSelectionListEntryMixin",
|
"feature.screenop.vanilla.WorldSelectionListEntryMixin",
|
||||||
"feature.screenop.yacl.CyclingControllerElementMixin",
|
"compat.yacl.CyclingControllerElementMixin",
|
||||||
"feature.screenop.yacl.SliderControllerElementMixin",
|
"compat.yacl.SliderControllerElementMixin",
|
||||||
"feature.screenop.yacl.YACLScreenMixin",
|
"compat.yacl.YACLScreenMixin",
|
||||||
"feature.settingsbutton.ControlsScreenMixin",
|
"feature.settingsbutton.ControlsScreenMixin",
|
||||||
"feature.virtualmouse.GameRendererMixin",
|
"feature.virtualmouse.GameRendererMixin",
|
||||||
"feature.virtualmouse.InputConstantsMixin",
|
"feature.virtualmouse.InputConstantsMixin",
|
||||||
|
Reference in New Issue
Block a user