aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/gui/config/ManagedConfig.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/gui/config/ManagedConfig.kt')
-rw-r--r--src/main/kotlin/gui/config/ManagedConfig.kt340
1 files changed, 186 insertions, 154 deletions
diff --git a/src/main/kotlin/gui/config/ManagedConfig.kt b/src/main/kotlin/gui/config/ManagedConfig.kt
index 0d942e2..44c6e59 100644
--- a/src/main/kotlin/gui/config/ManagedConfig.kt
+++ b/src/main/kotlin/gui/config/ManagedConfig.kt
@@ -1,5 +1,3 @@
-
-
package moe.nea.firmament.gui.config
import io.github.notenoughupdates.moulconfig.gui.CloseEventListener
@@ -26,157 +24,191 @@ import moe.nea.firmament.Firmament
import moe.nea.firmament.gui.FirmButtonComponent
import moe.nea.firmament.keybindings.SavedKeyBinding
import moe.nea.firmament.util.ScreenUtil.setScreenLater
-
-abstract class ManagedConfig(override val name: String) : ManagedConfigElement() {
-
- interface OptionHandler<T : Any> {
- fun initOption(opt: ManagedOption<T>) {}
- fun toJson(element: T): JsonElement?
- fun fromJson(element: JsonElement): T
- fun emitGuiElements(opt: ManagedOption<T>, guiAppender: GuiAppender)
- }
-
- val file = Firmament.CONFIG_DIR.resolve("$name.json")
- val data: JsonObject by lazy {
- try {
- Firmament.json.decodeFromString(
- file.readText()
- )
- } catch (e: Exception) {
- Firmament.logger.info("Could not read config $name. Loading empty config.")
- JsonObject(mutableMapOf())
- }
- }
-
- fun save() {
- val data = JsonObject(allOptions.mapNotNull { (key, value) ->
- value.toJson()?.let {
- key to it
- }
- }.toMap())
- file.parent.createDirectories()
- file.writeText(Firmament.json.encodeToString(data))
- }
-
-
- val allOptions = mutableMapOf<String, ManagedOption<*>>()
- val sortedOptions = mutableListOf<ManagedOption<*>>()
-
- private var latestGuiAppender: GuiAppender? = null
-
- 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")
- return ManagedOption(this, propertyName, default, handler).also {
- it.handler.initOption(it)
- it.load(data)
- allOptions[propertyName] = it
- sortedOptions.add(it)
- }
- }
-
- protected fun toggle(propertyName: String, default: () -> Boolean): ManagedOption<Boolean> {
- return option(propertyName, default, BooleanHandler(this))
- }
-
- protected fun duration(
- propertyName: String,
- min: Duration,
- max: Duration,
- default: () -> Duration,
- ): ManagedOption<Duration> {
- return option(propertyName, default, DurationHandler(this, min, max))
- }
-
-
- protected fun position(
- propertyName: String,
- width: Int,
- height: Int,
- default: () -> Point,
- ): ManagedOption<HudMeta> {
- val label = Text.translatable("firmament.config.${name}.${propertyName}")
- return option(propertyName, {
- val p = default()
- HudMeta(HudPosition(p.x, p.y, 1F), label, width, height)
- }, HudMetaHandler(this, label, width, height))
- }
-
- protected fun keyBinding(
- propertyName: String,
- default: () -> Int,
- ): ManagedOption<SavedKeyBinding> = keyBindingWithOutDefaultModifiers(propertyName) { SavedKeyBinding(default()) }
-
- protected fun keyBindingWithOutDefaultModifiers(
- propertyName: String,
- default: () -> SavedKeyBinding,
- ): ManagedOption<SavedKeyBinding> {
- return option(propertyName, default, KeyBindingHandler("firmament.config.${name}.${propertyName}", this))
- }
-
- protected fun keyBindingWithDefaultUnbound(
- propertyName: String,
- ): ManagedOption<SavedKeyBinding> {
- return keyBindingWithOutDefaultModifiers(propertyName) { SavedKeyBinding(GLFW.GLFW_KEY_UNKNOWN) }
- }
-
- protected fun integer(
- propertyName: String,
- min: Int,
- max: Int,
- default: () -> Int,
- ): ManagedOption<Int> {
- return option(propertyName, default, IntegerHandler(this, min, max))
- }
-
- protected fun button(propertyName: String, runnable: () -> Unit): ManagedOption<Unit> {
- return option(propertyName, { }, ClickHandler(this, runnable))
- }
-
- protected fun string(propertyName: String, default: () -> String): ManagedOption<String> {
- return option(propertyName, default, StringHandler(this))
- }
-
-
- fun reloadGui() {
- latestGuiAppender?.reloadables?.forEach { it() }
- }
-
- val translationKey get() = "firmament.config.${name}"
- val labelText = Text.translatable(translationKey)
-
- fun getConfigEditor(parent: Screen? = null): Screen {
- var screen: Screen? = null
- val guiapp = GuiAppender(400) { requireNotNull(screen) { "Screen Accessor called too early" } }
- latestGuiAppender = guiapp
- guiapp.appendFullRow(RowComponent(
- FirmButtonComponent(TextComponent("←")) {
- if (parent != null) {
- save()
- setScreenLater(parent)
- } else {
- AllConfigsGui.showAllGuis()
- }
- }
- ))
- sortedOptions.forEach { it.appendToGui(guiapp) }
- guiapp.reloadables.forEach { it() }
- val component = CenterComponent(PanelComponent(ScrollPanelComponent(400, 300, ColumnComponent(guiapp.panel)), 10, PanelComponent.DefaultBackgroundRenderer.VANILLA))
- screen = object : GuiComponentWrapper(GuiContext(component)) {
- override fun close() {
- if (context.onBeforeClose() == CloseEventListener.CloseAction.NO_OBJECTIONS_TO_CLOSE) {
- client!!.setScreen(parent)
- }
- }
- }
- return screen
- }
-
- fun showConfigEditor(parent: Screen? = null) {
- setScreenLater(getConfigEditor(parent))
- }
+import moe.nea.firmament.util.collections.InstanceList
+
+abstract class ManagedConfig(
+ override val name: String,
+ val category: Category,
+ // TODO: allow vararg secondaryCategories: Category,
+) : ManagedConfigElement() {
+ enum class Category {
+ // Böse Kategorie, nicht benutzten lol
+ MISC,
+ CHAT,
+ INVENTORY,
+ MINING,
+ EVENTS,
+ INTEGRATIONS,
+ META,
+ DEV,
+ ;
+
+ val labelText: Text = Text.translatable("firmament.config.category.${name.lowercase()}")
+ val configs: MutableList<ManagedConfig> = mutableListOf()
+ }
+
+ companion object {
+ val allManagedConfigs = InstanceList<ManagedConfig>("ManagedConfig")
+ }
+
+ interface OptionHandler<T : Any> {
+ fun initOption(opt: ManagedOption<T>) {}
+ fun toJson(element: T): JsonElement?
+ fun fromJson(element: JsonElement): T
+ fun emitGuiElements(opt: ManagedOption<T>, guiAppender: GuiAppender)
+ }
+
+ init {
+ allManagedConfigs.getAll().forEach {
+ require(it.name != name) { "Duplicate name '$name' used for config" }
+ }
+ allManagedConfigs.add(this)
+ category.configs.add(this)
+ }
+
+ val file = Firmament.CONFIG_DIR.resolve("$name.json")
+ val data: JsonObject by lazy {
+ try {
+ Firmament.json.decodeFromString(
+ file.readText()
+ )
+ } catch (e: Exception) {
+ Firmament.logger.info("Could not read config $name. Loading empty config.")
+ JsonObject(mutableMapOf())
+ }
+ }
+
+ fun save() {
+ val data = JsonObject(allOptions.mapNotNull { (key, value) ->
+ value.toJson()?.let {
+ key to it
+ }
+ }.toMap())
+ file.parent.createDirectories()
+ file.writeText(Firmament.json.encodeToString(data))
+ }
+
+
+ val allOptions = mutableMapOf<String, ManagedOption<*>>()
+ val sortedOptions = mutableListOf<ManagedOption<*>>()
+
+ private var latestGuiAppender: GuiAppender? = null
+
+ 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")
+ return ManagedOption(this, propertyName, default, handler).also {
+ it.handler.initOption(it)
+ it.load(data)
+ allOptions[propertyName] = it
+ sortedOptions.add(it)
+ }
+ }
+
+ protected fun toggle(propertyName: String, default: () -> Boolean): ManagedOption<Boolean> {
+ return option(propertyName, default, BooleanHandler(this))
+ }
+
+ protected fun duration(
+ propertyName: String,
+ min: Duration,
+ max: Duration,
+ default: () -> Duration,
+ ): ManagedOption<Duration> {
+ return option(propertyName, default, DurationHandler(this, min, max))
+ }
+
+
+ protected fun position(
+ propertyName: String,
+ width: Int,
+ height: Int,
+ default: () -> Point,
+ ): ManagedOption<HudMeta> {
+ val label = Text.translatable("firmament.config.${name}.${propertyName}")
+ return option(propertyName, {
+ val p = default()
+ HudMeta(HudPosition(p.x, p.y, 1F), label, width, height)
+ }, HudMetaHandler(this, label, width, height))
+ }
+
+ protected fun keyBinding(
+ propertyName: String,
+ default: () -> Int,
+ ): ManagedOption<SavedKeyBinding> = keyBindingWithOutDefaultModifiers(propertyName) { SavedKeyBinding(default()) }
+
+ protected fun keyBindingWithOutDefaultModifiers(
+ propertyName: String,
+ default: () -> SavedKeyBinding,
+ ): ManagedOption<SavedKeyBinding> {
+ return option(propertyName, default, KeyBindingHandler("firmament.config.${name}.${propertyName}", this))
+ }
+
+ protected fun keyBindingWithDefaultUnbound(
+ propertyName: String,
+ ): ManagedOption<SavedKeyBinding> {
+ return keyBindingWithOutDefaultModifiers(propertyName) { SavedKeyBinding(GLFW.GLFW_KEY_UNKNOWN) }
+ }
+
+ protected fun integer(
+ propertyName: String,
+ min: Int,
+ max: Int,
+ default: () -> Int,
+ ): ManagedOption<Int> {
+ return option(propertyName, default, IntegerHandler(this, min, max))
+ }
+
+ protected fun button(propertyName: String, runnable: () -> Unit): ManagedOption<Unit> {
+ return option(propertyName, { }, ClickHandler(this, runnable))
+ }
+
+ protected fun string(propertyName: String, default: () -> String): ManagedOption<String> {
+ return option(propertyName, default, StringHandler(this))
+ }
+
+
+ fun reloadGui() {
+ latestGuiAppender?.reloadables?.forEach { it() }
+ }
+
+ val translationKey get() = "firmament.config.${name}"
+ val labelText = Text.translatable(translationKey)
+
+ fun getConfigEditor(parent: Screen? = null): Screen {
+ var screen: Screen? = null
+ val guiapp = GuiAppender(400) { requireNotNull(screen) { "Screen Accessor called too early" } }
+ latestGuiAppender = guiapp
+ guiapp.appendFullRow(RowComponent(
+ FirmButtonComponent(TextComponent("←")) {
+ if (parent != null) {
+ save()
+ setScreenLater(parent)
+ } else {
+ AllConfigsGui.showAllGuis()
+ }
+ }
+ ))
+ sortedOptions.forEach { it.appendToGui(guiapp) }
+ guiapp.reloadables.forEach { it() }
+ val component = CenterComponent(PanelComponent(ScrollPanelComponent(400, 300, ColumnComponent(guiapp.panel)),
+ 10,
+ PanelComponent.DefaultBackgroundRenderer.VANILLA))
+ screen = object : GuiComponentWrapper(GuiContext(component)) {
+ override fun close() {
+ if (context.onBeforeClose() == CloseEventListener.CloseAction.NO_OBJECTIONS_TO_CLOSE) {
+ client!!.setScreen(parent)
+ }
+ }
+ }
+ return screen
+ }
+
+ fun showConfigEditor(parent: Screen? = null) {
+ setScreenLater(getConfigEditor(parent))
+ }
}