197 lines
5.2 KiB
Kotlin
197 lines
5.2 KiB
Kotlin
package net.shadowfacts.cacao
|
|
|
|
import net.minecraft.client.MinecraftClient
|
|
import net.minecraft.client.gui.screen.ingame.HandledScreen
|
|
import net.minecraft.client.util.math.MatrixStack
|
|
import net.minecraft.entity.player.PlayerInventory
|
|
import net.minecraft.screen.ScreenHandler
|
|
import net.minecraft.sound.SoundEvents
|
|
import net.minecraft.text.Text
|
|
import net.shadowfacts.cacao.geometry.Point
|
|
import net.shadowfacts.cacao.util.KeyModifiers
|
|
import net.shadowfacts.cacao.util.MouseButton
|
|
import net.shadowfacts.cacao.util.RenderHelper
|
|
import net.shadowfacts.cacao.window.ScreenHandlerWindow
|
|
import net.shadowfacts.cacao.window.Window
|
|
import org.lwjgl.glfw.GLFW
|
|
import org.lwjgl.opengl.GL11
|
|
import java.util.*
|
|
|
|
/**
|
|
* @author shadowfacts
|
|
*/
|
|
open class CacaoHandledScreen<Handler: ScreenHandler>(
|
|
handler: Handler,
|
|
playerInv: PlayerInventory,
|
|
title: Text,
|
|
): HandledScreen<Handler>(handler, playerInv, title), AbstractCacaoScreen {
|
|
|
|
private val _windows = LinkedList<Window>()
|
|
|
|
override val windows: List<Window> = _windows
|
|
|
|
private var hasAppeared = false
|
|
|
|
|
|
override fun <T: Window> addWindow(window: T, index: Int): T {
|
|
if (window is ScreenHandlerWindow && window.screenHandler != handler) {
|
|
throw RuntimeException("Adding ScreenHandlerWindow to CacaoHandledScreen with different screen handler is not supported")
|
|
}
|
|
if (hasAppeared) {
|
|
window.viewController.viewWillAppear()
|
|
}
|
|
|
|
_windows.add(index, window)
|
|
|
|
window.screen = this
|
|
window.wasAdded()
|
|
window.resize(width, height)
|
|
|
|
return window
|
|
}
|
|
|
|
override fun <T : Window> addWindow(window: T): T {
|
|
return addWindow(window, _windows.size)
|
|
}
|
|
|
|
override fun removeWindow(window: Window) {
|
|
_windows.remove(window)
|
|
if (windows.isEmpty()) {
|
|
onClose()
|
|
}
|
|
}
|
|
|
|
override fun screenWillAppear() {
|
|
windows.forEach {
|
|
it.viewController.viewWillAppear()
|
|
}
|
|
}
|
|
|
|
override fun init() {
|
|
super.init()
|
|
|
|
windows.forEach {
|
|
it.resize(width, height)
|
|
}
|
|
}
|
|
|
|
override fun onClose() {
|
|
super.onClose()
|
|
|
|
windows.forEach {
|
|
it.viewController.viewWillDisappear()
|
|
it.viewController.viewDidDisappear()
|
|
|
|
it.firstResponder = null
|
|
}
|
|
}
|
|
|
|
override fun drawBackground(matrixStack: MatrixStack, delta: Float, mouseX: Int, mouseY: Int) {
|
|
}
|
|
|
|
override fun drawForeground(matrixStack: MatrixStack, mouseX: Int, mouseY: Int) {
|
|
// no-op
|
|
}
|
|
|
|
override fun render(matrixStack: MatrixStack, mouseX: Int, mouseY: Int, delta: Float) {
|
|
val mouse = Point(mouseX, mouseY)
|
|
|
|
matrixStack.push()
|
|
matrixStack.translate(0.0, 0.0, -350.0)
|
|
|
|
for (i in windows.indices) {
|
|
val it = windows[i]
|
|
|
|
if (i == windows.size - 1) {
|
|
renderBackground(matrixStack)
|
|
}
|
|
|
|
if (it is ScreenHandlerWindow) {
|
|
if (i == windows.size - 1) {
|
|
super.render(matrixStack, mouseX, mouseY, delta)
|
|
} else {
|
|
// if the screen handler window is not the frontmost, we fake the mouse x/y to disable the slot mouseover effect
|
|
super.render(matrixStack, -1, -1, delta)
|
|
}
|
|
|
|
matrixStack.pop()
|
|
}
|
|
|
|
it.draw(matrixStack, mouse, delta)
|
|
}
|
|
|
|
drawMouseoverTooltip(matrixStack, mouseX, mouseY)
|
|
}
|
|
|
|
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
|
val window = windows.lastOrNull()
|
|
val result = window?.mouseClicked(Point(mouseX, mouseY), MouseButton.fromMC(button))
|
|
return if (result == true) {
|
|
RenderHelper.playSound(SoundEvents.UI_BUTTON_CLICK)
|
|
true
|
|
} else if (window is ScreenHandlerWindow) {
|
|
super.mouseClicked(mouseX, mouseY, button)
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
|
|
override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
|
|
val window = windows.lastOrNull()
|
|
val startPoint = Point(mouseX, mouseY)
|
|
val delta = Point(deltaX, deltaY)
|
|
val result = window?.mouseDragged(startPoint, delta, MouseButton.fromMC(button))
|
|
return if (result == true) {
|
|
true
|
|
} else if (window is ScreenHandlerWindow) {
|
|
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
|
|
override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
|
val window = windows.lastOrNull()
|
|
val result = window?.mouseReleased(Point(mouseX, mouseY), MouseButton.fromMC(button))
|
|
return if (result == true) {
|
|
true
|
|
} else if (window is ScreenHandlerWindow) {
|
|
super.mouseReleased(mouseX, mouseY, button)
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
|
|
override fun mouseScrolled(mouseX: Double, mouseY: Double, amount: Double): Boolean {
|
|
val window = windows.lastOrNull()
|
|
val result = window?.mouseScrolled(Point(mouseX, mouseY), amount)
|
|
return result == true
|
|
}
|
|
|
|
override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
|
|
if (keyCode == GLFW.GLFW_KEY_ESCAPE) {
|
|
windows.lastOrNull()?.removeFromScreen()
|
|
return true
|
|
} else {
|
|
val modifiersSet by lazy { KeyModifiers(modifiers) }
|
|
if (findResponder { it.keyPressed(keyCode, modifiersSet) }) {
|
|
return true
|
|
}
|
|
return super.keyPressed(keyCode, scanCode, modifiers)
|
|
}
|
|
}
|
|
|
|
override fun charTyped(char: Char, modifiers: Int): Boolean {
|
|
val modifiersSet by lazy { KeyModifiers(modifiers) }
|
|
if (findResponder { it.charTyped(char, modifiersSet) }) {
|
|
return true
|
|
}
|
|
return super.charTyped(char, modifiers)
|
|
}
|
|
|
|
override fun shouldCloseOnEsc(): Boolean {
|
|
return false
|
|
}
|
|
|
|
}
|