All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.peanuuutz.fork.ui.scene.screen.ScreenPointerService.kt Maven / Gradle / Ivy

The newest version!
package net.peanuuutz.fork.ui.scene.screen

import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import kotlinx.coroutines.Dispatchers
import net.peanuuutz.fork.coroutine.core.Client
import net.peanuuutz.fork.ui.ui.context.pointer.PointerIcon
import net.peanuuutz.fork.ui.ui.context.pointer.PointerService
import net.peanuuutz.fork.ui.ui.unit.FloatOffset
import net.peanuuutz.fork.util.fork.InternalForkApi
import net.peanuuutz.fork.util.minecraft.client
import org.lwjgl.glfw.GLFW
import kotlin.coroutines.EmptyCoroutineContext

@Stable
object ScreenPointerService : PointerService {
    // -------- Position --------

    override var position: FloatOffset
        get() = _position
        set(value) {
            if (_position == value) {
                return
            }
            _position = value
            recordPositionModification(value)
        }

    private var _position: FloatOffset by mutableStateOf(FloatOffset.Zero)

    @InternalForkApi
    fun setPosition(x: Float, y: Float) { // From Java
        position = FloatOffset(x, y)
    }

    private fun recordPositionModification(new: FloatOffset) {
        recordModification {
            val window = client.window
            val scaleFactor = window.scaleFactor
            val scaledX = new.x * scaleFactor
            val scaledY = new.y * scaleFactor
            GLFW.glfwSetCursorPos(window.handle, scaledX, scaledY)
        }
    }

    // -------- Icon --------

    private var icon = PointerIcon.Default

    private val iconStack: ArrayDeque = ArrayDeque(4)

    private val createdPointerHandle: MutableMap = mutableMapOf()

    override fun pushIcon(icon: PointerIcon) {
        iconStack.add(icon)
        if (ScreenPointerService.icon == icon) {
            return
        }
        ScreenPointerService.icon = icon
        recordIconModification(icon)
    }

    override fun popIcon() {
        iconStack.removeLastOrNull()
        val icon = iconStack.lastOrNull() ?: PointerIcon.Default
        if (ScreenPointerService.icon == icon) {
            return
        }
        ScreenPointerService.icon = icon
        recordIconModification(icon)
    }

    private fun recordIconModification(new: PointerIcon) {
        recordModification {
            val newPointer = createdPointerHandle.getOrPut(new) {
                GLFW.glfwCreateStandardCursor(new.code)
            }
            GLFW.glfwSetCursor(client.window.handle, newPointer)
        }
    }

    // -------- Record --------

    private fun recordModification(block: () -> Unit) {
        Dispatchers.Client.dispatch(EmptyCoroutineContext, block)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy