[WIP] Remove LibGUI
This commit is contained in:
@@ -122,11 +122,9 @@ dependencies {
|
|||||||
modImplementation(libs.fabric.loader)
|
modImplementation(libs.fabric.loader)
|
||||||
modImplementation(libs.fabric.kotlin)
|
modImplementation(libs.fabric.kotlin)
|
||||||
modImplementation(libs.modmenu)
|
modImplementation(libs.modmenu)
|
||||||
modImplementation(libs.libgui)
|
|
||||||
modImplementation(libs.moulconfig)
|
modImplementation(libs.moulconfig)
|
||||||
modImplementation(libs.manninghamMills)
|
modImplementation(libs.manninghamMills)
|
||||||
modCompileOnly(libs.explosiveenhancement)
|
modCompileOnly(libs.explosiveenhancement)
|
||||||
include(libs.libgui)
|
|
||||||
include(libs.manninghamMills)
|
include(libs.manninghamMills)
|
||||||
include(libs.moulconfig)
|
include(libs.moulconfig)
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ moulconfig = { module = "org.notenoughupdates.moulconfig:modern", version.ref =
|
|||||||
repoparser = { module = "moe.nea:neurepoparser", version.ref = "neurepoparser" }
|
repoparser = { module = "moe.nea:neurepoparser", version.ref = "neurepoparser" }
|
||||||
dbus_java_core = { module = "com.github.hypfvieh:dbus-java-core", version.ref = "dbus_java" }
|
dbus_java_core = { module = "com.github.hypfvieh:dbus-java-core", version.ref = "dbus_java" }
|
||||||
dbus_java_unixsocket = { module = "com.github.hypfvieh:dbus-java-transport-native-unixsocket", version.ref = "dbus_java" }
|
dbus_java_unixsocket = { module = "com.github.hypfvieh:dbus-java-transport-native-unixsocket", version.ref = "dbus_java" }
|
||||||
libgui = { module = "io.github.cottonmc:LibGui", version.ref = "libgui" }
|
|
||||||
mixinextras = { module = "io.github.llamalad7:mixinextras-fabric", version.ref = "mixinextras" }
|
mixinextras = { module = "io.github.llamalad7:mixinextras-fabric", version.ref = "mixinextras" }
|
||||||
jarvis_api = { module = "moe.nea.jarvis:jarvis-api", version.ref = "jarvis" }
|
jarvis_api = { module = "moe.nea.jarvis:jarvis-api", version.ref = "jarvis" }
|
||||||
jarvis_fabric = { module = "moe.nea.jarvis:jarvis-fabric", version.ref = "jarvis" }
|
jarvis_fabric = { module = "moe.nea.jarvis:jarvis-fabric", version.ref = "jarvis" }
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import moe.nea.firmament.features.world.FairySouls
|
|||||||
import moe.nea.firmament.gui.config.AllConfigsGui
|
import moe.nea.firmament.gui.config.AllConfigsGui
|
||||||
import moe.nea.firmament.gui.config.BooleanHandler
|
import moe.nea.firmament.gui.config.BooleanHandler
|
||||||
import moe.nea.firmament.gui.config.ManagedOption
|
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.HypixelStaticData
|
||||||
import moe.nea.firmament.repo.RepoManager
|
import moe.nea.firmament.repo.RepoManager
|
||||||
import moe.nea.firmament.util.FirmFormatters
|
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.SBData
|
||||||
import moe.nea.firmament.util.ScreenUtil
|
import moe.nea.firmament.util.ScreenUtil
|
||||||
import moe.nea.firmament.util.SkyblockId
|
import moe.nea.firmament.util.SkyblockId
|
||||||
import moe.nea.firmament.util.unformattedString
|
|
||||||
|
|
||||||
|
|
||||||
fun firmamentCommand() = literal("firmament") {
|
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") {
|
thenLiteral("price") {
|
||||||
thenArgument("item", string()) { item ->
|
thenArgument("item", string()) { item ->
|
||||||
suggestsList { RepoManager.neuRepo.items.items.keys }
|
suggestsList { RepoManager.neuRepo.items.items.keys }
|
||||||
@@ -155,7 +140,7 @@ fun firmamentCommand() = literal("firmament") {
|
|||||||
source.sendFeedback(
|
source.sendFeedback(
|
||||||
Text.stringifiedTranslatable(
|
Text.stringifiedTranslatable(
|
||||||
"firmament.price.bazaar.buy.price",
|
"firmament.price.bazaar.buy.price",
|
||||||
FirmFormatters.formatCurrency(bazaarData.quickStatus.buyPrice, 1)
|
FirmFormatters.formatCommas(bazaarData.quickStatus.buyPrice, 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
source.sendFeedback(
|
source.sendFeedback(
|
||||||
@@ -167,7 +152,7 @@ fun firmamentCommand() = literal("firmament") {
|
|||||||
source.sendFeedback(
|
source.sendFeedback(
|
||||||
Text.stringifiedTranslatable(
|
Text.stringifiedTranslatable(
|
||||||
"firmament.price.bazaar.sell.price",
|
"firmament.price.bazaar.sell.price",
|
||||||
FirmFormatters.formatCurrency(bazaarData.quickStatus.sellPrice, 1)
|
FirmFormatters.formatCommas(bazaarData.quickStatus.sellPrice, 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
source.sendFeedback(
|
source.sendFeedback(
|
||||||
@@ -182,7 +167,7 @@ fun firmamentCommand() = literal("firmament") {
|
|||||||
source.sendFeedback(
|
source.sendFeedback(
|
||||||
Text.stringifiedTranslatable(
|
Text.stringifiedTranslatable(
|
||||||
"firmament.price.lowestbin",
|
"firmament.price.lowestbin",
|
||||||
FirmFormatters.formatCurrency(lowestBin, 1)
|
FirmFormatters.formatCommas(lowestBin, 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,6 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.features.debug
|
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.Firmament
|
||||||
import moe.nea.firmament.events.TickEvent
|
import moe.nea.firmament.events.TickEvent
|
||||||
import moe.nea.firmament.features.FirmamentFeature
|
import moe.nea.firmament.features.FirmamentFeature
|
||||||
@@ -36,24 +30,8 @@ object DebugView : FirmamentFeature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun recalculateDebugWidget() {
|
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() {
|
override fun onLoad() {
|
||||||
TickEvent.subscribe {
|
TickEvent.subscribe {
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -39,17 +39,17 @@ object PriceData : FirmamentFeature {
|
|||||||
it.lines.add(Text.literal(""))
|
it.lines.add(Text.literal(""))
|
||||||
it.lines.add(
|
it.lines.add(
|
||||||
Text.stringifiedTranslatable("firmament.tooltip.bazaar.sell-order",
|
Text.stringifiedTranslatable("firmament.tooltip.bazaar.sell-order",
|
||||||
FirmFormatters.formatCurrency(bazaarData.quickStatus.sellPrice, 1))
|
FirmFormatters.formatCommas(bazaarData.quickStatus.sellPrice, 1))
|
||||||
)
|
)
|
||||||
it.lines.add(
|
it.lines.add(
|
||||||
Text.stringifiedTranslatable("firmament.tooltip.bazaar.buy-order",
|
Text.stringifiedTranslatable("firmament.tooltip.bazaar.buy-order",
|
||||||
FirmFormatters.formatCurrency(bazaarData.quickStatus.buyPrice, 1))
|
FirmFormatters.formatCommas(bazaarData.quickStatus.buyPrice, 1))
|
||||||
)
|
)
|
||||||
} else if (lowestBin != null) {
|
} else if (lowestBin != null) {
|
||||||
it.lines.add(Text.literal(""))
|
it.lines.add(Text.literal(""))
|
||||||
it.lines.add(
|
it.lines.add(
|
||||||
Text.stringifiedTranslatable("firmament.tooltip.ah.lowestbin",
|
Text.stringifiedTranslatable("firmament.tooltip.ah.lowestbin",
|
||||||
FirmFormatters.formatCurrency(lowestBin, 1))
|
FirmFormatters.formatCommas(lowestBin, 1))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import moe.nea.firmament.features.FirmamentFeature
|
|||||||
import moe.nea.firmament.gui.config.ManagedConfig
|
import moe.nea.firmament.gui.config.ManagedConfig
|
||||||
import moe.nea.firmament.gui.hud.MoulConfigHud
|
import moe.nea.firmament.gui.hud.MoulConfigHud
|
||||||
import moe.nea.firmament.util.BazaarPriceStrategy
|
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.SkyblockId
|
||||||
import moe.nea.firmament.util.data.ProfileSpecificDataHolder
|
import moe.nea.firmament.util.data.ProfileSpecificDataHolder
|
||||||
import moe.nea.firmament.util.formattedString
|
import moe.nea.firmament.util.formattedString
|
||||||
@@ -99,11 +99,11 @@ object PristineProfitTracker : FirmamentFeature {
|
|||||||
if (collectionPerSecond == null || moneyPerSecond == null) return
|
if (collectionPerSecond == null || moneyPerSecond == null) return
|
||||||
ProfitHud.collectionCurrent = collectionPerSecond
|
ProfitHud.collectionCurrent = collectionPerSecond
|
||||||
ProfitHud.collectionText = Text.stringifiedTranslatable("firmament.pristine-profit.collection",
|
ProfitHud.collectionText = Text.stringifiedTranslatable("firmament.pristine-profit.collection",
|
||||||
formatCurrency(collectionPerSecond * SECONDS_PER_HOUR,
|
formatCommas(collectionPerSecond * SECONDS_PER_HOUR,
|
||||||
1)).formattedString()
|
1)).formattedString()
|
||||||
ProfitHud.moneyCurrent = moneyPerSecond
|
ProfitHud.moneyCurrent = moneyPerSecond
|
||||||
ProfitHud.moneyText = Text.stringifiedTranslatable("firmament.pristine-profit.money",
|
ProfitHud.moneyText = Text.stringifiedTranslatable("firmament.pristine-profit.money",
|
||||||
formatCurrency(moneyPerSecond * SECONDS_PER_HOUR, 1))
|
formatCommas(moneyPerSecond * SECONDS_PER_HOUR, 1))
|
||||||
.formattedString()
|
.formattedString()
|
||||||
val data = DConfig.data
|
val data = DConfig.data
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
package moe.nea.firmament.gui
|
package moe.nea.firmament.gui
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem
|
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.MyResourceLocation
|
||||||
import io.github.notenoughupdates.moulconfig.common.RenderContext
|
import io.github.notenoughupdates.moulconfig.common.RenderContext
|
||||||
import io.github.notenoughupdates.moulconfig.gui.GuiComponent
|
import io.github.notenoughupdates.moulconfig.gui.GuiComponent
|
||||||
@@ -33,6 +31,24 @@ class BarComponent(
|
|||||||
return 8
|
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 {
|
companion object {
|
||||||
val resource = Firmament.identifier("textures/gui/bar.png")
|
val resource = Firmament.identifier("textures/gui/bar.png")
|
||||||
val left = Texture(resource, 0 / 64F, 0 / 64F, 4 / 64F, 8 / 64F)
|
val left = Texture(resource, 0 / 64F, 0 / 64F, 4 / 64F, 8 / 64F)
|
||||||
@@ -51,20 +67,21 @@ class BarComponent(
|
|||||||
sectionEnd: Double
|
sectionEnd: Double
|
||||||
) {
|
) {
|
||||||
if (sectionEnd < progress.get() && width == 4) {
|
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
|
return
|
||||||
}
|
}
|
||||||
if (sectionStart > progress.get() && width == 4) {
|
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
|
return
|
||||||
}
|
}
|
||||||
val increasePerPixel = (sectionEnd - sectionStart) / width
|
val increasePerPixel = (sectionEnd - sectionStart) / width
|
||||||
var valueAtPixel = sectionStart
|
var valueAtPixel = sectionStart
|
||||||
for (i in (0 until width)) {
|
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,
|
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 else emptyColor
|
||||||
if (valueAtPixel < progress.get()) fillColor.color else emptyColor.color
|
|
||||||
)
|
)
|
||||||
valueAtPixel += increasePerPixel
|
valueAtPixel += increasePerPixel
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,24 +15,31 @@ import io.github.notenoughupdates.moulconfig.gui.component.PanelComponent
|
|||||||
import io.github.notenoughupdates.moulconfig.observer.GetSetter
|
import io.github.notenoughupdates.moulconfig.observer.GetSetter
|
||||||
|
|
||||||
|
|
||||||
class FirmButtonComponent(
|
open class FirmButtonComponent(
|
||||||
child: GuiComponent,
|
child: GuiComponent,
|
||||||
|
val isEnabled: GetSetter<Boolean> = GetSetter.constant(true),
|
||||||
val action: Runnable,
|
val action: Runnable,
|
||||||
val isEnabled: GetSetter<Boolean> = GetSetter.constant(true)
|
|
||||||
) : PanelComponent(child) {
|
) : PanelComponent(child) {
|
||||||
|
|
||||||
/* TODO: make use of vanillas built in nine slicer */
|
/* TODO: make use of vanillas built in nine slicer */
|
||||||
val hoveredBg = NinePatch.builder(MyResourceLocation("minecraft", "textures/gui/sprites/widget/button_highlighted.png"))
|
val hoveredBg =
|
||||||
.cornerSize(5)
|
NinePatch.builder(MyResourceLocation("minecraft", "textures/gui/sprites/widget/button_highlighted.png"))
|
||||||
.cornerUv(5 / 200F, 5 / 20F)
|
.cornerSize(5)
|
||||||
.mode(NinePatch.Mode.STRETCHING)
|
.cornerUv(5 / 200F, 5 / 20F)
|
||||||
.build()
|
.mode(NinePatch.Mode.STRETCHING)
|
||||||
|
.build()
|
||||||
val unhoveredBg = NinePatch.builder(MyResourceLocation("minecraft", "textures/gui/sprites/widget/button.png"))
|
val unhoveredBg = NinePatch.builder(MyResourceLocation("minecraft", "textures/gui/sprites/widget/button.png"))
|
||||||
.cornerSize(5)
|
.cornerSize(5)
|
||||||
.cornerUv(5 / 200F, 5 / 20F)
|
.cornerUv(5 / 200F, 5 / 20F)
|
||||||
.mode(NinePatch.Mode.STRETCHING)
|
.mode(NinePatch.Mode.STRETCHING)
|
||||||
.build()
|
.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)
|
.cornerSize(5)
|
||||||
.cornerUv(5 / 200F, 5 / 20F)
|
.cornerUv(5 / 200F, 5 / 20F)
|
||||||
.mode(NinePatch.Mode.STRETCHING)
|
.mode(NinePatch.Mode.STRETCHING)
|
||||||
@@ -59,12 +66,15 @@ class FirmButtonComponent(
|
|||||||
return false
|
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) {
|
override fun render(context: GuiImmediateContext) {
|
||||||
context.renderContext.pushMatrix()
|
context.renderContext.pushMatrix()
|
||||||
context.renderContext.drawNinePatch(
|
context.renderContext.drawNinePatch(
|
||||||
if (!isEnabled.get()) disabledBg
|
getBackground(context),
|
||||||
else if (context.isHovered || isClicking) hoveredBg
|
|
||||||
else unhoveredBg,
|
|
||||||
0f, 0f, context.width, context.height
|
0f, 0f, context.width, context.height
|
||||||
)
|
)
|
||||||
context.renderContext.translate(insets.toFloat(), insets.toFloat(), 0f)
|
context.renderContext.translate(insets.toFloat(), insets.toFloat(), 0f)
|
||||||
|
|||||||
@@ -14,20 +14,20 @@ import io.github.notenoughupdates.moulconfig.observer.GetSetter
|
|||||||
import java.util.function.BiFunction
|
import java.util.function.BiFunction
|
||||||
|
|
||||||
class FixedComponent(
|
class FixedComponent(
|
||||||
val fixedWidth: GetSetter<Int>,
|
val fixedWidth: GetSetter<Int>?,
|
||||||
val fixedHeight: GetSetter<Int>,
|
val fixedHeight: GetSetter<Int>?,
|
||||||
val component: GuiComponent,
|
val component: GuiComponent,
|
||||||
) : 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 {
|
override fun <T : Any?> foldChildren(initial: T, visitor: BiFunction<GuiComponent, T, T>): T {
|
||||||
return visitor.apply(component, initial)
|
return visitor.apply(component, initial)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fixContext(context: GuiImmediateContext): GuiImmediateContext =
|
fun fixContext(context: GuiImmediateContext): GuiImmediateContext =
|
||||||
context.translated(0, 0, fixedWidth.get(), fixedHeight.get())
|
context.translated(0, 0, width, height)
|
||||||
|
|
||||||
override fun render(context: GuiImmediateContext) {
|
override fun render(context: GuiImmediateContext) {
|
||||||
component.render(fixContext(context))
|
component.render(fixContext(context))
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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())
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.config
|
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.JsonElement
|
||||||
import kotlinx.serialization.json.JsonPrimitive
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
import kotlinx.serialization.json.boolean
|
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) {
|
override fun emitGuiElements(opt: ManagedOption<Boolean>, guiAppender: GuiAppender) {
|
||||||
guiAppender.appendLabeledRow(
|
guiAppender.appendLabeledRow(
|
||||||
opt.labelText,
|
opt.labelText,
|
||||||
WToggleButton(opt.labelText).apply {
|
CenterComponent(SwitchComponent(object : GetSetter<Boolean> {
|
||||||
guiAppender.onReload { toggle = opt.value }
|
override fun get(): Boolean {
|
||||||
setOnToggle {
|
return opt.get()
|
||||||
opt.value = it
|
}
|
||||||
|
|
||||||
|
override fun set(newValue: Boolean) {
|
||||||
|
opt.set(newValue)
|
||||||
config.save()
|
config.save()
|
||||||
}
|
}
|
||||||
}
|
}, 200)
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.config
|
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 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> {
|
class ClickHandler(val config: ManagedConfig, val runnable: () -> Unit) : ManagedConfig.OptionHandler<Unit> {
|
||||||
override fun toJson(element: Unit): JsonElement? {
|
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) {
|
override fun emitGuiElements(opt: ManagedOption<Unit>, guiAppender: GuiAppender) {
|
||||||
guiAppender.appendLabeledRow(
|
guiAppender.appendLabeledRow(
|
||||||
Text.translatable("firmament.config.${config.name}.${opt.propertyName}"),
|
opt.labelText,
|
||||||
WButton(Text.translatable("firmament.config.${config.name}.${opt.propertyName}")).apply {
|
FirmButtonComponent(
|
||||||
setOnClick {
|
TextComponent(opt.labelText.string),
|
||||||
runnable()
|
action = runnable),
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,18 +6,16 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.config
|
package moe.nea.firmament.gui.config
|
||||||
|
|
||||||
import io.github.cottonmc.cotton.gui.widget.WBox
|
import io.github.notenoughupdates.moulconfig.common.IMinecraft
|
||||||
import io.github.cottonmc.cotton.gui.widget.WLabel
|
import io.github.notenoughupdates.moulconfig.gui.component.RowComponent
|
||||||
import io.github.cottonmc.cotton.gui.widget.WSlider
|
import io.github.notenoughupdates.moulconfig.gui.component.SliderComponent
|
||||||
import io.github.cottonmc.cotton.gui.widget.data.Axis
|
import io.github.notenoughupdates.moulconfig.gui.component.TextComponent
|
||||||
import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment
|
import io.github.notenoughupdates.moulconfig.observer.GetSetter
|
||||||
import java.util.function.IntConsumer
|
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import kotlinx.serialization.json.JsonPrimitive
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import kotlinx.serialization.json.long
|
import kotlinx.serialization.json.long
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
import kotlin.time.Duration.Companion.milliseconds
|
|
||||||
import kotlin.time.DurationUnit
|
import kotlin.time.DurationUnit
|
||||||
import kotlin.time.toDuration
|
import kotlin.time.toDuration
|
||||||
import net.minecraft.text.Text
|
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) {
|
override fun emitGuiElements(opt: ManagedOption<Duration>, guiAppender: GuiAppender) {
|
||||||
val label =
|
guiAppender.appendLabeledRow(
|
||||||
WLabel(Text.literal(FirmFormatters.formatTimespan(opt.value))).setVerticalAlignment(VerticalAlignment.CENTER)
|
opt.labelText,
|
||||||
guiAppender.appendLabeledRow(opt.labelText, WBox(Axis.HORIZONTAL).also {
|
RowComponent(
|
||||||
it.add(label, 40, 18)
|
TextComponent(IMinecraft.instance.defaultFontRenderer,
|
||||||
it.add(WSlider(min.inWholeMilliseconds.toInt(), max.inWholeMilliseconds.toInt(), Axis.HORIZONTAL).apply {
|
{ FirmFormatters.formatTimespan(opt.value) },
|
||||||
valueChangeListener = IntConsumer {
|
40,
|
||||||
opt.value = it.milliseconds
|
TextComponent.TextAlignment.CENTER,
|
||||||
label.text = Text.literal(FirmFormatters.formatTimespan(opt.value))
|
true,
|
||||||
config.save()
|
false),
|
||||||
}
|
SliderComponent(
|
||||||
guiAppender.onReload {
|
object : GetSetter<Float> {
|
||||||
value = opt.value.inWholeMilliseconds.toInt()
|
override fun get(): Float {
|
||||||
label.text = Text.literal(FirmFormatters.formatTimespan(opt.value))
|
return opt.value.toDouble(DurationUnit.SECONDS).toFloat()
|
||||||
}
|
}
|
||||||
}, 130, 18)
|
|
||||||
})
|
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
|
||||||
|
)
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,37 +6,39 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.config
|
package moe.nea.firmament.gui.config
|
||||||
|
|
||||||
import io.github.cottonmc.cotton.gui.widget.WBox
|
import io.github.notenoughupdates.moulconfig.gui.GuiComponent
|
||||||
import io.github.cottonmc.cotton.gui.widget.WLabel
|
import io.github.notenoughupdates.moulconfig.gui.component.RowComponent
|
||||||
import io.github.cottonmc.cotton.gui.widget.WWidget
|
import io.github.notenoughupdates.moulconfig.gui.component.TextComponent
|
||||||
import io.github.cottonmc.cotton.gui.widget.data.Axis
|
import io.github.notenoughupdates.moulconfig.observer.GetSetter
|
||||||
import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment
|
|
||||||
import net.minecraft.client.gui.screen.Screen
|
import net.minecraft.client.gui.screen.Screen
|
||||||
import net.minecraft.text.Text
|
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) {
|
class GuiAppender(val width: Int, val screenAccessor: () -> Screen) {
|
||||||
val panel = WBox(Axis.VERTICAL).also {
|
val panel = mutableListOf<GuiComponent>()
|
||||||
it.setSize(width, 200)
|
|
||||||
}
|
|
||||||
internal val reloadables = mutableListOf<(() -> Unit)>()
|
internal val reloadables = mutableListOf<(() -> Unit)>()
|
||||||
|
|
||||||
fun onReload(reloadable: () -> Unit) {
|
fun onReload(reloadable: () -> Unit) {
|
||||||
reloadables.add(reloadable)
|
reloadables.add(reloadable)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun appendLabeledRow(label: Text, right: WWidget) {
|
fun appendLabeledRow(label: Text, right: GuiComponent) {
|
||||||
appendSplitRow(
|
appendSplitRow(
|
||||||
WLabel(label).setVerticalAlignment(VerticalAlignment.CENTER),
|
TextComponent(label.string),
|
||||||
right
|
right
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun appendSplitRow(left: WWidget, right: WWidget) {
|
fun appendSplitRow(left: GuiComponent, right: GuiComponent) {
|
||||||
appendFullRow(WSplitPanel(left.also { it.setSize(width / 2, 18) }, right.also { it.setSize(width / 2, 18) }))
|
// 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) {
|
fun appendFullRow(widget: GuiComponent) {
|
||||||
panel.add(widget, width, 18)
|
panel.add(widget)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.config
|
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.Json
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import kotlinx.serialization.json.decodeFromJsonElement
|
import kotlinx.serialization.json.decodeFromJsonElement
|
||||||
import kotlinx.serialization.json.encodeToJsonElement
|
import kotlinx.serialization.json.encodeToJsonElement
|
||||||
import net.minecraft.text.MutableText
|
import net.minecraft.text.MutableText
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
|
import moe.nea.firmament.gui.FirmButtonComponent
|
||||||
import moe.nea.firmament.jarvis.JarvisIntegration
|
import moe.nea.firmament.jarvis.JarvisIntegration
|
||||||
import moe.nea.firmament.util.MC
|
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) {
|
override fun emitGuiElements(opt: ManagedOption<HudMeta>, guiAppender: GuiAppender) {
|
||||||
guiAppender.appendLabeledRow(opt.labelText, WButton(Text.stringifiedTranslatable("firmament.hud.edit", label))
|
guiAppender.appendLabeledRow(
|
||||||
.also {
|
opt.labelText,
|
||||||
it.setOnClick {
|
FirmButtonComponent(
|
||||||
MC.screen = JarvisIntegration.jarvis.getHudEditor(
|
TextComponent(
|
||||||
guiAppender.screenAccessor.invoke(),
|
Text.stringifiedTranslatable("firmament.hud.edit", label).string),
|
||||||
listOf(opt.value)
|
) {
|
||||||
)
|
MC.screen = JarvisIntegration.jarvis.getHudEditor(
|
||||||
}
|
guiAppender.screenAccessor.invoke(),
|
||||||
|
listOf(opt.value)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,16 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.config
|
package moe.nea.firmament.gui.config
|
||||||
|
|
||||||
import io.github.cottonmc.cotton.gui.widget.WBox
|
import io.github.notenoughupdates.moulconfig.common.IMinecraft
|
||||||
import io.github.cottonmc.cotton.gui.widget.WLabel
|
import io.github.notenoughupdates.moulconfig.gui.component.RowComponent
|
||||||
import io.github.cottonmc.cotton.gui.widget.WSlider
|
import io.github.notenoughupdates.moulconfig.gui.component.SliderComponent
|
||||||
import io.github.cottonmc.cotton.gui.widget.data.Axis
|
import io.github.notenoughupdates.moulconfig.gui.component.TextComponent
|
||||||
import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment
|
import io.github.notenoughupdates.moulconfig.observer.GetSetter
|
||||||
import java.util.function.IntConsumer
|
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import kotlinx.serialization.json.JsonPrimitive
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
import kotlinx.serialization.json.int
|
import kotlinx.serialization.json.int
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
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> {
|
class IntegerHandler(val config: ManagedConfig, val min: Int, val max: Int) : ManagedConfig.OptionHandler<Int> {
|
||||||
override fun toJson(element: Int): JsonElement? {
|
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) {
|
override fun emitGuiElements(opt: ManagedOption<Int>, guiAppender: GuiAppender) {
|
||||||
val label =
|
guiAppender.appendLabeledRow(
|
||||||
WLabel(Text.literal(opt.value.toString())).setVerticalAlignment(VerticalAlignment.CENTER)
|
opt.labelText,
|
||||||
guiAppender.appendLabeledRow(opt.labelText, WBox(Axis.HORIZONTAL).also {
|
RowComponent(
|
||||||
it.add(label, 40, 18)
|
TextComponent(IMinecraft.instance.defaultFontRenderer,
|
||||||
it.add(WSlider(min, max, Axis.HORIZONTAL).apply {
|
{ FirmFormatters.formatCommas(opt.value, 0) },
|
||||||
valueChangeListener = IntConsumer {
|
40,
|
||||||
opt.value = it
|
TextComponent.TextAlignment.CENTER,
|
||||||
label.text = Text.literal(opt.value.toString())
|
true,
|
||||||
config.save()
|
false),
|
||||||
}
|
SliderComponent(
|
||||||
guiAppender.onReload {
|
object : GetSetter<Float> {
|
||||||
value = opt.value
|
override fun get(): Float {
|
||||||
label.text = Text.literal(opt.value.toString())
|
return opt.value.toFloat()
|
||||||
}
|
}
|
||||||
}, 130, 18)
|
|
||||||
})
|
override fun set(newValue: Float) {
|
||||||
|
opt.value = newValue.toInt()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
min.toFloat(),
|
||||||
|
max.toFloat(),
|
||||||
|
0.1F,
|
||||||
|
130
|
||||||
|
)
|
||||||
|
))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,12 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.config
|
package moe.nea.firmament.gui.config
|
||||||
|
|
||||||
import io.github.cottonmc.cotton.gui.widget.WButton
|
import io.github.notenoughupdates.moulconfig.common.IMinecraft
|
||||||
import io.github.cottonmc.cotton.gui.widget.data.InputResult
|
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 org.lwjgl.glfw.GLFW
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
@@ -16,6 +20,7 @@ import kotlinx.serialization.json.encodeToJsonElement
|
|||||||
import net.minecraft.client.util.InputUtil
|
import net.minecraft.client.util.InputUtil
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import net.minecraft.util.Formatting
|
import net.minecraft.util.Formatting
|
||||||
|
import moe.nea.firmament.gui.FirmButtonComponent
|
||||||
import moe.nea.firmament.keybindings.FirmamentKeyBindings
|
import moe.nea.firmament.keybindings.FirmamentKeyBindings
|
||||||
import moe.nea.firmament.keybindings.SavedKeyBinding
|
import moe.nea.firmament.keybindings.SavedKeyBinding
|
||||||
|
|
||||||
@@ -36,61 +41,8 @@ class KeyBindingHandler(name: String, val managedConfig: ManagedConfig) : Manage
|
|||||||
var editing = false
|
var editing = false
|
||||||
var lastPressed = 0
|
var lastPressed = 0
|
||||||
var lastPressedNonModifier = 0
|
var lastPressedNonModifier = 0
|
||||||
var updateButton: (() -> Unit)? = null
|
var label: String = ""
|
||||||
val button = object : WButton() {
|
var button: FirmButtonComponent? = null
|
||||||
override fun onKeyPressed(ch: Int, key: Int, modifiers: Int): InputResult {
|
|
||||||
if (!editing) {
|
|
||||||
return super.onKeyPressed(ch, key, modifiers)
|
|
||||||
}
|
|
||||||
if (ch == GLFW.GLFW_KEY_ESCAPE) {
|
|
||||||
lastPressedNonModifier = 0
|
|
||||||
editing = false
|
|
||||||
lastPressed = 0
|
|
||||||
opt.value = SavedKeyBinding(GLFW.GLFW_KEY_UNKNOWN)
|
|
||||||
updateButton!!()
|
|
||||||
return InputResult.PROCESSED
|
|
||||||
}
|
|
||||||
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
|
|
||||||
|| ch == GLFW.GLFW_KEY_LEFT_CONTROL || ch == GLFW.GLFW_KEY_RIGHT_CONTROL
|
|
||||||
) {
|
|
||||||
lastPressed = ch
|
|
||||||
} else {
|
|
||||||
opt.value = SavedKeyBinding(
|
|
||||||
ch, modifiers
|
|
||||||
)
|
|
||||||
editing = false
|
|
||||||
lastPressed = 0
|
|
||||||
lastPressedNonModifier = 0
|
|
||||||
}
|
|
||||||
updateButton!!()
|
|
||||||
return InputResult.PROCESSED
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFocusLost() {
|
|
||||||
super.onFocusLost()
|
|
||||||
lastPressedNonModifier = 0
|
|
||||||
editing = false
|
|
||||||
lastPressed = 0
|
|
||||||
updateButton!!()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onKeyReleased(ch: Int, key: Int, modifiers: Int): InputResult {
|
|
||||||
if (!editing)
|
|
||||||
return super.onKeyReleased(ch, key, modifiers)
|
|
||||||
if (lastPressedNonModifier == ch || (lastPressedNonModifier == 0 && ch == lastPressed)) {
|
|
||||||
opt.value = SavedKeyBinding(
|
|
||||||
ch, modifiers
|
|
||||||
)
|
|
||||||
editing = false
|
|
||||||
lastPressed = 0
|
|
||||||
lastPressedNonModifier = 0
|
|
||||||
}
|
|
||||||
updateButton!!()
|
|
||||||
return InputResult.PROCESSED
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateLabel() {
|
fun updateLabel() {
|
||||||
val stroke = Text.literal("")
|
val stroke = Text.literal("")
|
||||||
if (opt.value.shift) {
|
if (opt.value.shift) {
|
||||||
@@ -105,16 +57,89 @@ class KeyBindingHandler(name: String, val managedConfig: ManagedConfig) : Manage
|
|||||||
stroke.append(InputUtil.Type.KEYSYM.createFromCode(opt.value.keyCode).localizedText)
|
stroke.append(InputUtil.Type.KEYSYM.createFromCode(opt.value.keyCode).localizedText)
|
||||||
if (editing)
|
if (editing)
|
||||||
stroke.styled { it.withColor(Formatting.YELLOW) }
|
stroke.styled { it.withColor(Formatting.YELLOW) }
|
||||||
button.setLabel(stroke)
|
label = (stroke).string
|
||||||
managedConfig.save()
|
managedConfig.save()
|
||||||
}
|
}
|
||||||
updateButton = ::updateLabel
|
button = object : FirmButtonComponent(
|
||||||
updateButton()
|
TextComponent(
|
||||||
button.setOnClick {
|
IMinecraft.instance.defaultFontRenderer,
|
||||||
editing = true
|
{ label },
|
||||||
button.requestFocus()
|
130,
|
||||||
updateButton()
|
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 false
|
||||||
|
}
|
||||||
|
if (ch == GLFW.GLFW_KEY_ESCAPE) {
|
||||||
|
lastPressedNonModifier = 0
|
||||||
|
editing = false
|
||||||
|
lastPressed = 0
|
||||||
|
opt.value = SavedKeyBinding(GLFW.GLFW_KEY_UNKNOWN)
|
||||||
|
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
|
||||||
|
|| ch == GLFW.GLFW_KEY_LEFT_CONTROL || ch == GLFW.GLFW_KEY_RIGHT_CONTROL
|
||||||
|
) {
|
||||||
|
lastPressed = ch
|
||||||
|
} else {
|
||||||
|
opt.value = SavedKeyBinding(
|
||||||
|
ch, modifiers
|
||||||
|
)
|
||||||
|
editing = false
|
||||||
|
lastPressed = 0
|
||||||
|
lastPressedNonModifier = 0
|
||||||
|
}
|
||||||
|
updateLabel()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLostFocus() {
|
||||||
|
lastPressedNonModifier = 0
|
||||||
|
editing = false
|
||||||
|
lastPressed = 0
|
||||||
|
updateLabel()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onKeyReleased(ch: Int, modifiers: Int): Boolean {
|
||||||
|
if (!editing)
|
||||||
|
return false
|
||||||
|
if (lastPressedNonModifier == ch || (lastPressedNonModifier == 0 && ch == lastPressed)) {
|
||||||
|
opt.value = SavedKeyBinding(ch, modifiers)
|
||||||
|
editing = false
|
||||||
|
lastPressed = 0
|
||||||
|
lastPressedNonModifier = 0
|
||||||
|
}
|
||||||
|
updateLabel()
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
updateLabel()
|
||||||
guiAppender.appendLabeledRow(opt.labelText, button)
|
guiAppender.appendLabeledRow(opt.labelText, button)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,17 +6,17 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.config
|
package moe.nea.firmament.gui.config
|
||||||
|
|
||||||
import io.github.cottonmc.cotton.gui.client.CottonClientScreen
|
import io.github.notenoughupdates.moulconfig.gui.CloseEventListener
|
||||||
import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription
|
import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper
|
||||||
import io.github.cottonmc.cotton.gui.widget.WBox
|
import io.github.notenoughupdates.moulconfig.gui.GuiContext
|
||||||
import io.github.cottonmc.cotton.gui.widget.WButton
|
import io.github.notenoughupdates.moulconfig.gui.component.CenterComponent
|
||||||
import io.github.cottonmc.cotton.gui.widget.WLabel
|
import io.github.notenoughupdates.moulconfig.gui.component.ColumnComponent
|
||||||
import io.github.cottonmc.cotton.gui.widget.data.Axis
|
import io.github.notenoughupdates.moulconfig.gui.component.PanelComponent
|
||||||
import io.github.cottonmc.cotton.gui.widget.data.Insets
|
import io.github.notenoughupdates.moulconfig.gui.component.RowComponent
|
||||||
import io.github.cottonmc.cotton.gui.widget.data.VerticalAlignment
|
import io.github.notenoughupdates.moulconfig.gui.component.ScrollPanelComponent
|
||||||
|
import io.github.notenoughupdates.moulconfig.gui.component.TextComponent
|
||||||
import moe.nea.jarvis.api.Point
|
import moe.nea.jarvis.api.Point
|
||||||
import org.lwjgl.glfw.GLFW
|
import org.lwjgl.glfw.GLFW
|
||||||
import kotlinx.serialization.decodeFromString
|
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
@@ -27,9 +27,8 @@ import kotlin.time.Duration
|
|||||||
import net.minecraft.client.gui.screen.Screen
|
import net.minecraft.client.gui.screen.Screen
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import moe.nea.firmament.Firmament
|
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.keybindings.SavedKeyBinding
|
||||||
import moe.nea.firmament.util.MC
|
|
||||||
import moe.nea.firmament.util.ScreenUtil.setScreenLater
|
import moe.nea.firmament.util.ScreenUtil.setScreenLater
|
||||||
|
|
||||||
abstract class ManagedConfig(override val name: String) : ManagedConfigElement() {
|
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}")
|
val labelText = Text.translatable("firmament.config.${name}")
|
||||||
|
|
||||||
fun getConfigEditor(parent: Screen? = null): CottonClientScreen {
|
fun getConfigEditor(parent: Screen? = null): Screen {
|
||||||
val lwgd = LightweightGuiDescription()
|
|
||||||
var screen: Screen? = null
|
var screen: Screen? = null
|
||||||
val guiapp = GuiAppender(400) { requireNotNull(screen) { "Screen Accessor called too early" } }
|
val guiapp = GuiAppender(400) { requireNotNull(screen) { "Screen Accessor called too early" } }
|
||||||
latestGuiAppender = guiapp
|
latestGuiAppender = guiapp
|
||||||
guiapp.panel.insets = Insets.ROOT_PANEL
|
guiapp.appendFullRow(RowComponent(
|
||||||
guiapp.appendFullRow(WBox(Axis.HORIZONTAL).also {
|
FirmButtonComponent(TextComponent("←")) {
|
||||||
it.add(WButton(Text.literal("←")).also {
|
if (parent != null) {
|
||||||
it.setOnClick {
|
|
||||||
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()
|
save()
|
||||||
MC.screen = parent
|
setScreenLater(parent)
|
||||||
|
} else {
|
||||||
|
AllConfigsGui.showAllGuis()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
))
|
||||||
|
sortedOptions.forEach { it.appendToGui(guiapp) }
|
||||||
|
guiapp.reloadables.forEach { it() }
|
||||||
|
val component = CenterComponent(PanelComponent(ScrollPanelComponent(400, 300, ColumnComponent(guiapp.panel)), 10, PanelComponent.DefaultBackgroundRenderer.VANILLA))
|
||||||
|
screen = object : GuiComponentWrapper(GuiContext(component)) {
|
||||||
|
override fun close() {
|
||||||
|
if (context.onBeforeClose() == CloseEventListener.CloseAction.NO_OBJECTIONS_TO_CLOSE) {
|
||||||
|
client!!.setScreen(parent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return screen
|
return screen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.config
|
package moe.nea.firmament.gui.config
|
||||||
|
|
||||||
|
import io.github.notenoughupdates.moulconfig.observer.GetSetter
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
import kotlin.properties.ReadWriteProperty
|
import kotlin.properties.ReadWriteProperty
|
||||||
@@ -18,7 +19,14 @@ class ManagedOption<T : Any>(
|
|||||||
val propertyName: String,
|
val propertyName: String,
|
||||||
val default: () -> T,
|
val default: () -> T,
|
||||||
val handler: ManagedConfig.OptionHandler<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 rawLabelText = "firmament.config.${element.name}.${propertyName}"
|
||||||
val labelText = Text.translatable(rawLabelText)
|
val labelText = Text.translatable(rawLabelText)
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.config
|
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.JsonElement
|
||||||
import kotlinx.serialization.json.JsonPrimitive
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
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) {
|
override fun emitGuiElements(opt: ManagedOption<String>, guiAppender: GuiAppender) {
|
||||||
guiAppender.appendLabeledRow(
|
guiAppender.appendLabeledRow(
|
||||||
opt.labelText,
|
opt.labelText,
|
||||||
WTextField(opt.labelText).apply {
|
TextFieldComponent(
|
||||||
maxLength = 1000
|
object : GetSetter<String> by opt {
|
||||||
suggestion = Text.translatableWithFallback(opt.rawLabelText + ".hint", "")
|
override fun set(newValue: String) {
|
||||||
guiAppender.onReload { text = opt.value }
|
opt.set(newValue)
|
||||||
setChangedListener {
|
config.save()
|
||||||
opt.value = it
|
}
|
||||||
config.save()
|
},
|
||||||
}
|
130,
|
||||||
}
|
suggestion = Text.translatableWithFallback(opt.rawLabelText + ".hint", "").string
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,12 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.gui.hud
|
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.GuiContext
|
||||||
import io.github.notenoughupdates.moulconfig.gui.component.TextComponent
|
import io.github.notenoughupdates.moulconfig.gui.component.TextComponent
|
||||||
import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper
|
|
||||||
import net.minecraft.resource.ResourceManager
|
import net.minecraft.resource.ResourceManager
|
||||||
import net.minecraft.resource.SynchronousResourceReloader
|
import net.minecraft.resource.SynchronousResourceReloader
|
||||||
|
import moe.nea.firmament.events.FinalizeResourceManagerEvent
|
||||||
import moe.nea.firmament.events.HudRenderEvent
|
import moe.nea.firmament.events.HudRenderEvent
|
||||||
import moe.nea.firmament.gui.config.HudMeta
|
import moe.nea.firmament.gui.config.HudMeta
|
||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
@@ -21,9 +22,11 @@ abstract class MoulConfigHud(
|
|||||||
val hudMeta: HudMeta,
|
val hudMeta: HudMeta,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
private val componentWrapper = object : GuiComponentWrapper(GuiContext(TextComponent("§cERROR"))) {
|
private val componentWrapper by lazy {
|
||||||
init {
|
object : GuiComponentWrapper(GuiContext(TextComponent("§cERROR"))) {
|
||||||
this.client = MC.instance
|
init {
|
||||||
|
this.client = MC.instance
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,7 +34,6 @@ abstract class MoulConfigHud(
|
|||||||
private var fragment: GuiContext? = null
|
private var fragment: GuiContext? = null
|
||||||
|
|
||||||
fun forceInit() {
|
fun forceInit() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun shouldRender(): Boolean {
|
open fun shouldRender(): Boolean {
|
||||||
@@ -53,11 +55,13 @@ abstract class MoulConfigHud(
|
|||||||
fragment!!.root.render(renderContextTranslated)
|
fragment!!.root.render(renderContextTranslated)
|
||||||
it.context.matrices.pop()
|
it.context.matrices.pop()
|
||||||
}
|
}
|
||||||
MC.resourceManager.registerReloader(object : SynchronousResourceReloader {
|
FinalizeResourceManagerEvent.subscribe {
|
||||||
override fun reload(manager: ResourceManager?) {
|
MC.resourceManager.registerReloader(object : SynchronousResourceReloader {
|
||||||
fragment = null
|
override fun reload(manager: ResourceManager?) {
|
||||||
}
|
fragment = null
|
||||||
})
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadFragment() {
|
fun loadFragment() {
|
||||||
|
|||||||
@@ -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")
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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")
|
|
||||||
}
|
|
||||||
@@ -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,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.keybindings
|
package moe.nea.firmament.keybindings
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import moe.nea.firmament.util.MC
|
|
||||||
import net.minecraft.client.MinecraftClient
|
import net.minecraft.client.MinecraftClient
|
||||||
import net.minecraft.client.util.InputUtil
|
import net.minecraft.client.util.InputUtil
|
||||||
import org.lwjgl.glfw.GLFW
|
import moe.nea.firmament.util.MC
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class SavedKeyBinding(
|
data class SavedKeyBinding(
|
||||||
@@ -38,6 +38,24 @@ data class SavedKeyBinding(
|
|||||||
modifiers and GLFW.GLFW_MOD_ALT != 0
|
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 {
|
fun isPressed(atLeast: Boolean = false): Boolean {
|
||||||
@@ -47,21 +65,21 @@ data class SavedKeyBinding(
|
|||||||
|
|
||||||
val ctrl = if (MinecraftClient.IS_SYSTEM_MAC) {
|
val ctrl = if (MinecraftClient.IS_SYSTEM_MAC) {
|
||||||
InputUtil.isKeyPressed(h, GLFW.GLFW_KEY_LEFT_SUPER)
|
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)
|
} 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)
|
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)
|
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)
|
if (atLeast)
|
||||||
return (ctrl >= this.ctrl) &&
|
return (ctrl >= this.ctrl) &&
|
||||||
(alt >= this.alt) &&
|
(alt >= this.alt) &&
|
||||||
(shift >= this.shift)
|
(shift >= this.shift)
|
||||||
|
|
||||||
return (ctrl == this.ctrl) &&
|
return (ctrl == this.ctrl) &&
|
||||||
(alt == this.alt) &&
|
(alt == this.alt) &&
|
||||||
(shift == this.shift)
|
(shift == this.shift)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun matches(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
|
override fun matches(keyCode: Int, scanCode: Int, modifiers: Int): Boolean {
|
||||||
|
|||||||
@@ -79,10 +79,10 @@ data class SBItemStack(
|
|||||||
) {
|
) {
|
||||||
val stats = petInfo.interpolatedStatsAtLevel(level) ?: return
|
val stats = petInfo.interpolatedStatsAtLevel(level) ?: return
|
||||||
stats.otherNumbers.forEachIndexed { index, it ->
|
stats.otherNumbers.forEachIndexed { index, it ->
|
||||||
replacementData[index.toString()] = FirmFormatters.formatCurrency(it, 1)
|
replacementData[index.toString()] = FirmFormatters.formatCommas(it, 1)
|
||||||
}
|
}
|
||||||
stats.statNumbers.forEach { (t, u) ->
|
stats.statNumbers.forEach { (t, u) ->
|
||||||
replacementData[t] = FirmFormatters.formatCurrency(u, 1)
|
replacementData[t] = FirmFormatters.formatCommas(u, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
package moe.nea.firmament.repo
|
package moe.nea.firmament.repo
|
||||||
|
|
||||||
import com.mojang.serialization.Dynamic
|
import com.mojang.serialization.Dynamic
|
||||||
import io.github.cottonmc.cotton.gui.client.CottonHud
|
|
||||||
import io.github.moulberry.repo.IReloadable
|
import io.github.moulberry.repo.IReloadable
|
||||||
import io.github.moulberry.repo.NEURepository
|
import io.github.moulberry.repo.NEURepository
|
||||||
import io.github.moulberry.repo.data.NEUItem
|
import io.github.moulberry.repo.data.NEUItem
|
||||||
|
import io.github.notenoughupdates.moulconfig.xml.Bind
|
||||||
import java.text.NumberFormat
|
import java.text.NumberFormat
|
||||||
import java.util.*
|
import java.util.UUID
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@@ -32,6 +32,9 @@ import net.minecraft.nbt.NbtElement
|
|||||||
import net.minecraft.nbt.NbtOps
|
import net.minecraft.nbt.NbtOps
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import moe.nea.firmament.Firmament
|
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.LegacyTagParser
|
||||||
import moe.nea.firmament.util.MC
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.SkyblockId
|
import moe.nea.firmament.util.SkyblockId
|
||||||
@@ -135,6 +138,30 @@ object ItemCache : IReloadable {
|
|||||||
fun NEUItem.getIdentifier() = skyblockId.identifier
|
fun NEUItem.getIdentifier() = skyblockId.identifier
|
||||||
|
|
||||||
var job: Job? = null
|
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) {
|
override fun reload(repository: NEURepository) {
|
||||||
val j = job
|
val j = job
|
||||||
@@ -147,18 +174,18 @@ object ItemCache : IReloadable {
|
|||||||
job = Firmament.coroutineScope.launch {
|
job = Firmament.coroutineScope.launch {
|
||||||
val items = repository.items?.items
|
val items = repository.items?.items
|
||||||
if (items == null) {
|
if (items == null) {
|
||||||
CottonHud.remove(RepoManager.progressBar)
|
ReloadProgressHud.isEnabled = false
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
val recacheItems = I18n.translate("firmament.repo.cache")
|
val recacheItems = I18n.translate("firmament.repo.cache")
|
||||||
RepoManager.progressBar.reportProgress(recacheItems, 0, items.size)
|
ReloadProgressHud.reportProgress(recacheItems, 0, items.size)
|
||||||
CottonHud.add(RepoManager.progressBar)
|
ReloadProgressHud.isEnabled = true
|
||||||
var i = 0
|
var i = 0
|
||||||
items.values.forEach {
|
items.values.forEach {
|
||||||
it.asItemStack() // Rebuild cache
|
it.asItemStack() // Rebuild cache
|
||||||
RepoManager.progressBar.reportProgress(recacheItems, i++, items.size)
|
ReloadProgressHud.reportProgress(recacheItems, i++, items.size)
|
||||||
}
|
}
|
||||||
CottonHud.remove(RepoManager.progressBar)
|
ReloadProgressHud.isEnabled = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
package moe.nea.firmament.repo
|
package moe.nea.firmament.repo
|
||||||
|
|
||||||
import io.github.cottonmc.cotton.gui.client.CottonHud
|
|
||||||
import io.github.moulberry.repo.NEURecipeCache
|
import io.github.moulberry.repo.NEURecipeCache
|
||||||
import io.github.moulberry.repo.NEURepository
|
import io.github.moulberry.repo.NEURepository
|
||||||
import io.github.moulberry.repo.NEURepositoryException
|
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
|
||||||
import moe.nea.firmament.Firmament.logger
|
import moe.nea.firmament.Firmament.logger
|
||||||
import moe.nea.firmament.gui.config.ManagedConfig
|
import moe.nea.firmament.gui.config.ManagedConfig
|
||||||
import moe.nea.firmament.hud.ProgressBar
|
|
||||||
import moe.nea.firmament.rei.PetData
|
import moe.nea.firmament.rei.PetData
|
||||||
import moe.nea.firmament.util.MinecraftDispatcher
|
import moe.nea.firmament.util.MinecraftDispatcher
|
||||||
import moe.nea.firmament.util.SkyblockId
|
import moe.nea.firmament.util.SkyblockId
|
||||||
@@ -54,12 +52,6 @@ object RepoManager {
|
|||||||
|
|
||||||
var recentlyFailedToUpdateItemList = false
|
var recentlyFailedToUpdateItemList = false
|
||||||
|
|
||||||
val progressBar by lazy {
|
|
||||||
ProgressBar("", null, 0).also {
|
|
||||||
it.setSize(180, 22)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val neuRepo: NEURepository = NEURepository.of(RepoDownloadManager.repoSavedLocation).apply {
|
val neuRepo: NEURepository = NEURepository.of(RepoDownloadManager.repoSavedLocation).apply {
|
||||||
registerReloadListener(ItemCache)
|
registerReloadListener(ItemCache)
|
||||||
registerReloadListener(ExpLadders)
|
registerReloadListener(ExpLadders)
|
||||||
@@ -98,14 +90,13 @@ object RepoManager {
|
|||||||
|
|
||||||
fun launchAsyncUpdate(force: Boolean = false) {
|
fun launchAsyncUpdate(force: Boolean = false) {
|
||||||
Firmament.coroutineScope.launch {
|
Firmament.coroutineScope.launch {
|
||||||
progressBar.reportProgress("Downloading", 0, null)
|
ItemCache.ReloadProgressHud.reportProgress("Downloading", 0, -1) // TODO: replace with a proper boundy bar
|
||||||
CottonHud.add(progressBar)
|
ItemCache.ReloadProgressHud.isEnabled = true
|
||||||
try {
|
try {
|
||||||
RepoDownloadManager.downloadUpdate(force)
|
RepoDownloadManager.downloadUpdate(force)
|
||||||
progressBar.reportProgress("Download complete", 1, 1)
|
ItemCache.ReloadProgressHud.reportProgress("Download complete", 1, 1)
|
||||||
} finally {
|
} finally {
|
||||||
CottonHud.remove(progressBar)
|
ItemCache.ReloadProgressHud.isEnabled = false
|
||||||
|
|
||||||
}
|
}
|
||||||
reload()
|
reload()
|
||||||
}
|
}
|
||||||
@@ -113,14 +104,14 @@ object RepoManager {
|
|||||||
|
|
||||||
fun reload() {
|
fun reload() {
|
||||||
try {
|
try {
|
||||||
progressBar.reportProgress("Reloading from Disk", 0, null)
|
ItemCache.ReloadProgressHud.reportProgress("Reloading from Disk", 0, -1) // TODO: replace with a proper boundy bar
|
||||||
CottonHud.add(progressBar)
|
ItemCache.ReloadProgressHud.isEnabled = true
|
||||||
neuRepo.reload()
|
neuRepo.reload()
|
||||||
} catch (exc: NEURepositoryException) {
|
} catch (exc: NEURepositoryException) {
|
||||||
MinecraftClient.getInstance().player?.sendMessage(
|
MinecraftClient.getInstance().player?.sendMessage(
|
||||||
Text.literal("Failed to reload repository. This will result in some mod features not working.")
|
Text.literal("Failed to reload repository. This will result in some mod features not working.")
|
||||||
)
|
)
|
||||||
CottonHud.remove(progressBar)
|
ItemCache.ReloadProgressHud.isEnabled = false
|
||||||
exc.printStackTrace()
|
exc.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,21 +11,22 @@ import kotlin.math.absoluteValue
|
|||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
||||||
object FirmFormatters {
|
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
|
val α = long / 1000
|
||||||
if (α != 0L) {
|
if (α != 0L) {
|
||||||
return formatCurrency(α, segments) + "," + (long - α * 1000).toString().padStart(3, '0')
|
return formatCommas(α, segments) + "," + (long - α * 1000).toString().padStart(3, '0')
|
||||||
}
|
}
|
||||||
return long.toString()
|
return long.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun formatCurrency(float: Float, fractionalDigits: Int): String = formatCurrency(float.toDouble(), fractionalDigits)
|
fun formatCommas(float: Float, fractionalDigits: Int): String = formatCommas(float.toDouble(), fractionalDigits)
|
||||||
fun formatCurrency(double: Double, fractionalDigits: Int): String {
|
fun formatCommas(double: Double, fractionalDigits: Int): String {
|
||||||
val long = double.toLong()
|
val long = double.toLong()
|
||||||
val δ = (double - long).absoluteValue
|
val δ = (double - long).absoluteValue
|
||||||
val μ = pow(10, fractionalDigits)
|
val μ = pow(10, fractionalDigits)
|
||||||
val digits = (μ * δ).toInt().toString().padStart(fractionalDigits, '0').trimEnd('0')
|
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 {
|
fun formatDistance(distance: Double): String {
|
||||||
@@ -34,8 +35,29 @@ object FirmFormatters {
|
|||||||
return "%dm".format(distance.toInt())
|
return "%dm".format(distance.toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun formatTimespan(duration: Duration): String {
|
fun formatTimespan(duration: Duration, millis: Boolean = false): String {
|
||||||
return duration.toString()
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,9 +77,9 @@ object MoulConfigUtils {
|
|||||||
override fun createInstance(context: XMLContext<*>, element: Element): FirmButtonComponent {
|
override fun createInstance(context: XMLContext<*>, element: Element): FirmButtonComponent {
|
||||||
return FirmButtonComponent(
|
return FirmButtonComponent(
|
||||||
context.getChildFragment(element),
|
context.getChildFragment(element),
|
||||||
context.getMethodFromAttribute(element, QName("onClick")),
|
|
||||||
context.getPropertyFromAttribute(element, QName("enabled"), Boolean::class.java)
|
context.getPropertyFromAttribute(element, QName("enabled"), Boolean::class.java)
|
||||||
?: GetSetter.constant(true)
|
?: GetSetter.constant(true),
|
||||||
|
context.getMethodFromAttribute(element, QName("onClick")),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
src/main/resources/assets/firmament/gui/repo_reload.xml
Normal file
14
src/main/resources/assets/firmament/gui/repo_reload.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
-->
|
||||||
|
|
||||||
|
<Root xmlns="http://notenoughupdates.org/moulconfig" xmlns:firm="http://firmament.nea.moe/moulconfig">
|
||||||
|
<Row>
|
||||||
|
<firm:Bar progress="@current" total="@max" emptyColor="#30ff30" fillColor="#30aa30"/>
|
||||||
|
<Text text="@label"/>
|
||||||
|
</Row>
|
||||||
|
</Root>
|
||||||
@@ -97,6 +97,7 @@
|
|||||||
"firmament.config.waypoints": "Waypoints",
|
"firmament.config.waypoints": "Waypoints",
|
||||||
"firmament.config.waypoints.temp-waypoint-duration": "Temporary Waypoint Duration",
|
"firmament.config.waypoints.temp-waypoint-duration": "Temporary Waypoint Duration",
|
||||||
"firmament.config.waypoints.show-index": "Show ordered waypoint indexes",
|
"firmament.config.waypoints.show-index": "Show ordered waypoint indexes",
|
||||||
|
"firmament.config.waypoints.skip-to-nearest": "Allow skipping waypoints",
|
||||||
"firmament.recipe.forge.time": "Forging Time: %s",
|
"firmament.recipe.forge.time": "Forging Time: %s",
|
||||||
"firmament.recipe.mobs.drops": "§e§lDrop Chance: %s",
|
"firmament.recipe.mobs.drops": "§e§lDrop Chance: %s",
|
||||||
"firmament.recipe.mobs.name": "§8[§7Lv %d§8] §c%s",
|
"firmament.recipe.mobs.name": "§8[§7Lv %d§8] §c%s",
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
@@ -15,3 +15,4 @@ accessible field net/minecraft/entity/passive/AbstractHorseEntity items Lnet/min
|
|||||||
accessible field net/minecraft/entity/passive/AbstractHorseEntity SADDLED_FLAG I
|
accessible field net/minecraft/entity/passive/AbstractHorseEntity SADDLED_FLAG I
|
||||||
accessible field net/minecraft/entity/passive/AbstractHorseEntity HORSE_FLAGS Lnet/minecraft/entity/data/TrackedData;
|
accessible field net/minecraft/entity/passive/AbstractHorseEntity HORSE_FLAGS Lnet/minecraft/entity/data/TrackedData;
|
||||||
accessible method net/minecraft/resource/NamespaceResourceManager loadMetadata (Lnet/minecraft/resource/InputSupplier;)Lnet/minecraft/resource/metadata/ResourceMetadata;
|
accessible method net/minecraft/resource/NamespaceResourceManager loadMetadata (Lnet/minecraft/resource/InputSupplier;)Lnet/minecraft/resource/metadata/ResourceMetadata;
|
||||||
|
accessible method net/minecraft/client/gui/DrawContext drawTexturedQuad (Lnet/minecraft/util/Identifier;IIIIIFFFFFFFF)V
|
||||||
|
|||||||
Reference in New Issue
Block a user