diff options
author | Linnea Gräf <nea@nea.moe> | 2024-07-01 03:42:51 +0200 |
---|---|---|
committer | Linnea Gräf <nea@nea.moe> | 2024-07-03 21:05:51 +0200 |
commit | 5ee4b8d925eb12e068038a1fd2e1f35cdd8ef87e (patch) | |
tree | a5b0a6fbc8878ae62bb2c3a01dbb255388353fda /src/main/kotlin/moe/nea/firmament | |
parent | dff1f9c0e2b728dba902d72816104abccc61f511 (diff) | |
download | Firmament-5ee4b8d925eb12e068038a1fd2e1f35cdd8ef87e.tar.gz Firmament-5ee4b8d925eb12e068038a1fd2e1f35cdd8ef87e.tar.bz2 Firmament-5ee4b8d925eb12e068038a1fd2e1f35cdd8ef87e.zip |
[WIP] Remove LibGUI
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament')
38 files changed, 402 insertions, 1117 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/commands/rome.kt b/src/main/kotlin/moe/nea/firmament/commands/rome.kt index dc46f1f..6ec09f2 100644 --- a/src/main/kotlin/moe/nea/firmament/commands/rome.kt +++ b/src/main/kotlin/moe/nea/firmament/commands/rome.kt @@ -20,7 +20,6 @@ import moe.nea.firmament.features.world.FairySouls import moe.nea.firmament.gui.config.AllConfigsGui import moe.nea.firmament.gui.config.BooleanHandler import moe.nea.firmament.gui.config.ManagedOption -import moe.nea.firmament.gui.profileviewer.ProfileViewer import moe.nea.firmament.repo.HypixelStaticData import moe.nea.firmament.repo.RepoManager import moe.nea.firmament.util.FirmFormatters @@ -28,7 +27,6 @@ import moe.nea.firmament.util.MC import moe.nea.firmament.util.SBData import moe.nea.firmament.util.ScreenUtil import moe.nea.firmament.util.SkyblockId -import moe.nea.firmament.util.unformattedString fun firmamentCommand() = literal("firmament") { @@ -127,19 +125,6 @@ fun firmamentCommand() = literal("firmament") { } } } - thenLiteral("pv") { - thenExecute { - ProfileViewer.onCommand(source, MC.player!!.name.unformattedString) - } - thenArgument("name", string()) { name -> - suggestsList { - MC.world?.players?.filter { it.uuid?.version() == 4 }?.map { it.name.unformattedString } ?: listOf() - } - thenExecute { - ProfileViewer.onCommand(source, get(name)) - } - } - } thenLiteral("price") { thenArgument("item", string()) { item -> suggestsList { RepoManager.neuRepo.items.items.keys } @@ -155,7 +140,7 @@ fun firmamentCommand() = literal("firmament") { source.sendFeedback( Text.stringifiedTranslatable( "firmament.price.bazaar.buy.price", - FirmFormatters.formatCurrency(bazaarData.quickStatus.buyPrice, 1) + FirmFormatters.formatCommas(bazaarData.quickStatus.buyPrice, 1) ) ) source.sendFeedback( @@ -167,7 +152,7 @@ fun firmamentCommand() = literal("firmament") { source.sendFeedback( Text.stringifiedTranslatable( "firmament.price.bazaar.sell.price", - FirmFormatters.formatCurrency(bazaarData.quickStatus.sellPrice, 1) + FirmFormatters.formatCommas(bazaarData.quickStatus.sellPrice, 1) ) ) source.sendFeedback( @@ -182,7 +167,7 @@ fun firmamentCommand() = literal("firmament") { source.sendFeedback( Text.stringifiedTranslatable( "firmament.price.lowestbin", - FirmFormatters.formatCurrency(lowestBin, 1) + FirmFormatters.formatCommas(lowestBin, 1) ) ) } diff --git a/src/main/kotlin/moe/nea/firmament/features/debug/DebugView.kt b/src/main/kotlin/moe/nea/firmament/features/debug/DebugView.kt index 4ba8eee..972eb1f 100644 --- a/src/main/kotlin/moe/nea/firmament/features/debug/DebugView.kt +++ b/src/main/kotlin/moe/nea/firmament/features/debug/DebugView.kt @@ -6,12 +6,6 @@ package moe.nea.firmament.features.debug -import io.github.cottonmc.cotton.gui.client.CottonHud -import io.github.cottonmc.cotton.gui.widget.WBox -import io.github.cottonmc.cotton.gui.widget.WDynamicLabel -import io.github.cottonmc.cotton.gui.widget.data.Axis -import java.util.stream.Collectors -import kotlin.time.Duration.Companion.seconds import moe.nea.firmament.Firmament import moe.nea.firmament.events.TickEvent import moe.nea.firmament.features.FirmamentFeature @@ -36,24 +30,8 @@ object DebugView : FirmamentFeature { } fun recalculateDebugWidget() { - storedVariables.entries.removeIf { it.value.timer.passedTime() > 1.seconds } - debugWidget.streamChildren().collect(Collectors.toList()).forEach { - debugWidget.remove(it) - } - storedVariables.entries.forEach { - debugWidget.add(WDynamicLabel({ "${it.key}: ${it.value.obj}" })) - } - debugWidget.layout() - if (storedVariables.isNotEmpty()) { - CottonHud.add(debugWidget, 20, 20) - } else { - CottonHud.remove(debugWidget) - } } - val debugWidget = WBox(Axis.VERTICAL) - - override fun onLoad() { TickEvent.subscribe { synchronized(this) { diff --git a/src/main/kotlin/moe/nea/firmament/features/debug/ObjectRenderer.kt b/src/main/kotlin/moe/nea/firmament/features/debug/ObjectRenderer.kt deleted file mode 100644 index 18f502c..0000000 --- a/src/main/kotlin/moe/nea/firmament/features/debug/ObjectRenderer.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.features.debug - -import io.github.cottonmc.cotton.gui.widget.WBox -import io.github.cottonmc.cotton.gui.widget.WLabel -import io.github.cottonmc.cotton.gui.widget.WWidget -import io.github.cottonmc.cotton.gui.widget.data.Axis -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import kotlin.reflect.KProperty1 -import net.minecraft.text.Text -import moe.nea.firmament.gui.WSpacer - -class ObjectRenderer(val box: WBox) { - var indent = 0 - - fun beginObject() { - indent++ - } - - fun endObject() { - indent-- - } - - fun emit(label: String, widget: WWidget) { - WSpacer(WBox(Axis.VERTICAL).also { - it.add(WWidget()) - it.add(widget) - }, indent * 18) - } - - fun <T : Any?> getDebuggingView(label: String, obj: T) { - if (obj == null) { - emit(label, WLabel(Text.literal("§cnull"))) - return - } - if (obj is String) { - emit(label, WLabel(Text.literal(Json.encodeToString(obj)))) - } - getObject(label, obj) - } - - fun <T : Any> getObject(label: String, obj: T) { - emit(label, WLabel(Text.literal(obj::class.simpleName ?: "<unknown>"))) - beginObject() - for (prop in obj::class.members.filterIsInstance<KProperty1<T, *>>()) { - val child = prop.get(obj) - getDebuggingView(prop.name, child) - } - endObject() - } - -} diff --git a/src/main/kotlin/moe/nea/firmament/features/inventory/PriceData.kt b/src/main/kotlin/moe/nea/firmament/features/inventory/PriceData.kt index fb99c7c..2e6d5c6 100644 --- a/src/main/kotlin/moe/nea/firmament/features/inventory/PriceData.kt +++ b/src/main/kotlin/moe/nea/firmament/features/inventory/PriceData.kt @@ -39,17 +39,17 @@ object PriceData : FirmamentFeature { it.lines.add(Text.literal("")) it.lines.add( Text.stringifiedTranslatable("firmament.tooltip.bazaar.sell-order", - FirmFormatters.formatCurrency(bazaarData.quickStatus.sellPrice, 1)) + FirmFormatters.formatCommas(bazaarData.quickStatus.sellPrice, 1)) ) it.lines.add( Text.stringifiedTranslatable("firmament.tooltip.bazaar.buy-order", - FirmFormatters.formatCurrency(bazaarData.quickStatus.buyPrice, 1)) + FirmFormatters.formatCommas(bazaarData.quickStatus.buyPrice, 1)) ) } else if (lowestBin != null) { it.lines.add(Text.literal("")) it.lines.add( Text.stringifiedTranslatable("firmament.tooltip.ah.lowestbin", - FirmFormatters.formatCurrency(lowestBin, 1)) + FirmFormatters.formatCommas(lowestBin, 1)) ) } } diff --git a/src/main/kotlin/moe/nea/firmament/features/mining/PristineProfitTracker.kt b/src/main/kotlin/moe/nea/firmament/features/mining/PristineProfitTracker.kt index 1597501..dd2d2fb 100644 --- a/src/main/kotlin/moe/nea/firmament/features/mining/PristineProfitTracker.kt +++ b/src/main/kotlin/moe/nea/firmament/features/mining/PristineProfitTracker.kt @@ -18,7 +18,7 @@ import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.gui.config.ManagedConfig import moe.nea.firmament.gui.hud.MoulConfigHud import moe.nea.firmament.util.BazaarPriceStrategy -import moe.nea.firmament.util.FirmFormatters.formatCurrency +import moe.nea.firmament.util.FirmFormatters.formatCommas import moe.nea.firmament.util.SkyblockId import moe.nea.firmament.util.data.ProfileSpecificDataHolder import moe.nea.firmament.util.formattedString @@ -99,11 +99,11 @@ object PristineProfitTracker : FirmamentFeature { if (collectionPerSecond == null || moneyPerSecond == null) return ProfitHud.collectionCurrent = collectionPerSecond ProfitHud.collectionText = Text.stringifiedTranslatable("firmament.pristine-profit.collection", - formatCurrency(collectionPerSecond * SECONDS_PER_HOUR, - 1)).formattedString() + formatCommas(collectionPerSecond * SECONDS_PER_HOUR, + 1)).formattedString() ProfitHud.moneyCurrent = moneyPerSecond ProfitHud.moneyText = Text.stringifiedTranslatable("firmament.pristine-profit.money", - formatCurrency(moneyPerSecond * SECONDS_PER_HOUR, 1)) + formatCommas(moneyPerSecond * SECONDS_PER_HOUR, 1)) .formattedString() val data = DConfig.data if (data != null) { diff --git a/src/main/kotlin/moe/nea/firmament/gui/BarComponent.kt b/src/main/kotlin/moe/nea/firmament/gui/BarComponent.kt index 91b5735..38e898d 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/BarComponent.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/BarComponent.kt @@ -7,8 +7,6 @@ package moe.nea.firmament.gui import com.mojang.blaze3d.systems.RenderSystem -import io.github.cottonmc.cotton.gui.client.ScreenDrawing -import io.github.cottonmc.cotton.gui.widget.data.Texture import io.github.notenoughupdates.moulconfig.common.MyResourceLocation import io.github.notenoughupdates.moulconfig.common.RenderContext import io.github.notenoughupdates.moulconfig.gui.GuiComponent @@ -33,6 +31,24 @@ class BarComponent( return 8 } + data class Texture( + val identifier: Identifier, + val u1: Float, val v1: Float, + val u2: Float, val v2: Float, + ) { + fun draw(context: DrawContext, x: Int, y: Int, width: Int, height: Int, color: Color) { + context.drawTexturedQuad( + identifier, + x, y, x + width, x + height, 0, + u1, u2, v1, v2, + color.red / 255F, + color.green / 255F, + color.blue / 255F, + color.alpha / 255F, + ) + } + } + companion object { val resource = Firmament.identifier("textures/gui/bar.png") val left = Texture(resource, 0 / 64F, 0 / 64F, 4 / 64F, 8 / 64F) @@ -51,20 +67,21 @@ class BarComponent( sectionEnd: Double ) { if (sectionEnd < progress.get() && width == 4) { - ScreenDrawing.texturedRect(context, x, y, 4, 8, texture, fillColor.color) + texture.draw(context, x, y, 4, 8, fillColor) return } if (sectionStart > progress.get() && width == 4) { - ScreenDrawing.texturedRect(context, x, y, 4, 8, texture, emptyColor.color) + texture.draw(context, x, y, 4, 8, emptyColor) return } val increasePerPixel = (sectionEnd - sectionStart) / width var valueAtPixel = sectionStart for (i in (0 until width)) { - ScreenDrawing.texturedRect( + val newTex = + Texture(texture.identifier, texture.u1 + i / 64F, texture.v1, texture.u1 + (i + 1) / 64F, texture.v2) + newTex.draw( context, x + i, y, 1, 8, - texture.image, texture.u1 + i / 64F, texture.v1, texture.u1 + (i + 1) / 64F, texture.v2, - if (valueAtPixel < progress.get()) fillColor.color else emptyColor.color + if (valueAtPixel < progress.get()) fillColor else emptyColor ) valueAtPixel += increasePerPixel } diff --git a/src/main/kotlin/moe/nea/firmament/gui/FirmButtonComponent.kt b/src/main/kotlin/moe/nea/firmament/gui/FirmButtonComponent.kt index 30f280c..d1e223e 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/FirmButtonComponent.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/FirmButtonComponent.kt @@ -15,24 +15,31 @@ import io.github.notenoughupdates.moulconfig.gui.component.PanelComponent import io.github.notenoughupdates.moulconfig.observer.GetSetter -class FirmButtonComponent( +open class FirmButtonComponent( child: GuiComponent, + val isEnabled: GetSetter<Boolean> = GetSetter.constant(true), val action: Runnable, - val isEnabled: GetSetter<Boolean> = 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 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")) + 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() + val activeBg = NinePatch.builder(MyResourceLocation("firmament", "textures/gui/sprites/widget/button_active.png")) .cornerSize(5) .cornerUv(5 / 200F, 5 / 20F) .mode(NinePatch.Mode.STRETCHING) @@ -59,12 +66,15 @@ class FirmButtonComponent( return false } + open fun getBackground(context: GuiImmediateContext): NinePatch<MyResourceLocation> = + if (!isEnabled.get()) disabledBg + else if (context.isHovered || isClicking) hoveredBg + else unhoveredBg + override fun render(context: GuiImmediateContext) { context.renderContext.pushMatrix() context.renderContext.drawNinePatch( - if (!isEnabled.get()) disabledBg - else if (context.isHovered || isClicking) hoveredBg - else unhoveredBg, + getBackground(context), 0f, 0f, context.width, context.height ) context.renderContext.translate(insets.toFloat(), insets.toFloat(), 0f) diff --git a/src/main/kotlin/moe/nea/firmament/gui/FixedComponent.kt b/src/main/kotlin/moe/nea/firmament/gui/FixedComponent.kt index c98feda..15d6bfc 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/FixedComponent.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/FixedComponent.kt @@ -14,20 +14,20 @@ import io.github.notenoughupdates.moulconfig.observer.GetSetter import java.util.function.BiFunction class FixedComponent( - val fixedWidth: GetSetter<Int>, - val fixedHeight: GetSetter<Int>, + val fixedWidth: GetSetter<Int>?, + val fixedHeight: GetSetter<Int>?, val component: GuiComponent, ) : GuiComponent() { - override fun getWidth(): Int = fixedWidth.get() + override fun getWidth(): Int = fixedWidth?.get() ?: component.width - override fun getHeight(): Int = fixedHeight.get() + override fun getHeight(): Int = fixedHeight?.get() ?: component.height override fun <T : Any?> foldChildren(initial: T, visitor: BiFunction<GuiComponent, T, T>): T { return visitor.apply(component, initial) } fun fixContext(context: GuiImmediateContext): GuiImmediateContext = - context.translated(0, 0, fixedWidth.get(), fixedHeight.get()) + context.translated(0, 0, width, height) override fun render(context: GuiImmediateContext) { component.render(fixContext(context)) diff --git a/src/main/kotlin/moe/nea/firmament/gui/WBar.kt b/src/main/kotlin/moe/nea/firmament/gui/WBar.kt deleted file mode 100644 index 5772aac..0000000 --- a/src/main/kotlin/moe/nea/firmament/gui/WBar.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.gui - -import com.mojang.blaze3d.systems.RenderSystem -import io.github.cottonmc.cotton.gui.client.ScreenDrawing -import io.github.cottonmc.cotton.gui.widget.WWidget -import io.github.cottonmc.cotton.gui.widget.data.Texture -import me.shedaniel.math.Color -import net.minecraft.client.gui.DrawContext -import moe.nea.firmament.Firmament - -open class WBar( - var progress: Double, - var total: Double, - val fillColor: Color, - val emptyColor: Color = fillColor.darker(2.0), -) : WWidget() { - companion object { - val resource = Firmament.identifier("textures/gui/bar.png") - val left = Texture(resource, 0 / 64F, 0 / 64F, 4 / 64F, 8 / 64F) - val middle = Texture(resource, 4 / 64F, 0 / 64F, 8 / 64F, 8 / 64F) - val right = Texture(resource, 8 / 64F, 0 / 64F, 12 / 64F, 8 / 64F) - val segmentOverlay = Texture(resource, 12 / 64F, 0 / 64F, 15 / 64F, 8 / 64F) - } - - override fun canResize(): Boolean { - return true - } - - private fun drawSection( - context: DrawContext, - texture: Texture, - x: Int, - y: Int, - width: Int, - sectionStart: Double, - sectionEnd: Double - ) { - if (sectionEnd < progress && width == 4) { - ScreenDrawing.texturedRect(context, x, y, 4, 8, texture, fillColor.color) - return - } - if (sectionStart > progress && width == 4) { - ScreenDrawing.texturedRect(context, x, y, 4, 8, texture, emptyColor.color) - return - } - val increasePerPixel = (sectionEnd - sectionStart / 4) - var valueAtPixel = sectionStart - for (i in (0 until width)) { - ScreenDrawing.texturedRect( - context, x + i, y, 1, 8, - texture.image, texture.u1 + i / 64F, texture.v1, texture.u1 + (i + 1) / 64F, texture.v2, - if (valueAtPixel < progress) fillColor.color else emptyColor.color - ) - valueAtPixel += increasePerPixel - } - } - - override fun paint(context: DrawContext, x: Int, y: Int, mouseX: Int, mouseY: Int) { - var i = 0 - while (i < width - 4) { - drawSection( - context, - if (i == 0) left else middle, - x + i, y, - (width - (i + 4)).coerceAtMost(4), - i * total / width, (i + 4) * total / width - ) - i += 4 - } - drawSection(context, right, x + width - 4, y, 4, (width - 4) * total / width, total) - RenderSystem.setShaderColor(1F, 1F, 1F, 1F) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/gui/WCenteringPanel.kt b/src/main/kotlin/moe/nea/firmament/gui/WCenteringPanel.kt deleted file mode 100644 index 69a59f5..0000000 --- a/src/main/kotlin/moe/nea/firmament/gui/WCenteringPanel.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.gui - -import io.github.cottonmc.cotton.gui.widget.WPanel -import io.github.cottonmc.cotton.gui.widget.WWidget -import io.github.cottonmc.cotton.gui.widget.data.Axis - -data class WCenteringPanel( - val child: WWidget, - val axis: Axis, -) : WPanel() { - init { - child.parent = this - } - - override fun setSize(x: Int, y: Int) { - super.setSize(x, y) - if (!child.canResize()) return - if (axis == Axis.HORIZONTAL) { - child.setSize(child.width, y) - } else { - child.setSize(x, child.height) - } - } - - override fun layout() { - super.layout() - child.setLocation( - axis.choose((child.width + width) / 2, child.x), - axis.choose(child.y, (child.height + height) / 2), - ) - } - - -} diff --git a/src/main/kotlin/moe/nea/firmament/gui/WFixedPanel.kt b/src/main/kotlin/moe/nea/firmament/gui/WFixedPanel.kt deleted file mode 100644 index 0fd724b..0000000 --- a/src/main/kotlin/moe/nea/firmament/gui/WFixedPanel.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.gui - -import io.github.cottonmc.cotton.gui.widget.WPanel -import io.github.cottonmc.cotton.gui.widget.WWidget - -class WFixedPanel() : WPanel() { - var child: WWidget - set(value) { - children.clear() - setSize(0, 0) - value.parent = this - children.add(value) - } - get() = children.single() - - constructor(child: WWidget) : this() { - this.child = child - } - - override fun layout() { - setSize(0, 0) - super.layout() - } - - override fun canResize(): Boolean = false -} diff --git a/src/main/kotlin/moe/nea/firmament/gui/WSpacer.kt b/src/main/kotlin/moe/nea/firmament/gui/WSpacer.kt deleted file mode 100644 index 8cdc4b8..0000000 --- a/src/main/kotlin/moe/nea/firmament/gui/WSpacer.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.gui - -import io.github.cottonmc.cotton.gui.widget.WPanel -import io.github.cottonmc.cotton.gui.widget.WWidget - -class WSpacer(val child: WWidget, val spaceLeft: Int) : WPanel() { - init { - children.add(child) - child.setLocation(spaceLeft, 0) - } - - override fun getWidth(): Int { - return child.width + spaceLeft - } - - override fun getHeight(): Int { - return child.height - } -} diff --git a/src/main/kotlin/moe/nea/firmament/gui/WSplitPanel.kt b/src/main/kotlin/moe/nea/firmament/gui/WSplitPanel.kt deleted file mode 100644 index 1469880..0000000 --- a/src/main/kotlin/moe/nea/firmament/gui/WSplitPanel.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.gui - -import io.github.cottonmc.cotton.gui.widget.WPanel -import io.github.cottonmc.cotton.gui.widget.WPanelWithInsets -import io.github.cottonmc.cotton.gui.widget.WWidget - -class WSplitPanel(val left: WWidget, val right: WWidget) : WPanelWithInsets() { - init { - left.parent = this - right.parent = this - children.add(left) - children.add(right) - } - - override fun layout() { - expandToFit(left, insets) - expandToFit(right, insets) - (left as? WPanel)?.layout() - (right as? WPanel)?.layout() - left.setLocation(insets.left, insets.top) - right.setLocation(width - insets.right - right.width, insets.top) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/gui/WTightScrollPanel.kt b/src/main/kotlin/moe/nea/firmament/gui/WTightScrollPanel.kt deleted file mode 100644 index e4c3989..0000000 --- a/src/main/kotlin/moe/nea/firmament/gui/WTightScrollPanel.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.gui - -import io.github.cottonmc.cotton.gui.widget.WPanel -import io.github.cottonmc.cotton.gui.widget.WScrollPanel -import io.github.cottonmc.cotton.gui.widget.WWidget - -class WTightScrollPanel(val widget: WWidget, val margin: Int = 3) : WScrollPanel(widget) { - override fun setSize(x: Int, y: Int) { - (widget as? WPanel)?.layout() - super.setSize(widget.width + 8 + margin, y) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/gui/WTitledItem.kt b/src/main/kotlin/moe/nea/firmament/gui/WTitledItem.kt deleted file mode 100644 index a1d4d68..0000000 --- a/src/main/kotlin/moe/nea/firmament/gui/WTitledItem.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.gui - -import com.mojang.blaze3d.systems.RenderSystem -import io.github.cottonmc.cotton.gui.client.BackgroundPainter -import io.github.cottonmc.cotton.gui.widget.TooltipBuilder -import io.github.cottonmc.cotton.gui.widget.WWidget -import net.minecraft.client.gui.DrawContext -import net.minecraft.client.item.TooltipType -import net.minecraft.item.ItemStack -import net.minecraft.text.Text -import moe.nea.firmament.util.MC - -open class WTitledItem(var stack: ItemStack, val countString: Text = Text.empty()) : WWidget() { - var backgroundPainter: BackgroundPainter = BackgroundPainter.SLOT - override fun canResize(): Boolean = true - override fun paint(context: DrawContext, x: Int, y: Int, mouseX: Int, mouseY: Int) { - backgroundPainter.paintBackground(context, x, y, this) - context.matrices.push() - context.matrices.translate(x.toFloat(), y.toFloat(), 0F) - context.matrices.scale(width / 18F, height / 18F, 1F) - RenderSystem.enableDepthTest() - context.drawItemWithoutEntity(stack, 18 / 2 - 8, 18 / 2 - 8) - context.matrices.translate(0F, 0F, 200F) - context.drawText(MC.font, countString, 19 - 2 - MC.font.getWidth(countString), 6 + 3, 0xFFFFFF, true) - context.matrices.pop() - } - - override fun addTooltip(tooltip: TooltipBuilder) { - tooltip.add(*stack.getTooltip(null, null, TooltipType.BASIC).toTypedArray()) - } - -} diff --git a/src/main/kotlin/moe/nea/firmament/gui/config/BooleanHandler.kt b/src/main/kotlin/moe/nea/firmament/gui/config/BooleanHandler.kt index adbeeaf..85afeb4 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/config/BooleanHandler.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/config/BooleanHandler.kt @@ -6,7 +6,9 @@ package moe.nea.firmament.gui.config -import io.github.cottonmc.cotton.gui.widget.WToggleButton +import io.github.notenoughupdates.moulconfig.gui.component.CenterComponent +import io.github.notenoughupdates.moulconfig.gui.component.SwitchComponent +import io.github.notenoughupdates.moulconfig.observer.GetSetter import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.boolean @@ -24,13 +26,16 @@ class BooleanHandler(val config: ManagedConfig) : ManagedConfig.OptionHandler<Bo override fun emitGuiElements(opt: ManagedOption<Boolean>, guiAppender: GuiAppender) { guiAppender.appendLabeledRow( opt.labelText, - WToggleButton(opt.labelText).apply { - guiAppender.onReload { toggle = opt.value } - setOnToggle { - opt.value = it + CenterComponent(SwitchComponent(object : GetSetter<Boolean> { + override fun get(): Boolean { + return opt.get() + } + + override fun set(newValue: Boolean) { + opt.set(newValue) config.save() } - } - ) + }, 200) + )) } } diff --git a/src/main/kotlin/moe/nea/firmament/gui/config/ClickHandler.kt b/src/main/kotlin/moe/nea/firmament/gui/config/ClickHandler.kt index 7fbad06..eef6559 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/config/ClickHandler.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/config/ClickHandler.kt @@ -6,9 +6,9 @@ package moe.nea.firmament.gui.config -import io.github.cottonmc.cotton.gui.widget.WButton +import io.github.notenoughupdates.moulconfig.gui.component.TextComponent import kotlinx.serialization.json.JsonElement -import net.minecraft.text.Text +import moe.nea.firmament.gui.FirmButtonComponent class ClickHandler(val config: ManagedConfig, val runnable: () -> Unit) : ManagedConfig.OptionHandler<Unit> { override fun toJson(element: Unit): JsonElement? { @@ -19,12 +19,10 @@ class ClickHandler(val config: ManagedConfig, val runnable: () -> Unit) : Manage override fun emitGuiElements(opt: ManagedOption<Unit>, guiAppender: GuiAppender) { guiAppender.appendLabeledRow( - Text.translatable("firmament.config.${config.name}.${opt.propertyName}"), - WButton(Text.translatable("firmament.config.${config.name}.${opt.propertyName}")).apply { - setOnClick { - runnable() - } - }, + opt.labelText, + FirmButtonComponent( + TextComponent(opt.labelText.string), + action = runnable), ) } } diff --git a/src/main/kotlin/moe/nea/firmament/gui/config/DurationHandler.kt b/src/main/kotlin/moe/nea/firmament/gui/config/DurationHandler.kt index 29a8ed6..c4eac03 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/config/DurationHandler.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/config/DurationHandler.kt @@ -6,18 +6,16 @@ package moe.nea.firmament.gui.config -import io.github.cottonmc.cotton.gui.widget.WBox -import io.github.cottonmc.cotton.gui.widget.WLabel -import io.github.cottonmc.cotton.gui.widget.WSlider -import io.github.cottonmc.cotton.gui.widget.data.Axis -import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment -import java.util.function.IntConsumer +import io.github.notenoughupdates.moulconfig.common.IMinecraft +import io.github.notenoughupdates.moulconfig.gui.component.RowComponent +import io.github.notenoughupdates.moulconfig.gui.component.SliderComponent +import io.github.notenoughupdates.moulconfig.gui.component.TextComponent +import io.github.notenoughupdates.moulconfig.observer.GetSetter import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.long import kotlin.time.Duration -import kotlin.time.Duration.Companion.milliseconds import kotlin.time.DurationUnit import kotlin.time.toDuration import net.minecraft.text.Text @@ -34,22 +32,31 @@ class DurationHandler(val config: ManagedConfig, val min: Duration, val max: Dur } override fun emitGuiElements(opt: ManagedOption<Duration>, guiAppender: GuiAppender) { - val label = - WLabel(Text.literal(FirmFormatters.formatTimespan(opt.value))).setVerticalAlignment(VerticalAlignment.CENTER) - guiAppender.appendLabeledRow(opt.labelText, WBox(Axis.HORIZONTAL).also { - it.add(label, 40, 18) - it.add(WSlider(min.inWholeMilliseconds.toInt(), max.inWholeMilliseconds.toInt(), Axis.HORIZONTAL).apply { - valueChangeListener = IntConsumer { - opt.value = it.milliseconds - label.text = Text.literal(FirmFormatters.formatTimespan(opt.value)) - config.save() - } - guiAppender.onReload { - value = opt.value.inWholeMilliseconds.toInt() - label.text = Text.literal(FirmFormatters.formatTimespan(opt.value)) - } - }, 130, 18) - }) + guiAppender.appendLabeledRow( + opt.labelText, + RowComponent( + TextComponent(IMinecraft.instance.defaultFontRenderer, + { FirmFormatters.formatTimespan(opt.value) }, + 40, + TextComponent.TextAlignment.CENTER, + true, + false), + SliderComponent( + object : GetSetter<Float> { + override fun get(): Float { + return opt.value.toDouble(DurationUnit.SECONDS).toFloat() + } + + override fun set(newValue: Float) { + opt.value = newValue.toDouble().toDuration(DurationUnit.SECONDS) + } + }, + min.toDouble(DurationUnit.SECONDS).toFloat(), + max.toDouble(DurationUnit.SECONDS).toFloat(), + 0.1F, + 130 + ) + )) } } diff --git a/src/main/kotlin/moe/nea/firmament/gui/config/GuiAppender.kt b/src/main/kotlin/moe/nea/firmament/gui/config/GuiAppender.kt index 3c6e502..aabcd24 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/config/GuiAppender.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/config/GuiAppender.kt @@ -6,37 +6,39 @@ package moe.nea.firmament.gui.config -import io.github.cottonmc.cotton.gui.widget.WBox -import io.github.cottonmc.cotton.gui.widget.WLabel -import io.github.cottonmc.cotton.gui.widget.WWidget -import io.github.cottonmc.cotton.gui.widget.data.Axis -import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment +import io.github.notenoughupdates.moulconfig.gui.GuiComponent +import io.github.notenoughupdates.moulconfig.gui.component.RowComponent +import io.github.notenoughupdates.moulconfig.gui.component.TextComponent +import io.github.notenoughupdates.moulconfig.observer.GetSetter import net.minecraft.client.gui.screen.Screen import net.minecraft.text.Text -import moe.nea.firmament.gui.WSplitPanel +import moe.nea.firmament.gui.FixedComponent class GuiAppender(val width: Int, val screenAccessor: () -> Screen) { - val panel = WBox(Axis.VERTICAL).also { - it.setSize(width, 200) - } + val panel = mutableListOf<GuiComponent>() internal val reloadables = mutableListOf<(() -> Unit)>() fun onReload(reloadable: () -> Unit) { reloadables.add(reloadable) } - fun appendLabeledRow(label: Text, right: WWidget) { + fun appendLabeledRow(label: Text, right: GuiComponent) { appendSplitRow( - WLabel(label).setVerticalAlignment(VerticalAlignment.CENTER), + TextComponent(label.string), right ) } - fun appendSplitRow(left: WWidget, right: WWidget) { - appendFullRow(WSplitPanel(left.also { it.setSize(width / 2, 18) }, right.also { it.setSize(width / 2, 18) })) + fun appendSplitRow(left: GuiComponent, right: GuiComponent) { + // TODO: make this more dynamic + // i could just make a component that allows for using half the available size + appendFullRow(RowComponent( + FixedComponent(GetSetter.constant(width / 2), null, left), + FixedComponent(GetSetter.constant(width / 2), null, right), + )) } - fun appendFullRow(widget: WWidget) { - panel.add(widget, width, 18) + fun appendFullRow(widget: GuiComponent) { + panel.add(widget) } } diff --git a/src/main/kotlin/moe/nea/firmament/gui/config/HudMetaHandler.kt b/src/main/kotlin/moe/nea/firmament/gui/config/HudMetaHandler.kt index 7df98e3..a2147e8 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/config/HudMetaHandler.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/config/HudMetaHandler.kt @@ -6,13 +6,14 @@ package moe.nea.firmament.gui.config -import io.github.cottonmc.cotton.gui.widget.WButton +import io.github.notenoughupdates.moulconfig.gui.component.TextComponent import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.decodeFromJsonElement import kotlinx.serialization.json.encodeToJsonElement import net.minecraft.text.MutableText import net.minecraft.text.Text +import moe.nea.firmament.gui.FirmButtonComponent import moe.nea.firmament.jarvis.JarvisIntegration import moe.nea.firmament.util.MC @@ -27,14 +28,16 @@ class HudMetaHandler(val config: ManagedConfig, val label: MutableText, val widt } override fun emitGuiElements(opt: ManagedOption<HudMeta>, guiAppender: GuiAppender) { - guiAppender.appendLabeledRow(opt.labelText, WButton(Text.stringifiedTranslatable("firmament.hud.edit", label)) - .also { - it.setOnClick { - MC.screen = JarvisIntegration.jarvis.getHudEditor( - guiAppender.screenAccessor.invoke(), - listOf(opt.value) - ) - } + guiAppender.appendLabeledRow( + opt.labelText, + FirmButtonComponent( + TextComponent( + Text.stringifiedTranslatable("firmament.hud.edit", label).string), + ) { + MC.screen = JarvisIntegration.jarvis.getHudEditor( + guiAppender.screenAccessor.invoke(), + listOf(opt.value) + ) }) } } diff --git a/src/main/kotlin/moe/nea/firmament/gui/config/IntegerHandler.kt b/src/main/kotlin/moe/nea/firmament/gui/config/IntegerHandler.kt index 77d09cb..bb6f5c4 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/config/IntegerHandler.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/config/IntegerHandler.kt @@ -6,17 +6,16 @@ package moe.nea.firmament.gui.config -import io.github.cottonmc.cotton.gui.widget.WBox -import io.github.cottonmc.cotton.gui.widget.WLabel -import io.github.cottonmc.cotton.gui.widget.WSlider -import io.github.cottonmc.cotton.gui.widget.data.Axis -import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment -import java.util.function.IntConsumer +import io.github.notenoughupdates.moulconfig.common.IMinecraft +import io.github.notenoughupdates.moulconfig.gui.component.RowComponent +import io.github.notenoughupdates.moulconfig.gui.component.SliderComponent +import io.github.notenoughupdates.moulconfig.gui.component.TextComponent +import io.github.notenoughupdates.moulconfig.observer.GetSetter import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.int import kotlinx.serialization.json.jsonPrimitive -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> { override fun toJson(element: Int): JsonElement? { @@ -28,22 +27,32 @@ class IntegerHandler(val config: ManagedConfig, val min: Int, val max: Int) : Ma } override fun emitGuiElements(opt: ManagedOption<Int>, guiAppender: GuiAppender) { - val label = - WLabel(Text.literal(opt.value.toString())).setVerticalAlignment(VerticalAlignment.CENTER) - guiAppender.appendLabeledRow(opt.labelText, WBox(Axis.HORIZONTAL).also { - it.add(label, 40, 18) - it.add(WSlider(min, max, Axis.HORIZONTAL).apply { - valueChangeListener = IntConsumer { - opt.value = it - label.text = Text.literal(opt.value.toString()) - config.save() - } - guiAppender.onReload { - value = opt.value - label.text = Text.literal(opt.value.toString()) - } - }, 130, 18) - }) + guiAppender.appendLabeledRow( + opt.labelText, + RowComponent( + TextComponent(IMinecraft.instance.defaultFontRenderer, + { FirmFormatters.formatCommas(opt.value, 0) }, + 40, + TextComponent.TextAlignment.CENTER, + true, + false), + SliderComponent( + object : GetSetter<Float> { + override fun get(): Float { + return opt.value.toFloat() + } + + override fun set(newValue: Float) { + opt.value = newValue.toInt() + } + }, + min.toFloat(), + max.toFloat(), + 0.1F, + 130 + ) + )) + } } diff --git a/src/main/kotlin/moe/nea/firmament/gui/config/KeyBindingHandler.kt b/src/main/kotlin/moe/nea/firmament/gui/config/KeyBindingHandler.kt index a9d5a2e..d347101 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/config/KeyBindingHandler.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/config/KeyBindingHandler.kt @@ -6,8 +6,12 @@ package moe.nea.firmament.gui.config -import io.github.cottonmc.cotton.gui.widget.WButton -import io.github.cottonmc.cotton.gui.widget.data.InputResult +import io.github.notenoughupdates.moulconfig.common.IMinecraft +import io.github.notenoughupdates.moulconfig.common.MyResourceLocation +import io.github.notenoughupdates.moulconfig.deps.libninepatch.NinePatch +import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext +import io.github.notenoughupdates.moulconfig.gui.KeyboardEvent +import io.github.notenoughupdates.moulconfig.gui.component.TextComponent import org.lwjgl.glfw.GLFW import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement @@ -16,6 +20,7 @@ import kotlinx.serialization.json.encodeToJsonElement import net.minecraft.client.util.InputUtil import net.minecraft.text.Text import net.minecraft.util.Formatting +import moe.nea.firmament.gui.FirmButtonComponent import moe.nea.firmament.keybindings.FirmamentKeyBindings import moe.nea.firmament.keybindings.SavedKeyBinding @@ -36,19 +41,66 @@ class KeyBindingHandler(name: String, val managedConfig: ManagedConfig) : Manage var editing = false var lastPressed = 0 var lastPressedNonModifier = 0 - var updateButton: (() -> Unit)? = null - val button = object : WButton() { - override fun onKeyPressed(ch: Int, key: Int, modifiers: Int): InputResult { + var label: String = "" + var button: FirmButtonComponent? = null + fun updateLabel() { + val stroke = Text.literal("") + if (opt.value.shift) { + stroke.append("SHIFT + ") // TODO: translations? + } + if (opt.value.alt) { + stroke.append("ALT + ") + } + if (opt.value.ctrl) { + stroke.append("CTRL + ") + } + stroke.append(InputUtil.Type.KEYSYM.createFromCode(opt.value.keyCode).localizedText) + if (editing) + stroke.styled { it.withColor(Formatting.YELLOW) } + label = (stroke).string + managedConfig.save() + } + button = object : FirmButtonComponent( + TextComponent( + IMinecraft.instance.defaultFontRenderer, + { label }, + 130, + TextComponent.TextAlignment.LEFT, + false, + false + ), action = { + if (editing) { + button!!.blur() + } else { + editing = true + button!!.requestFocus() + updateLabel() + } + }) { + override fun keyboardEvent(event: KeyboardEvent, context: GuiImmediateContext): Boolean { + if (event is KeyboardEvent.KeyPressed) { + if (event.pressed) onKeyPressed(event.keycode, SavedKeyBinding.getModInt()) + else onKeyReleased(event.keycode, SavedKeyBinding.getModInt()) + } + return super.keyboardEvent(event, context) + } + + override fun getBackground(context: GuiImmediateContext): NinePatch<MyResourceLocation> { + if (editing) return activeBg + return super.getBackground(context) + } + + fun onKeyPressed(ch: Int, modifiers: Int): Boolean { if (!editing) { - return super.onKeyPressed(ch, key, modifiers) + return false } if (ch == GLFW.GLFW_KEY_ESCAPE) { lastPressedNonModifier = 0 editing = false lastPressed = 0 opt.value = SavedKeyBinding(GLFW.GLFW_KEY_UNKNOWN) - updateButton!!() - return InputResult.PROCESSED + updateLabel() + return true } if (ch == GLFW.GLFW_KEY_LEFT_SHIFT || ch == GLFW.GLFW_KEY_RIGHT_SHIFT || ch == GLFW.GLFW_KEY_LEFT_ALT || ch == GLFW.GLFW_KEY_RIGHT_ALT @@ -63,58 +115,31 @@ class KeyBindingHandler(name: String, val managedConfig: ManagedConfig) : Manage lastPressed = 0 lastPressedNonModifier = 0 } - updateButton!!() - return InputResult.PROCESSED + updateLabel() + return true } - override fun onFocusLost() { - super.onFocusLost() + override fun onLostFocus() { lastPressedNonModifier = 0 editing = false lastPressed = 0 - updateButton!!() + updateLabel() } - override fun onKeyReleased(ch: Int, key: Int, modifiers: Int): InputResult { + fun onKeyReleased(ch: Int, modifiers: Int): Boolean { if (!editing) - return super.onKeyReleased(ch, key, modifiers) + return false if (lastPressedNonModifier == ch || (lastPressedNonModifier == 0 && ch == lastPressed)) { - opt.value = SavedKeyBinding( - ch, modifiers - ) + opt.value = SavedKeyBinding(ch, modifiers) editing = false lastPressed = 0 lastPressedNonModifier = 0 } - updateButton!!() - return InputResult.PROCESSED - } - } - - fun updateLabel() { - val stroke = Text.literal("") - if (opt.value.shift) { - stroke.append("SHIFT + ") // TODO: translations? + updateLabel() + return true } - if (opt.value.alt) { - stroke.append("ALT + ") - } - if (opt.value.ctrl) { - stroke.append("CTRL + ") - } - stroke.append(InputUtil.Type.KEYSYM.createFromCode(opt.value.keyCode).localizedText) - if (editing) - stroke.styled { it.withColor(Formatting.YELLOW) } - button.setLabel(stroke) - managedConfig.save() - } - updateButton = ::updateLabel - updateButton() - button.setOnClick { - editing = true - button.requestFocus() - updateButton() } + updateLabel() guiAppender.appendLabeledRow(opt.labelText, button) } diff --git a/src/main/kotlin/moe/nea/firmament/gui/config/ManagedConfig.kt b/src/main/kotlin/moe/nea/firmament/gui/config/ManagedConfig.kt index 8109aed..104cd52 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/config/ManagedConfig.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/config/ManagedConfig.kt @@ -6,17 +6,17 @@ package moe.nea.firmament.gui.config -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.data.Axis -import io.github.cottonmc.cotton.gui.widget.data.Insets -import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment +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.gui.component.CenterComponent +import io.github.notenoughupdates.moulconfig.gui.component.ColumnComponent +import io.github.notenoughupdates.moulconfig.gui.component.PanelComponent +import io.github.notenoughupdates.moulconfig.gui.component.RowComponent +import io.github.notenoughupdates.moulconfig.gui.component.ScrollPanelComponent +import io.github.notenoughupdates.moulconfig.gui.component.TextComponent import moe.nea.jarvis.api.Point import org.lwjgl.glfw.GLFW -import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject @@ -27,9 +27,8 @@ import kotlin.time.Duration import net.minecraft.client.gui.screen.Screen import net.minecraft.text.Text import moe.nea.firmament.Firmament -import moe.nea.firmament.gui.WTightScrollPanel +import moe.nea.firmament.gui.FirmButtonComponent import moe.nea.firmament.keybindings.SavedKeyBinding -import moe.nea.firmament.util.MC import moe.nea.firmament.util.ScreenUtil.setScreenLater abstract class ManagedConfig(override val name: String) : ManagedConfigElement() { @@ -150,45 +149,30 @@ abstract class ManagedConfig(override val name: String) : ManagedConfigElement() val labelText = Text.translatable("firmament.config.${name}") - fun getConfigEditor(parent: Screen? = null): CottonClientScreen { - val lwgd = LightweightGuiDescription() + fun getConfigEditor(parent: Screen? = null): Screen { var screen: Screen? = null val guiapp = GuiAppender(400) { requireNotNull(screen) { "Screen Accessor called too early" } } latestGuiAppender = guiapp - guiapp.panel.insets = Insets.ROOT_PANEL - guiapp.appendFullRow(WBox(Axis.HORIZONTAL).also { - it.add(WButton(Text.literal("←")).also { - it.setOnClick { - if (parent != null) { - save() - setScreenLater(parent) - } else { - AllConfigsGui.showAllGuis() - } + guiapp.appendFullRow(RowComponent( + FirmButtonComponent(TextComponent("←")) { + if (parent != null) { + save() + setScreenLater(parent) + } else { + AllConfigsGui.showAllGuis() } - }) - it.add(WLabel(labelText).also { - it.verticalAlignment = VerticalAlignment.CENTER - }) - }) + } + )) sortedOptions.forEach { it.appendToGui(guiapp) } guiapp.reloadables.forEach { it() } - lwgd.setRootPanel(WTightScrollPanel(guiapp.panel).also { - it.setSize(400, 300) - }) - screen = - object : CottonClientScreen(lwgd) { - override fun init() { - latestGuiAppender = guiapp - super.init() - } - - override fun close() { - latestGuiAppender = null - save() - MC.screen = parent + 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 } diff --git a/src/main/kotlin/moe/nea/firmament/gui/config/ManagedOption.kt b/src/main/kotlin/moe/nea/firmament/gui/config/ManagedOption.kt index 3ffe0b0..b3eb75e 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/config/ManagedOption.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/config/ManagedOption.kt @@ -6,6 +6,7 @@ package moe.nea.firmament.gui.config +import io.github.notenoughupdates.moulconfig.observer.GetSetter import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject import kotlin.properties.ReadWriteProperty @@ -18,7 +19,14 @@ class ManagedOption<T : Any>( val propertyName: String, val default: () -> T, val handler: ManagedConfig.OptionHandler<T> -) : ReadWriteProperty<Any?, T> { +) : ReadWriteProperty<Any?, T>, GetSetter<T> { + override fun set(newValue: T) { + this.value = newValue + } + + override fun get(): T { + return this.value + } val rawLabelText = "firmament.config.${element.name}.${propertyName}" val labelText = Text.translatable(rawLabelText) diff --git a/src/main/kotlin/moe/nea/firmament/gui/config/StringHandler.kt b/src/main/kotlin/moe/nea/firmament/gui/config/StringHandler.kt index a405f47..5a525c9 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/config/StringHandler.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/config/StringHandler.kt @@ -6,7 +6,8 @@ package moe.nea.firmament.gui.config -import io.github.cottonmc.cotton.gui.widget.WTextField +import io.github.notenoughupdates.moulconfig.gui.component.TextFieldComponent +import io.github.notenoughupdates.moulconfig.observer.GetSetter import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.jsonPrimitive @@ -24,15 +25,16 @@ class StringHandler(val config: ManagedConfig) : ManagedConfig.OptionHandler<Str override fun emitGuiElements(opt: ManagedOption<String>, guiAppender: GuiAppender) { guiAppender.appendLabeledRow( opt.labelText, - WTextField(opt.labelText).apply { - maxLength = 1000 - suggestion = Text.translatableWithFallback(opt.rawLabelText + ".hint", "") - guiAppender.onReload { text = opt.value } - setChangedListener { - opt.value = it - config.save() - } - } + TextFieldComponent( + object : GetSetter<String> by opt { + override fun set(newValue: String) { + opt.set(newValue) + config.save() + } + }, + 130, + suggestion = Text.translatableWithFallback(opt.rawLabelText + ".hint", "").string + ), ) } } diff --git a/src/main/kotlin/moe/nea/firmament/gui/hud/MoulConfigHud.kt b/src/main/kotlin/moe/nea/firmament/gui/hud/MoulConfigHud.kt index afc8740..55c9835 100644 --- a/src/main/kotlin/moe/nea/firmament/gui/hud/MoulConfigHud.kt +++ b/src/main/kotlin/moe/nea/firmament/gui/hud/MoulConfigHud.kt @@ -6,11 +6,12 @@ package moe.nea.firmament.gui.hud +import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper import io.github.notenoughupdates.moulconfig.gui.GuiContext import io.github.notenoughupdates.moulconfig.gui.component.TextComponent -import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper import net.minecraft.resource.ResourceManager import net.minecraft.resource.SynchronousResourceReloader +import moe.nea.firmament.events.FinalizeResourceManagerEvent import moe.nea.firmament.events.HudRenderEvent import moe.nea.firmament.gui.config.HudMeta import moe.nea.firmament.util.MC @@ -21,9 +22,11 @@ abstract class MoulConfigHud( val hudMeta: HudMeta, ) { companion object { - private val componentWrapper = object : GuiComponentWrapper(GuiContext(TextComponent("§cERROR"))) { - init { - this.client = MC.instance + private val componentWrapper by lazy { + object : GuiComponentWrapper(GuiContext(TextComponent("§cERROR"))) { + init { + this.client = MC.instance + } } } } @@ -31,7 +34,6 @@ abstract class MoulConfigHud( private var fragment: GuiContext? = null fun forceInit() { - } open fun shouldRender(): Boolean { @@ -53,11 +55,13 @@ abstract class MoulConfigHud( fragment!!.root.render(renderContextTranslated) it.context.matrices.pop() } - MC.resourceManager.registerReloader(object : SynchronousResourceReloader { - override fun reload(manager: ResourceManager?) { - fragment = null - } - }) + FinalizeResourceManagerEvent.subscribe { + MC.resourceManager.registerReloader(object : SynchronousResourceReloader { + override fun reload(manager: ResourceManager?) { + fragment = null + } + }) + } } fun loadFragment() { diff --git a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/PetsPage.kt b/src/main/kotlin/moe/nea/firmament/gui/profileviewer/PetsPage.kt deleted file mode 100644 index 6daeca4..0000000 --- a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/PetsPage.kt +++ /dev/null @@ -1,110 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.gui.profileviewer - -import io.github.cottonmc.cotton.gui.client.BackgroundPainter -import io.github.cottonmc.cotton.gui.widget.WBox -import io.github.cottonmc.cotton.gui.widget.WGridPanel -import io.github.cottonmc.cotton.gui.widget.WText -import io.github.cottonmc.cotton.gui.widget.WWidget -import io.github.cottonmc.cotton.gui.widget.data.Axis -import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment -import io.github.cottonmc.cotton.gui.widget.data.InputResult -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.icon.Icon -import io.github.cottonmc.cotton.gui.widget.icon.ItemIcon -import io.github.moulberry.repo.data.Rarity -import net.minecraft.item.ItemStack -import net.minecraft.item.Items -import net.minecraft.text.Text -import net.minecraft.util.Formatting -import moe.nea.firmament.gui.WTightScrollPanel -import moe.nea.firmament.gui.WTitledItem -import moe.nea.firmament.rei.PetData -import moe.nea.firmament.rei.SBItemStack -import moe.nea.firmament.repo.RepoManager -import moe.nea.firmament.util.FirmFormatters - -object PetsPage : ProfilePage { - private fun petOverview(profileViewer: ProfileViewer, choosePet: (ItemStack) -> Unit) = WGridPanel().also { panel -> - panel.insets = Insets.ROOT_PANEL - panel.add(WText(Text.literal(profileViewer.account.getDisplayName(profileViewer.primaryName))), 0, 0, 6, 1) - panel.add((WTightScrollPanel(WGridPanel().also { it -> - it.setGaps(8, 8) - - for ((i, pet) in profileViewer.member.pets.map { - SBItemStack(it.itemId, PetData(it.tier, it.type.name, it.exp)) - }.sortedWith( - Comparator.comparing<SBItemStack?, Rarity?> { it.petData!!.rarity }.reversed() - .thenDescending(Comparator.comparing { it.petData!!.levelData.currentLevel }) - .thenDescending(Comparator.comparing { it.petData!!.petId }) - ).withIndex()) { - val stack = pet.asItemStack() - it.add(object : WTitledItem(stack) { - override fun onClick(x: Int, y: Int, button: Int): InputResult { - choosePet(stack) - return InputResult.PROCESSED - } - }, i % 9, i / 9, 1, 1) - } - it.layout() - })), 0, 1, 12, 8) - petStats(profileViewer).withIndex().forEach { (i, it) -> - panel.add(it, 0, 10 + i, 8, 1) - } - } - - private fun petStats(profileViewer: ProfileViewer): List<WWidget> { - val petScore = profileViewer.member.pets.groupBy { it.type } - .map { it.value.maxBy { it.tier } } - .sumOf { RepoManager.neuRepo.constants.bonuses.getPetValue(it.tier) } - - return listOf( - WText( - Text.literal("Pet Score: ").styled { it.withColor(Formatting.AQUA) } - .append(Text.literal("$petScore").styled { it.withColor(Formatting.GOLD) }) - ), - WText( - Text.literal("Magic Find: ").styled { it.withColor(Formatting.AQUA) } - .append( - Text.literal( - FirmFormatters.formatCurrency( - RepoManager.neuRepo.constants.bonuses.getPetRewards( - petScore - )["magic_find"] ?: 0.0F, 1 - ) - ) - .styled { it.withColor(Formatting.GOLD) }) - ) - ) - } - - override fun getElements(profileViewer: ProfileViewer): WWidget { - return WBox(Axis.HORIZONTAL).also { - it.insets = Insets.ROOT_PANEL - val item = WTitledItem(ItemStack.EMPTY) - item.backgroundPainter = BackgroundPainter.VANILLA - it.add(WBox(Axis.VERTICAL).also { box -> - box.add(petOverview(profileViewer) { item.stack = it }) - }) - val b = WBox(Axis.VERTICAL).also { box -> - box.verticalAlignment = VerticalAlignment.CENTER - box.horizontalAlignment = HorizontalAlignment.CENTER - box.add(item, 128, 128) - } - it.add(b) - it.layout() - b.setSize(b.width + 20, it.height) - } - } - - override val icon: Icon - get() = ItemIcon(Items.BONE) - override val text: Text - get() = Text.translatable("firmament.pv.pets") -} diff --git a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/ProfilePage.kt b/src/main/kotlin/moe/nea/firmament/gui/profileviewer/ProfilePage.kt deleted file mode 100644 index 3d599ee..0000000 --- a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/ProfilePage.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.gui.profileviewer - -import io.github.cottonmc.cotton.gui.widget.WWidget -import io.github.cottonmc.cotton.gui.widget.icon.Icon -import net.minecraft.text.Text - -interface ProfilePage { - fun getElements(profileViewer: ProfileViewer): WWidget - val icon: Icon - val text: Text -} diff --git a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/ProfileViewer.kt b/src/main/kotlin/moe/nea/firmament/gui/profileviewer/ProfileViewer.kt deleted file mode 100644 index ada7603..0000000 --- a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/ProfileViewer.kt +++ /dev/null @@ -1,77 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.gui.profileviewer - -import io.github.cottonmc.cotton.gui.client.CottonClientScreen -import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription -import io.github.cottonmc.cotton.gui.widget.WTabPanel -import moe.nea.firmament.Firmament -import moe.nea.firmament.apis.Member -import moe.nea.firmament.apis.PlayerData -import moe.nea.firmament.apis.Profile -import moe.nea.firmament.apis.Routes -import moe.nea.firmament.util.ScreenUtil -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource -import net.minecraft.text.Text -import java.util.* - -class ProfileViewer( - val primaryPlayer: UUID, - val playerNames: Map<UUID, String>, - val accountData: Map<UUID, PlayerData>, - val profile: Profile, -) : LightweightGuiDescription() { - - val member: Member = profile.members[primaryPlayer] ?: error("Primary player not in profile") - val primaryName: String = playerNames[primaryPlayer] ?: error("Primary player has no name") - val account: PlayerData = accountData[primaryPlayer] ?: error("Primary player has no data") - - init { - val panel = WTabPanel().also { rootPanel = it } - panel.backgroundPainter - listOf<ProfilePage>(SkillPage, PetsPage) - .forEach { page -> - panel.add(page.getElements(this)) { - it.icon(page.icon) - it.tooltip(page.text) - } - } - } - - companion object { - suspend fun onCommand(source: FabricClientCommandSource, name: String) { - source.sendFeedback(Text.stringifiedTranslatable("firmament.pv.lookingup", name)) - try { - val uuid = Routes.getUUIDForPlayerName(name) - if (uuid == null) { - source.sendError(Text.stringifiedTranslatable("firmament.pv.noplayer", name)) - return - } - val name = Routes.getPlayerNameForUUID(uuid) ?: name - val names = mapOf(uuid to (name)) - val data = Routes.getAccountData(uuid) - if (data == null) { - source.sendError(Text.stringifiedTranslatable("firmament.pv.noprofile", name)) - return - } - val accountData = mapOf(data.uuid to data) - val profiles = Routes.getProfiles(uuid) - val profile = profiles?.profiles?.find { it.selected } - if (profile == null) { - source.sendFeedback(Text.stringifiedTranslatable("firmament.pv.noprofile", name)) - return - } - ScreenUtil.setScreenLater(CottonClientScreen(ProfileViewer(uuid, names, accountData, profile))) - } catch (e: Exception) { - Firmament.logger.error("Error loading profile data for $name", e) - source.sendError(Text.stringifiedTranslatable("firmament.pv.badprofile", name, e.message)) - } - } - } -} - - diff --git a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/ProfileViewerLibrary.kt b/src/main/kotlin/moe/nea/firmament/gui/profileviewer/ProfileViewerLibrary.kt deleted file mode 100644 index 0c99f67..0000000 --- a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/ProfileViewerLibrary.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.gui.profileviewer - -import com.mojang.brigadier.StringReader -import io.github.cottonmc.cotton.gui.client.CottonClientScreen -import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription -import io.github.cottonmc.cotton.gui.widget.WGridPanel -import io.github.cottonmc.cotton.gui.widget.WText -import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment -import moe.nea.lisp.LispData -import moe.nea.lisp.LispExecutionContext -import moe.nea.lisp.LispParser -import moe.nea.lisp.bind.AutoBinder -import moe.nea.lisp.bind.LispBinding -import moe.nea.lisp.bind.UnmapForeignObject -import net.minecraft.command.argument.ItemStringReader -import net.minecraft.item.ItemStack -import net.minecraft.text.Text -import moe.nea.firmament.gui.WTitledItem -import moe.nea.firmament.util.MC -import moe.nea.firmament.util.ScreenUtil -import moe.nea.firmament.util.item.setCustomName -import moe.nea.firmament.util.modifyLore - -class ProfileViewerLibrary { - - @LispBinding("mk-item") - fun makeItem(itemType: String, title: String, vararg lore: String): LispData.ForeignObject<ItemStack> { - val item = ItemStringReader(MC.defaultRegistries).consume(StringReader(itemType)) - val itemStack = ItemStack(item.item.value()) - itemStack.applyComponentsFrom(item.components) - itemStack.modifyLore { lore.map { Text.literal(it) } } - itemStack.setCustomName(Text.literal(title)) - return LispData.ForeignObject(itemStack) - } - - @LispBinding("def-page") - fun defPage(name: String, @UnmapForeignObject icon: ItemStack) { - pages.add(Pair(name, icon)) - } - - val pages = mutableListOf<Pair<String, ItemStack>>() - val coreEnvironment = LispExecutionContext() - - fun run() { - val t = coreEnvironment.genBindings() - val ab = AutoBinder() - ab.bindTo(this, t) - val prog = LispParser.parse( - "testfile.lisp", """ - (def-page "Test" (mk-item "minecraft:tnt" "§aThis is a test page" "§aMore text")) - (def-page "Skills" (mk-item "minecraft:diamond_sword" "§aThis is a test page" "§aMore text")) - """.trimIndent() - ) - coreEnvironment.executeProgram(t, prog) - val light = LightweightGuiDescription() - val root = light.rootPanel as WGridPanel - root.setGaps(8, 8) - pages.forEachIndexed { i, (name, item) -> - root.add(WTitledItem(item), 0, i) - root.add(WText(Text.literal(name)).also { it.verticalAlignment = VerticalAlignment.CENTER }, 1, i, 6, 1) - } - ScreenUtil.setScreenLater(CottonClientScreen(light)) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/SkillPage.kt b/src/main/kotlin/moe/nea/firmament/gui/profileviewer/SkillPage.kt deleted file mode 100644 index 64f4f2c..0000000 --- a/src/main/kotlin/moe/nea/firmament/gui/profileviewer/SkillPage.kt +++ /dev/null @@ -1,146 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.gui.profileviewer - -import io.github.cottonmc.cotton.gui.widget.* -import io.github.cottonmc.cotton.gui.widget.data.Axis -import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment -import io.github.cottonmc.cotton.gui.widget.data.Insets -import io.github.cottonmc.cotton.gui.widget.icon.Icon -import io.github.cottonmc.cotton.gui.widget.icon.ItemIcon -import moe.nea.firmament.apis.* -import moe.nea.firmament.gui.WBar -import moe.nea.firmament.gui.WFixedPanel -import moe.nea.firmament.gui.WTitledItem -import moe.nea.firmament.hud.horizontal -import moe.nea.firmament.rei.FirmamentReiPlugin.Companion.asItemEntry -import moe.nea.firmament.rei.SBItemEntryDefinition -import moe.nea.firmament.repo.HypixelStaticData -import moe.nea.firmament.repo.ItemCache.asItemStack -import moe.nea.firmament.repo.RepoManager -import moe.nea.firmament.util.FirmFormatters -import moe.nea.firmament.util.modifyLore -import moe.nea.firmament.util.toShedaniel -import moe.nea.firmament.util.toTextColor -import net.minecraft.item.ItemStack -import net.minecraft.item.Items -import net.minecraft.text.Style -import net.minecraft.text.Text -import net.minecraft.util.DyeColor -import net.minecraft.util.Formatting -import moe.nea.firmament.util.item.setCustomName - -object SkillPage : ProfilePage { - - private fun skillBar(profileViewer: ProfileViewer, skill: Skill): WBar { - val leveling = RepoManager.neuRepo.constants.leveling - val exp = skill.accessor.get(profileViewer.member) - val maxLevel = skill.getMaximumLevel(leveling) - val level = skill.getLadder(leveling) - .runningFold(0.0) { a, b -> a + b } - .filter { it <= exp }.size - .coerceAtMost(maxLevel) - return object : WBar( - level.toDouble(), maxLevel.toDouble(), - skill.color.toShedaniel(), skill.color.toShedaniel().darker(2.0) - ) { - override fun addTooltip(tooltip: TooltipBuilder) { - tooltip.add(Text.literal("$level/$maxLevel")) - tooltip.add(Text.stringifiedTranslatable("firmament.pv.skills.total", FirmFormatters.formatCurrency(exp, 1))) - } - } - } - - private fun collectionItem(type: CollectionType, info: CollectionInfo, color: DyeColor, profile: Profile): WWidget { - val collectionCount = profile.members.values.sumOf { it.collection[type] ?: 0 } - val unlockedTiers = info.tiers.count { it.amountRequired <= collectionCount } - return WTitledItem( - SBItemEntryDefinition.getEntry(type.skyblockId).asItemEntry().value.copy() - .also { - it.setCustomName( - Text.literal(info.name).fillStyle( - Style.EMPTY.withItalic(false).withBold(true) - .withColor(color.toTextColor()) - ) - ) - it.modifyLore { old -> - listOf( - Text.literal("${info.name} Collection: $collectionCount / ${info.tiers.last().amountRequired}"), - Text.literal("Tiers unlocked: $unlockedTiers / ${info.tiers.size}") - ).map { - it.fillStyle( - Style.EMPTY.withItalic(false).withColor(Formatting.GRAY) - ) - } - } - }, countString = Text.literal("$unlockedTiers").styled { - if (unlockedTiers == info.maxTiers) - it.withColor(Formatting.YELLOW) - else it - } - ) - } - - private fun collectionPanel(profileViewer: ProfileViewer): WTabPanel { - return WTabPanel().also { - val data = HypixelStaticData.collectionData - val panels = mutableListOf<WPanel>() - for ((collectionKind, collections) in data.entries) { - val skillT = CollectionCategory.values().find { it.name == collectionKind } - val color = skillT?.color ?: DyeColor.WHITE - val icon = skillT?.icon?.let { RepoManager.getNEUItem(it).asItemStack() } ?: ItemStack(Items.ITEM_FRAME) - val panel = WBox(Axis.HORIZONTAL).also { - it.horizontalAlignment = HorizontalAlignment.CENTER - it.add(WFixedPanel(WGridPanel().also { - it.insets = Insets.ROOT_PANEL - it.setGaps(2, 2) - var x = 0 - var y = 0 - for (item in collections.items) { - it.add(collectionItem(item.key, item.value, color, profileViewer.profile), x, y, 1, 1) - x++ - if (x == 5) { - x = 0 - y++ - } - } - })) - } - panels.add(panel) - it.add(panel) { - it.tooltip( - Text.translatable("firmament.pv.skills.${collectionKind.lowercase()}") - .styled { it.withColor(color.toTextColor()) }) - it.icon(ItemIcon(icon)) - } - } - it.layout() - val tabWidth = it.width - panels.forEach { it.setSize(tabWidth - Insets.ROOT_PANEL.horizontal, it.height) } - } - } - - override fun getElements(profileViewer: ProfileViewer): WWidget { - return WBox(Axis.HORIZONTAL).also { - it.insets = Insets.ROOT_PANEL - it.add(WGridPanel().also { - it.add(WText(Text.literal(profileViewer.account.getDisplayName(profileViewer.primaryName))), 0, 0, 8, 1) - for ((i, skill) in Skill.values().withIndex()) { - it.add(WText(Text.translatable("firmament.pv.skills.${skill.name.lowercase()}")), 0, i + 1, 4, 1) - it.add(skillBar(profileViewer, skill), 4, i + 1, 4, 1) - } - }) - it.add(collectionPanel(profileViewer)) - } - } - - override val icon: Icon - get() = ItemIcon(ItemStack(Items.IRON_SWORD)) - override val text: Text - get() = Text.translatable("firmament.pv.skills") -} diff --git a/src/main/kotlin/moe/nea/firmament/hud/RepoDownloadProgress.kt b/src/main/kotlin/moe/nea/firmament/hud/RepoDownloadProgress.kt deleted file mode 100644 index 3f7c1f7..0000000 --- a/src/main/kotlin/moe/nea/firmament/hud/RepoDownloadProgress.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe> - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package moe.nea.firmament.hud - -import io.github.cottonmc.cotton.gui.client.ScreenDrawing -import io.github.cottonmc.cotton.gui.widget.WWidget -import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment -import io.github.cottonmc.cotton.gui.widget.data.Insets -import kotlin.math.roundToInt -import kotlin.math.sin -import net.minecraft.client.gui.DrawContext - - -val Insets.vertical get() = bottom + top -val Insets.horizontal get() = left + right - -class ProgressBar( - var label: String, - var total: Int?, // If total is null, then make it a bouncy rectangle - var progress: Int = 0, -) : WWidget() { - - var insets: Insets = Insets(7) - override fun canResize(): Boolean = true - - - fun reportProgress(label: String, progress: Int, total: Int?) { - synchronized(this) { - this.label = label - this.progress = progress - this.total = total - } - - } - - override fun paint(context: DrawContext, x: Int, y: Int, mouseX: Int, mouseY: Int) { - ScreenDrawing.coloredRect(context, x, y, width, height, 0xFF808080.toInt()) - val (l, prog) = synchronized(this) { - label to (progress to total) - } - val (p, t) = prog - - if (t == null) { - ScreenDrawing.coloredRect( - context, - (x + (1 + sin(System.currentTimeMillis().toDouble() / 1000)) * width * 3 / 4 / 2).roundToInt(), - y, - width / 4, - height, - 0xFF00FF00.toInt() - ) - } else { - ScreenDrawing.coloredRect(context, x, y, width * p / t, height, 0xFF00FF00.toInt()) - } - ScreenDrawing.drawString( - context, - if (t != null) "$l ($p/$t)" else l, - HorizontalAlignment.CENTER, - x + insets.left, - y + insets.top, - width - insets.horizontal, - height - insets.vertical, - ) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/keybindings/SavedKeyBinding.kt b/src/main/kotlin/moe/nea/firmament/keybindings/SavedKeyBinding.kt index c5205bc..56865cc 100644 --- a/src/main/kotlin/moe/nea/firmament/keybindings/SavedKeyBinding.kt +++ b/src/main/kotlin/moe/nea/firmament/keybindings/SavedKeyBinding.kt @@ -6,11 +6,11 @@ package moe.nea.firmament.keybindings +import org.lwjgl.glfw.GLFW import kotlinx.serialization.Serializable -import moe.nea.firmament.util.MC import net.minecraft.client.MinecraftClient import net.minecraft.client.util.InputUtil -import org.lwjgl.glfw.GLFW +import moe.nea.firmament.util.MC @Serializable data class SavedKeyBinding( @@ -38,6 +38,24 @@ data class SavedKeyBinding( modifiers and GLFW.GLFW_MOD_ALT != 0 ) } + + fun getModInt(): Int { + val h = MC.window.handle + val ctrl = if (MinecraftClient.IS_SYSTEM_MAC) { + InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_SUPER) + || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SUPER) + } else InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_CONTROL) + || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_CONTROL) + val shift = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_SHIFT) + || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SHIFT) + val alt = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_ALT) + || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_ALT) + var mods = 0 + if (ctrl) mods = mods or GLFW.GLFW_MOD_CONTROL + if (shift) mods = mods or GLFW.GLFW_MOD_SHIFT + if (alt) mods = mods or GLFW.GLFW_MOD_ALT + return mods + } } fun isPressed(atLeast: Boolean = false): Boolean { @@ -47,21 +65,21 @@ data class SavedKeyBinding( val ctrl = if (MinecraftClient.IS_SYSTEM_MAC) { InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_SUPER) - || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SUPER) + || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SUPER) } else InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_CONTROL) - || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_CONTROL) + || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_CONTROL) val shift = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_SHIFT) - || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SHIFT) + || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_SHIFT) val alt = InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_ALT) - || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_ALT) + || InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_RIGHT_ALT) if (atLeast) return (ctrl >= this.ctrl) && - (alt >= this.alt) && - (shift >= this.shift) + (alt >= this.alt) && + (shift >= this.shift) return (ctrl == this.ctrl) && - (alt == this.alt) && - (shift == this.shift) + (alt == this.alt) && + (shift == this.shift) } override fun matches(keyCode: Int, scanCode: Int, modifiers: Int): Boolean { diff --git a/src/main/kotlin/moe/nea/firmament/rei/SBItemEntryDefinition.kt b/src/main/kotlin/moe/nea/firmament/rei/SBItemEntryDefinition.kt index 0cdb17e..2a20ff1 100644 --- a/src/main/kotlin/moe/nea/firmament/rei/SBItemEntryDefinition.kt +++ b/src/main/kotlin/moe/nea/firmament/rei/SBItemEntryDefinition.kt @@ -79,10 +79,10 @@ data class SBItemStack( ) { val stats = petInfo.interpolatedStatsAtLevel(level) ?: return stats.otherNumbers.forEachIndexed { index, it -> - replacementData[index.toString()] = FirmFormatters.formatCurrency(it, 1) + replacementData[index.toString()] = FirmFormatters.formatCommas(it, 1) } stats.statNumbers.forEach { (t, u) -> - replacementData[t] = FirmFormatters.formatCurrency(u, 1) + replacementData[t] = FirmFormatters.formatCommas(u, 1) } } diff --git a/src/main/kotlin/moe/nea/firmament/repo/ItemCache.kt b/src/main/kotlin/moe/nea/firmament/repo/ItemCache.kt index adeb1c5..21d264c 100644 --- a/src/main/kotlin/moe/nea/firmament/repo/ItemCache.kt +++ b/src/main/kotlin/moe/nea/firmament/repo/ItemCache.kt @@ -8,12 +8,12 @@ package moe.nea.firmament.repo import com.mojang.serialization.Dynamic -import io.github.cottonmc.cotton.gui.client.CottonHud import io.github.moulberry.repo.IReloadable import io.github.moulberry.repo.NEURepository import io.github.moulberry.repo.data.NEUItem +import io.github.notenoughupdates.moulconfig.xml.Bind import java.text.NumberFormat -import java.util.* +import java.util.UUID import java.util.concurrent.ConcurrentHashMap import org.apache.logging.log4j.LogManager import kotlinx.coroutines.Job @@ -32,6 +32,9 @@ import net.minecraft.nbt.NbtElement import net.minecraft.nbt.NbtOps import net.minecraft.text.Text import moe.nea.firmament.Firmament +import moe.nea.firmament.gui.config.HudMeta +import moe.nea.firmament.gui.config.HudPosition +import moe.nea.firmament.gui.hud.MoulConfigHud import moe.nea.firmament.util.LegacyTagParser import moe.nea.firmament.util.MC import moe.nea.firmament.util.SkyblockId @@ -135,6 +138,30 @@ object ItemCache : IReloadable { fun NEUItem.getIdentifier() = skyblockId.identifier var job: Job? = null + object ReloadProgressHud : MoulConfigHud( + "repo_reload", HudMeta(HudPosition(0.0, 0.0, 1F), Text.literal("Repo Reload"), 180, 18)) { + + + var isEnabled = false + override fun shouldRender(): Boolean { + return isEnabled + } + + @get:Bind("current") + var current: Double = 0.0 + + @get:Bind("label") + var label: String = "" + + @get:Bind("max") + var max: Double = 0.0 + + fun reportProgress(label: String, current: Int, max: Int) { + this.label = label + this.current = current.toDouble() + this.max = max.toDouble() + } + } override fun reload(repository: NEURepository) { val j = job @@ -147,18 +174,18 @@ object ItemCache : IReloadable { job = Firmament.coroutineScope.launch { val items = repository.items?.items if (items == null) { - CottonHud.remove(RepoManager.progressBar) + ReloadProgressHud.isEnabled = false return@launch } val recacheItems = I18n.translate("firmament.repo.cache") - RepoManager.progressBar.reportProgress(recacheItems, 0, items.size) - CottonHud.add(RepoManager.progressBar) + ReloadProgressHud.reportProgress(recacheItems, 0, items.size) + ReloadProgressHud.isEnabled = true var i = 0 items.values.forEach { it.asItemStack() // Rebuild cache - RepoManager.progressBar.reportProgress(recacheItems, i++, items.size) + ReloadProgressHud.reportProgress(recacheItems, i++, items.size) } - CottonHud.remove(RepoManager.progressBar) + ReloadProgressHud.isEnabled = false } } diff --git a/src/main/kotlin/moe/nea/firmament/repo/RepoManager.kt b/src/main/kotlin/moe/nea/firmament/repo/RepoManager.kt index db17e6a..f556a8b 100644 --- a/src/main/kotlin/moe/nea/firmament/repo/RepoManager.kt +++ b/src/main/kotlin/moe/nea/firmament/repo/RepoManager.kt @@ -6,7 +6,6 @@ package moe.nea.firmament.repo -import io.github.cottonmc.cotton.gui.client.CottonHud import io.github.moulberry.repo.NEURecipeCache import io.github.moulberry.repo.NEURepository import io.github.moulberry.repo.NEURepositoryException @@ -21,7 +20,6 @@ import net.minecraft.text.Text import moe.nea.firmament.Firmament import moe.nea.firmament.Firmament.logger import moe.nea.firmament.gui.config.ManagedConfig -import moe.nea.firmament.hud.ProgressBar import moe.nea.firmament.rei.PetData import moe.nea.firmament.util.MinecraftDispatcher import moe.nea.firmament.util.SkyblockId @@ -54,12 +52,6 @@ object RepoManager { var recentlyFailedToUpdateItemList = false - val progressBar by lazy { - ProgressBar("", null, 0).also { - it.setSize(180, 22) - } - } - val neuRepo: NEURepository = NEURepository.of(RepoDownloadManager.repoSavedLocation).apply { registerReloadListener(ItemCache) registerReloadListener(ExpLadders) @@ -98,14 +90,13 @@ object RepoManager { fun launchAsyncUpdate(force: Boolean = false) { Firmament.coroutineScope.launch { - progressBar.reportProgress("Downloading", 0, null) - CottonHud.add(progressBar) + ItemCache.ReloadProgressHud.reportProgress("Downloading", 0, -1) // TODO: replace with a proper boundy bar + ItemCache.ReloadProgressHud.isEnabled = true try { RepoDownloadManager.downloadUpdate(force) - progressBar.reportProgress("Download complete", 1, 1) + ItemCache.ReloadProgressHud.reportProgress("Download complete", 1, 1) } finally { - CottonHud.remove(progressBar) - + ItemCache.ReloadProgressHud.isEnabled = false } reload() } @@ -113,14 +104,14 @@ object RepoManager { fun reload() { try { - progressBar.reportProgress("Reloading from Disk", 0, null) - CottonHud.add(progressBar) + ItemCache.ReloadProgressHud.reportProgress("Reloading from Disk", 0, -1) // TODO: replace with a proper boundy bar + ItemCache.ReloadProgressHud.isEnabled = true neuRepo.reload() } catch (exc: NEURepositoryException) { MinecraftClient.getInstance().player?.sendMessage( Text.literal("Failed to reload repository. This will result in some mod features not working.") ) - CottonHud.remove(progressBar) + ItemCache.ReloadProgressHud.isEnabled = false exc.printStackTrace() } } diff --git a/src/main/kotlin/moe/nea/firmament/util/FirmFormatters.kt b/src/main/kotlin/moe/nea/firmament/util/FirmFormatters.kt index c07f53d..087bb2f 100644 --- a/src/main/kotlin/moe/nea/firmament/util/FirmFormatters.kt +++ b/src/main/kotlin/moe/nea/firmament/util/FirmFormatters.kt @@ -11,21 +11,22 @@ import kotlin.math.absoluteValue import kotlin.time.Duration object FirmFormatters { - fun formatCurrency(long: Long, segments: Int = 3): String { + fun formatCommas(int: Int, segments: Int = 3): String = formatCommas(int.toLong(), segments) + fun formatCommas(long: Long, segments: Int = 3): String { val α = long / 1000 if (α != 0L) { - return formatCurrency(α, segments) + "," + (long - α * 1000).toString().padStart(3, '0') + return formatCommas(α, segments) + "," + (long - α * 1000).toString().padStart(3, '0') } return long.toString() } - fun formatCurrency(float: Float, fractionalDigits: Int): String = formatCurrency(float.toDouble(), fractionalDigits) - fun formatCurrency(double: Double, fractionalDigits: Int): String { + fun formatCommas(float: Float, fractionalDigits: Int): String = formatCommas(float.toDouble(), fractionalDigits) + fun formatCommas(double: Double, fractionalDigits: Int): String { val long = double.toLong() val δ = (double - long).absoluteValue val μ = pow(10, fractionalDigits) val digits = (μ * δ).toInt().toString().padStart(fractionalDigits, '0').trimEnd('0') - return formatCurrency(long) + (if (digits.isEmpty()) "" else ".$digits") + return formatCommas(long) + (if (digits.isEmpty()) "" else ".$digits") } fun formatDistance(distance: Double): String { @@ -34,8 +35,29 @@ object FirmFormatters { return "%dm".format(distance.toInt()) } - fun formatTimespan(duration: Duration): String { - return duration.toString() + fun formatTimespan(duration: Duration, millis: Boolean = false): String { + if (duration.isInfinite()) { + return if (duration.isPositive()) "∞" + else "-∞" + } + val sb = StringBuilder() + if (duration.isNegative()) sb.append("-") + duration.toComponents { days, hours, minutes, seconds, nanoseconds -> + if (days > 0) { + sb.append(days).append("d") + } + if (hours > 0) { + sb.append(hours).append("h") + } + if (minutes > 0) { + sb.append(minutes).append("m") + } + sb.append(seconds).append("s") + if (millis) { + sb.append(nanoseconds / 1_000_000).append("ms") + } + } + return sb.toString() } } diff --git a/src/main/kotlin/moe/nea/firmament/util/MoulConfigUtils.kt b/src/main/kotlin/moe/nea/firmament/util/MoulConfigUtils.kt index 3c77dc4..2884dc5 100644 --- a/src/main/kotlin/moe/nea/firmament/util/MoulConfigUtils.kt +++ b/src/main/kotlin/moe/nea/firmament/util/MoulConfigUtils.kt @@ -77,9 +77,9 @@ object MoulConfigUtils { 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) + ?: GetSetter.constant(true), + context.getMethodFromAttribute(element, QName("onClick")), ) } |