1
0
forked from Clones/Controlify
Files
Controlify/src/main/java/dev/isxander/controlify/gui/controllers/AbstractBindController.java

153 lines
5.7 KiB
Java

package dev.isxander.controlify.gui.controllers;
import dev.isxander.controlify.api.event.ControlifyEvents;
import dev.isxander.controlify.bindings.EmptyBind;
import dev.isxander.controlify.bindings.IBind;
import dev.isxander.controlify.controller.ControllerState;
import dev.isxander.controlify.screenop.ComponentProcessor;
import dev.isxander.controlify.screenop.ScreenProcessor;
import dev.isxander.yacl3.api.Controller;
import dev.isxander.yacl3.api.Option;
import dev.isxander.yacl3.api.utils.Dimension;
import dev.isxander.yacl3.gui.YACLScreen;
import dev.isxander.yacl3.gui.controllers.ControllerWidget;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import org.lwjgl.glfw.GLFW;
import java.util.Optional;
public abstract class AbstractBindController<T extends ControllerState> implements Controller<IBind<T>> {
private final Option<IBind<T>> option;
public final dev.isxander.controlify.controller.Controller<T, ?> controller;
private boolean conflicting;
public AbstractBindController(Option<IBind<T>> option, dev.isxander.controlify.controller.Controller<T, ?> controller) {
this.option = option;
this.controller = controller;
}
@Override
public Option<IBind<T>> option() {
return this.option;
}
@Override
public Component formatValue() {
return Component.empty();
}
public void setConflicting(boolean conflicting) {
this.conflicting = conflicting;
}
public boolean getConflicting() {
return this.conflicting;
}
@Override
public abstract AbstractBindControllerElement<T> provideWidget(YACLScreen yaclScreen, Dimension<Integer> dimension);
public abstract static class AbstractBindControllerElement<T extends ControllerState> extends ControllerWidget<AbstractBindController<T>> implements ComponentProcessor, ControlifyEvents.ControllerStateUpdate {
private boolean awaitingControllerInput = false;
private boolean justTookInput = false;
private final Component awaitingText = Component.translatable("controlify.gui.bind_input_awaiting").withStyle(ChatFormatting.ITALIC);
public AbstractBindControllerElement(AbstractBindController<T> control, YACLScreen screen, Dimension<Integer> dim) {
super(control, screen, dim);
}
@Override
protected void drawValueText(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
if (awaitingControllerInput) {
graphics.drawString(textRenderer, awaitingText, getDimension().xLimit() - textRenderer.width(awaitingText) - getXPadding(), (int)(getDimension().centerY() - textRenderer.lineHeight / 2f), 0xFFFFFF, true);
} else {
var bind = control.option().pendingValue();
bind.draw(graphics, getDimension().xLimit() - bind.drawSize().width(), getDimension().centerY());
}
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (isFocused() && keyCode == GLFW.GLFW_KEY_ENTER && !awaitingControllerInput) {
awaitingControllerInput = true;
ControllerBindHandler.setBindListener(this);
return true;
}
return false;
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (getDimension().isPointInside((int)mouseX, (int)mouseY)) {
awaitingControllerInput = true;
ControllerBindHandler.setBindListener(this);
return true;
}
return false;
}
@Override
public boolean overrideControllerButtons(ScreenProcessor<?> screen, dev.isxander.controlify.controller.Controller<?, ?> controller) {
if (controller != control.controller) return true;
if (!justTookInput && !awaitingControllerInput) {
if (controller.bindings().GUI_PRESS.justPressed()) {
ControllerBindHandler.setBindListener(this);
return awaitingControllerInput = true;
}
}
if (justTookInput) {
justTookInput = false;
return true;
}
return false;
}
@Override
public void onControllerStateUpdate(dev.isxander.controlify.controller.Controller<?, ?> controller) {
if (controller != control.controller) return;
if (!awaitingControllerInput) return;
Optional<IBind<T>> pressedBind = getPressedBind();
if (pressedBind.isPresent()) {
control.option().requestSet(pressedBind.get());
awaitingControllerInput = false;
justTookInput = true;
ControllerBindHandler.clearBindListener();
}
}
@Override
public boolean overrideControllerNavigation(ScreenProcessor<?> screen, dev.isxander.controlify.controller.Controller<?, ?> controller) {
return awaitingControllerInput || justTookInput;
}
@Override
protected int getHoveredControlWidth() {
return getUnhoveredControlWidth();
}
@Override
protected int getUnhoveredControlWidth() {
if (awaitingControllerInput)
return textRenderer.width(awaitingText);
return control.option().pendingValue().drawSize().width();
}
@Override
protected int getValueColor() {
return control.conflicting ? 0xFF5555 : super.getValueColor();
}
public abstract Optional<IBind<T>> getPressedBind();
}
}