diff options
Diffstat (limited to 'src/main/kotlin/gui/config')
-rw-r--r-- | src/main/kotlin/gui/config/AllConfigsGui.kt | 46 | ||||
-rw-r--r-- | src/main/kotlin/gui/config/ManagedConfig.kt | 340 | ||||
-rw-r--r-- | src/main/kotlin/gui/config/ManagedOption.kt | 2 |
3 files changed, 224 insertions, 164 deletions
diff --git a/src/main/kotlin/gui/config/AllConfigsGui.kt b/src/main/kotlin/gui/config/AllConfigsGui.kt index c72b8b0..0e68bc8 100644 --- a/src/main/kotlin/gui/config/AllConfigsGui.kt +++ b/src/main/kotlin/gui/config/AllConfigsGui.kt @@ -4,24 +4,35 @@ 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.repo.RepoManager import moe.nea.firmament.util.MC import moe.nea.firmament.util.MoulConfigUtils import moe.nea.firmament.util.ScreenUtil.setScreenLater object AllConfigsGui { +// +// val allConfigs +// get() = listOf( +// RepoManager.Config +// ) + FeatureManager.allFeatures.mapNotNull { it.config } - val allConfigs - get() = listOf( - RepoManager.Config - ) + FeatureManager.allFeatures.mapNotNull { it.config } + object ConfigConfig : ManagedConfig("configconfig", Category.META) { + val enableYacl by toggle("enable-yacl") { false } + } fun <T> List<T>.toObservableList(): ObservableList<T> = ObservableList(this) - class MainMapping(val allConfigs: List<ManagedConfig>) { + class CategoryMapping(val category: ManagedConfig.Category) { @get:Bind("configs") - val configs = allConfigs.map { EntryMapping(it) }.toObservableList() + val configs = category.configs.map { EntryMapping(it) }.toObservableList() + + @Bind + fun name() = category.labelText.string + + @Bind + fun close() { + MC.screen?.close() + } class EntryMapping(val config: ManagedConfig) { @Bind @@ -34,12 +45,29 @@ object AllConfigsGui { } } + class CategoryView { + @get:Bind("categories") + val categories = ManagedConfig.Category.entries + .map { CategoryEntry(it) } + .toObservableList() + + class CategoryEntry(val category: ManagedConfig.Category) { + @Bind + fun name() = category.labelText.string + + @Bind + fun open() { + MC.screen = MoulConfigUtils.loadScreen("config/category", CategoryMapping(category), MC.screen) + } + } + } + fun makeBuiltInScreen(parent: Screen? = null): Screen { - return MoulConfigUtils.loadScreen("config/main", MainMapping(allConfigs), parent) + return MoulConfigUtils.loadScreen("config/main", CategoryView(), parent) } fun makeScreen(parent: Screen? = null): Screen { - val wantedKey = if (RepoManager.Config.enableYacl) "yacl" else "builtin" + val wantedKey = if (ConfigConfig.enableYacl) "yacl" else "builtin" val provider = FirmamentConfigScreenProvider.providers.find { it.key == wantedKey } ?: FirmamentConfigScreenProvider.providers.first() return provider.open(parent) 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)) + } } diff --git a/src/main/kotlin/gui/config/ManagedOption.kt b/src/main/kotlin/gui/config/ManagedOption.kt index b7264e8..4a8d773 100644 --- a/src/main/kotlin/gui/config/ManagedOption.kt +++ b/src/main/kotlin/gui/config/ManagedOption.kt @@ -11,7 +11,7 @@ import net.minecraft.text.Text import moe.nea.firmament.Firmament class ManagedOption<T : Any>( - val element: ManagedConfigElement, + val element: ManagedConfig, val propertyName: String, val default: () -> T, val handler: ManagedConfig.OptionHandler<T> |