mirror of
https://github.com/TeamMidnightDust/MidnightControls.git
synced 2025-12-14 07:35:10 +01:00
MidnightControls 0.1.0 (Beta)
Changes from LambdaControls: - Support for Steam Deck and Dualsense - Support for L4, L5, R4, R5 buttons - Updated Libraries - New Logo and Name - Lots of Bugfixes - MidnightConfig backend
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of midnightcontrols.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.gui;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.Controller;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.option.SpruceOption;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
|
||||
import dev.lambdaurora.spruceui.widget.text.SpruceTextAreaWidget;
|
||||
import net.minecraft.client.toast.SystemToast;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
/**
|
||||
* Represents the controller mappings file editor screen.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.7.0
|
||||
* @since 1.4.3
|
||||
*/
|
||||
public class MappingsStringInputWidget extends SpruceContainerWidget {
|
||||
private final SpruceOption reloadMappingsOption;
|
||||
private String mappings;
|
||||
private SpruceTextAreaWidget textArea;
|
||||
|
||||
protected MappingsStringInputWidget(Position position, int width, int height) {
|
||||
super(position, width, height);
|
||||
//super(new TranslatableText("midnightcontrols.menu.title.mappings.string"));
|
||||
|
||||
this.reloadMappingsOption = ReloadControllerMappingsOption.newOption(btn -> {
|
||||
this.writeMappings();
|
||||
});
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
public void removed() {
|
||||
this.writeMappings();
|
||||
Controller.updateMappings();
|
||||
}
|
||||
|
||||
public void onClose() {
|
||||
this.removed();
|
||||
}
|
||||
|
||||
public void writeMappings() {
|
||||
if (this.textArea != null) {
|
||||
this.mappings = this.textArea.getText();
|
||||
try {
|
||||
var fw = new FileWriter(MidnightControlsClient.MAPPINGS_FILE, false);
|
||||
fw.write(this.mappings);
|
||||
fw.close();
|
||||
} catch (IOException e) {
|
||||
if (this.client != null)
|
||||
this.client.getToastManager().add(SystemToast.create(this.client, SystemToast.Type.TUTORIAL_HINT,
|
||||
new TranslatableText("midnightcontrols.controller.mappings.error.write"), LiteralText.EMPTY));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
if (this.textArea != null) {
|
||||
this.mappings = this.textArea.getText();
|
||||
}
|
||||
|
||||
var mappings = "";
|
||||
|
||||
if (this.mappings != null)
|
||||
mappings = this.mappings;
|
||||
else if (MidnightControlsClient.MAPPINGS_FILE.exists()) {
|
||||
try {
|
||||
mappings = String.join("\n", Files.readAllLines(MidnightControlsClient.MAPPINGS_FILE.toPath()));
|
||||
this.mappings = mappings;
|
||||
} catch (IOException e) {
|
||||
/* Ignored */
|
||||
}
|
||||
}
|
||||
|
||||
int textFieldWidth = (int) (this.width * (5.0 / 6.0));
|
||||
this.textArea = new SpruceTextAreaWidget(Position.of(this, this.width / 2 - textFieldWidth / 2, 0), textFieldWidth, this.height - 50, new LiteralText(mappings));
|
||||
this.textArea.setText(mappings);
|
||||
// Display as many lines as possible
|
||||
this.textArea.setDisplayedLines(this.textArea.getInnerHeight() / this.client.textRenderer.fontHeight);
|
||||
this.addChild(this.textArea);
|
||||
|
||||
this.addChild(this.reloadMappingsOption.createWidget(Position.of(this.width / 2 - 155, this.height - 29), 310));
|
||||
}
|
||||
|
||||
/*public void renderTitle(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 8, 16777215);
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of midnightcontrols.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.gui;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.ControlsMode;
|
||||
import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
|
||||
import eu.midnightdust.midnightcontrols.client.HudSide;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
|
||||
import dev.lambdaurora.spruceui.hud.Hud;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents the midnightcontrols HUD.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.7.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class MidnightControlsHud extends Hud {
|
||||
private final MidnightControlsClient mod;
|
||||
private MinecraftClient client;
|
||||
private int attackWidth = 0;
|
||||
private int attackButtonWidth = 0;
|
||||
private int dropItemWidth = 0;
|
||||
private int dropItemButtonWidth = 0;
|
||||
private int inventoryWidth = 0;
|
||||
private int inventoryButtonWidth = 0;
|
||||
private int swapHandsWidth = 0;
|
||||
private int swapHandsButtonWidth = 0;
|
||||
private int useWidth = 0;
|
||||
private int useButtonWidth = 0;
|
||||
private BlockHitResult placeHitResult;
|
||||
private String attackAction = "";
|
||||
private String placeAction = "";
|
||||
private int ticksDisplayedCrosshair = 0;
|
||||
|
||||
public MidnightControlsHud(@NotNull MidnightControlsClient mod) {
|
||||
super(new Identifier(MidnightControlsConstants.NAMESPACE, "hud/button_indicator"));
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(@NotNull MinecraftClient client, int screenWidth, int screenHeight) {
|
||||
super.init(client, screenWidth, screenHeight);
|
||||
this.client = client;
|
||||
this.inventoryWidth = this.width(ButtonBinding.INVENTORY);
|
||||
this.inventoryButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.INVENTORY);
|
||||
this.swapHandsWidth = this.width(ButtonBinding.SWAP_HANDS);
|
||||
this.swapHandsButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.SWAP_HANDS);
|
||||
this.dropItemWidth = this.width(ButtonBinding.DROP_ITEM);
|
||||
this.dropItemButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.DROP_ITEM);
|
||||
this.attackButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.ATTACK);
|
||||
this.useButtonWidth = MidnightControlsRenderer.getBindingIconWidth(ButtonBinding.USE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the midnightcontrols' HUD.
|
||||
*/
|
||||
@Override
|
||||
public void render(MatrixStack matrices, float tickDelta) {
|
||||
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && this.client.currentScreen == null) {
|
||||
int y = bottom(2);
|
||||
this.renderFirstIcons(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y);
|
||||
this.renderSecondIcons(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y);
|
||||
this.renderFirstSection(matrices, MidnightControlsConfig.hudSide == HudSide.LEFT ? 2 : client.getWindow().getScaledWidth() - 2, y);
|
||||
this.renderSecondSection(matrices, MidnightControlsConfig.hudSide == HudSide.RIGHT ? 2 : client.getWindow().getScaledWidth() - 2, y);
|
||||
}
|
||||
|
||||
if (this.mod.reacharound.isLastReacharoundVertical()) {
|
||||
// Render crosshair indicator.
|
||||
var window = this.client.getWindow();
|
||||
var text = "[ ]";
|
||||
|
||||
float scale = Math.min(5, this.ticksDisplayedCrosshair + tickDelta) / 5F;
|
||||
scale *= scale;
|
||||
int opacity = ((int) (255 * scale)) << 24;
|
||||
|
||||
this.client.textRenderer.draw(matrices, text, window.getScaledWidth() / 2.f - this.client.textRenderer.getWidth(text) / 2.f,
|
||||
window.getScaledHeight() / 2.f - 4, 0xCCCCCC | opacity);
|
||||
}
|
||||
}
|
||||
|
||||
public void renderFirstIcons(MatrixStack matrices, int x, int y) {
|
||||
int offset = 2 + this.inventoryWidth + this.inventoryButtonWidth + 4;
|
||||
int currentX = MidnightControlsConfig.hudSide == HudSide.LEFT ? x : x - this.inventoryButtonWidth;
|
||||
this.drawButton(matrices, currentX, y, ButtonBinding.INVENTORY, true);
|
||||
this.drawButton(matrices, currentX += (MidnightControlsConfig.hudSide == HudSide.LEFT ? offset : -offset), y, ButtonBinding.SWAP_HANDS, true);
|
||||
offset = 2 + this.swapHandsWidth + this.dropItemButtonWidth + 4;
|
||||
if (this.client.options.showSubtitles && MidnightControlsConfig.hudSide == HudSide.RIGHT) {
|
||||
currentX += -offset;
|
||||
} else {
|
||||
currentX = MidnightControlsConfig.hudSide == HudSide.LEFT ? x : x - this.dropItemButtonWidth;
|
||||
y -= 24;
|
||||
}
|
||||
this.drawButton(matrices, currentX, y, ButtonBinding.DROP_ITEM, !this.client.player.getMainHandStack().isEmpty());
|
||||
}
|
||||
|
||||
public void renderSecondIcons(MatrixStack matrices, int x, int y) {
|
||||
int offset;
|
||||
int currentX = x;
|
||||
if (!this.placeAction.isEmpty()) {
|
||||
if (MidnightControlsConfig.hudSide == HudSide.LEFT)
|
||||
currentX -= this.useButtonWidth;
|
||||
this.drawButton(matrices, currentX, y, ButtonBinding.USE, true);
|
||||
offset = 2 + this.useWidth + 4;
|
||||
if (this.client.options.showSubtitles && MidnightControlsConfig.hudSide == HudSide.LEFT) {
|
||||
currentX -= offset;
|
||||
} else {
|
||||
currentX = x;
|
||||
y -= 24;
|
||||
}
|
||||
}
|
||||
|
||||
if (MidnightControlsConfig.hudSide == HudSide.LEFT)
|
||||
currentX -= this.attackButtonWidth;
|
||||
|
||||
this.drawButton(matrices, currentX, y, ButtonBinding.ATTACK, this.attackWidth != 0);
|
||||
}
|
||||
|
||||
public void renderFirstSection(MatrixStack matrices, int x, int y) {
|
||||
int currentX = MidnightControlsConfig.hudSide == HudSide.LEFT ? x + this.inventoryButtonWidth + 2 : x - this.inventoryButtonWidth - 2 - this.inventoryWidth;
|
||||
this.drawTip(matrices, currentX, y, ButtonBinding.INVENTORY, true);
|
||||
currentX += MidnightControlsConfig.hudSide == HudSide.LEFT ? this.inventoryWidth + 4 + this.swapHandsButtonWidth + 2
|
||||
: -this.swapHandsWidth - 2 - this.swapHandsButtonWidth - 4;
|
||||
this.drawTip(matrices, currentX, y, ButtonBinding.SWAP_HANDS, true);
|
||||
if (this.client.options.showSubtitles && MidnightControlsConfig.hudSide == HudSide.RIGHT) {
|
||||
currentX += -this.dropItemWidth - 2 - this.dropItemButtonWidth - 4;
|
||||
} else {
|
||||
y -= 24;
|
||||
currentX = MidnightControlsConfig.hudSide == HudSide.LEFT ? x + this.dropItemButtonWidth + 2 : x - this.dropItemButtonWidth - 2 - this.dropItemWidth;
|
||||
}
|
||||
this.drawTip(matrices, currentX, y, ButtonBinding.DROP_ITEM, !this.client.player.getMainHandStack().isEmpty());
|
||||
}
|
||||
|
||||
public void renderSecondSection(MatrixStack matrices, int x, int y) {
|
||||
int currentX = x;
|
||||
|
||||
if (!this.placeAction.isEmpty()) {
|
||||
currentX += MidnightControlsConfig.hudSide == HudSide.RIGHT ? this.useButtonWidth + 2 : -this.useButtonWidth - 2 - this.useWidth;
|
||||
|
||||
this.drawTip(matrices, currentX, y, this.placeAction, true);
|
||||
|
||||
if (this.client.options.showSubtitles && MidnightControlsConfig.hudSide == HudSide.LEFT) {
|
||||
currentX -= 4;
|
||||
} else {
|
||||
currentX = x;
|
||||
y -= 24;
|
||||
}
|
||||
}
|
||||
|
||||
currentX += MidnightControlsConfig.hudSide == HudSide.RIGHT ? this.attackButtonWidth + 2 : -this.attackButtonWidth - 2 - this.attackWidth;
|
||||
|
||||
this.drawTip(matrices, currentX, y, this.attackAction, this.attackWidth != 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) {
|
||||
if (this.client.crosshairTarget == null)
|
||||
return;
|
||||
|
||||
String placeAction;
|
||||
|
||||
// Update "Use" tip status.
|
||||
if (this.client.crosshairTarget.getType() == HitResult.Type.MISS) {
|
||||
this.placeHitResult = this.mod.reacharound.getLastReacharoundResult();
|
||||
this.attackAction = "";
|
||||
this.attackWidth = 0;
|
||||
} else {
|
||||
if (this.client.crosshairTarget.getType() == HitResult.Type.BLOCK)
|
||||
this.placeHitResult = (BlockHitResult) this.client.crosshairTarget;
|
||||
else
|
||||
this.placeHitResult = null;
|
||||
|
||||
this.attackAction = this.client.crosshairTarget.getType() == HitResult.Type.BLOCK ? "midnightcontrols.action.hit" : ButtonBinding.ATTACK.getTranslationKey();
|
||||
this.attackWidth = this.width(attackAction);
|
||||
}
|
||||
|
||||
if (this.mod.reacharound.isLastReacharoundVertical()) {
|
||||
if (this.ticksDisplayedCrosshair < 5)
|
||||
this.ticksDisplayedCrosshair++;
|
||||
} else {
|
||||
this.ticksDisplayedCrosshair = 0;
|
||||
}
|
||||
|
||||
var customAttackAction = MidnightControlsCompat.getAttackActionAt(this.client, this.placeHitResult);
|
||||
if (customAttackAction != null) {
|
||||
this.attackAction = customAttackAction;
|
||||
this.attackWidth = this.width(customAttackAction);
|
||||
}
|
||||
|
||||
ItemStack stack = null;
|
||||
if (this.client.player != null) {
|
||||
stack = this.client.player.getMainHandStack();
|
||||
if (stack == null || stack.isEmpty())
|
||||
stack = this.client.player.getOffHandStack();
|
||||
}
|
||||
if (stack == null || stack.isEmpty()) {
|
||||
placeAction = "";
|
||||
} else {
|
||||
if (this.placeHitResult != null && stack.getItem() instanceof BlockItem) {
|
||||
placeAction = "midnightcontrols.action.place";
|
||||
} else {
|
||||
placeAction = ButtonBinding.USE.getTranslationKey();
|
||||
}
|
||||
}
|
||||
|
||||
var customUseAction = MidnightControlsCompat.getUseActionAt(this.client, this.placeHitResult);
|
||||
if (customUseAction != null)
|
||||
placeAction = customUseAction;
|
||||
|
||||
this.placeAction = placeAction;
|
||||
|
||||
// Cache the "Use" tip width.
|
||||
if (this.placeAction.isEmpty())
|
||||
this.useWidth = 0;
|
||||
else
|
||||
this.useWidth = this.width(this.placeAction);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTicks() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private int bottom(int y) {
|
||||
return this.client.getWindow().getScaledHeight() - y - MidnightControlsRenderer.ICON_SIZE;
|
||||
}
|
||||
|
||||
private int width(@NotNull ButtonBinding binding) {
|
||||
return this.width(binding.getTranslationKey());
|
||||
}
|
||||
|
||||
private int width(@Nullable String text) {
|
||||
if (text == null || text.isEmpty())
|
||||
return 0;
|
||||
return this.client.textRenderer.getWidth(I18n.translate(text));
|
||||
}
|
||||
|
||||
private void drawButton(MatrixStack matrices, int x, int y, @NotNull ButtonBinding button, boolean display) {
|
||||
if (display)
|
||||
MidnightControlsRenderer.drawButton(matrices, x, y, button, this.client);
|
||||
}
|
||||
|
||||
private void drawTip(MatrixStack matrices, int x, int y, @NotNull ButtonBinding button, boolean display) {
|
||||
this.drawTip(matrices, x, y, button.getTranslationKey(), display);
|
||||
}
|
||||
|
||||
private void drawTip(MatrixStack matrices, int x, int y, @NotNull String action, boolean display) {
|
||||
if (!display)
|
||||
return;
|
||||
var translatedAction = I18n.translate(action);
|
||||
int textY = (MidnightControlsRenderer.ICON_SIZE / 2 - this.client.textRenderer.fontHeight / 2) + 1;
|
||||
this.client.textRenderer.draw(matrices, translatedAction, (float) x, (float) (y + textY), 14737632);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of midnightcontrols.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.gui;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightInput;
|
||||
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
|
||||
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawableHelper;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
/**
|
||||
* Represents the midnightcontrols renderer.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.7.0
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class MidnightControlsRenderer {
|
||||
public static final int ICON_SIZE = 20;
|
||||
private static final int BUTTON_SIZE = 15;
|
||||
private static final int AXIS_SIZE = 18;
|
||||
|
||||
public static int getButtonSize(int button) {
|
||||
return switch (button) {
|
||||
case -1 -> 0;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 100, GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 200,
|
||||
GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 100, GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 200,
|
||||
GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 100, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 200,
|
||||
GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 100, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 200 -> AXIS_SIZE;
|
||||
default -> BUTTON_SIZE;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the binding icon width.
|
||||
*
|
||||
* @param binding the binding
|
||||
* @return the width
|
||||
*/
|
||||
public static int getBindingIconWidth(@NotNull ButtonBinding binding) {
|
||||
return getBindingIconWidth(binding.getButton());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the binding icon width.
|
||||
*
|
||||
* @param buttons the buttons
|
||||
* @return the width
|
||||
*/
|
||||
public static int getBindingIconWidth(int[] buttons) {
|
||||
int width = 0;
|
||||
for (int i = 0; i < buttons.length; i++) {
|
||||
width += ICON_SIZE;
|
||||
if (i + 1 < buttons.length) {
|
||||
width += 2;
|
||||
}
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
public static ButtonSize drawButton(MatrixStack matrices, int x, int y, @NotNull ButtonBinding button, @NotNull MinecraftClient client) {
|
||||
return drawButton(matrices, x, y, button.getButton(), client);
|
||||
}
|
||||
|
||||
public static ButtonSize drawButton(MatrixStack matrices, int x, int y, int[] buttons, @NotNull MinecraftClient client) {
|
||||
int height = 0;
|
||||
int length = 0;
|
||||
int currentX = x;
|
||||
for (int i = 0; i < buttons.length; i++) {
|
||||
int btn = buttons[i];
|
||||
int size = drawButton(matrices, currentX, y, btn, client);
|
||||
if (size > height)
|
||||
height = size;
|
||||
length += size;
|
||||
if (i + 1 < buttons.length) {
|
||||
length += 2;
|
||||
currentX = x + length;
|
||||
}
|
||||
}
|
||||
return new ButtonSize(length, height);
|
||||
}
|
||||
|
||||
public static int drawButton(MatrixStack matrices, int x, int y, int button, @NotNull MinecraftClient client) {
|
||||
boolean second = false;
|
||||
if (button == -1)
|
||||
return 0;
|
||||
else if (button >= 500) {
|
||||
button -= 1000;
|
||||
second = true;
|
||||
}
|
||||
|
||||
int controllerType = MidnightControlsConfig.controllerType.getId();
|
||||
boolean axis = false;
|
||||
int buttonOffset = button * 15;
|
||||
switch (button) {
|
||||
case 15 -> buttonOffset = 0;
|
||||
case 16 -> buttonOffset = 18;
|
||||
case 17 -> buttonOffset = 36;
|
||||
case 18 -> buttonOffset = 54;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER -> buttonOffset = 7 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER -> buttonOffset = 8 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_BACK -> buttonOffset = 4 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_START -> buttonOffset = 6 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_GUIDE -> buttonOffset = 5 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB -> buttonOffset = 15 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB -> buttonOffset = 16 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 100 -> {
|
||||
buttonOffset = 0;
|
||||
axis = true;
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 100 -> {
|
||||
buttonOffset = 18;
|
||||
axis = true;
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 100 -> {
|
||||
buttonOffset = 2 * 18;
|
||||
axis = true;
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 100 -> {
|
||||
buttonOffset = 3 * 18;
|
||||
axis = true;
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X + 200 -> {
|
||||
buttonOffset = 4 * 18;
|
||||
axis = true;
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y + 200 -> {
|
||||
buttonOffset = 5 * 18;
|
||||
axis = true;
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X + 200 -> {
|
||||
buttonOffset = 6 * 18;
|
||||
axis = true;
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y + 200 -> {
|
||||
buttonOffset = 7 * 18;
|
||||
axis = true;
|
||||
}
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 100, GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER + 200 -> buttonOffset = 9 * 15;
|
||||
case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 100, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER + 200 -> buttonOffset = 10 * 15;
|
||||
}
|
||||
|
||||
RenderSystem.setShaderTexture(0, axis ? MidnightControlsClient.CONTROLLER_AXIS : button >= 15 && button <= 19 ? MidnightControlsClient.CONTROLLER_EXPANDED :MidnightControlsClient.CONTROLLER_BUTTONS);
|
||||
RenderSystem.disableDepthTest();
|
||||
|
||||
int assetSize = axis || (button >= 15 && button <= 18) ? AXIS_SIZE : BUTTON_SIZE;
|
||||
|
||||
RenderSystem.setShaderColor(1.f, second ? 0.f : 1.f, 1.f, 1.f);
|
||||
DrawableHelper.drawTexture(matrices, x + (ICON_SIZE / 2 - assetSize / 2), y + (ICON_SIZE / 2 - assetSize / 2),
|
||||
(float) buttonOffset, (float) (controllerType * assetSize),
|
||||
assetSize, assetSize,
|
||||
256, 256);
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
return ICON_SIZE;
|
||||
}
|
||||
|
||||
public static int drawButtonTip(MatrixStack matrices, int x, int y, @NotNull ButtonBinding button, boolean display, @NotNull MinecraftClient client) {
|
||||
return drawButtonTip(matrices, x, y, button.getButton(), button.getTranslationKey(), display, client);
|
||||
}
|
||||
|
||||
public static int drawButtonTip(MatrixStack matrices, int x, int y, int[] button, @NotNull String action, boolean display, @NotNull MinecraftClient client) {
|
||||
if (display) {
|
||||
int buttonWidth = drawButton(matrices, x, y, button, client).length();
|
||||
|
||||
var translatedAction = I18n.translate(action);
|
||||
int textY = (MidnightControlsRenderer.ICON_SIZE / 2 - client.textRenderer.fontHeight / 2) + 1;
|
||||
|
||||
return client.textRenderer.drawWithShadow(matrices, translatedAction, (float) (x + buttonWidth + 2), (float) (y + textY), 14737632);
|
||||
}
|
||||
|
||||
return -10;
|
||||
}
|
||||
|
||||
private static int getButtonTipWidth(@NotNull String action, @NotNull TextRenderer textRenderer) {
|
||||
return 15 + 5 + textRenderer.getWidth(action);
|
||||
}
|
||||
|
||||
public static void renderVirtualCursor(@NotNull MatrixStack matrices, @NotNull MinecraftClient client) {
|
||||
if (!MidnightControlsConfig.virtualMouse || (client.currentScreen == null
|
||||
|| MidnightInput.isScreenInteractive(client.currentScreen)))
|
||||
return;
|
||||
|
||||
int mouseX = (int) (client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth());
|
||||
int mouseY = (int) (client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight());
|
||||
|
||||
boolean hoverSlot = false;
|
||||
|
||||
if (client.currentScreen instanceof HandledScreenAccessor inventoryScreen) {
|
||||
int guiLeft = inventoryScreen.getX();
|
||||
int guiTop = inventoryScreen.getY();
|
||||
|
||||
Slot slot = inventoryScreen.midnightcontrols$getSlotAt(mouseX, mouseY);
|
||||
|
||||
if (slot != null) {
|
||||
mouseX = guiLeft + slot.x;
|
||||
mouseY = guiTop + slot.y;
|
||||
hoverSlot = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hoverSlot) {
|
||||
var slot = MidnightControlsCompat.getSlotAt(client.currentScreen, mouseX, mouseY);
|
||||
|
||||
if (slot != null) {
|
||||
mouseX = slot.x();
|
||||
mouseY = slot.y();
|
||||
hoverSlot = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hoverSlot) {
|
||||
mouseX -= 8;
|
||||
mouseY -= 8;
|
||||
}
|
||||
|
||||
drawCursor(matrices, mouseX, mouseY, hoverSlot, client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the virtual cursor.
|
||||
*
|
||||
* @param matrices the matrix stack
|
||||
* @param x x coordinate
|
||||
* @param y y coordinate
|
||||
* @param hoverSlot true if hovering a slot, else false
|
||||
* @param client the client instance
|
||||
*/
|
||||
public static void drawCursor(@NotNull MatrixStack matrices, int x, int y, boolean hoverSlot, @NotNull MinecraftClient client) {
|
||||
RenderSystem.disableDepthTest();
|
||||
|
||||
RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f);
|
||||
RenderSystem.setShaderTexture(0, MidnightControlsClient.CURSOR_TEXTURE);
|
||||
DrawableHelper.drawTexture(matrices, x, y,
|
||||
hoverSlot ? 16.f : 0.f, MidnightControlsConfig.virtualMouseSkin.ordinal() * 16.f,
|
||||
16, 16, 32, 64);
|
||||
RenderSystem.enableDepthTest();
|
||||
}
|
||||
|
||||
public record ButtonSize(int length, int height) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of midnightcontrols.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.gui;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.MidnightControls;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.Controller;
|
||||
import eu.midnightdust.midnightcontrols.client.gui.widget.ControllerControlsWidget;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.SpruceTexts;
|
||||
import dev.lambdaurora.spruceui.option.*;
|
||||
import dev.lambdaurora.spruceui.screen.SpruceScreen;
|
||||
import dev.lambdaurora.spruceui.widget.AbstractSpruceWidget;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceLabelWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceOptionListWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.tabbed.SpruceTabbedWidget;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
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 net.minecraft.util.Util;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
/**
|
||||
* Represents the midnightcontrols settings screen.
|
||||
*/
|
||||
public class MidnightControlsSettingsScreen extends SpruceScreen {
|
||||
private static final Text SDL2_GAMEPAD_TOOL = new LiteralText("SDL2 Gamepad Tool").formatted(Formatting.GREEN);
|
||||
public static final String GAMEPAD_TOOL_URL = "https://generalarcade.com/gamepadtool/";
|
||||
final MidnightControlsClient mod = MidnightControlsClient.get();
|
||||
private final Screen parent;
|
||||
// General options
|
||||
private final SpruceOption inputModeOption;
|
||||
private final SpruceOption autoSwitchModeOption;
|
||||
private final SpruceOption rotationSpeedOption;
|
||||
private final SpruceOption mouseSpeedOption;
|
||||
private final SpruceOption virtualMouseOption;
|
||||
private final SpruceOption resetOption;
|
||||
// Gameplay options
|
||||
private final SpruceOption analogMovementOption;
|
||||
private final SpruceOption autoJumpOption;
|
||||
private final SpruceOption fastBlockPlacingOption;
|
||||
private final SpruceOption frontBlockPlacingOption;
|
||||
private final SpruceOption verticalReacharoundOption;
|
||||
private final SpruceOption flyDriftingOption;
|
||||
private final SpruceOption flyVerticalDriftingOption;
|
||||
// Appearance options
|
||||
private final SpruceOption controllerTypeOption;
|
||||
private final SpruceOption virtualMouseSkinOption;
|
||||
private final SpruceOption hudEnableOption;
|
||||
private final SpruceOption hudSideOption;
|
||||
// Controller options
|
||||
private final SpruceOption controllerOption =
|
||||
new SpruceCyclingOption("midnightcontrols.menu.controller",
|
||||
amount -> {
|
||||
int id = MidnightControlsConfig.getController().id();
|
||||
id += amount;
|
||||
if (id > GLFW.GLFW_JOYSTICK_LAST)
|
||||
id = GLFW.GLFW_JOYSTICK_1;
|
||||
id = searchNextAvailableController(id, false);
|
||||
MidnightControlsConfig.setController(Controller.byId(id));
|
||||
},
|
||||
option -> {
|
||||
var controller = MidnightControlsConfig.getController();
|
||||
var controllerName = controller.getName();
|
||||
if (!controller.isConnected())
|
||||
return option.getDisplayText(new LiteralText(controllerName).formatted(Formatting.RED));
|
||||
else if (!controller.isGamepad())
|
||||
return option.getDisplayText(new LiteralText(controllerName).formatted(Formatting.GOLD));
|
||||
else
|
||||
return option.getDisplayText(new LiteralText(controllerName));
|
||||
}, null);
|
||||
private final SpruceOption secondControllerOption = new SpruceCyclingOption("midnightcontrols.menu.controller2",
|
||||
amount -> {
|
||||
int id = MidnightControlsConfig.getSecondController().map(Controller::id).orElse(-1);
|
||||
id += amount;
|
||||
if (id > GLFW.GLFW_JOYSTICK_LAST)
|
||||
id = -1;
|
||||
id = searchNextAvailableController(id, true);
|
||||
MidnightControlsConfig.setSecondController(id == -1 ? null : Controller.byId(id));
|
||||
},
|
||||
option -> MidnightControlsConfig.getSecondController().map(controller -> {
|
||||
var controllerName = controller.getName();
|
||||
if (!controller.isConnected())
|
||||
return option.getDisplayText(new LiteralText(controllerName).formatted(Formatting.RED));
|
||||
else if (!controller.isGamepad())
|
||||
return option.getDisplayText(new LiteralText(controllerName).formatted(Formatting.GOLD));
|
||||
else
|
||||
return option.getDisplayText(new LiteralText(controllerName));
|
||||
}).orElse(option.getDisplayText(SpruceTexts.OPTIONS_OFF.shallowCopy().formatted(Formatting.RED))),
|
||||
new TranslatableText("midnightcontrols.tooltip.controller2"));
|
||||
private final SpruceOption unfocusedInputOption;
|
||||
private final SpruceOption invertsRightXAxis;
|
||||
private final SpruceOption invertsRightYAxis;
|
||||
private final SpruceOption rightDeadZoneOption;
|
||||
private final SpruceOption leftDeadZoneOption;
|
||||
private final SpruceOption[] maxAnalogValueOptions = new SpruceOption[]{
|
||||
maxAnalogValueOption("midnightcontrols.menu.max_left_x_value", GLFW.GLFW_GAMEPAD_AXIS_LEFT_X),
|
||||
maxAnalogValueOption("midnightcontrols.menu.max_left_y_value", GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y),
|
||||
maxAnalogValueOption("midnightcontrols.menu.max_right_x_value", GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X),
|
||||
maxAnalogValueOption("midnightcontrols.menu.max_right_y_value", GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y)
|
||||
};
|
||||
|
||||
private static SpruceOption maxAnalogValueOption(String key, int axis) {
|
||||
return new SpruceDoubleOption(key, .25f, 1.f, 0.05f,
|
||||
() -> MidnightControlsConfig.getAxisMaxValue(axis),
|
||||
newValue -> MidnightControlsConfig.setAxisMaxValue(axis, newValue),
|
||||
option -> option.getDisplayText(new LiteralText(String.format("%.2f", option.get()))),
|
||||
new TranslatableText(key.replace("menu", "tooltip"))
|
||||
);
|
||||
}
|
||||
|
||||
private final MutableText controllerMappingsUrlText = new LiteralText("(")
|
||||
.append(new LiteralText(GAMEPAD_TOOL_URL).formatted(Formatting.GOLD))
|
||||
.append("),");
|
||||
|
||||
private static int searchNextAvailableController(int newId, boolean allowNone) {
|
||||
if ((allowNone && newId == -1) || newId == 0) return newId;
|
||||
|
||||
boolean connected = Controller.byId(newId).isConnected();
|
||||
if (!connected) {
|
||||
newId++;
|
||||
}
|
||||
|
||||
if (newId > GLFW.GLFW_JOYSTICK_LAST)
|
||||
newId = allowNone ? -1 : GLFW.GLFW_JOYSTICK_1;
|
||||
|
||||
return connected ? newId : searchNextAvailableController(newId, allowNone);
|
||||
}
|
||||
|
||||
public MidnightControlsSettingsScreen(Screen parent, boolean hideControls) {
|
||||
super(new TranslatableText("midnightcontrols.title.settings"));
|
||||
this.parent = parent;
|
||||
// General options
|
||||
this.inputModeOption = new SpruceCyclingOption("midnightcontrols.menu.controls_mode",
|
||||
amount -> {
|
||||
var next = MidnightControlsConfig.controlsMode.next();
|
||||
MidnightControlsConfig.controlsMode = next;
|
||||
MidnightControlsConfig.save();
|
||||
|
||||
if (this.client.player != null) {
|
||||
ClientPlayNetworking.getSender().sendPacket(MidnightControls.CONTROLS_MODE_CHANNEL, this.mod.makeControlsModeBuffer(next));
|
||||
}
|
||||
}, option -> option.getDisplayText(new TranslatableText(MidnightControlsConfig.controlsMode.getTranslationKey())),
|
||||
new TranslatableText("midnightcontrols.tooltip.controls_mode"));
|
||||
this.autoSwitchModeOption = new SpruceToggleBooleanOption("midnightcontrols.menu.auto_switch_mode", () -> MidnightControlsConfig.autoSwitchMode,
|
||||
value -> MidnightControlsConfig.autoSwitchMode = value, new TranslatableText("midnightcontrols.tooltip.auto_switch_mode"));
|
||||
this.rotationSpeedOption = new SpruceDoubleOption("midnightcontrols.menu.rotation_speed", 0.0, 100.0, .5f,
|
||||
() -> MidnightControlsConfig.rotationSpeed,
|
||||
value -> MidnightControlsConfig.rotationSpeed = value, option -> option.getDisplayText(new LiteralText(String.valueOf(option.get()))),
|
||||
new TranslatableText("midnightcontrols.tooltip.rotation_speed"));
|
||||
this.mouseSpeedOption = new SpruceDoubleOption("midnightcontrols.menu.mouse_speed", 0.0, 150.0, .5f,
|
||||
() -> MidnightControlsConfig.mouseSpeed,
|
||||
value -> MidnightControlsConfig.mouseSpeed = value, option -> option.getDisplayText(new LiteralText(String.valueOf(option.get()))),
|
||||
new TranslatableText("midnightcontrols.tooltip.mouse_speed"));
|
||||
this.resetOption = SpruceSimpleActionOption.reset(btn -> {
|
||||
// TODO
|
||||
MidnightControlsConfig.init("midnightcontrols", MidnightControlsConfig.class);
|
||||
var client = MinecraftClient.getInstance();
|
||||
this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
|
||||
});
|
||||
// Gameplay options
|
||||
this.analogMovementOption = new SpruceToggleBooleanOption("midnightcontrols.menu.analog_movement",
|
||||
() -> MidnightControlsConfig.analogMovement, value -> MidnightControlsConfig.analogMovement = value,
|
||||
new TranslatableText("midnightcontrols.tooltip.analog_movement"));
|
||||
this.autoJumpOption = new SpruceToggleBooleanOption("options.autoJump",
|
||||
() -> this.client.options.autoJump,
|
||||
newValue -> this.client.options.autoJump = newValue,
|
||||
null);
|
||||
this.fastBlockPlacingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.fast_block_placing", () -> MidnightControlsConfig.fastBlockPlacing,
|
||||
value -> MidnightControlsConfig.fastBlockPlacing = value, new TranslatableText("midnightcontrols.tooltip.fast_block_placing"));
|
||||
this.frontBlockPlacingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.reacharound.horizontal", () -> MidnightControlsConfig.horizontalReacharound,
|
||||
value -> MidnightControlsConfig.horizontalReacharound = value, new TranslatableText("midnightcontrols.tooltip.reacharound.horizontal"));
|
||||
this.verticalReacharoundOption = new SpruceToggleBooleanOption("midnightcontrols.menu.reacharound.vertical", () -> MidnightControlsConfig.verticalReacharound,
|
||||
value -> MidnightControlsConfig.verticalReacharound = value, new TranslatableText("midnightcontrols.tooltip.reacharound.vertical"));
|
||||
this.flyDriftingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.fly_drifting", () -> MidnightControlsConfig.flyDrifting,
|
||||
value -> MidnightControlsConfig.flyDrifting = value, new TranslatableText("midnightcontrols.tooltip.fly_drifting"));
|
||||
this.flyVerticalDriftingOption = new SpruceToggleBooleanOption("midnightcontrols.menu.fly_drifting_vertical", () -> MidnightControlsConfig.verticalFlyDrifting,
|
||||
value -> MidnightControlsConfig.verticalFlyDrifting = value, new TranslatableText("midnightcontrols.tooltip.fly_drifting_vertical"));
|
||||
// Appearance options
|
||||
this.controllerTypeOption = new SpruceCyclingOption("midnightcontrols.menu.controller_type",
|
||||
amount -> MidnightControlsConfig.controllerType = MidnightControlsConfig.controllerType.next(),
|
||||
option -> option.getDisplayText(MidnightControlsConfig.controllerType.getTranslatedText()),
|
||||
new TranslatableText("midnightcontrols.tooltip.controller_type"));
|
||||
this.virtualMouseSkinOption = new SpruceCyclingOption("midnightcontrols.menu.virtual_mouse.skin",
|
||||
amount -> MidnightControlsConfig.virtualMouseSkin = MidnightControlsConfig.virtualMouseSkin.next(),
|
||||
option -> option.getDisplayText(MidnightControlsConfig.virtualMouseSkin.getTranslatedText()),
|
||||
null);
|
||||
this.hudEnableOption = new SpruceToggleBooleanOption("midnightcontrols.menu.hud_enable", () -> MidnightControlsConfig.hudEnable,
|
||||
this.mod::setHudEnabled, new TranslatableText("midnightcontrols.tooltip.hud_enable"));
|
||||
this.hudSideOption = new SpruceCyclingOption("midnightcontrols.menu.hud_side",
|
||||
amount -> MidnightControlsConfig.hudSide = MidnightControlsConfig.hudSide.next(),
|
||||
option -> option.getDisplayText(MidnightControlsConfig.hudSide.getTranslatedText()),
|
||||
new TranslatableText("midnightcontrols.tooltip.hud_side"));
|
||||
// Controller options
|
||||
this.rightDeadZoneOption = new SpruceDoubleOption("midnightcontrols.menu.right_dead_zone", 0.05, 1.0, .05f,
|
||||
() -> MidnightControlsConfig.rightDeadZone,
|
||||
value -> MidnightControlsConfig.rightDeadZone = value, option -> {
|
||||
var value = String.valueOf(option.get());
|
||||
return option.getDisplayText(new LiteralText(value.substring(0, Math.min(value.length(), 5))));
|
||||
}, new TranslatableText("midnightcontrols.tooltip.right_dead_zone"));
|
||||
this.leftDeadZoneOption = new SpruceDoubleOption("midnightcontrols.menu.left_dead_zone", 0.05, 1.0, .05f,
|
||||
() -> MidnightControlsConfig.leftDeadZone,
|
||||
value -> MidnightControlsConfig.leftDeadZone = value, option -> {
|
||||
var value = String.valueOf(option.get());
|
||||
return option.getDisplayText(new LiteralText(value.substring(0, Math.min(value.length(), 5))));
|
||||
}, new TranslatableText("midnightcontrols.tooltip.left_dead_zone"));
|
||||
this.invertsRightXAxis = new SpruceToggleBooleanOption("midnightcontrols.menu.invert_right_x_axis", () -> MidnightControlsConfig.invertRightXAxis,
|
||||
value -> MidnightControlsConfig.invertRightXAxis = value, null);
|
||||
this.invertsRightYAxis = new SpruceToggleBooleanOption("midnightcontrols.menu.invert_right_y_axis", () -> MidnightControlsConfig.invertRightYAxis,
|
||||
value -> MidnightControlsConfig.invertRightYAxis = value, null);
|
||||
this.unfocusedInputOption = new SpruceToggleBooleanOption("midnightcontrols.menu.unfocused_input", () -> MidnightControlsConfig.unfocusedInput,
|
||||
value -> MidnightControlsConfig.unfocusedInput = value, new TranslatableText("midnightcontrols.tooltip.unfocused_input"));
|
||||
this.virtualMouseOption = new SpruceToggleBooleanOption("midnightcontrols.menu.virtual_mouse", () -> MidnightControlsConfig.virtualMouse,
|
||||
value -> MidnightControlsConfig.virtualMouse = value, new TranslatableText("midnightcontrols.tooltip.virtual_mouse"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed() {
|
||||
MidnightControlsConfig.save();
|
||||
super.removed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() {
|
||||
MidnightControlsConfig.save();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
private int getTextHeight() {
|
||||
return (5 + this.textRenderer.fontHeight) * 3 + 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
|
||||
this.buildTabs();
|
||||
|
||||
this.addDrawableChild(this.resetOption.createWidget(Position.of(this.width / 2 - 155, this.height - 29), 150));
|
||||
this.addDrawableChild(new ButtonWidget(this.width / 2 - 155 + 160, this.height - 29, 150, 20, SpruceTexts.GUI_DONE,
|
||||
btn -> this.client.setScreen(this.parent)));
|
||||
}
|
||||
|
||||
public void buildTabs() {
|
||||
var tabs = new SpruceTabbedWidget(Position.of(0, 24), this.width, this.height - 32 - 24,
|
||||
null,
|
||||
Math.max(116, this.width / 8), 0);
|
||||
this.addDrawableChild(tabs);
|
||||
|
||||
tabs.addSeparatorEntry(new TranslatableText("midnightcontrols.menu.separator.general"));
|
||||
tabs.addTabEntry(new TranslatableText("midnightcontrols.menu.title.general"), null,
|
||||
this::buildGeneralTab);
|
||||
tabs.addTabEntry(new TranslatableText("midnightcontrols.menu.title.gameplay"), null,
|
||||
this::buildGameplayTab);
|
||||
tabs.addTabEntry(new TranslatableText("midnightcontrols.menu.title.visual"), null,
|
||||
this::buildVisualTab);
|
||||
|
||||
tabs.addSeparatorEntry(new TranslatableText("options.controls"));
|
||||
tabs.addTabEntry(new TranslatableText("midnightcontrols.menu.title.controller_controls"), null,
|
||||
this::buildControllerControlsTab);
|
||||
|
||||
tabs.addSeparatorEntry(new TranslatableText("midnightcontrols.menu.separator.controller"));
|
||||
tabs.addTabEntry(new TranslatableText("midnightcontrols.menu.title.controller"), null,
|
||||
this::buildControllerTab);
|
||||
tabs.addTabEntry(new TranslatableText("midnightcontrols.menu.title.mappings.string"), null,
|
||||
this::buildMappingsStringEditorTab);
|
||||
}
|
||||
|
||||
public SpruceOptionListWidget buildGeneralTab(int width, int height) {
|
||||
var list = new SpruceOptionListWidget(Position.origin(), width, height);
|
||||
list.addSingleOptionEntry(this.inputModeOption);
|
||||
list.addSingleOptionEntry(this.autoSwitchModeOption);
|
||||
list.addSingleOptionEntry(this.rotationSpeedOption);
|
||||
list.addSingleOptionEntry(this.mouseSpeedOption);
|
||||
list.addSingleOptionEntry(this.virtualMouseOption);
|
||||
return list;
|
||||
}
|
||||
|
||||
public SpruceOptionListWidget buildGameplayTab(int width, int height) {
|
||||
var list = new SpruceOptionListWidget(Position.origin(), width, height);
|
||||
list.addSingleOptionEntry(this.analogMovementOption);
|
||||
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 buildVisualTab(int width, int height) {
|
||||
var list = new SpruceOptionListWidget(Position.origin(), width, height);
|
||||
list.addSingleOptionEntry(this.controllerTypeOption);
|
||||
list.addSingleOptionEntry(this.virtualMouseSkinOption);
|
||||
list.addSingleOptionEntry(new SpruceSeparatorOption("midnightcontrols.menu.title.hud", true, null));
|
||||
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 AbstractSpruceWidget buildControllerTab(int width, int height) {
|
||||
var root = new SpruceContainerWidget(Position.origin(), width, height);
|
||||
|
||||
var aboutMappings1 = new SpruceLabelWidget(Position.of(0, 2),
|
||||
new TranslatableText("midnightcontrols.controller.mappings.1", SDL2_GAMEPAD_TOOL),
|
||||
width, true);
|
||||
|
||||
var gamepadToolUrlLabel = new SpruceLabelWidget(Position.of(0, aboutMappings1.getHeight() + 4),
|
||||
this.controllerMappingsUrlText, width,
|
||||
label -> Util.getOperatingSystem().open(GAMEPAD_TOOL_URL), true);
|
||||
gamepadToolUrlLabel.setTooltip(new TranslatableText("chat.link.open"));
|
||||
|
||||
var aboutMappings3 = new SpruceLabelWidget(Position.of(0,
|
||||
aboutMappings1.getHeight() + gamepadToolUrlLabel.getHeight() + 6),
|
||||
new TranslatableText("midnightcontrols.controller.mappings.3", Formatting.GREEN.toString(), Formatting.RESET.toString()),
|
||||
width, true);
|
||||
|
||||
int listHeight = height - 8 - aboutMappings1.getHeight() - aboutMappings3.getHeight() - gamepadToolUrlLabel.getHeight();
|
||||
var labels = new SpruceContainerWidget(Position.of(0,
|
||||
listHeight),
|
||||
width, height - listHeight);
|
||||
labels.addChild(aboutMappings1);
|
||||
labels.addChild(gamepadToolUrlLabel);
|
||||
labels.addChild(aboutMappings3);
|
||||
|
||||
var list = new SpruceOptionListWidget(Position.origin(), width, listHeight);
|
||||
list.addSingleOptionEntry(this.controllerOption);
|
||||
list.addSingleOptionEntry(this.secondControllerOption);
|
||||
list.addSingleOptionEntry(this.unfocusedInputOption);
|
||||
list.addOptionEntry(this.invertsRightXAxis, this.invertsRightYAxis);
|
||||
list.addSingleOptionEntry(this.rightDeadZoneOption);
|
||||
list.addSingleOptionEntry(this.leftDeadZoneOption);
|
||||
for (var option : this.maxAnalogValueOptions) {
|
||||
list.addSingleOptionEntry(option);
|
||||
}
|
||||
|
||||
root.addChild(list);
|
||||
root.addChild(labels);
|
||||
return root;
|
||||
}
|
||||
|
||||
public SpruceContainerWidget buildMappingsStringEditorTab(int width, int height) {
|
||||
return new MappingsStringInputWidget(Position.origin(), width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTitle(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
drawCenteredText(matrices, this.textRenderer, I18n.translate("midnightcontrols.menu.title"), this.width / 2, 8, 16777215);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of midnightcontrols.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.gui;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.client.controller.Controller;
|
||||
import dev.lambdaurora.spruceui.option.SpruceSimpleActionOption;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.toast.SystemToast;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Represents the option to reload the controller mappings.
|
||||
*/
|
||||
public class ReloadControllerMappingsOption {
|
||||
private static final String KEY = "midnightcontrols.menu.reload_controller_mappings";
|
||||
|
||||
public static SpruceSimpleActionOption newOption(@Nullable Consumer<SpruceButtonWidget> before) {
|
||||
return SpruceSimpleActionOption.of(KEY, btn -> {
|
||||
var client = MinecraftClient.getInstance();
|
||||
if (before != null)
|
||||
before.accept(btn);
|
||||
Controller.updateMappings();
|
||||
if (client.currentScreen instanceof MidnightControlsSettingsScreen)
|
||||
client.currentScreen.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
|
||||
client.getToastManager().add(SystemToast.create(client, SystemToast.Type.TUTORIAL_HINT,
|
||||
new TranslatableText("midnightcontrols.controller.mappings.updated"), LiteralText.EMPTY));
|
||||
}, new TranslatableText("midnightcontrols.tooltip.reload_controller_mappings"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of midnightcontrols.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.gui;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
import eu.midnightdust.midnightcontrols.client.ring.RingPage;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
|
||||
/**
|
||||
* Represents the controls ring screen.
|
||||
*
|
||||
* @author LambdAurora
|
||||
* @version 1.4.3
|
||||
* @since 1.4.3
|
||||
*/
|
||||
public class RingScreen extends Screen {
|
||||
protected final MidnightControlsClient mod;
|
||||
|
||||
public RingScreen() {
|
||||
super(new TranslatableText("midnightcontrols.menu.title.ring"));
|
||||
this.mod = MidnightControlsClient.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldPause() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
super.render(matrices, mouseX, mouseY, delta);
|
||||
|
||||
RingPage page = this.mod.ring.getCurrentPage();
|
||||
|
||||
page.render(matrices, this.textRenderer, this.width, this.height, mouseX, mouseY, delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased(double mouseX, double mouseY, int button) {
|
||||
/*if (midnightcontrolsClient.BINDING_RING.matchesMouse(button)) {
|
||||
this.onClose();
|
||||
return true;
|
||||
}*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of midnightcontrols.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.gui;
|
||||
|
||||
import dev.lambdaurora.spruceui.widget.SpruceTexturedButtonWidget;
|
||||
import eu.midnightdust.midnightcontrols.client.HudSide;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.util.KeyBindingAccessor;
|
||||
import net.minecraft.client.gui.screen.ChatScreen;
|
||||
import net.minecraft.client.gui.screen.GameMenuScreen;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.ingame.InventoryScreen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.gui.widget.TexturedButtonWidget;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.util.Arm;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y;
|
||||
|
||||
/**
|
||||
* Represents the touchscreen overlay
|
||||
*/
|
||||
public class TouchscreenOverlay extends Screen {
|
||||
public static final Identifier WIDGETS_LOCATION = new Identifier("midnightcontrols", "textures/gui/widgets.png");
|
||||
private MidnightControlsClient mod;
|
||||
private SpruceTexturedButtonWidget jumpButton;
|
||||
private SpruceTexturedButtonWidget flyButton;
|
||||
private SpruceTexturedButtonWidget flyUpButton;
|
||||
private SpruceTexturedButtonWidget flyDownButton;
|
||||
private int flyButtonEnableTicks = 0;
|
||||
private int forwardButtonTick = 0;
|
||||
private SpruceTexturedButtonWidget forwardLeftButton;
|
||||
private SpruceTexturedButtonWidget forwardRightButton;
|
||||
private SpruceTexturedButtonWidget startSneakButton;
|
||||
private SpruceTexturedButtonWidget endSneakButton;
|
||||
|
||||
public TouchscreenOverlay(@NotNull MidnightControlsClient mod)
|
||||
{
|
||||
super(new LiteralText("Touchscreen overlay"));
|
||||
this.mod = mod;
|
||||
this.passEvents = true;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean shouldPause()
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean keyPressed(int keyCode, int scanCode, int modifiers)
|
||||
// {
|
||||
// super.keyPressed(keyCode,scanCode,modifiers);
|
||||
// //return false;
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// private void pauseGame(boolean bl)
|
||||
// {
|
||||
// if (this.client == null)
|
||||
// return;
|
||||
// boolean bl2 = this.client.isIntegratedServerRunning() && !this.client.getServer().isRemote();
|
||||
// if (bl2) {
|
||||
// this.client.setScreen(new GameMenuScreen(!bl));
|
||||
// this.client.getSoundManager().pauseAll();
|
||||
// } else {
|
||||
// this.client.setScreen(new GameMenuScreen(true));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Updates the forward button ticks cooldown.
|
||||
// *
|
||||
// * @param state The button state.
|
||||
// *
|
||||
// */
|
||||
// private void updateForwardButtonsState(boolean state)
|
||||
// {
|
||||
// if (state)
|
||||
// this.forwardButtonTick = -1;
|
||||
// else
|
||||
// this.forwardButtonTick = 20;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Updates the jump buttons.
|
||||
// */
|
||||
// private void updateJumpButtons()
|
||||
// {
|
||||
// if (this.client == null)
|
||||
// return;
|
||||
// if (!this.client.interactionManager.isFlyingLocked()) {
|
||||
// boolean oldStateFly = this.flyButton.visible;
|
||||
// this.jumpButton.visible = false;
|
||||
// this.flyButton.visible = true;
|
||||
// this.flyUpButton.visible = true;
|
||||
// this.flyDownButton.visible = true;
|
||||
// if (oldStateFly != this.flyButton.visible) {
|
||||
// this.flyButtonEnableTicks = 5;
|
||||
// this.handleJump(null, false);
|
||||
// } else if (this.flyButtonEnableTicks > 0)
|
||||
// this.flyButtonEnableTicks--;
|
||||
// } else {
|
||||
// this.jumpButton.visible = true;
|
||||
// this.flyButton.visible = false;
|
||||
// this.flyUpButton.visible = false;
|
||||
// this.flyDownButton.visible = false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Handles the jump button.
|
||||
// *
|
||||
// * @param btn The pressed button.
|
||||
// * @param state The state of the jump button.
|
||||
// */
|
||||
// private void handleJump(ButtonWidget btn, boolean state)
|
||||
// {
|
||||
// ((KeyBindingAccessor) this.client.options.keyJump).midnightcontrols$handlePressState(state);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void tick()
|
||||
// {
|
||||
// if (this.forwardButtonTick > 0) {
|
||||
// this.forwardButtonTick--;
|
||||
// } else if (this.forwardButtonTick == 0) {
|
||||
// if (this.forwardLeftButton.visible)
|
||||
// this.forwardLeftButton.visible = false;
|
||||
// if (this.forwardRightButton.visible)
|
||||
// this.forwardRightButton.visible = false;
|
||||
// }
|
||||
// this.updateJumpButtons();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void init()
|
||||
// {
|
||||
// super.init();
|
||||
// int scaledWidth = this.client.getWindow().getScaledWidth();
|
||||
// int scaledHeight = this.client.getWindow().getScaledHeight();
|
||||
// this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2 - 20, 0, 20, 20, 0, 106, 20, ButtonWidget.WIDGETS_LOCATION, 256, 256,
|
||||
// btn -> this.client.setScreen(new ChatScreen("")), LiteralText.EMPTY));
|
||||
// this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2, 0, 20, 20, 0, 0, 20, WIDGETS_LOCATION, 256, 256,
|
||||
// btn -> this.pauseGame(false)));
|
||||
// // Inventory buttons.
|
||||
// int inventoryButtonX = scaledWidth / 2;
|
||||
// int inventoryButtonY = scaledHeight - 16 - 5;
|
||||
// if (this.client.options.mainArm == Arm.LEFT) {
|
||||
// inventoryButtonX = inventoryButtonX - 91 - 24;
|
||||
// } else {
|
||||
// inventoryButtonX = inventoryButtonX + 91 + 4;
|
||||
// }
|
||||
// this.addDrawableChild(new TexturedButtonWidget(inventoryButtonX, inventoryButtonY, 20, 20, 20, 0, 20, WIDGETS_LOCATION, 256, 256,
|
||||
// btn -> {
|
||||
// if (this.client.interactionManager.hasRidingInventory()) {
|
||||
// this.client.player.openRidingInventory();
|
||||
// } else {
|
||||
// this.client.getTutorialManager().onInventoryOpened();
|
||||
// this.client.openScreen(new InventoryScreen(this.client.player));
|
||||
// }
|
||||
// }));
|
||||
// int jumpButtonX, swapHandsX, sneakButtonX;
|
||||
// int sneakButtonY = scaledHeight - 10 - 40 - 5;
|
||||
// if (MidnightControlsConfig.hudSide == HudSide.LEFT) {
|
||||
// jumpButtonX = scaledWidth - 20 - 20;
|
||||
// swapHandsX = jumpButtonX - 5 - 40;
|
||||
// sneakButtonX = 10 + 20 + 5;
|
||||
// } else {
|
||||
// jumpButtonX = 20;
|
||||
// swapHandsX = jumpButtonX + 5 + 40;
|
||||
// sneakButtonX = scaledWidth - 10 - 40 - 5;
|
||||
// }
|
||||
// // Swap items hand.
|
||||
// this.addDrawableChild(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY, 20, 20, 0, 160, 20, WIDGETS_LOCATION,
|
||||
// (btn, state) -> {
|
||||
// if (state) {
|
||||
// if (!this.client.player.isSpectator()) {
|
||||
// this.client.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.SWAP_ITEM_WITH_OFFHAND, BlockPos.ORIGIN, Direction.DOWN));
|
||||
// }
|
||||
// }
|
||||
// }));
|
||||
// // Drop
|
||||
// this.addDrawableChild(new SpruceTexturedButtonWidget(swapHandsX, sneakButtonY + 5 + 20, 20, 20, 20, 160, 20, WIDGETS_LOCATION,
|
||||
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyDrop).midnightcontrols$handlePressState(state)));
|
||||
// // Jump keys
|
||||
// this.addDrawableChild(this.jumpButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY, 20, 20, 0, 40, 20, WIDGETS_LOCATION,
|
||||
// this::handleJump));
|
||||
// this.addDrawableChild(this.flyButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY, 20, 20, 20, 40, 20, WIDGETS_LOCATION,
|
||||
// (btn, state) -> {
|
||||
// if (this.flyButtonEnableTicks == 0) this.client..abilities.flying = false;
|
||||
// }));
|
||||
// this.addDrawableChild(this.flyUpButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY - 5 - 20, 20, 20, 40, 40, 20, WIDGETS_LOCATION,
|
||||
// this::handleJump));
|
||||
// this.addDrawableChild(this.flyDownButton = new SpruceTexturedButtonWidget(jumpButtonX, sneakButtonY + 20 + 5, 20, 20, 60, 40, 20, WIDGETS_LOCATION,
|
||||
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(state)));
|
||||
// this.updateJumpButtons();
|
||||
// // Movements keys
|
||||
// this.addDrawableChild((this.startSneakButton = new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY, 20, 20, 0, 120, 20, WIDGETS_LOCATION,
|
||||
// (btn, state) -> {
|
||||
// if (state) {
|
||||
// ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(true);
|
||||
// this.startSneakButton.setVisible(false);
|
||||
// this.endSneakButton.setVisible(true);
|
||||
// }
|
||||
// })));
|
||||
// this.addDrawableChild((this.endSneakButton = new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY, 20, 20, 20, 120, 20, WIDGETS_LOCATION,
|
||||
// (btn, state) -> {
|
||||
// if (state) {
|
||||
// ((KeyBindingAccessor) this.client.options.keySneak).midnightcontrols$handlePressState(false);
|
||||
// this.endSneakButton.setVisible(false);
|
||||
// this.startSneakButton.setVisible(true);
|
||||
// }
|
||||
// })));
|
||||
// this.endSneakButton.setVisible(false);
|
||||
// this.addDrawableChild(this.forwardLeftButton = new SpruceTexturedButtonWidget(sneakButtonX - 20 - 5, sneakButtonY - 5 - 20, 20, 20, 80, 80, 20, WIDGETS_LOCATION,
|
||||
// (btn, state) -> {
|
||||
// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state);
|
||||
// ((KeyBindingAccessor) this.client.options.keyLeft).midnightcontrols$handlePressState(state);
|
||||
// this.updateForwardButtonsState(state);
|
||||
// }));
|
||||
// this.forwardLeftButton.setVisible(false);
|
||||
// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY - 5 - 20, 20, 20, 0, 80, 20, WIDGETS_LOCATION,
|
||||
// (btn, state) -> {
|
||||
// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state);
|
||||
// this.updateForwardButtonsState(state);
|
||||
// this.forwardLeftButton.setVisible(true);
|
||||
// this.forwardRightButton.setVisible(true);
|
||||
// }));
|
||||
// this.addDrawableChild(this.forwardRightButton = new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY - 5 - 20, 20, 20, 100, 80, 20, WIDGETS_LOCATION,
|
||||
// (btn, state) -> {
|
||||
// ((KeyBindingAccessor) this.client.options.keyForward).midnightcontrols$handlePressState(state);
|
||||
// ((KeyBindingAccessor) this.client.options.keyRight).midnightcontrols$handlePressState(state);
|
||||
// this.updateForwardButtonsState(state);
|
||||
// }));
|
||||
// this.forwardRightButton.setVisible(true);
|
||||
// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX + 20 + 5, sneakButtonY, 20, 20, 20, 80, 20, WIDGETS_LOCATION,
|
||||
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyRight).midnightcontrols$handlePressState(state)));
|
||||
// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX, sneakButtonY + 20 + 5, 20, 20, 40, 80, 20, WIDGETS_LOCATION,
|
||||
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyBack).midnightcontrols$handlePressState(state)));
|
||||
// this.addDrawableChild(new SpruceTexturedButtonWidget(sneakButtonX - 20 - 5, sneakButtonY, 20, 20, 60, 80, 20, WIDGETS_LOCATION,
|
||||
// (btn, state) -> ((KeyBindingAccessor) this.client.options.keyLeft).midnightcontrols$handlePressState(state)));
|
||||
//
|
||||
// this.children().forEach(button -> {
|
||||
// if (button instanceof SpruceTexturedButtonWidget) {
|
||||
// ((SpruceTexturedButtonWidget) button).setSilent(true);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean mouseClicked(double mouseX, double mouseY, int button)
|
||||
// {
|
||||
// if (mouseY >= (double) (this.height - 22) && this.client != null && this.client.player != null) {
|
||||
// int centerX = this.width / 2;
|
||||
// if (mouseX >= (double) (centerX - 90) && mouseX <= (double) (centerX + 90)) {
|
||||
// for (int slot = 0; slot < 9; ++slot) {
|
||||
// int slotX = centerX - 90 + slot * 20 + 2;
|
||||
// if (mouseX >= (double) slotX && mouseX <= (double) (slotX + 20)) {
|
||||
// this.client.player.getInventory().selectedSlot = slot;
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return super.mouseClicked(mouseX, mouseY, button);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY)
|
||||
// {
|
||||
// if (button == GLFW.GLFW_MOUSE_BUTTON_1 && this.client != null) {
|
||||
// if (deltaY > 0.01)
|
||||
// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 2);
|
||||
// else if (deltaY < 0.01)
|
||||
// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 1);
|
||||
//
|
||||
// if (deltaX > 0.01)
|
||||
// this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 2);
|
||||
// else if (deltaX < 0.01)
|
||||
// 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);
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of midnightcontrols.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.gui.widget;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
|
||||
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsRenderer;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.SpruceTexts;
|
||||
import dev.lambdaurora.spruceui.widget.AbstractSpruceIconButtonWidget;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents a controller button widget.
|
||||
*/
|
||||
public class ControllerButtonWidget extends AbstractSpruceIconButtonWidget {
|
||||
private ButtonBinding binding;
|
||||
private int iconWidth;
|
||||
|
||||
public ControllerButtonWidget(Position position, int width, @NotNull ButtonBinding binding, @NotNull PressAction action) {
|
||||
super(position, width, 20, ButtonBinding.getLocalizedButtonName(binding.getButton()[0]), action);
|
||||
this.binding = binding;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
int length = binding.getButton().length;
|
||||
this.setMessage(this.binding.isNotBound() ? SpruceTexts.NOT_BOUND.copy() :
|
||||
(length > 0 ? ButtonBinding.getLocalizedButtonName(binding.getButton()[0]) : new LiteralText("<>")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getMessage() {
|
||||
if (this.binding.getButton().length > 1)
|
||||
return LiteralText.EMPTY;
|
||||
return super.getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int renderIcon(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
int x = this.getX();
|
||||
if (this.binding.getButton().length > 1) {
|
||||
x += (this.width / 2 - this.iconWidth / 2) - 4;
|
||||
}
|
||||
var size = MidnightControlsRenderer.drawButton(matrices, x, this.getY(), this.binding, MinecraftClient.getInstance());
|
||||
this.iconWidth = size.length();
|
||||
return size.height();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of midnightcontrols.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.gui.widget;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.InputManager;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.SpruceTexts;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
|
||||
import net.minecraft.client.gui.screen.option.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 MidnightControlsClient 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 = MidnightControlsClient.get();
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
this.addChild(new SpruceButtonWidget(Position.of(this, this.width / 2 - 155, 18), 310, 20,
|
||||
new TranslatableText("midnightcontrols.menu.keyboard_controls"),
|
||||
btn -> this.client.setScreen(new ControlsOptionsScreen(null, this.client.options))));
|
||||
this.bindingsListWidget = new ControlsListWidget(Position.of(this, 0, 43), this.width, this.height - 43 - 35, 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 -> MidnightControlsConfig.setButtonBinding(binding, binding.getDefaultButton()))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderWidget(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
drawCenteredText(matrices, this.client.textRenderer, new TranslatableText("midnightcontrols.menu.title.controller_controls"),
|
||||
this.getX() + this.width / 2, this.getY() + 4, 16777215);
|
||||
this.resetButton.setActive(InputManager.streamBindings().anyMatch(Predicates.not(ButtonBinding::isDefault)));
|
||||
super.renderWidget(matrices, mouseX, mouseY, delta);
|
||||
}
|
||||
|
||||
public void finishBindingEdit(int... buttons) {
|
||||
if (this.focusedBinding == null) return;
|
||||
MidnightControlsConfig.setButtonBinding(this.focusedBinding, buttons);
|
||||
this.focusedBinding = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
|
||||
*
|
||||
* This file is part of midnightcontrols.
|
||||
*
|
||||
* Licensed under the MIT license. For more information,
|
||||
* see the LICENSE file.
|
||||
*/
|
||||
|
||||
package eu.midnightdust.midnightcontrols.client.gui.widget;
|
||||
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
|
||||
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.ButtonCategory;
|
||||
import eu.midnightdust.midnightcontrols.client.controller.InputManager;
|
||||
import dev.lambdaurora.spruceui.Position;
|
||||
import dev.lambdaurora.spruceui.SpruceTexts;
|
||||
import dev.lambdaurora.spruceui.navigation.NavigationDirection;
|
||||
import dev.lambdaurora.spruceui.navigation.NavigationUtils;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceButtonWidget;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceSeparatorWidget;
|
||||
import dev.lambdaurora.spruceui.widget.SpruceWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceEntryListWidget;
|
||||
import dev.lambdaurora.spruceui.widget.container.SpruceParentWidget;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
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.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 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 implements SpruceParentWidget<SpruceWidget> {
|
||||
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, parent.getWidth() / 2 - 8, 0), 110, this.binding, btn -> {
|
||||
gui.focusedBinding = binding;
|
||||
MidnightControlsClient.get().input.beginControlsInput(gui);
|
||||
}) {
|
||||
protected Text getNarrationMessage() {
|
||||
return 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.editButton.getPosition().getRelativeX() + this.editButton.getWidth() + 2, 0),
|
||||
44, 20, new TranslatableText("controls.reset"),
|
||||
btn -> MidnightControlsConfig.setButtonBinding(binding, binding.getDefaultButton())) {
|
||||
protected Text getNarrationMessage() {
|
||||
return new TranslatableText("narrator.controls.reset", bindingName);
|
||||
}
|
||||
};
|
||||
this.children.add(this.resetButton);
|
||||
this.unbindButton = new SpruceButtonWidget(Position.of(this,
|
||||
this.editButton.getPosition().getRelativeX() + this.editButton.getWidth() + 2, 0),
|
||||
this.resetButton.getWidth(), this.resetButton.getHeight(), SpruceTexts.GUI_UNBIND,
|
||||
btn -> {
|
||||
MidnightControlsConfig.setButtonBinding(binding, UNBOUND);
|
||||
gui.focusedBinding = null;
|
||||
MidnightControlsClient.get().input.beginControlsInput(null);
|
||||
}) {
|
||||
protected Text getNarrationMessage() {
|
||||
return new TranslatableText("midnightcontrols.narrator.unbound", bindingName);
|
||||
}
|
||||
};
|
||||
this.children.add(this.unbindButton);
|
||||
|
||||
this.position.setRelativeX(4);
|
||||
this.width -= 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpruceWidget> children() {
|
||||
return this.children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable SpruceWidget getFocused() {
|
||||
return this.focused;
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
|
||||
/* Input */
|
||||
|
||||
@Override
|
||||
protected boolean onMouseClick(double mouseX, double mouseY, int button) {
|
||||
var 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;
|
||||
}
|
||||
|
||||
/* Rendering */
|
||||
|
||||
@Override
|
||||
protected void renderWidget(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
boolean focused = gui.focusedBinding == this.binding;
|
||||
|
||||
var textRenderer = ControlsListWidget.this.client.textRenderer;
|
||||
int height = this.getHeight();
|
||||
//float textX = (float) (this.getX() + 70 - ControlsListWidget.this.maxTextLength);
|
||||
int textY = this.getY() + height / 2;
|
||||
textRenderer.draw(matrices, this.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) {
|
||||
var 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)) {
|
||||
var text = this.editButton.getMessage().copy();
|
||||
this.editButton.setMessage(text.formatted(Formatting.RED));
|
||||
} else if (this.binding.isNotBound()) {
|
||||
var 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, 2, 0), this.getWidth() - 4,
|
||||
new LiteralText(category.getTranslatedName())) {
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return CategoryEntry.this.getWidth() - 4;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return this.parent.getInnerWidth();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user