PhysicalConnectivity/src/main/kotlin/net/shadowfacts/cacao/CacaoHandledScreen.kt

93 lines
2.6 KiB
Kotlin

package net.shadowfacts.cacao
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.MouseButton
import net.shadowfacts.cacao.util.RenderHelper
import net.shadowfacts.cacao.window.ScreenHandlerWindow
import net.shadowfacts.cacao.window.Window
import java.util.*
/**
* @author shadowfacts
*/
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
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")
}
_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)
}
override fun init() {
super.init()
windows.forEach {
it.resize(width, height)
}
}
override fun drawBackground(matrixStack: MatrixStack, delta: Float, mouseX: Int, mouseY: Int) {
// no-op
}
override fun render(matrixStack: MatrixStack, mouseX: Int, mouseY: Int, delta: Float) {
renderBackground(matrixStack)
val mouse = Point(mouseX, mouseY)
windows.forEachIndexed { index, it ->
it.draw(matrixStack, mouse, delta)
if (it is ScreenHandlerWindow) {
if (index == 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)
}
}
}
}
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
}
}
}