From dff1f9c0e2b728dba902d72816104abccc61f511 Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Sat, 15 Jun 2024 19:54:47 +0200 Subject: WIP: Terrible MoulConfig rewrite --- build.gradle.kts | 3 +- gradle/libs.versions.toml | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../moe/nea/firmament/gui/FirmButtonComponent.kt | 74 ++++++++++++++++++++++ .../kotlin/moe/nea/firmament/gui/FixedComponent.kt | 43 +++++++++++++ .../moe/nea/firmament/gui/config/AllConfigsGui.kt | 72 +++++++-------------- .../moe/nea/firmament/util/MoulConfigUtils.kt | 62 ++++++++++++++++++ .../firmament/gui/button_editor_fragment.xml | 3 +- .../resources/assets/firmament/gui/config/main.xml | 36 +++++++++++ .../assets/firmament/gui/pristine_profit.xml | 4 +- 10 files changed, 243 insertions(+), 58 deletions(-) create mode 100644 src/main/kotlin/moe/nea/firmament/gui/FirmButtonComponent.kt create mode 100644 src/main/kotlin/moe/nea/firmament/gui/FixedComponent.kt create mode 100644 src/main/resources/assets/firmament/gui/config/main.xml diff --git a/build.gradle.kts b/build.gradle.kts index 4fe313d..df4f25f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,7 +16,7 @@ plugins { kotlin("jvm") version "1.9.23" kotlin("plugin.serialization") version "1.9.23" // id("com.bnorm.power.kotlin-power-assert") version "0.13.0" - id("dev.architectury.loom") version "1.6.394" + id("dev.architectury.loom") version "1.6.397" id("com.github.johnrengelman.shadow") version "8.1.1" id("moe.nea.licenseextractificator") // id("io.github.juuxel.loom-vineflower") version "1.11.0" @@ -76,6 +76,7 @@ repositories { } maven( "https://repo.hypixel.net/repository/Hypixel/") maven("https://maven.azureaaron.net/snapshots") + mavenLocal() } kotlin { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 46a2360..e848e89 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,7 +29,7 @@ hotswap_agent = "1.4.2-SNAPSHOT" mixinextras = "0.3.5" jarvis = "1.1.1" nealisp = "1.0.0" -moulconfig = "3.0.0-beta.12" +moulconfig = "9999.9999.9999" manninghamMills = "2.4.1" [libraries] diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0c78a30..4c78103 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -4,6 +4,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/kotlin/moe/nea/firmament/gui/FirmButtonComponent.kt b/src/main/kotlin/moe/nea/firmament/gui/FirmButtonComponent.kt new file mode 100644 index 0000000..30f280c --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/gui/FirmButtonComponent.kt @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: 2024 Linnea Gräf + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package moe.nea.firmament.gui + +import io.github.notenoughupdates.moulconfig.common.MyResourceLocation +import io.github.notenoughupdates.moulconfig.deps.libninepatch.NinePatch +import io.github.notenoughupdates.moulconfig.gui.GuiComponent +import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext +import io.github.notenoughupdates.moulconfig.gui.MouseEvent +import io.github.notenoughupdates.moulconfig.gui.component.PanelComponent +import io.github.notenoughupdates.moulconfig.observer.GetSetter + + +class FirmButtonComponent( + child: GuiComponent, + val action: Runnable, + val isEnabled: GetSetter = GetSetter.constant(true) +) : PanelComponent(child) { + + /* TODO: make use of vanillas built in nine slicer */ + val hoveredBg = NinePatch.builder(MyResourceLocation("minecraft", "textures/gui/sprites/widget/button_highlighted.png")) + .cornerSize(5) + .cornerUv(5 / 200F, 5 / 20F) + .mode(NinePatch.Mode.STRETCHING) + .build() + val unhoveredBg = NinePatch.builder(MyResourceLocation("minecraft", "textures/gui/sprites/widget/button.png")) + .cornerSize(5) + .cornerUv(5 / 200F, 5 / 20F) + .mode(NinePatch.Mode.STRETCHING) + .build() + val disabledBg = NinePatch.builder(MyResourceLocation("minecraft", "textures/gui/sprites/widget/button_disabled.png")) + .cornerSize(5) + .cornerUv(5 / 200F, 5 / 20F) + .mode(NinePatch.Mode.STRETCHING) + .build() + + var isClicking = false + override fun mouseEvent(mouseEvent: MouseEvent, context: GuiImmediateContext): Boolean { + if (!isEnabled.get()) return false + if (isClicking) { + if (mouseEvent is MouseEvent.Click && !mouseEvent.mouseState && mouseEvent.mouseButton == 0) { + isClicking = false + if (context.isHovered) { + action.run() + } + return true + } + } + if (!context.isHovered) return false + if (mouseEvent !is MouseEvent.Click) return false + if (mouseEvent.mouseState && mouseEvent.mouseButton == 0) { + isClicking = true + return true + } + return false + } + + override fun render(context: GuiImmediateContext) { + context.renderContext.pushMatrix() + context.renderContext.drawNinePatch( + if (!isEnabled.get()) disabledBg + else if (context.isHovered || isClicking) hoveredBg + else unhoveredBg, + 0f, 0f, context.width, context.height + ) + context.renderContext.translate(insets.toFloat(), insets.toFloat(), 0f) + element.render(getChildContext(context)) + context.renderContext.popMatrix() + } +} diff --git a/src/main/kotlin/moe/nea/firmament/gui/FixedComponent.kt b/src/main/kotlin/moe/nea/firmament/gui/FixedComponent.kt new file mode 100644 index 0000000..c98feda --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/gui/FixedComponent.kt @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2024 Linnea Gräf + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package moe.nea.firmament.gui + +import io.github.notenoughupdates.moulconfig.gui.GuiComponent +import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext +import io.github.notenoughupdates.moulconfig.gui.KeyboardEvent +import io.github.notenoughupdates.moulconfig.gui.MouseEvent +import io.github.notenoughupdates.moulconfig.observer.GetSetter +import java.util.function.BiFunction + +class FixedComponent( + val fixedWidth: GetSetter, + val fixedHeight: GetSetter, + val component: GuiComponent, +) : GuiComponent() { + override fun getWidth(): Int = fixedWidth.get() + + override fun getHeight(): Int = fixedHeight.get() + + override fun foldChildren(initial: T, visitor: BiFunction): T { + return visitor.apply(component, initial) + } + + fun fixContext(context: GuiImmediateContext): GuiImmediateContext = + context.translated(0, 0, fixedWidth.get(), fixedHeight.get()) + + override fun render(context: GuiImmediateContext) { + component.render(fixContext(context)) + } + + override fun mouseEvent(mouseEvent: MouseEvent, context: GuiImmediateContext): Boolean { + return component.mouseEvent(mouseEvent, fixContext(context)) + } + + override fun keyboardEvent(event: KeyboardEvent, context: GuiImmediateContext): Boolean { + return component.keyboardEvent(event, fixContext(context)) + } +} diff --git a/src/main/kotlin/moe/nea/firmament/gui/config/AllConfigsGui.kt b/src/main/kotlin/moe/nea/firmament/gui/config/AllConfigsGui.kt index 1b2b2e4..a7d34b2 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/config/AllConfigsGui.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/config/AllConfigsGui.kt @@ -1,29 +1,21 @@ /* * SPDX-FileCopyrightText: 2023 Linnea Gräf + * SPDX-FileCopyrightText: 2024 Linnea Gräf * * SPDX-License-Identifier: GPL-3.0-or-later */ package moe.nea.firmament.gui.config -import io.github.cottonmc.cotton.gui.client.BackgroundPainter -import io.github.cottonmc.cotton.gui.client.CottonClientScreen -import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription -import io.github.cottonmc.cotton.gui.widget.WBox -import io.github.cottonmc.cotton.gui.widget.WButton -import io.github.cottonmc.cotton.gui.widget.WLabel -import io.github.cottonmc.cotton.gui.widget.WScrollPanel -import io.github.cottonmc.cotton.gui.widget.data.Axis -import io.github.cottonmc.cotton.gui.widget.data.Insets +import io.github.notenoughupdates.moulconfig.observer.ObservableList +import io.github.notenoughupdates.moulconfig.xml.Bind +import net.minecraft.client.gui.screen.Screen +import net.minecraft.text.Text import moe.nea.firmament.features.FeatureManager -import moe.nea.firmament.gui.WFixedPanel -import moe.nea.firmament.gui.WSplitPanel import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.util.MC +import moe.nea.firmament.util.MoulConfigUtils import moe.nea.firmament.util.ScreenUtil.setScreenLater -import net.minecraft.client.gui.screen.Screen -import net.minecraft.text.Text -import kotlin.streams.asSequence object AllConfigsGui { @@ -32,45 +24,25 @@ object AllConfigsGui { RepoManager.Config ) + FeatureManager.allFeatures.mapNotNull { it.config } - fun makeScreen(parent: Screen? = null): CottonClientScreen { - val lwgd = LightweightGuiDescription() - var screen: CottonClientScreen? = null - val configs = allConfigs - val box = WBox(Axis.VERTICAL) - configs.forEach { config -> - val panel = WSplitPanel( - WLabel(Text.translatable("firmament.config.${config.name}")), - WButton(Text.translatable("firmanent.config.edit")).also { - it.setOnClick { - config.showConfigEditor(screen) - } - it.setSize(40, 18) - } - ) - panel.insets = Insets.ROOT_PANEL - panel.backgroundPainter = BackgroundPainter.VANILLA - box.add((panel)) - } - box.streamChildren().asSequence() - .forEach { it.setSize(380, 0) } - lwgd.setRootPanel(WBox( - Axis.VERTICAL - ).also { - it.insets = Insets.ROOT_PANEL - box.layout() - it.add(WFixedPanel((WScrollPanel((box)).also { - it.verticalScrollBar.scrollingSpeed = 12 - it.setSize(400, 300) - }))) - it.setSize(400, 300) - }) + fun List.toObservableList(): ObservableList = ObservableList(this) - screen = object : CottonClientScreen(lwgd) { - override fun close() { - MC.screen = parent + class MainMapping(val allConfigs: List) { + @get:Bind("configs") + val configs = allConfigs.map { EntryMapping(it) }.toObservableList() + + class EntryMapping(val config: ManagedConfig) { + @Bind + fun name() = Text.translatable("firmament.config.${config.name}").string + + @Bind + fun openEditor() { + config.showConfigEditor(MC.screen) } } - return screen + } + + fun makeScreen(parent: Screen? = null): Screen { + return MoulConfigUtils.loadScreen("config/main", MainMapping(allConfigs), parent) } fun showAllGuis() { diff --git a/src/main/kotlin/moe/nea/firmament/util/MoulConfigUtils.kt b/src/main/kotlin/moe/nea/firmament/util/MoulConfigUtils.kt index 34188a2..3c77dc4 100644 --- a/src/main/kotlin/moe/nea/firmament/util/MoulConfigUtils.kt +++ b/src/main/kotlin/moe/nea/firmament/util/MoulConfigUtils.kt @@ -1,5 +1,6 @@ /* * SPDX-FileCopyrightText: 2023 Linnea Gräf + * SPDX-FileCopyrightText: 2024 Linnea Gräf * * SPDX-License-Identifier: GPL-3.0-or-later */ @@ -7,7 +8,10 @@ package moe.nea.firmament.util import io.github.notenoughupdates.moulconfig.common.MyResourceLocation +import io.github.notenoughupdates.moulconfig.gui.CloseEventListener +import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper import io.github.notenoughupdates.moulconfig.gui.GuiContext +import io.github.notenoughupdates.moulconfig.observer.GetSetter import io.github.notenoughupdates.moulconfig.xml.ChildCount import io.github.notenoughupdates.moulconfig.xml.XMLContext import io.github.notenoughupdates.moulconfig.xml.XMLGuiLoader @@ -17,7 +21,10 @@ import java.io.File import javax.xml.namespace.QName import me.shedaniel.math.Color import org.w3c.dom.Element +import net.minecraft.client.gui.screen.Screen import moe.nea.firmament.gui.BarComponent +import moe.nea.firmament.gui.FirmButtonComponent +import moe.nea.firmament.gui.FixedComponent object MoulConfigUtils { val firmUrl = "http://firmament.nea.moe/moulconfig" @@ -62,6 +69,51 @@ object MoulConfigUtils { return mapOf("progress" to true, "total" to true, "emptyColor" to true, "fillColor" to true) } }) + uni.registerLoader(object : XMLGuiLoader.Basic { + override fun getName(): QName { + return QName(firmUrl, "Button") + } + + override fun createInstance(context: XMLContext<*>, element: Element): FirmButtonComponent { + return FirmButtonComponent( + context.getChildFragment(element), + context.getMethodFromAttribute(element, QName("onClick")), + context.getPropertyFromAttribute(element, QName("enabled"), Boolean::class.java) + ?: GetSetter.constant(true) + ) + } + + override fun getChildCount(): ChildCount { + return ChildCount.ONE + } + + override fun getAttributeNames(): Map { + return mapOf("onClick" to true, "enabled" to false) + } + }) + uni.registerLoader(object : XMLGuiLoader.Basic { + 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 { + return mapOf("width" to true, "height" to true) + } + }) } fun generateXSD( @@ -86,6 +138,16 @@ object MoulConfigUtils { """.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"))) } diff --git a/src/main/resources/assets/firmament/gui/button_editor_fragment.xml b/src/main/resources/assets/firmament/gui/button_editor_fragment.xml index e28afc0..1cf3df2 100644 --- a/src/main/resources/assets/firmament/gui/button_editor_fragment.xml +++ b/src/main/resources/assets/firmament/gui/button_editor_fragment.xml @@ -6,8 +6,7 @@ SPDX-FileCopyrightText: 2023 Linnea Gräf SPDX-License-Identifier: GPL-3.0-or-later --> - + diff --git a/src/main/resources/assets/firmament/gui/config/main.xml b/src/main/resources/assets/firmament/gui/config/main.xml new file mode 100644 index 0000000..a5fc245 --- /dev/null +++ b/src/main/resources/assets/firmament/gui/config/main.xml @@ -0,0 +1,36 @@ + + + + + +
+ + + + + + + +
+ +
+ +
+ + + +
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/assets/firmament/gui/pristine_profit.xml b/src/main/resources/assets/firmament/gui/pristine_profit.xml index 5f9ea43..1754f69 100644 --- a/src/main/resources/assets/firmament/gui/pristine_profit.xml +++ b/src/main/resources/assets/firmament/gui/pristine_profit.xml @@ -6,9 +6,7 @@ SPDX-FileCopyrightText: 2023 Linnea Gräf SPDX-License-Identifier: GPL-3.0-or-later --> - + -- cgit