Add slightly more modular options
This commit is contained in:
@@ -21,7 +21,7 @@ class BooleanHandler(val config: ManagedConfig) : ManagedConfig.OptionHandler<Bo
|
|||||||
return element.jsonPrimitive.boolean
|
return element.jsonPrimitive.boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun emitGuiElements(opt: ManagedConfig.Option<Boolean>, guiAppender: GuiAppender) {
|
override fun emitGuiElements(opt: ManagedOption<Boolean>, guiAppender: GuiAppender) {
|
||||||
guiAppender.appendLabeledRow(
|
guiAppender.appendLabeledRow(
|
||||||
opt.labelText,
|
opt.labelText,
|
||||||
WToggleButton(opt.labelText).apply {
|
WToggleButton(opt.labelText).apply {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
package moe.nea.firmament.gui.config
|
package moe.nea.firmament.gui.config
|
||||||
|
|
||||||
import io.github.cottonmc.cotton.gui.widget.WButton
|
import io.github.cottonmc.cotton.gui.widget.WButton
|
||||||
import io.github.cottonmc.cotton.gui.widget.WLabel
|
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
|
|
||||||
@@ -18,7 +17,7 @@ class ClickHandler(val config: ManagedConfig, val runnable: () -> Unit) : Manage
|
|||||||
|
|
||||||
override fun fromJson(element: JsonElement) {}
|
override fun fromJson(element: JsonElement) {}
|
||||||
|
|
||||||
override fun emitGuiElements(opt: ManagedConfig.Option<Unit>, guiAppender: GuiAppender) {
|
override fun emitGuiElements(opt: ManagedOption<Unit>, guiAppender: GuiAppender) {
|
||||||
guiAppender.appendLabeledRow(
|
guiAppender.appendLabeledRow(
|
||||||
Text.translatable("firmament.config.${config.name}.${opt.propertyName}"),
|
Text.translatable("firmament.config.${config.name}.${opt.propertyName}"),
|
||||||
WButton(Text.translatable("firmament.config.${config.name}.${opt.propertyName}")).apply {
|
WButton(Text.translatable("firmament.config.${config.name}.${opt.propertyName}")).apply {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class DurationHandler(val config: ManagedConfig, val min: Duration, val max: Dur
|
|||||||
return element.jsonPrimitive.long.toDuration(DurationUnit.MILLISECONDS)
|
return element.jsonPrimitive.long.toDuration(DurationUnit.MILLISECONDS)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun emitGuiElements(opt: ManagedConfig.Option<Duration>, guiAppender: GuiAppender) {
|
override fun emitGuiElements(opt: ManagedOption<Duration>, guiAppender: GuiAppender) {
|
||||||
val label =
|
val label =
|
||||||
WLabel(Text.literal(FirmFormatters.formatTimespan(opt.value))).setVerticalAlignment(VerticalAlignment.CENTER)
|
WLabel(Text.literal(FirmFormatters.formatTimespan(opt.value))).setVerticalAlignment(VerticalAlignment.CENTER)
|
||||||
guiAppender.appendLabeledRow(opt.labelText, WBox(Axis.HORIZONTAL).also {
|
guiAppender.appendLabeledRow(opt.labelText, WBox(Axis.HORIZONTAL).also {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class HudMetaHandler(val config: ManagedConfig, val label: MutableText, val widt
|
|||||||
return HudMeta(Json.decodeFromJsonElement(element), label, width, height)
|
return HudMeta(Json.decodeFromJsonElement(element), label, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun emitGuiElements(opt: ManagedConfig.Option<HudMeta>, guiAppender: GuiAppender) {
|
override fun emitGuiElements(opt: ManagedOption<HudMeta>, guiAppender: GuiAppender) {
|
||||||
guiAppender.appendLabeledRow(opt.labelText, WButton(Text.translatable("firmament.hud.edit", label))
|
guiAppender.appendLabeledRow(opt.labelText, WButton(Text.translatable("firmament.hud.edit", label))
|
||||||
.also {
|
.also {
|
||||||
it.setOnClick {
|
it.setOnClick {
|
||||||
|
|||||||
@@ -16,9 +16,7 @@ import kotlinx.serialization.json.JsonElement
|
|||||||
import kotlinx.serialization.json.JsonPrimitive
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
import kotlinx.serialization.json.int
|
import kotlinx.serialization.json.int
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import kotlin.time.Duration.Companion.milliseconds
|
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import moe.nea.firmament.util.FirmFormatters
|
|
||||||
|
|
||||||
class IntegerHandler(val config: ManagedConfig, val min: Int, val max: Int) : ManagedConfig.OptionHandler<Int> {
|
class IntegerHandler(val config: ManagedConfig, val min: Int, val max: Int) : ManagedConfig.OptionHandler<Int> {
|
||||||
override fun toJson(element: Int): JsonElement? {
|
override fun toJson(element: Int): JsonElement? {
|
||||||
@@ -29,7 +27,7 @@ class IntegerHandler(val config: ManagedConfig, val min: Int, val max: Int) : Ma
|
|||||||
return element.jsonPrimitive.int
|
return element.jsonPrimitive.int
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun emitGuiElements(opt: ManagedConfig.Option<Int>, guiAppender: GuiAppender) {
|
override fun emitGuiElements(opt: ManagedOption<Int>, guiAppender: GuiAppender) {
|
||||||
val label =
|
val label =
|
||||||
WLabel(Text.literal(opt.value.toString())).setVerticalAlignment(VerticalAlignment.CENTER)
|
WLabel(Text.literal(opt.value.toString())).setVerticalAlignment(VerticalAlignment.CENTER)
|
||||||
guiAppender.appendLabeledRow(opt.labelText, WBox(Axis.HORIZONTAL).also {
|
guiAppender.appendLabeledRow(opt.labelText, WBox(Axis.HORIZONTAL).also {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription
|
|||||||
import io.github.cottonmc.cotton.gui.widget.WBox
|
import io.github.cottonmc.cotton.gui.widget.WBox
|
||||||
import io.github.cottonmc.cotton.gui.widget.WButton
|
import io.github.cottonmc.cotton.gui.widget.WButton
|
||||||
import io.github.cottonmc.cotton.gui.widget.WLabel
|
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.Axis
|
||||||
import io.github.cottonmc.cotton.gui.widget.data.Insets
|
import io.github.cottonmc.cotton.gui.widget.data.Insets
|
||||||
import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment
|
import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment
|
||||||
@@ -23,8 +22,6 @@ import kotlinx.serialization.json.JsonObject
|
|||||||
import kotlin.io.path.createDirectories
|
import kotlin.io.path.createDirectories
|
||||||
import kotlin.io.path.readText
|
import kotlin.io.path.readText
|
||||||
import kotlin.io.path.writeText
|
import kotlin.io.path.writeText
|
||||||
import kotlin.properties.ReadWriteProperty
|
|
||||||
import kotlin.reflect.KProperty
|
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
import net.minecraft.client.gui.screen.Screen
|
import net.minecraft.client.gui.screen.Screen
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
@@ -33,67 +30,12 @@ import moe.nea.firmament.gui.WTightScrollPanel
|
|||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.ScreenUtil.setScreenLater
|
import moe.nea.firmament.util.ScreenUtil.setScreenLater
|
||||||
|
|
||||||
abstract class ManagedConfig(val name: String) {
|
abstract class ManagedConfig(override val name: String) : ManagedConfigElement() {
|
||||||
|
|
||||||
interface OptionHandler<T : Any> {
|
interface OptionHandler<T : Any> {
|
||||||
fun toJson(element: T): JsonElement?
|
fun toJson(element: T): JsonElement?
|
||||||
fun fromJson(element: JsonElement): T
|
fun fromJson(element: JsonElement): T
|
||||||
fun emitGuiElements(opt: Option<T>, guiAppender: GuiAppender)
|
fun emitGuiElements(opt: ManagedOption<T>, guiAppender: GuiAppender)
|
||||||
}
|
|
||||||
|
|
||||||
inner class Option<T : Any> internal constructor(
|
|
||||||
val config: ManagedConfig,
|
|
||||||
val propertyName: String,
|
|
||||||
val default: () -> T,
|
|
||||||
val handler: OptionHandler<T>
|
|
||||||
) : ReadWriteProperty<Any?, T> {
|
|
||||||
|
|
||||||
val rawLabelText = "firmament.config.${config.name}.${propertyName}"
|
|
||||||
val labelText = Text.translatable(rawLabelText)
|
|
||||||
|
|
||||||
private lateinit var _value: T
|
|
||||||
private var loaded = false
|
|
||||||
var value: T
|
|
||||||
get() {
|
|
||||||
if (!loaded)
|
|
||||||
load()
|
|
||||||
return _value
|
|
||||||
}
|
|
||||||
set(value) {
|
|
||||||
loaded = true
|
|
||||||
_value = value
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
|
||||||
this.value = value
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun load() {
|
|
||||||
if (data.containsKey(propertyName)) {
|
|
||||||
try {
|
|
||||||
value = handler.fromJson(data[propertyName]!!)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Firmament.logger.error(
|
|
||||||
"Exception during loading of config file $name. This will reset this config.",
|
|
||||||
e
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value = default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun toJson(): JsonElement? {
|
|
||||||
return handler.toJson(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun appendToGui(guiapp: GuiAppender) {
|
|
||||||
handler.emitGuiElements(this, guiapp)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val file = Firmament.CONFIG_DIR.resolve("$name.json")
|
val file = Firmament.CONFIG_DIR.resolve("$name.json")
|
||||||
@@ -119,20 +61,25 @@ abstract class ManagedConfig(val name: String) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val allOptions = mutableMapOf<String, Option<*>>()
|
val allOptions = mutableMapOf<String, ManagedOption<*>>()
|
||||||
val sortedOptions = mutableListOf<Option<*>>()
|
val sortedOptions = mutableListOf<ManagedOption<*>>()
|
||||||
|
|
||||||
private var latestGuiAppender: GuiAppender? = null
|
private var latestGuiAppender: GuiAppender? = null
|
||||||
|
|
||||||
protected fun <T : Any> option(propertyName: String, default: () -> T, handler: OptionHandler<T>): Option<T> {
|
protected fun <T : Any> option(
|
||||||
|
propertyName: String,
|
||||||
|
default: () -> T,
|
||||||
|
handler: OptionHandler<T>
|
||||||
|
): ManagedOption<T> {
|
||||||
if (propertyName in allOptions) error("Cannot register the same name twice")
|
if (propertyName in allOptions) error("Cannot register the same name twice")
|
||||||
return Option(this, propertyName, default, handler).also {
|
return ManagedOption(this, propertyName, default, handler).also {
|
||||||
|
it.load(data)
|
||||||
allOptions[propertyName] = it
|
allOptions[propertyName] = it
|
||||||
sortedOptions.add(it)
|
sortedOptions.add(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun toggle(propertyName: String, default: () -> Boolean): Option<Boolean> {
|
protected fun toggle(propertyName: String, default: () -> Boolean): ManagedOption<Boolean> {
|
||||||
return option(propertyName, default, BooleanHandler(this))
|
return option(propertyName, default, BooleanHandler(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +88,7 @@ abstract class ManagedConfig(val name: String) {
|
|||||||
min: Duration,
|
min: Duration,
|
||||||
max: Duration,
|
max: Duration,
|
||||||
default: () -> Duration,
|
default: () -> Duration,
|
||||||
): Option<Duration> {
|
): ManagedOption<Duration> {
|
||||||
return option(propertyName, default, DurationHandler(this, min, max))
|
return option(propertyName, default, DurationHandler(this, min, max))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +98,7 @@ abstract class ManagedConfig(val name: String) {
|
|||||||
width: Int,
|
width: Int,
|
||||||
height: Int,
|
height: Int,
|
||||||
default: () -> Point,
|
default: () -> Point,
|
||||||
): Option<HudMeta> {
|
): ManagedOption<HudMeta> {
|
||||||
val label = Text.translatable("firmament.config.${name}.${propertyName}")
|
val label = Text.translatable("firmament.config.${name}.${propertyName}")
|
||||||
return option(propertyName, {
|
return option(propertyName, {
|
||||||
val p = default()
|
val p = default()
|
||||||
@@ -164,20 +111,19 @@ abstract class ManagedConfig(val name: String) {
|
|||||||
min: Int,
|
min: Int,
|
||||||
max: Int,
|
max: Int,
|
||||||
default: () -> Int,
|
default: () -> Int,
|
||||||
): Option<Int> {
|
): ManagedOption<Int> {
|
||||||
return option(propertyName, default, IntegerHandler(this, min, max))
|
return option(propertyName, default, IntegerHandler(this, min, max))
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun button(propertyName: String, runnable: () -> Unit): Option<Unit> {
|
protected fun button(propertyName: String, runnable: () -> Unit): ManagedOption<Unit> {
|
||||||
return option(propertyName, { }, ClickHandler(this, runnable))
|
return option(propertyName, { }, ClickHandler(this, runnable))
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun string(propertyName: String, default: () -> String): Option<String> {
|
protected fun string(propertyName: String, default: () -> String): ManagedOption<String> {
|
||||||
return option(propertyName, default, StringHandler(this))
|
return option(propertyName, default, StringHandler(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun reloadGui() {
|
fun reloadGui() {
|
||||||
latestGuiAppender?.reloadables?.forEach {it() }
|
latestGuiAppender?.reloadables?.forEach {it() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package moe.nea.firmament.gui.config
|
||||||
|
|
||||||
|
abstract class ManagedConfigElement {
|
||||||
|
abstract val name: String
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package moe.nea.firmament.gui.config
|
||||||
|
|
||||||
|
import kotlinx.serialization.json.JsonElement
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlin.properties.ReadWriteProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
import net.minecraft.text.Text
|
||||||
|
import moe.nea.firmament.Firmament
|
||||||
|
|
||||||
|
class ManagedOption<T : Any>(
|
||||||
|
val element: ManagedConfigElement,
|
||||||
|
val propertyName: String,
|
||||||
|
val default: () -> T,
|
||||||
|
val handler: ManagedConfig.OptionHandler<T>
|
||||||
|
) : ReadWriteProperty<Any?, T> {
|
||||||
|
|
||||||
|
val rawLabelText = "firmament.config.${element.name}.${propertyName}"
|
||||||
|
val labelText = Text.translatable(rawLabelText)
|
||||||
|
|
||||||
|
lateinit var value: T
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
||||||
|
this.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
fun load(root: JsonElement) {
|
||||||
|
if (root is JsonObject && root.containsKey(propertyName)) {
|
||||||
|
try {
|
||||||
|
value = handler.fromJson(root[propertyName]!!)
|
||||||
|
return
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Firmament.logger.error(
|
||||||
|
"Exception during loading of config file ${element.name}. This will reset this config.",
|
||||||
|
e
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value = default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toJson(): JsonElement? {
|
||||||
|
return handler.toJson(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun appendToGui(guiapp: GuiAppender) {
|
||||||
|
handler.emitGuiElements(this, guiapp)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.config
|
package moe.nea.firmament.gui.config
|
||||||
|
|
||||||
import io.github.cottonmc.cotton.gui.widget.WLabel
|
|
||||||
import io.github.cottonmc.cotton.gui.widget.WTextField
|
import io.github.cottonmc.cotton.gui.widget.WTextField
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import kotlinx.serialization.json.JsonPrimitive
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
@@ -22,7 +21,7 @@ class StringHandler(val config: ManagedConfig) : ManagedConfig.OptionHandler<Str
|
|||||||
return element.jsonPrimitive.content
|
return element.jsonPrimitive.content
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun emitGuiElements(opt: ManagedConfig.Option<String>, guiAppender: GuiAppender) {
|
override fun emitGuiElements(opt: ManagedOption<String>, guiAppender: GuiAppender) {
|
||||||
guiAppender.appendLabeledRow(
|
guiAppender.appendLabeledRow(
|
||||||
opt.labelText,
|
opt.labelText,
|
||||||
WTextField(opt.labelText).apply {
|
WTextField(opt.labelText).apply {
|
||||||
|
|||||||
Reference in New Issue
Block a user