aboutsummaryrefslogtreecommitdiff
path: root/src/compat/yacl/java/YaclIntegration.kt
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-10-13 19:53:10 +0200
committerLinnea Gräf <nea@nea.moe>2024-10-13 19:53:10 +0200
commit87b851373071490bb371ba1160f85f0341579cb2 (patch)
tree45d267d83baad2e3cb6caad6127f6a4d40e7fcbf /src/compat/yacl/java/YaclIntegration.kt
parente6142bb93619dee768fc18b87ffdd28558d4bcab (diff)
downloadFirmament-87b851373071490bb371ba1160f85f0341579cb2.tar.gz
Firmament-87b851373071490bb371ba1160f85f0341579cb2.tar.bz2
Firmament-87b851373071490bb371ba1160f85f0341579cb2.zip
Add YACL config menu
Diffstat (limited to 'src/compat/yacl/java/YaclIntegration.kt')
-rw-r--r--src/compat/yacl/java/YaclIntegration.kt119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/compat/yacl/java/YaclIntegration.kt b/src/compat/yacl/java/YaclIntegration.kt
new file mode 100644
index 0000000..6c9354a
--- /dev/null
+++ b/src/compat/yacl/java/YaclIntegration.kt
@@ -0,0 +1,119 @@
+package moe.nea.firmament.compat.yacl
+
+import com.google.auto.service.AutoService
+import dev.isxander.yacl3.api.Binding
+import dev.isxander.yacl3.api.ButtonOption
+import dev.isxander.yacl3.api.ConfigCategory
+import dev.isxander.yacl3.api.LabelOption
+import dev.isxander.yacl3.api.Option
+import dev.isxander.yacl3.api.YetAnotherConfigLib
+import dev.isxander.yacl3.api.controller.ControllerBuilder
+import dev.isxander.yacl3.api.controller.DoubleSliderControllerBuilder
+import dev.isxander.yacl3.api.controller.IntegerSliderControllerBuilder
+import dev.isxander.yacl3.api.controller.StringControllerBuilder
+import dev.isxander.yacl3.api.controller.TickBoxControllerBuilder
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.seconds
+import kotlin.time.DurationUnit
+import net.minecraft.client.gui.screen.Screen
+import net.minecraft.text.Text
+import moe.nea.firmament.gui.config.AllConfigsGui
+import moe.nea.firmament.gui.config.BooleanHandler
+import moe.nea.firmament.gui.config.ClickHandler
+import moe.nea.firmament.gui.config.DurationHandler
+import moe.nea.firmament.gui.config.FirmamentConfigScreenProvider
+import moe.nea.firmament.gui.config.HudMeta
+import moe.nea.firmament.gui.config.HudMetaHandler
+import moe.nea.firmament.gui.config.IntegerHandler
+import moe.nea.firmament.gui.config.KeyBindingHandler
+import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.gui.config.ManagedOption
+import moe.nea.firmament.gui.config.StringHandler
+import moe.nea.firmament.keybindings.SavedKeyBinding
+import moe.nea.firmament.util.FirmFormatters
+
+
+@AutoService(FirmamentConfigScreenProvider::class)
+class YaclIntegration : FirmamentConfigScreenProvider {
+ fun buildCategories() =
+ AllConfigsGui.allConfigs
+ .map(::buildCategory)
+
+ private fun buildCategory(managedConfig: ManagedConfig): ConfigCategory {
+ return ConfigCategory.createBuilder()
+ .name(managedConfig.labelText)
+ .also {
+ it.rootGroupBuilder()
+ .options(buildOptions(managedConfig.sortedOptions))
+ }
+ .build()
+ }
+
+ fun buildOptions(options: List<ManagedOption<*>>): Collection<Option<*>> =
+ options.map { buildOption(it) }
+
+ private fun <T : Any> buildOption(managedOption: ManagedOption<T>): Option<*> {
+ val handler = managedOption.handler
+ val binding = Binding.generic(managedOption.default(), managedOption::value, managedOption::value.setter)
+ fun <T> createDefaultBinding(function: (Option<T>) -> ControllerBuilder<T>): Option.Builder<T> {
+ return Option.createBuilder<T>()
+ .name(managedOption.labelText)
+ .binding(binding as Binding<T>)
+ .controller { function(it) }
+ }
+ when (handler) {
+ is ClickHandler -> return ButtonOption.createBuilder()
+ .name(managedOption.labelText)
+ .action { t, u ->
+ handler.runnable()
+ }
+ .build()
+
+ is HudMetaHandler -> return ButtonOption.createBuilder()
+ .name(managedOption.labelText)
+ .action { t, u ->
+ handler.openEditor(managedOption as ManagedOption<HudMeta>, t)
+ }
+ .build()
+
+ is BooleanHandler -> return createDefaultBinding(TickBoxControllerBuilder::create).build()
+ is StringHandler -> return createDefaultBinding(StringControllerBuilder::create).build()
+ is IntegerHandler -> return createDefaultBinding {
+ IntegerSliderControllerBuilder.create(it).range(handler.min, handler.max).step(1)
+ }.build()
+
+ is DurationHandler -> return Option.createBuilder<Double>()
+ .name(managedOption.labelText)
+ .binding((binding as Binding<Duration>).xmap({ it.toDouble(DurationUnit.SECONDS) }, { it.seconds }))
+ .controller {
+ DoubleSliderControllerBuilder.create(it)
+ .formatValue { Text.literal(FirmFormatters.formatTimespan(it.seconds)) }
+ .step(0.1)
+ .range(handler.min.toDouble(DurationUnit.SECONDS), handler.max.toDouble(DurationUnit.SECONDS))
+ }
+ .build()
+
+ is KeyBindingHandler -> return createDefaultBinding {
+ KeybindingBuilder(it, managedOption as ManagedOption<SavedKeyBinding>)
+ }.build()
+
+ else -> return LabelOption.create(Text.literal("This option is currently unhandled for this config menu. Please report this as a bug."))
+ }
+ }
+
+
+ fun buildConfig(): YetAnotherConfigLib {
+ return YetAnotherConfigLib.createBuilder()
+ .title(Text.literal("Firmament"))
+ .categories(buildCategories())
+ .build()
+ }
+
+ override val key: String
+ get() = "yacl"
+
+ override fun open(parent: Screen?): Screen {
+ return buildConfig().generateScreen(parent)
+ }
+
+}