diff options
Diffstat (limited to 'src/main/kotlin/util/MoulConfigUtils.kt')
-rw-r--r-- | src/main/kotlin/util/MoulConfigUtils.kt | 443 |
1 files changed, 248 insertions, 195 deletions
diff --git a/src/main/kotlin/util/MoulConfigUtils.kt b/src/main/kotlin/util/MoulConfigUtils.kt index 00561d1..54528dd 100644 --- a/src/main/kotlin/util/MoulConfigUtils.kt +++ b/src/main/kotlin/util/MoulConfigUtils.kt @@ -1,12 +1,15 @@ - - package moe.nea.firmament.util +import io.github.notenoughupdates.moulconfig.common.IMinecraft import io.github.notenoughupdates.moulconfig.common.MyResourceLocation import io.github.notenoughupdates.moulconfig.gui.CloseEventListener +import io.github.notenoughupdates.moulconfig.gui.GuiComponent import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper import io.github.notenoughupdates.moulconfig.gui.GuiContext +import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext +import io.github.notenoughupdates.moulconfig.gui.MouseEvent import io.github.notenoughupdates.moulconfig.observer.GetSetter +import io.github.notenoughupdates.moulconfig.platform.ModernRenderContext import io.github.notenoughupdates.moulconfig.xml.ChildCount import io.github.notenoughupdates.moulconfig.xml.XMLContext import io.github.notenoughupdates.moulconfig.xml.XMLGuiLoader @@ -19,6 +22,7 @@ import me.shedaniel.math.Color import org.w3c.dom.Element import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds +import net.minecraft.client.gui.DrawContext import net.minecraft.client.gui.screen.Screen import moe.nea.firmament.gui.BarComponent import moe.nea.firmament.gui.FirmButtonComponent @@ -26,205 +30,254 @@ import moe.nea.firmament.gui.FirmHoverComponent import moe.nea.firmament.gui.FixedComponent import moe.nea.firmament.gui.ImageComponent import moe.nea.firmament.gui.TickComponent +import moe.nea.firmament.util.render.isUntranslatedGuiDrawContext object MoulConfigUtils { - val firmUrl = "http://firmament.nea.moe/moulconfig" - val universe = XMLUniverse.getDefaultUniverse().also { uni -> - uni.registerMapper(java.awt.Color::class.java) { - if (it.startsWith("#")) { - val hexString = it.substring(1) - val hex = hexString.toInt(16) - if (hexString.length == 6) { - return@registerMapper java.awt.Color(hex) - } - if (hexString.length == 8) { - return@registerMapper java.awt.Color(hex, true) - } - error("Hexcolor $it needs to be exactly 6 or 8 hex digits long") - } - return@registerMapper java.awt.Color(it.toInt(), true) - } - uni.registerMapper(Color::class.java) { - val color = uni.mapXMLObject(it, java.awt.Color::class.java) - Color.ofRGBA(color.red, color.green, color.blue, color.alpha) - } - uni.registerLoader(object : XMLGuiLoader.Basic<BarComponent> { - override fun getName(): QName { - return QName(firmUrl, "Bar") - } - - override fun createInstance(context: XMLContext<*>, element: Element): BarComponent { - return BarComponent( - context.getPropertyFromAttribute(element, QName("progress"), Double::class.java)!!, - context.getPropertyFromAttribute(element, QName("total"), Double::class.java)!!, - context.getPropertyFromAttribute(element, QName("fillColor"), Color::class.java)!!.get(), - context.getPropertyFromAttribute(element, QName("emptyColor"), Color::class.java)!!.get(), - ) - } - - override fun getChildCount(): ChildCount { - return ChildCount.NONE - } - - override fun getAttributeNames(): Map<String, Boolean> { - return mapOf("progress" to true, "total" to true, "emptyColor" to true, "fillColor" to true) - } - }) - uni.registerLoader(object : XMLGuiLoader.Basic<FirmHoverComponent> { - override fun createInstance(context: XMLContext<*>, element: Element): FirmHoverComponent { - return FirmHoverComponent( - context.getChildFragment(element), - context.getPropertyFromAttribute(element, QName("lines"), List::class.java) as Supplier<List<String>>, - context.getPropertyFromAttribute(element, QName("delay"), Duration::class.java, 0.6.seconds), - ) - } - - override fun getName(): QName { - return QName(firmUrl, "Hover") - } - - override fun getChildCount(): ChildCount { - return ChildCount.ONE - } - - override fun getAttributeNames(): Map<String, Boolean> { - return mapOf( - "lines" to true, - "delay" to false, - ) - } - - }) - uni.registerLoader(object : XMLGuiLoader.Basic<FirmButtonComponent> { - override fun getName(): QName { - return QName(firmUrl, "Button") - } - - override fun createInstance(context: XMLContext<*>, element: Element): FirmButtonComponent { - return FirmButtonComponent( - context.getChildFragment(element), - context.getPropertyFromAttribute(element, QName("enabled"), Boolean::class.java) - ?: GetSetter.constant(true), - context.getPropertyFromAttribute(element, QName("noBackground"), Boolean::class.java, false), - context.getMethodFromAttribute(element, QName("onClick")), - ) - } - - override fun getChildCount(): ChildCount { - return ChildCount.ONE - } - - override fun getAttributeNames(): Map<String, Boolean> { - return mapOf("onClick" to true, "enabled" to false, "noBackground" to false) - } - }) - uni.registerLoader(object : XMLGuiLoader.Basic<ImageComponent> { - override fun createInstance(context: XMLContext<*>, element: Element): ImageComponent { - return ImageComponent( - context.getPropertyFromAttribute(element, QName("width"), Int::class.java)!!.get(), - context.getPropertyFromAttribute(element, QName("height"), Int::class.java)!!.get(), - context.getPropertyFromAttribute(element, QName("resource"), MyResourceLocation::class.java)!!, - context.getPropertyFromAttribute(element, QName("u1"), Float::class.java, 0f), - context.getPropertyFromAttribute(element, QName("u2"), Float::class.java, 1f), - context.getPropertyFromAttribute(element, QName("v1"), Float::class.java, 0f), - context.getPropertyFromAttribute(element, QName("v2"), Float::class.java, 1f), - ) - } - - override fun getName(): QName { - return QName(firmUrl, "Image") - } - - override fun getChildCount(): ChildCount { - return ChildCount.NONE - } - - override fun getAttributeNames(): Map<String, Boolean> { - return mapOf( - "width" to true, "height" to true, - "resource" to true, - "u1" to false, - "u2" to false, - "v1" to false, - "v2" to false, - ) - } - }) - uni.registerLoader(object : XMLGuiLoader.Basic<TickComponent> { - override fun createInstance(context: XMLContext<*>, element: Element): TickComponent { - return TickComponent(context.getMethodFromAttribute(element, QName("tick"))) - } - - override fun getName(): QName { - return QName(firmUrl, "Tick") - } - - override fun getChildCount(): ChildCount { - return ChildCount.NONE - } - - override fun getAttributeNames(): Map<String, Boolean> { - return mapOf("tick" to true) - } - }) - uni.registerLoader(object : XMLGuiLoader.Basic<FixedComponent> { - override fun createInstance(context: XMLContext<*>, element: Element): FixedComponent { - return FixedComponent( - context.getPropertyFromAttribute(element, QName("width"), Int::class.java) - ?: error("Requires width specified"), - context.getPropertyFromAttribute(element, QName("height"), Int::class.java) - ?: error("Requires height specified"), - context.getChildFragment(element) - ) - } - - override fun getName(): QName { - return QName(firmUrl, "Fixed") - } - - override fun getChildCount(): ChildCount { - return ChildCount.ONE - } - - override fun getAttributeNames(): Map<String, Boolean> { - return mapOf("width" to true, "height" to true) - } - }) - } - - fun generateXSD( - file: File, - namespace: String - ) { - val generator = XSDGenerator(universe, namespace) - generator.writeAll() - generator.dumpToFile(file) - } - - @JvmStatic - fun main(args: Array<out String>) { - generateXSD(File("MoulConfig.xsd"), XMLUniverse.MOULCONFIG_XML_NS) - generateXSD(File("MoulConfig.Firmament.xsd"), firmUrl) - File("wrapper.xsd").writeText(""" + val firmUrl = "http://firmament.nea.moe/moulconfig" + val universe = XMLUniverse.getDefaultUniverse().also { uni -> + uni.registerMapper(java.awt.Color::class.java) { + if (it.startsWith("#")) { + val hexString = it.substring(1) + val hex = hexString.toInt(16) + if (hexString.length == 6) { + return@registerMapper java.awt.Color(hex) + } + if (hexString.length == 8) { + return@registerMapper java.awt.Color(hex, true) + } + error("Hexcolor $it needs to be exactly 6 or 8 hex digits long") + } + return@registerMapper java.awt.Color(it.toInt(), true) + } + uni.registerMapper(Color::class.java) { + val color = uni.mapXMLObject(it, java.awt.Color::class.java) + Color.ofRGBA(color.red, color.green, color.blue, color.alpha) + } + uni.registerLoader(object : XMLGuiLoader.Basic<BarComponent> { + override fun getName(): QName { + return QName(firmUrl, "Bar") + } + + override fun createInstance(context: XMLContext<*>, element: Element): BarComponent { + return BarComponent( + context.getPropertyFromAttribute(element, QName("progress"), Double::class.java)!!, + context.getPropertyFromAttribute(element, QName("total"), Double::class.java)!!, + context.getPropertyFromAttribute(element, QName("fillColor"), Color::class.java)!!.get(), + context.getPropertyFromAttribute(element, QName("emptyColor"), Color::class.java)!!.get(), + ) + } + + override fun getChildCount(): ChildCount { + return ChildCount.NONE + } + + override fun getAttributeNames(): Map<String, Boolean> { + return mapOf("progress" to true, "total" to true, "emptyColor" to true, "fillColor" to true) + } + }) + uni.registerLoader(object : XMLGuiLoader.Basic<FirmHoverComponent> { + override fun createInstance(context: XMLContext<*>, element: Element): FirmHoverComponent { + return FirmHoverComponent( + context.getChildFragment(element), + context.getPropertyFromAttribute(element, + QName("lines"), + List::class.java) as Supplier<List<String>>, + context.getPropertyFromAttribute(element, QName("delay"), Duration::class.java, 0.6.seconds), + ) + } + + override fun getName(): QName { + return QName(firmUrl, "Hover") + } + + override fun getChildCount(): ChildCount { + return ChildCount.ONE + } + + override fun getAttributeNames(): Map<String, Boolean> { + return mapOf( + "lines" to true, + "delay" to false, + ) + } + + }) + uni.registerLoader(object : XMLGuiLoader.Basic<FirmButtonComponent> { + override fun getName(): QName { + return QName(firmUrl, "Button") + } + + override fun createInstance(context: XMLContext<*>, element: Element): FirmButtonComponent { + return FirmButtonComponent( + context.getChildFragment(element), + context.getPropertyFromAttribute(element, QName("enabled"), Boolean::class.java) + ?: GetSetter.constant(true), + context.getPropertyFromAttribute(element, QName("noBackground"), Boolean::class.java, false), + context.getMethodFromAttribute(element, QName("onClick")), + ) + } + + override fun getChildCount(): ChildCount { + return ChildCount.ONE + } + + override fun getAttributeNames(): Map<String, Boolean> { + return mapOf("onClick" to true, "enabled" to false, "noBackground" to false) + } + }) + uni.registerLoader(object : XMLGuiLoader.Basic<ImageComponent> { + override fun createInstance(context: XMLContext<*>, element: Element): ImageComponent { + return ImageComponent( + context.getPropertyFromAttribute(element, QName("width"), Int::class.java)!!.get(), + context.getPropertyFromAttribute(element, QName("height"), Int::class.java)!!.get(), + context.getPropertyFromAttribute(element, QName("resource"), MyResourceLocation::class.java)!!, + context.getPropertyFromAttribute(element, QName("u1"), Float::class.java, 0f), + context.getPropertyFromAttribute(element, QName("u2"), Float::class.java, 1f), + context.getPropertyFromAttribute(element, QName("v1"), Float::class.java, 0f), + context.getPropertyFromAttribute(element, QName("v2"), Float::class.java, 1f), + ) + } + + override fun getName(): QName { + return QName(firmUrl, "Image") + } + + override fun getChildCount(): ChildCount { + return ChildCount.NONE + } + + override fun getAttributeNames(): Map<String, Boolean> { + return mapOf( + "width" to true, "height" to true, + "resource" to true, + "u1" to false, + "u2" to false, + "v1" to false, + "v2" to false, + ) + } + }) + uni.registerLoader(object : XMLGuiLoader.Basic<TickComponent> { + override fun createInstance(context: XMLContext<*>, element: Element): TickComponent { + return TickComponent(context.getMethodFromAttribute(element, QName("tick"))) + } + + override fun getName(): QName { + return QName(firmUrl, "Tick") + } + + override fun getChildCount(): ChildCount { + return ChildCount.NONE + } + + override fun getAttributeNames(): Map<String, Boolean> { + return mapOf("tick" to true) + } + }) + uni.registerLoader(object : XMLGuiLoader.Basic<FixedComponent> { + override fun createInstance(context: XMLContext<*>, element: Element): FixedComponent { + return FixedComponent( + context.getPropertyFromAttribute(element, QName("width"), Int::class.java) + ?: error("Requires width specified"), + context.getPropertyFromAttribute(element, QName("height"), Int::class.java) + ?: error("Requires height specified"), + context.getChildFragment(element) + ) + } + + override fun getName(): QName { + return QName(firmUrl, "Fixed") + } + + override fun getChildCount(): ChildCount { + return ChildCount.ONE + } + + override fun getAttributeNames(): Map<String, Boolean> { + return mapOf("width" to true, "height" to true) + } + }) + } + + fun generateXSD( + file: File, + namespace: String + ) { + val generator = XSDGenerator(universe, namespace) + generator.writeAll() + generator.dumpToFile(file) + } + + @JvmStatic + fun main(args: Array<out String>) { + generateXSD(File("MoulConfig.xsd"), XMLUniverse.MOULCONFIG_XML_NS) + generateXSD(File("MoulConfig.Firmament.xsd"), firmUrl) + File("wrapper.xsd").writeText(""" <?xml version="1.0" encoding="UTF-8" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:import namespace="http://notenoughupdates.org/moulconfig" schemaLocation="MoulConfig.xsd"/> <xs:import namespace="http://firmament.nea.moe/moulconfig" schemaLocation="MoulConfig.Firmament.xsd"/> </xs:schema> """.trimIndent()) - } - - fun loadScreen(name: String, bindTo: Any, parent: Screen?): Screen { - return object : GuiComponentWrapper(loadGui(name, bindTo)) { - override fun close() { - if (context.onBeforeClose() == CloseEventListener.CloseAction.NO_OBJECTIONS_TO_CLOSE) { - client!!.setScreen(parent) - } - } - } - } - - fun loadGui(name: String, bindTo: Any): GuiContext { - return GuiContext(universe.load(bindTo, MyResourceLocation("firmament", "gui/$name.xml"))) - } + } + + fun loadScreen(name: String, bindTo: Any, parent: Screen?): Screen { + return object : GuiComponentWrapper(loadGui(name, bindTo)) { + override fun close() { + if (context.onBeforeClose() == CloseEventListener.CloseAction.NO_OBJECTIONS_TO_CLOSE) { + client!!.setScreen(parent) + } + } + } + } + + // TODO: move this utility into moulconfig (also rework guicontext into an interface so i can make this mesh better into vanilla) + fun GuiContext.adopt(element: GuiComponent) = element.foldRecursive(Unit, { comp, unit -> comp.context = this }) + + fun clickMCComponentInPlace( + component: GuiComponent, + x: Int, + y: Int, + w: Int, + h: Int, + mouseX: Int, mouseY: Int, + mouseEvent: MouseEvent + ): Boolean { + val immContext = createInPlaceFullContext(null, mouseX, mouseY) + return component.mouseEvent(mouseEvent, immContext.translated(x, y, w, h)) + } + + fun createInPlaceFullContext(drawContext: DrawContext?, mouseX: Int, mouseY: Int): GuiImmediateContext { + assert(drawContext?.isUntranslatedGuiDrawContext() != false) + val context = drawContext?.let(::ModernRenderContext) + ?: IMinecraft.instance.provideTopLevelRenderContext() + val immContext = GuiImmediateContext(context, + 0, 0, 0, 0, + mouseX, mouseY, + mouseX, mouseY, + mouseX.toFloat(), + mouseY.toFloat()) + return immContext + } + + fun DrawContext.drawMCComponentInPlace( + component: GuiComponent, + x: Int, + y: Int, + w: Int, + h: Int, + mouseX: Int, + mouseY: Int + ) { + val immContext = createInPlaceFullContext(this, mouseX, mouseY) + matrices.push() + matrices.translate(x.toFloat(), y.toFloat(), 0F) + component.render(immContext.translated(x, y, w, h)) + matrices.pop() + } + + + fun loadGui(name: String, bindTo: Any): GuiContext { + return GuiContext(universe.load(bindTo, MyResourceLocation("firmament", "gui/$name.xml"))) + } } |