diff --git a/common/src/main/java/io/github/notenoughupdates/moulconfig/common/IMinecraft.kt b/common/src/main/java/io/github/notenoughupdates/moulconfig/common/IMinecraft.kt index 4f6f43104..ef3312c6f 100644 --- a/common/src/main/java/io/github/notenoughupdates/moulconfig/common/IMinecraft.kt +++ b/common/src/main/java/io/github/notenoughupdates/moulconfig/common/IMinecraft.kt @@ -37,6 +37,8 @@ interface IMinecraft { fun sendClickableChatMessage(message: String, action: String, type: ClickType) + fun getKeyName(keyCode: Int): String + /** * This is a method to provide a render context. Note that constructing this context directly will potentially give * you an incorrect render state, leading to visual glitches. Depending on your platform, this might also require diff --git a/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorKeybind.java b/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorKeybind.java new file mode 100644 index 000000000..f3d2749b9 --- /dev/null +++ b/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorKeybind.java @@ -0,0 +1,129 @@ +package io.github.notenoughupdates.moulconfig.gui.editors; + +import io.github.notenoughupdates.moulconfig.GuiTextures; +import io.github.notenoughupdates.moulconfig.common.IMinecraft; +import io.github.notenoughupdates.moulconfig.common.RenderContext; +import io.github.notenoughupdates.moulconfig.gui.GuiComponent; +import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext; +import io.github.notenoughupdates.moulconfig.gui.KeyboardEvent; +import io.github.notenoughupdates.moulconfig.gui.MouseEvent; +import io.github.notenoughupdates.moulconfig.processor.ProcessedOption; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; + +public class GuiOptionEditorKeybind extends ComponentEditor { + private boolean editingKeycode = false; + GuiComponent component; + + public GuiOptionEditorKeybind(ProcessedOption option, int defaultKeyCode) { + super(option); + + component = wrapComponent(new GuiComponent() { + @Override + public int getWidth() { + return 0; + } + + @Override + public int getHeight() { + return 30; + } + + @Override + public void render(@NotNull GuiImmediateContext context) { + int height = getHeight(); + RenderContext renderContext = context.getRenderContext(); + int width = getWidth(); + + renderContext.color(1, 1, 1, 1); + IMinecraft.instance.bindTexture(GuiTextures.BUTTON); + renderContext.drawTexturedRect(width / 6 - 24, height - 7 - 14, 48, 16); + + + String keyName = IMinecraft.instance.getKeyName((int) option.get()); + String text = editingKeycode ? "> " + keyName + " <" : keyName; + renderContext.drawStringCenteredScaledMaxWidth(text, + IMinecraft.instance.getDefaultFontRenderer(), + width / 6, height - 7 - 6, + false, 38, 0xFF303030 + ); + + int resetX = width / 6 - 24 + 48 + 3; + int resetY = height - 7 - 14 + 3; + + IMinecraft.instance.bindTexture(GuiTextures.RESET); + renderContext.color(1, 1, 1, 1); + renderContext.drawTexturedRect(resetX, resetY, 10, 11); + int mouseX = context.getMouseX(); + int mouseY = context.getMouseY(); + if (mouseX >= resetX && mouseX < resetX + 10 && + mouseY >= resetY && mouseY < resetY + 11) { + renderContext.scheduleDrawTooltip(Collections.singletonList( + "§cReset to Default" + )); + } + } + + @Override + public boolean mouseEvent(@NotNull MouseEvent mouseEvent, @NotNull GuiImmediateContext context) { + if (!(mouseEvent instanceof MouseEvent.Click)) return false; + MouseEvent.Click click = (MouseEvent.Click) mouseEvent; + if (click.getMouseState() && click.getMouseButton() != -1 && editingKeycode) { + editingKeycode = false; + int mouseButton = click.getMouseButton(); + System.out.println(mouseButton); + option.set(mouseButton); + return true; + } + + if (click.getMouseState() && click.getMouseButton() == 0) { + int height = getHeight(); + int width = getHeight(); + int mouseX = context.getMouseX(); + int mouseY = context.getMouseY(); + if (mouseX > width / 6 - 24 && mouseX < width / 6 + 24 && + mouseY > height - 7 - 14 && mouseY < height - 7 + 2) { + editingKeycode = true; + return true; + } + if (mouseX > width / 6 - 24 + 48 + 3 && mouseX < width / 6 - 24 + 48 + 13 && + mouseY > height - 7 - 14 + 3 && mouseY < height - 7 - 14 + 3 + 11) { + option.set(defaultKeyCode); + return true; + } + } + + return false; + } + + @Override + public boolean keyboardEvent(KeyboardEvent keyboardEvent, GuiImmediateContext context) { + boolean wasKeyPressedEvent = keyboardEvent instanceof KeyboardEvent.KeyPressed; + if (wasKeyPressedEvent) { + if (editingKeycode) { + KeyboardEvent.KeyPressed keyPressed = (KeyboardEvent.KeyPressed) keyboardEvent; + editingKeycode = false; + int keyCode = -1; + int keycode = keyPressed.getKeycode(); + if (keycode != 256 /* GLFW_KEY_ESCAPE*/ && keycode != 0) { + keyCode = keycode; + } + //if (keyCode > 256) keyCode = 0; + option.set(keyCode); + return true; + } else { + return false; + } + } + + return editingKeycode; + } + }); + } + + @Override + public @NotNull GuiComponent getDelegate() { + return component; + } +} diff --git a/common/src/main/java/io/github/notenoughupdates/moulconfig/processor/BuiltinMoulConfigGuis.java b/common/src/main/java/io/github/notenoughupdates/moulconfig/processor/BuiltinMoulConfigGuis.java index 91307420e..e71c737b1 100644 --- a/common/src/main/java/io/github/notenoughupdates/moulconfig/processor/BuiltinMoulConfigGuis.java +++ b/common/src/main/java/io/github/notenoughupdates/moulconfig/processor/BuiltinMoulConfigGuis.java @@ -43,7 +43,8 @@ public static void addProcessors(MoulConfigProcessor processor) { processedOption, configEditorDropdown.values() )); - + processor.registerConfigEditor(ConfigEditorKeybind.class, (processedOption, keybind) -> + new GuiOptionEditorKeybind(processedOption, keybind.defaultKey())); processor.registerConfigEditor(ConfigEditorSlider.class, (processedOption, configEditorSlider) -> new GuiOptionEditorSlider(processedOption, configEditorSlider.minValue(), configEditorSlider.maxValue(), configEditorSlider.minStep())); processor.registerConfigEditor(ConfigEditorInfoText.class, (processedOption, configEditorInfoText) -> diff --git a/legacy/src/main/java/io/github/notenoughupdates/moulconfig/internal/ForgeMinecraft.kt b/legacy/src/main/java/io/github/notenoughupdates/moulconfig/internal/ForgeMinecraft.kt index cb6c0cb3c..8a595c288 100644 --- a/legacy/src/main/java/io/github/notenoughupdates/moulconfig/internal/ForgeMinecraft.kt +++ b/legacy/src/main/java/io/github/notenoughupdates/moulconfig/internal/ForgeMinecraft.kt @@ -130,6 +130,10 @@ class ForgeMinecraft : IMinecraft { ) } + override fun getKeyName(keyCode: Int): String { + return KeybindHelper.getKeyName(keyCode) + } + override fun isMouseButtonDown(mouseButton: Int): Boolean { return Mouse.isButtonDown(mouseButton) } diff --git a/modern/src/main/kotlin/io/github/notenoughupdates/moulconfig/platform/ModernKeybindHelper.kt b/modern/src/main/kotlin/io/github/notenoughupdates/moulconfig/platform/ModernKeybindHelper.kt new file mode 100644 index 000000000..245fc0ca7 --- /dev/null +++ b/modern/src/main/kotlin/io/github/notenoughupdates/moulconfig/platform/ModernKeybindHelper.kt @@ -0,0 +1,19 @@ +package io.github.notenoughupdates.moulconfig.platform + +import net.minecraft.client.util.InputUtil + +object ModernKeybindHelper { + fun getKeyName(keyCode: Int): String { + if (keyCode == -1) { + return "NONE" + } else if (keyCode in 0..9) { + return "Button ${keyCode+1}" + } else { + var keyName = InputUtil.fromKeyCode(keyCode, 0).localizedText.string + if (keyName == null) { + keyName = "???" + } + return keyName + } + } +} diff --git a/modern/src/main/kotlin/io/github/notenoughupdates/moulconfig/platform/ModernMinecraft.kt b/modern/src/main/kotlin/io/github/notenoughupdates/moulconfig/platform/ModernMinecraft.kt index 0f4769b2d..9fdc88f81 100644 --- a/modern/src/main/kotlin/io/github/notenoughupdates/moulconfig/platform/ModernMinecraft.kt +++ b/modern/src/main/kotlin/io/github/notenoughupdates/moulconfig/platform/ModernMinecraft.kt @@ -162,6 +162,10 @@ class ModernMinecraft : IMinecraft { }) } + override fun getKeyName(keyCode: Int): String { + return ModernKeybindHelper.getKeyName(keyCode) + } + override fun provideTopLevelRenderContext(): RenderContext { return ModernRenderContext( DrawContext( diff --git a/modern/src/main/kotlin/io/github/notenoughupdates/moulconfig/test/TestCategoryA.kt b/modern/src/main/kotlin/io/github/notenoughupdates/moulconfig/test/TestCategoryA.kt index 78622772a..db0d2bf11 100644 --- a/modern/src/main/kotlin/io/github/notenoughupdates/moulconfig/test/TestCategoryA.kt +++ b/modern/src/main/kotlin/io/github/notenoughupdates/moulconfig/test/TestCategoryA.kt @@ -3,8 +3,8 @@ package io.github.notenoughupdates.moulconfig.test import com.google.gson.annotations.Expose import io.github.notenoughupdates.moulconfig.annotations.* import io.github.notenoughupdates.moulconfig.observer.Property +import org.lwjgl.glfw.GLFW import java.util.* -import kotlin.collections.ArrayList class TestCategoryA { @ConfigOption(name = "Test Option", desc = "Test toggle") @@ -90,4 +90,9 @@ class TestCategoryA { return str } } + + @Expose + @ConfigOption(name = "Keybind", desc = "The Number One") + @ConfigEditorKeybind(defaultKey = GLFW.GLFW_KEY_1) + var slot1: Int = GLFW.GLFW_KEY_1 }