Mouse cursors support

This commit is contained in:
DBotThePony 2024-01-04 18:36:52 +07:00
parent 005c8b0396
commit c52995541b
Signed by: DBot
GPG Key ID: DCC23B5715498507
9 changed files with 88 additions and 5 deletions

View File

@ -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);
}
}

View File

@ -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<Long>()
private var BEAM_CURSOR by WriteOnce<Long>()
private var HAND_CURSOR by WriteOnce<Long>()
private var NOT_ALLOWED_CURSOR by WriteOnce<Long>()
private var CROSSHAIR_CURSOR by WriteOnce<Long>()
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

View File

@ -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<out S : Screen>(
var markerPos = backgroundColor.toHSV()
protected set
override val cursorType: CursorType
get() = if (isDisabled.get()) CursorType.NOT_ALLOWED else CursorType.CROSSHAIR
fun setColor(color: Either<RGBAColor, HSVColor>) {
color.map(
{ markerPos = it.toHSV(); if (it.canRepresentHue()) backgroundColor = HSVColor(it.toHSV().hue, 1f, 1f).toRGBA() },
@ -146,6 +150,9 @@ abstract class AbstractColorWangPanel<out S : Screen>(
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<out S : Screen>(
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<S>(screen, middleStrip, width = 50f) {
init {
dock = Dock.RIGHT

View File

@ -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<out S : Screen> @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<out S : Screen> @JvmOverloads constructor(
if (scissor) {
popScissorRect()
}
if (isHovered) {
cursorType.setTo()
}
}
fun updateAbsolutePosition() {

View File

@ -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<out S : Screen>(
}
}
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
}

View File

@ -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<out S : Screen> @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<out S : Screen> @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<out S : Screen> @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<out S : Screen> @JvmOverloads constructor(
super.tickInner()
if (isFocusedThis) {
if (!isAvailable.asBoolean) {
if (!isEnabled.asBoolean) {
killFocus()
return
}
@ -70,7 +71,7 @@ open class NetworkNumberInputPanel<out S : Screen> @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

View File

@ -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<out S : Screen>(
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)

View File

@ -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<out S : Screen>(
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) {

View File

@ -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<out S : Screen>(
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) {