package net.shadowfacts.cacao import net.minecraft.client.MinecraftClient import net.minecraft.client.gui.screen.Screen import net.minecraft.sound.SoundEvents import net.minecraft.text.LiteralText import net.shadowfacts.cacao.geometry.Point import net.shadowfacts.cacao.util.MouseButton import net.shadowfacts.cacao.util.RenderHelper import net.shadowfacts.kiwidsl.dsl import java.util.* /** * This class serves as the bridge between Cacao and a Minecraft [Screen]. It renders Cacao [Window]s in Minecraft and * sends input events from Minecraft back to Cacao objects. * * @author shadowfacts */ open class CacaoScreen: Screen(LiteralText("CacaoScreen")) { // _windows is the internal, mutable object, since we only want it to by mutated by the add/removeWindow methods. private val _windows = LinkedList() /** * The list of windows that belong to this screen. * This list should never be modified directly, only by using the [addWindow]/[removeWindow] methods. */ val windows: List = _windows /** * Adds the given window to this screen's window list. * By default, the new window is added at the tail of the window list, making it the active window. * Only the active window will receive input events. * * @param window The Window to add to this screen. * @param index The index to insert the window into the window list at. * @return The window that was added, as a convenience. */ fun addWindow(window: T, index: Int = _windows.size): T { _windows.add(index, window) window.screen = this window.wasAdded() window.resize(width, height) return window } /** * Removes the given window from this screen's window list. */ fun removeWindow(window: Window) { _windows.remove(window) } override fun init() { super.init() windows.forEach { it.resize(width, height) } } override fun render(mouseX: Int, mouseY: Int, delta: Float) { if (minecraft != null) { // workaround this.minecraft sometimes being null causing a crash renderBackground() } val mouse = Point(mouseX, mouseY) windows.forEach { it.draw(mouse, 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 { 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 result == true } 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 result == true } }