diff --git a/src/main/java/gay/asoji/innerpastels/events/KeyInputEvent.java b/src/main/java/gay/asoji/innerpastels/events/KeyInputEvent.java index 4498b211..07b7e5fe 100644 --- a/src/main/java/gay/asoji/innerpastels/events/KeyInputEvent.java +++ b/src/main/java/gay/asoji/innerpastels/events/KeyInputEvent.java @@ -12,11 +12,11 @@ @FunctionalInterface public interface KeyInputEvent { - Event EVENT = EventFactory.createArrayBacked(KeyInputEvent.class, (listeners) -> (key, scancode, action, mods) -> { + Event EVENT = EventFactory.createArrayBacked(KeyInputEvent.class, (listeners) -> (key, action, mods) -> { for (KeyInputEvent listener : listeners) { - listener.onKeyInput(key, scancode, action, mods); + listener.onKeyInput(key, action, mods); } }); - void onKeyInput(int key, int scancode, InputAction action, int mods); + void onKeyInput(int key, InputAction action, int mods); } diff --git a/src/main/java/gay/asoji/innerpastels/mixins/KeyboardHandlerMixin.java b/src/main/java/gay/asoji/innerpastels/mixins/KeyboardHandlerMixin.java index 7bda55d8..dba6b2f7 100644 --- a/src/main/java/gay/asoji/innerpastels/mixins/KeyboardHandlerMixin.java +++ b/src/main/java/gay/asoji/innerpastels/mixins/KeyboardHandlerMixin.java @@ -21,7 +21,7 @@ private void onKeyPress(long handle, int key, int scancode, int action, int mods return; InputAction inputAction = InputAction.from(action); - KeyInputEvent.EVENT.invoker().onKeyInput(key, scancode, inputAction, mods); + KeyInputEvent.EVENT.invoker().onKeyInput(key, inputAction, mods); } diff --git a/src/main/java/gay/asoji/innerpastels/mixins/MinecraftClientMixin.java b/src/main/java/gay/asoji/innerpastels/mixins/MinecraftClientMixin.java deleted file mode 100644 index 0f5fc63b..00000000 --- a/src/main/java/gay/asoji/innerpastels/mixins/MinecraftClientMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package gay.asoji.innerpastels.mixins; - -import com.mojang.blaze3d.platform.Window; -import gay.asoji.innerpastels.client.imgui.InnerPastelsImGuiImpl; -import net.minecraft.client.Minecraft; -import net.minecraft.client.main.GameConfig; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(Minecraft.class) -public class MinecraftClientMixin { - @Shadow @Final private Window window; - - @Inject(at = @At("TAIL"),method = "") - private void onGLFWInit(GameConfig gameConfig, CallbackInfo ci){ - InnerPastelsImGuiImpl.INSTANCE.glfwInit(window.getWindow()); - } -} diff --git a/src/main/java/gay/asoji/innerpastels/mixins/MinecraftMixin.java b/src/main/java/gay/asoji/innerpastels/mixins/MinecraftMixin.java new file mode 100644 index 00000000..27d41d1f --- /dev/null +++ b/src/main/java/gay/asoji/innerpastels/mixins/MinecraftMixin.java @@ -0,0 +1,16 @@ +package gay.asoji.innerpastels.mixins; + +import gay.asoji.innerpastels.client.imgui.InnerPastelsImGuiImpl; +import net.minecraft.client.Minecraft; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Minecraft.class) +public class MinecraftMixin { + @Inject(method = "close", at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;shutdownExecutors()V", shift = At.Shift.BEFORE)) + public void close(CallbackInfo ci) { + InnerPastelsImGuiImpl.INSTANCE.destroy(); // destroying your fathers bed since 2024 + } +} diff --git a/src/main/java/gay/asoji/innerpastels/mixins/MouseHandlerMixin.java b/src/main/java/gay/asoji/innerpastels/mixins/MouseHandlerMixin.java index 7fb3d4cd..01505822 100644 --- a/src/main/java/gay/asoji/innerpastels/mixins/MouseHandlerMixin.java +++ b/src/main/java/gay/asoji/innerpastels/mixins/MouseHandlerMixin.java @@ -1,5 +1,6 @@ package gay.asoji.innerpastels.mixins; +import gay.asoji.innerpastels.client.imgui.InnerPastelsImGuiImpl; import gay.asoji.innerpastels.events.InputAction; import gay.asoji.innerpastels.events.MouseInputEvent; import gay.asoji.innerpastels.events.MouseScrollInputEvent; @@ -11,6 +12,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(MouseHandler.class) public class MouseHandlerMixin { @@ -33,4 +35,23 @@ private void onScroll(long windowPointer, double xOffset, double yOffset, Callba MouseScrollInputEvent.EVENT.invoker().onScroll(xOffset, yOffset); } + + @Inject(method = "grabMouse", at = @At("HEAD")) + public void grabMouse(CallbackInfo ci) { + InnerPastelsImGuiImpl.INSTANCE.mouseFocus(); + } + + @Inject(method = "xpos", at = @At("HEAD"), cancellable = true) + public void cancelMouseX(CallbackInfoReturnable cir) { + if (InnerPastelsImGuiImpl.INSTANCE.isMouseHidden()) { + cir.setReturnValue(Double.MIN_VALUE); + } + } + + @Inject(method = "ypos", at = @At("HEAD"), cancellable = true) + public void cancelMouseY(CallbackInfoReturnable cir) { + if (InnerPastelsImGuiImpl.INSTANCE.isMouseHidden()) { + cir.setReturnValue(Double.MIN_VALUE); + } + } } diff --git a/src/main/kotlin/gay/asoji/innerpastels/client/InnerPastelsClient.kt b/src/main/kotlin/gay/asoji/innerpastels/client/InnerPastelsClient.kt index 7c7bef2b..58f63b91 100644 --- a/src/main/kotlin/gay/asoji/innerpastels/client/InnerPastelsClient.kt +++ b/src/main/kotlin/gay/asoji/innerpastels/client/InnerPastelsClient.kt @@ -1,19 +1,15 @@ package gay.asoji.innerpastels.client import com.mojang.blaze3d.platform.InputConstants -import gay.asoji.innerpastels.InnerPastels -import gay.asoji.innerpastels.client.imgui.InnerPastelsImGuiImpl -import gay.asoji.innerpastels.client.imgui.InnerPastelsImGuiImpl.implGl3 -import gay.asoji.innerpastels.client.imgui.InnerPastelsImGuiImpl.implGlfw import gay.asoji.innerpastels.client.imgui.ImGuiPanel +import gay.asoji.innerpastels.client.imgui.InnerPastelsImGuiImpl import gay.asoji.innerpastels.client.imgui.InnerPastelsImGuiImpl.endFrame -import gay.asoji.innerpastels.client.imgui.InnerPastelsImGuiImpl.imGui -import gay.asoji.innerpastels.client.imgui.InnerPastelsImGuiImpl.windowHandle +import gay.asoji.innerpastels.client.imgui.InnerPastelsImGuiImpl.initialize +import gay.asoji.innerpastels.client.imgui.InnerPastelsImGuiImpl.startFrame import gay.asoji.innerpastels.events.InputAction import gay.asoji.innerpastels.events.KeyInputEvent import gay.asoji.innerpastels.events.MouseInputEvent import gay.asoji.innerpastels.events.MouseScrollInputEvent -import imgui.ImGui import imgui.type.ImBoolean import net.fabricmc.api.ClientModInitializer import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents @@ -23,7 +19,6 @@ import net.fabricmc.loader.api.FabricLoader import net.minecraft.client.KeyMapping import net.minecraft.client.Minecraft import org.lwjgl.glfw.GLFW -import java.util.* class InnerPastelsClient : ClientModInitializer { private var isImGuiRenderEnabled: Boolean = false @@ -32,7 +27,8 @@ class InnerPastelsClient : ClientModInitializer { "key.innerpastels.developerui", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_M, - "category.innerpastels.developer") + "category.innerpastels.developer" + ) fun initializeDevKeybinds() { val toggleUIKeybind = KeyBindingHelper.registerKeyBinding(DEVELOPER_UI_BINDING) @@ -44,56 +40,46 @@ class InnerPastelsClient : ClientModInitializer { while (DEVELOPER_UI_BINDING.consumeClick()) { if (client.player != null && client.screen == null) { isImGuiRenderEnabled = !isImGuiRenderEnabled - - implGl3.dispose() - implGlfw.dispose() } } } override fun onInitializeClient() { if (FabricLoader.getInstance().isDevelopmentEnvironment) { - // THIS IS PROBABLY NOT CORRECT, IF IT ISNT, FUCKING REMOVE IT LATER, ALL CONTEXT CREATION SHOULD PROBABLY BE FUCKING LEFT TO THE IMPL [OR THE PANEL ITSELF]? - ImGui.createContext() initializeDevKeybinds() } HudRenderCallback.EVENT.register { gui, tickDelta -> - if (!isImGuiRenderEnabled) { - return@register - } - implGlfw.newFrame() - ImGui.newFrame() + initialize(Minecraft.getInstance().window.window) + startFrame() - panels.forEach { - it.render(ImBoolean()) + if (isImGuiRenderEnabled) { + panels.forEach { + it.render(ImBoolean()) + } } - implGl3.renderDrawData(ImGui.getDrawData()) - ImGui.render() - endFrame(windowHandle) + endFrame() } - KeyInputEvent.EVENT.register { key, scancode, action, mods -> - when (action) { - InputAction.PRESS -> InnerPastelsImGuiImpl.keyPressed(key, scancode, mods) - InputAction.RELEASE -> InnerPastelsImGuiImpl.keyReleased(key, scancode, mods) + KeyInputEvent.EVENT.register { key, action, mods -> + when (action ?: return@register) { + InputAction.PRESS -> InnerPastelsImGuiImpl.keyPress(key, mods) + InputAction.RELEASE -> InnerPastelsImGuiImpl.keyRelease(key, mods) } } MouseInputEvent.EVENT.register { button, action, mods -> val mouseX = Minecraft.getInstance().mouseHandler.xpos() val mouseY = Minecraft.getInstance().mouseHandler.ypos() - when (action) { - InputAction.PRESS -> InnerPastelsImGuiImpl.mouseClicked(mouseX, mouseY, button) - InputAction.RELEASE -> InnerPastelsImGuiImpl.mouseReleased(mouseX, mouseY, button) + when (action ?: return@register) { + InputAction.PRESS -> InnerPastelsImGuiImpl.mouseClick(mouseX, mouseY, button) + InputAction.RELEASE -> InnerPastelsImGuiImpl.mouseRelease(mouseX, mouseY, button) } } - MouseScrollInputEvent.EVENT.register{ xOffset, yOffset -> - val mouseX = Minecraft.getInstance().mouseHandler.xpos() - val mouseY = Minecraft.getInstance().mouseHandler.ypos() - InnerPastelsImGuiImpl.mouseScrolled(mouseX, mouseY, xOffset, yOffset) + MouseScrollInputEvent.EVENT.register { xOffset, yOffset -> + InnerPastelsImGuiImpl.mouseScroll(xOffset, yOffset) } } diff --git a/src/main/kotlin/gay/asoji/innerpastels/client/imgui/InnerPastelsImGuiImpl.kt b/src/main/kotlin/gay/asoji/innerpastels/client/imgui/InnerPastelsImGuiImpl.kt index 83303229..bbb8f9ac 100644 --- a/src/main/kotlin/gay/asoji/innerpastels/client/imgui/InnerPastelsImGuiImpl.kt +++ b/src/main/kotlin/gay/asoji/innerpastels/client/imgui/InnerPastelsImGuiImpl.kt @@ -1,135 +1,154 @@ package gay.asoji.innerpastels.client.imgui -import imgui.ImFontAtlas -import imgui.ImFontConfig import imgui.ImGui +import imgui.flag.ImGuiCol import imgui.flag.ImGuiConfigFlags import imgui.gl3.ImGuiImplGl3 import imgui.glfw.ImGuiImplGlfw +import imgui.internal.ImGuiContext import net.fabricmc.api.EnvType import net.fabricmc.api.Environment -import net.minecraft.client.Minecraft import org.lwjgl.glfw.GLFW -import org.lwjgl.glfw.GLFW.glfwGetCurrentContext -import org.lwjgl.glfw.GLFW.glfwMakeContextCurrent - @Environment(EnvType.CLIENT) object InnerPastelsImGuiImpl { - var implGl3: ImGuiImplGl3 = ImGuiImplGl3() - var implGlfw: ImGuiImplGlfw = ImGuiImplGlfw() - var imGui: ImGui = ImGui() - var imGuiIO = ImGui.getIO() - var windowHandle: Long = Minecraft.getInstance().window.window - - // GLFW Initialization for imgui. - fun glfwInit(handle: Long) { - implGlfw.init(handle, false) - implGl3.init() - - ImGui.createContext() - imGuiInit() - windowHandle = handle - } + var isInitialized = false + private set - fun imGuiInit() { - imGuiIO.iniFilename = null - imGuiIO.addConfigFlags(ImGuiConfigFlags.NavEnableKeyboard) - imGuiIO.addConfigFlags(ImGuiConfigFlags.DockingEnable) - imGuiIO.addConfigFlags(ImGuiConfigFlags.ViewportsEnable) + lateinit var imguiContext: ImGuiContext + private set - val fontAtlas: ImFontAtlas = imGuiIO.getFonts() - val fontConfig = ImFontConfig() + lateinit var imguiGl3: ImGuiImplGl3 + private set - fontConfig.glyphRanges = fontAtlas.glyphRangesCyrillic + lateinit var imguiGlfw: ImGuiImplGlfw + private set - fontAtlas.addFontDefault() + val isMouseHidden: Boolean + get() = isInitialized && ImGui.getIO().wantCaptureMouse - fontConfig.mergeMode = true - fontConfig.pixelSnapH = true + fun initialize(handle: Long) { + if (isInitialized) { + return + } - fontConfig.destroy() + imguiGlfw = ImGuiImplGlfw() + imguiGl3 = ImGuiImplGl3() - } + imGuiInitialize() + imguiGlfw.init(handle, true) + imguiGl3.init() - fun endFrame(windowPtr: Long) { - implGl3.renderDrawData(ImGui.getDrawData()) + isInitialized = true + } - if (ImGui.getIO().hasConfigFlags(ImGuiConfigFlags.ViewportsEnable)) { - val backupWindowPtr = glfwGetCurrentContext() - ImGui.updatePlatformWindows() - ImGui.renderPlatformWindowsDefault() - glfwMakeContextCurrent(backupWindowPtr) + fun mouseFocus() { + if (!isInitialized) { + return } + + ImGui.setWindowFocus(null) } - fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean { - if (imGuiIO.getMouseDown(button)) { - imGuiIO.setMouseDown(booleanArrayOf(true)) + fun mouseClick(mouseX: Double, mouseY: Double, button: Int): Boolean { + if (!isInitialized || !ImGui.getIO().wantCaptureMouse) { + return false } - return imGuiIO.wantCaptureMouse + ImGui.getIO().setMousePos(mouseX.toFloat(), mouseY.toFloat()) + ImGui.getIO().setMouseDown(button, true) + return true } - fun mouseScrolled(mouseX: Double, mouseY: Double, scrollX: Double, scrollY: Double): Boolean { - if (imGuiIO.wantCaptureMouse) { - imGuiIO.mouseWheelH = scrollX.toFloat() - imGuiIO.mouseWheel = scrollY.toFloat() + fun mouseRelease(mouseX: Double, mouseY: Double, button: Int): Boolean { + if (!isInitialized || !ImGui.getIO().wantCaptureMouse) { + return false } - return imGuiIO.wantCaptureMouse + ImGui.getIO().setMousePos(mouseX.toFloat(), mouseY.toFloat()) + ImGui.getIO().setMouseDown(button, false) + return true } - fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean { - if (imGuiIO.wantCaptureMouse) { - if (imGuiIO.getMouseDown(button)) { - imGuiIO.setMouseDown(booleanArrayOf(false)) - } + fun mouseScroll(xOff: Double, yOff: Double): Boolean { + if (!isInitialized || !ImGui.getIO().wantCaptureMouse) { + return false } - return imGuiIO.wantCaptureMouse + ImGui.getIO().mouseWheelH = xOff.toFloat() + ImGui.getIO().mouseWheel = yOff.toFloat() + return true } - fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean { - if (imGuiIO.wantCaptureKeyboard) { - imGuiIO.keyCtrl = modifiers and GLFW.GLFW_MOD_CONTROL != 0 - imGuiIO.keyShift = modifiers and GLFW.GLFW_MOD_SHIFT != 0 - imGuiIO.keyAlt = modifiers and GLFW.GLFW_MOD_ALT != 0 - imGuiIO.keySuper = modifiers and GLFW.GLFW_MOD_SUPER != 0 - - if (imGuiIO.getKeysDown(keyCode)) { - imGuiIO.setKeysDown(booleanArrayOf(false)) - } + fun keyPress(keyCode: Int, mods: Int): Boolean { + if (!isInitialized || !ImGui.getIO().wantCaptureKeyboard) { + return false } - return imGuiIO.wantCaptureKeyboard + ImGui.getIO().keyCtrl = mods and GLFW.GLFW_MOD_CONTROL != 0 + ImGui.getIO().keyAlt = mods and GLFW.GLFW_MOD_ALT != 0 + ImGui.getIO().keyShift = mods and GLFW.GLFW_MOD_SHIFT != 0 + ImGui.getIO().keySuper = mods and GLFW.GLFW_MOD_SUPER != 0 + ImGui.getIO().setKeysDown(keyCode, true) + return true } - fun keyReleased(keyCode: Int, scanCode: Int, modifiers: Int): Boolean { - if (imGuiIO.wantCaptureKeyboard) { - imGuiIO.keyCtrl = modifiers and GLFW.GLFW_MOD_CONTROL != 0 - imGuiIO.keyShift = modifiers and GLFW.GLFW_MOD_SHIFT != 0 - imGuiIO.keyAlt = modifiers and GLFW.GLFW_MOD_ALT != 0 - imGuiIO.keySuper = modifiers and GLFW.GLFW_MOD_SUPER != 0 + fun keyRelease(keyCode: Int, mods: Int): Boolean { + if (!isInitialized || !ImGui.getIO().wantCaptureKeyboard) { + return false + } + + ImGui.getIO().keyCtrl = mods and GLFW.GLFW_MOD_CONTROL != 0 + ImGui.getIO().keyAlt = mods and GLFW.GLFW_MOD_ALT != 0 + ImGui.getIO().keyShift = mods and GLFW.GLFW_MOD_SHIFT != 0 + ImGui.getIO().keySuper = mods and GLFW.GLFW_MOD_SUPER != 0 + ImGui.getIO().setKeysDown(keyCode, false) + return true + } - if (imGuiIO.getKeysDown(keyCode)) { - imGuiIO.setKeysDown(booleanArrayOf(false)) - } + fun destroy() { + if (!isInitialized) { + return } - return imGuiIO.wantCaptureKeyboard + imguiGl3.dispose() + imguiGlfw.dispose() + ImGui.destroyContext(imguiContext) + } + + fun startFrame() { + imguiGlfw.newFrame() + ImGui.newFrame() } - fun charTyped(codePoint: Char, modifiers: Int): Boolean { - if (imGuiIO.wantCaptureKeyboard) { - imGuiIO.keyCtrl = modifiers and GLFW.GLFW_MOD_CONTROL != 0 - imGuiIO.keyShift = modifiers and GLFW.GLFW_MOD_SHIFT != 0 - imGuiIO.keyAlt = modifiers and GLFW.GLFW_MOD_ALT != 0 - imGuiIO.keySuper = modifiers and GLFW.GLFW_MOD_SUPER != 0 + fun endFrame() { + ImGui.render() + imguiGl3.renderDrawData(ImGui.getDrawData()) - imGuiIO.addInputCharacter(codePoint.code) + if (ImGui.getIO().hasConfigFlags(ImGuiConfigFlags.ViewportsEnable)) { + val backupHandle = GLFW.glfwGetCurrentContext(); + ImGui.updatePlatformWindows(); + ImGui.renderPlatformWindowsDefault(); + GLFW.glfwMakeContextCurrent(backupHandle); } + } - return imGuiIO.wantCaptureKeyboard + private fun imGuiInitialize() { + imguiContext = ImGui.createContext() + + val io = ImGui.getIO() + io.iniFilename = null + io.configViewportsNoTaskBarIcon = true; + io.addConfigFlags(ImGuiConfigFlags.NavEnableKeyboard) + io.addConfigFlags(ImGuiConfigFlags.DockingEnable) + io.addConfigFlags(ImGuiConfigFlags.ViewportsEnable) + io.configViewportsNoTaskBarIcon = true + io.fonts.addFontDefault() + + if (io.hasConfigFlags(ImGuiConfigFlags.ViewportsEnable)) { + val style = ImGui.getStyle() + style.windowRounding = 0.0f + style.setColor(ImGuiCol.WindowBg, ImGui.getColorU32(ImGuiCol.WindowBg, 1f)) + } } } \ No newline at end of file diff --git a/src/main/resources/innerpastels.mixins.json b/src/main/resources/innerpastels.mixins.json index e10cfeac..addda126 100644 --- a/src/main/resources/innerpastels.mixins.json +++ b/src/main/resources/innerpastels.mixins.json @@ -6,8 +6,8 @@ "mixins": [ ], "client": [ - "MinecraftClientMixin", "KeyboardHandlerMixin", + "MinecraftMixin", "MouseHandlerMixin" ], "injectors": {