diff --git a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java index 424e15699..8f0b0c57b 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java +++ b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java @@ -241,6 +241,7 @@ public final class OverdriveThatMatters { EVENT_BUS.addListener(EventPriority.LOWEST, ClientTickHandlerKt::onClientTick); EVENT_BUS.addListener(EventPriority.HIGHEST, ClientTickHandlerKt::onClientConnected); EVENT_BUS.addListener(EventPriority.HIGHEST, ClientTickHandlerKt::onClientDisconnected); + EVENT_BUS.addListener(EventPriority.NORMAL, ClientTickHandlerKt::onClientPostRender); EVENT_BUS.addListener(EventPriority.NORMAL, ClientEventHandlerKt::tooltipEvent); EVENT_BUS.addListener(EventPriority.NORMAL, QuantumBatteryItem.Companion::clientDisconnect); @@ -254,5 +255,6 @@ public final class OverdriveThatMatters { EVENT_BUS.addListener(EventPriority.NORMAL, ExosuitModel::onPlayerRendered); event.enqueueWork(GlobalEventHandlerKt::recordClientThread); + event.enqueueWork(ClientTickHandlerKt::createCursors); } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/ClientTickHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/ClientTickHandler.kt index 0d812203e..4b456c734 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/ClientTickHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/ClientTickHandler.kt @@ -2,14 +2,62 @@ package ru.dbotthepony.mc.otm.client import net.minecraftforge.client.event.ClientPlayerNetworkEvent import net.minecraftforge.event.TickEvent +import net.minecraftforge.event.TickEvent.RenderTickEvent +import org.lwjgl.glfw.GLFW import ru.dbotthepony.mc.otm.core.util.IConditionalTickable import ru.dbotthepony.mc.otm.core.util.ITickable import ru.dbotthepony.mc.otm.core.util.TickList +import ru.dbotthepony.mc.otm.core.util.WriteOnce import ru.dbotthepony.mc.otm.isClient +import java.util.function.LongSupplier private val preTickList = TickList() private val postTickList = TickList() +var MODIFIED_CURSOR = false + private set + +private var MODIFIED_CURSOR_FRAMES = 3 + +private var ARROW_CURSOR by WriteOnce() +private var BEAM_CURSOR by WriteOnce() +private var HAND_CURSOR by WriteOnce() +private var NOT_ALLOWED_CURSOR by WriteOnce() +private var CROSSHAIR_CURSOR by WriteOnce() + +fun createCursors() { + ARROW_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_ARROW_CURSOR) + BEAM_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_IBEAM_CURSOR) + HAND_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_POINTING_HAND_CURSOR) + NOT_ALLOWED_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_NOT_ALLOWED_CURSOR) + CROSSHAIR_CURSOR = GLFW.glfwCreateStandardCursor(GLFW.GLFW_CROSSHAIR_CURSOR) + + check(ARROW_CURSOR != 0L) { "Failed to create ARROW_CURSOR. Are we not on main game thread?" } + check(BEAM_CURSOR != 0L) { "Failed to create BEAM_CURSOR. Are we not on main game thread?" } + check(HAND_CURSOR != 0L) { "Failed to create HAND_CURSOR. Are we not on main game thread?" } + check(NOT_ALLOWED_CURSOR != 0L) { "Failed to create NOT_ALLOWED_CURSOR. Are we not on main game thread?" } + check(CROSSHAIR_CURSOR != 0L) { "Failed to create CROSSHAIR_CURSOR. Are we not on main game thread?" } +} + +enum class CursorType(val pointer: LongSupplier) { + ARROW(::ARROW_CURSOR), BEAM(::BEAM_CURSOR), HAND(::HAND_CURSOR), NOT_ALLOWED(::NOT_ALLOWED_CURSOR), CROSSHAIR(::CROSSHAIR_CURSOR); + + fun setTo() { + GLFW.glfwSetCursor(minecraft.window.window, pointer.asLong) + MODIFIED_CURSOR = true + MODIFIED_CURSOR_FRAMES = 2 + } +} + +fun onClientPostRender(event: RenderTickEvent) { + if (event.phase == TickEvent.Phase.END) { + if (MODIFIED_CURSOR_FRAMES-- <= 0 && MODIFIED_CURSOR) { + GLFW.glfwSetCursor(minecraft.window.window, ARROW_CURSOR) + MODIFIED_CURSOR = false + } + } +} + var LOGGED_IN = false private set diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/ColorPicker.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/ColorPicker.kt index 3c5d8bf4e..da7fec976 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/ColorPicker.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/ColorPicker.kt @@ -7,6 +7,7 @@ import net.minecraft.client.gui.screens.Screen import net.minecraft.network.chat.Component import net.minecraft.resources.ResourceLocation import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.client.CursorType import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.playGuiClickSound import ru.dbotthepony.mc.otm.client.render.sprites.MatterySprite @@ -39,6 +40,9 @@ open class ColorBoxPanel( var markerPos = backgroundColor.toHSV() protected set + override val cursorType: CursorType + get() = if (isDisabled.get()) CursorType.NOT_ALLOWED else CursorType.CROSSHAIR + fun setColor(color: Either) { color.map( { markerPos = it.toHSV(); if (it.canRepresentHue()) backgroundColor = HSVColor(it.toHSV().hue, 1f, 1f).toRGBA() }, @@ -146,6 +150,9 @@ abstract class AbstractColorWangPanel( protected abstract fun onWangInput(newPosition: Float) + override val cursorType: CursorType + get() = if (isDisabled.get()) CursorType.NOT_ALLOWED else CursorType.ARROW + init { scissor = true } @@ -577,6 +584,9 @@ open class ColorPickerPanel( val middleStrip = EditablePanel(screen, this) val palette = ColorPalettePanel(screen, this, callback = { onPaletteChoose(it) }, isDisabled = isDisabled) + override val cursorType: CursorType + get() = if (isDisabled.get()) CursorType.NOT_ALLOWED else CursorType.ARROW + val hexInput = object : TextInputPanel(screen, middleStrip, width = 50f) { init { dock = Dock.RIGHT diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt index bde047208..bf05cdb7a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt @@ -17,6 +17,7 @@ import net.minecraft.world.inventory.Slot import net.minecraft.world.item.ItemStack import org.apache.logging.log4j.LogManager import ru.dbotthepony.mc.otm.SystemTime +import ru.dbotthepony.mc.otm.client.CursorType import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.moveMousePosScaled @@ -421,6 +422,7 @@ open class EditablePanel @JvmOverloads constructor( var acceptMouseInput = true var acceptKeyboardInput = true var grabMouseInput = false + open val cursorType: CursorType get() = CursorType.ARROW fun tryToGrabMouseInput(): Boolean { if (grabMouseInput) { @@ -898,6 +900,10 @@ open class EditablePanel @JvmOverloads constructor( if (scissor) { popScissorRect() } + + if (isHovered) { + cursorType.setTo() + } } fun updateAbsolutePosition() { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/AbstractButtonPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/AbstractButtonPanel.kt index e1da380a4..188b134de 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/AbstractButtonPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/AbstractButtonPanel.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.client.screen.panels.button import com.mojang.blaze3d.platform.InputConstants import net.minecraft.client.gui.screens.Screen +import ru.dbotthepony.mc.otm.client.CursorType import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.playGuiClickSound import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel @@ -30,6 +31,9 @@ abstract class AbstractButtonPanel( } } + override val cursorType: CursorType + get() = if (isDisabled) CursorType.NOT_ALLOWED else CursorType.ARROW + override fun test(value: Int): Boolean { return value == InputConstants.MOUSE_BUTTON_LEFT } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/NetworkNumberInputPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/NetworkNumberInputPanel.kt index f37fc4501..8b81f30f7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/NetworkNumberInputPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/NetworkNumberInputPanel.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.client.screen.panels.input import net.minecraft.client.gui.screens.Screen import net.minecraft.network.chat.Component +import ru.dbotthepony.mc.otm.client.CursorType import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel import ru.dbotthepony.mc.otm.core.TextComponent @@ -14,7 +15,7 @@ open class NetworkNumberInputPanel @JvmOverloads constructor( parent: EditablePanel<*>?, val networkValue: () -> BigDecimal, val callback: (BigDecimal) -> Unit, - val isAvailable: BooleanSupplier = BooleanSupplier { true }, + val isEnabled: BooleanSupplier = BooleanSupplier { true }, x: Float = 0f, y: Float = 0f, width: Float = 0f, @@ -35,7 +36,7 @@ open class NetworkNumberInputPanel @JvmOverloads constructor( screen = screen, parent = parent, callback = widget::accept, - isAvailable = { widget.allowSpectators || minecraft.player?.isSpectator != true }, + isEnabled = { widget.allowSpectators || minecraft.player?.isSpectator != true }, networkValue = networkValue, x = x, y = y, @@ -48,7 +49,7 @@ open class NetworkNumberInputPanel @JvmOverloads constructor( protected var inputStr = "" override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean { - if (!isAvailable.asBoolean) { + if (!isEnabled.asBoolean) { return true } @@ -59,7 +60,7 @@ open class NetworkNumberInputPanel @JvmOverloads constructor( super.tickInner() if (isFocusedThis) { - if (!isAvailable.asBoolean) { + if (!isEnabled.asBoolean) { killFocus() return } @@ -70,7 +71,7 @@ open class NetworkNumberInputPanel @JvmOverloads constructor( if (nextUpdateFromServer < System.currentTimeMillis()) { getOrCreateWidget().value = networkValue.invoke().toPlainString() inputStr = getOrCreateWidget().value - } else if (isAvailable.asBoolean) { + } else if (isEnabled.asBoolean) { if (inputStr != getOrCreateWidget().value) { inputStr = getOrCreateWidget().value diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/TextInputPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/TextInputPanel.kt index a18bfcdf9..bd7a9111b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/TextInputPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/TextInputPanel.kt @@ -13,6 +13,7 @@ import net.minecraft.client.gui.screens.Screen import net.minecraft.client.renderer.GameRenderer import net.minecraft.network.chat.Component import org.joml.Vector2i +import ru.dbotthepony.mc.otm.client.CursorType import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.isCtrlDown import ru.dbotthepony.mc.otm.client.isShiftDown @@ -151,6 +152,9 @@ open class TextInputPanel( open var backgroundColor = RGBAColor.BLACK open var isActive = true + override val cursorType: CursorType + get() = if (isActive) CursorType.BEAM else CursorType.NOT_ALLOWED + init { scissor = true dockPadding = DockProperty(2f, 2f, 2f, 2f) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/util/AnalogScrollBarPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/util/AnalogScrollBarPanel.kt index 83a7f8f7d..2e4f66893 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/util/AnalogScrollBarPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/util/AnalogScrollBarPanel.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.client.screen.panels.util import com.mojang.blaze3d.platform.InputConstants import net.minecraft.client.gui.screens.Screen +import ru.dbotthepony.mc.otm.client.CursorType import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel @@ -26,6 +27,9 @@ open class AnalogScrollBarPanel( var isScrolling = false private set + override val cursorType: CursorType + get() = if (maxScroll.invoke(this@AnalogScrollBarPanel) <= 0) CursorType.NOT_ALLOWED else CursorType.ARROW + override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { if (this@AnalogScrollBarPanel.width == ScrollBarConstants.SLIM_WIDTH) { if (isScrolling) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/util/DiscreteScrollBarPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/util/DiscreteScrollBarPanel.kt index e5f9a23f2..c402ff43e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/util/DiscreteScrollBarPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/util/DiscreteScrollBarPanel.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.client.screen.panels.util import com.mojang.blaze3d.platform.InputConstants import net.minecraft.client.gui.screens.Screen +import ru.dbotthepony.mc.otm.client.CursorType import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel import kotlin.math.roundToInt @@ -20,6 +21,9 @@ open class DiscreteScrollBarPanel( var isScrolling = false private set + override val cursorType: CursorType + get() = if (maxScroll.invoke(this@DiscreteScrollBarPanel) <= 0) CursorType.NOT_ALLOWED else CursorType.ARROW + override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { if (this@DiscreteScrollBarPanel.width == ScrollBarConstants.SLIM_WIDTH) { if (isScrolling) {