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/gui | |
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/gui')
26 files changed, 290 insertions, 899 deletions
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") -} |