Skip to content

Commit

Permalink
Change console output for legibility
Browse files Browse the repository at this point in the history
Container width/height x/y swap fix
InventoryWidget
  • Loading branch information
ATPStorages committed Aug 28, 2024
1 parent 9432bb7 commit cc232ec
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package breadmod.client.screen.sound_block

import breadmod.ModMain.DATA_DIR
import breadmod.ModMain.modLocation
import breadmod.menu.block.SoundBlockMenu
import breadmod.util.gui.SerializedScreenFactory
import breadmod.util.gui.widget.BackgroundWidget
import breadmod.util.gui.widget.ContainerWidget
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory
Expand All @@ -11,11 +13,17 @@ internal object SoundBlockScreenFactory : SerializedScreenFactory<SoundBlockMenu
DATA_DIR.resolve("sound_block_screen.json")
) {
override fun default(): ContainerWidget = ContainerWidget(
600, 600,
0, 0,
176, 166,
0f,
Component.empty(),
mutableMapOf()
mutableMapOf(
BackgroundWidget.TexturedBackgroundWidget(
0, 0,
176, 166,
modLocation("textures", "gui", "container", "sound_block.png")
) to (0.0 to "background")
)
)

override fun create(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package breadmod.client.screen.sound_block

import breadmod.ModMain.modLocation
import breadmod.menu.block.SoundBlockMenu
import breadmod.util.gui.SerializedScreen
import breadmod.util.gui.widget.ContainerWidget
import breadmod.util.gui.widget.SlotWidget
import breadmod.util.gui.widget.InventoryWidget
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory
Expand All @@ -15,35 +14,22 @@ internal class SoundBlockSerializedScreen(
pTitle: Component,
rootWidget: ContainerWidget
) : SerializedScreen<SoundBlockMenu>(pMenu, pInventory, pTitle, rootWidget) {
private val texture = modLocation("textures", "gui", "container", "sound_block.png")
private val imageWidth = 176
private val imageHeight = 166

/**
* Renders this [SoundBlockSerializedScreen].
* @author Logan McLean (implementation), Miko Elbrecht (javadoc)
* @since 1.0.0
*/
override fun render(pGuiGraphics: GuiGraphics, pMouseX: Int, pMouseY: Int, pPartialTick: Float) {
renderBackground(pGuiGraphics)
pGuiGraphics.blit(texture, rootWidget.x, rootWidget.y, 0, 0, 176, 166)
super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick)
}

override fun tick() {
rootWidget.tick()
}

override fun init() {
super.init()
rootWidget.x = (width - imageWidth) / 2
rootWidget.y = (height - imageHeight) / 2
}
val image = rootWidget.getTaggedWidget("background")
rootWidget.x = (width - image.width) / 2
rootWidget.y = (height - image.height) / 2

init {
for (rI in 3 downTo 0) repeat(9) { cI ->
val linear = rI * 9 + cI
rootWidget.addWidget(SlotWidget(cI * 16, rI * 16, pInventory.getItem(linear)), 0.0)
}
rootWidget.addWidget(InventoryWidget(4, 35, pInventory), 0.0, "inventory")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ internal object ToolGunCreatorSpawnMenuFactory : SerializedScreenFactory<ToolGun
internal var lastSaved: String? = null

override fun default(): ContainerWidget = ContainerWidget(
600, 600,
0, 0,
600, 600,
0f,
Component.empty(),
mutableMapOf(
Expand Down Expand Up @@ -64,18 +64,18 @@ internal object ToolGunCreatorSpawnMenuFactory : SerializedScreenFactory<ToolGun
28, 28,
304, 144,
Color(0f, 0f, 0f, 0.1f)
) to 0.0,
) to (0.0 to null),
BackgroundWidget.SolidColorBackgroundWidget(
29, 29,
302, 142,
Color(0f, 0f, 0f, 0.1f)
) to 0.1,
) to (0.1 to null),
TextWidget(
31, 31,
300, rgMinecraft.font.lineHeight,
Component.literal("Test"),
pCentering = TextWidget.CenteringType.NONE
) to 0.2
) to (0.2 to null)
)
)

Expand Down
50 changes: 48 additions & 2 deletions src/main/kotlin/breadmod/logging/ConsoleColorAppender.kt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ class ConsoleColorAppender(
// const val MAGENTA = 5
const val CYAN = 6
const val WHITE = 7

private val threadColors = mutableMapOf<String, Pair<String, List<Int>>>()
private var lastThreadColor: String? = null
}

private val colors = mapOf(
Expand All @@ -82,6 +85,50 @@ class ConsoleColorAppender(
return new
}

private fun String.getColorForString(): String {
val color = threadColors[this]
if (color != null) return color.first
else {
val last = threadColors[lastThreadColor]
lastThreadColor = this

val new =
if (last == null)
(((ESC + (FOREGROUND + RED) + END) + this) + ESC + RESET + END) to mutableListOf(FOREGROUND + RED)
else {
val newLast = last.second.toMutableList()
newLast[0] += 1
for (index in 0..newLast.size) {
val current = newLast.getOrNull(index) ?: break

if (current >= (FOREGROUND + BRIGHT + WHITE)) {
newLast[index] = FOREGROUND + RED
if (newLast.size == index + 1) newLast.add(FOREGROUND + RED)
else newLast[index + 1] += 1
} else if (current < (FOREGROUND + BRIGHT + RED) && current >= (FOREGROUND + WHITE)) {
newLast[index] = FOREGROUND + BRIGHT + RED
if (newLast.size == index + 1) newLast.add(FOREGROUND + RED)
else newLast[index + 1] += 1
} else break
}

var newStr = ""
for (index in this.indices) {
val localColor = newLast.getOrNull(index)
if (localColor != null) newStr += ESC + localColor + END + this[index]
else {
newStr += this.slice(index..<this.length)
break
}
}
(newStr + ESC + RESET + END) to newLast
}

threadColors[this] = new
return new.first
}
}

/**
* Acts upon a given [LogEvent] for colorization.
* @author Miko Elbrecht
Expand All @@ -98,8 +145,7 @@ class ConsoleColorAppender(

val prepend = "[${ESC + (FOREGROUND + BRIGHT + BLUE) + END}${formattedTime}${ESC + RESET + END}" +
"/${colors[event.level.standardLevel]}${event.level.toString().padEnd(5)}${ESC + RESET + END}] " +
"[${ESC + (FOREGROUND + GREEN) + END}${event.threadName}${ESC + RESET + END}/" +
"${ESC + (FOREGROUND + CYAN) + END}${event.loggerName}${ESC + RESET + END}]"
"[${event.threadName.getColorForString()}/" + "${event.loggerName.getColorForString()}]"

event.thrownProxy.let {
val prependStrippedLength = prepend.replace(Regex("\u001B\\[.+?m"), "").length
Expand Down
21 changes: 21 additions & 0 deletions src/main/kotlin/breadmod/util/gui/SerializedScreen.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package breadmod.util.gui

import breadmod.ModMain.LOGGER
import breadmod.util.gui.widget.ContainerWidget
import net.minecraft.client.gui.screens.Screen
import net.minecraft.client.gui.screens.inventory.MenuAccess
Expand Down Expand Up @@ -50,4 +51,24 @@ open class SerializedScreen<T : AbstractContainerMenu>(
* @since 1.0.0
*/
override fun getMenu(): T = pMenu

/**
* Pushes mouse inputs to the provided [rootWidget].
* @param pMouseX The X position of the mouse.
* @param pMouseY The Y position of the mouse.
* @param pButton The button on the mouse that was clicked.
* @return Whether the mouse click was handled by the [rootWidget].
* @author Miko Elbrecht
* @since 1.0.0
*/
override fun mouseClicked(pMouseX: Double, pMouseY: Double, pButton: Int): Boolean {
LOGGER.info("Mouse clicked at $pMouseX, $pMouseY with button $pButton")
LOGGER.info("Root widget at ${rootWidget.x}, ${rootWidget.y} with size ${rootWidget.width}, ${rootWidget.height}")

if (
pMouseX >= rootWidget.x && pMouseY >= rootWidget.y &&
pMouseX <= (rootWidget.width + rootWidget.x) && pMouseY <= (rootWidget.height + rootWidget.y)
) return rootWidget.mouseClicked(pMouseX, pMouseY, pButton)
return false
}
}
28 changes: 27 additions & 1 deletion src/main/kotlin/breadmod/util/gui/widget/BackgroundWidget.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import net.minecraft.client.gui.components.AbstractWidget
import net.minecraft.client.gui.narration.NarrationElementOutput
import net.minecraft.client.renderer.RenderType
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import java.awt.Color

/**
Expand Down Expand Up @@ -46,12 +47,37 @@ abstract class BackgroundWidget private constructor(
private val pRenderType: RenderType = RenderType.gui()
) : BackgroundWidget(pX, pY, pWidth, pHeight) {
/**
* Renders this [TextWidget].
* Renders this [SolidColorBackgroundWidget].
* @author Miko Elbrecht
* @since 1.0.0
*/
override fun renderWidget(pGuiGraphics: GuiGraphics, pMouseX: Int, pMouseY: Int, pPartialTick: Float) {
pGuiGraphics.fill(pRenderType, 0, 0, width, height, pColor.rgb)
}
}

/**
* A light widget that renders a textured background 1:1 with the size of the widget.
* @param pX The X position of the widget.
* @param pY The Y position of the widget.
* @param pWidth The width of the widget.
* @param pHeight The height of the widget.
* @param pTexture The texture of the background
* @author Miko Elbrecht
* @since 1.0.0
*/
class TexturedBackgroundWidget(
pX: Int, pY: Int,
pWidth: Int, pHeight: Int,
private val pTexture: ResourceLocation
) : BackgroundWidget(pX, pY, pWidth, pHeight) {
/**
* Renders this [TexturedBackgroundWidget].
* @author Miko Elbrecht
* @since 1.0.0
*/
override fun renderWidget(pGuiGraphics: GuiGraphics, pMouseX: Int, pMouseY: Int, pPartialTick: Float) {
pGuiGraphics.blit(pTexture, 0, 0, 0, 0, width, height)
}
}
}
62 changes: 33 additions & 29 deletions src/main/kotlin/breadmod/util/gui/widget/ContainerWidget.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.*
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.components.AbstractWidget
import net.minecraft.client.gui.components.EditBox
import net.minecraft.client.gui.narration.NarratedElementType
import net.minecraft.client.gui.narration.NarrationElementOutput
import net.minecraft.network.chat.Component
import org.joml.Matrix4f
import kotlin.math.roundToInt

/**
* A widget that can contain other widgets.
Expand All @@ -28,19 +27,21 @@ import org.joml.Matrix4f
* @since 1.0
*/
@Serializable(with = ContainerWidget.Serializer::class)
class ContainerWidget(
pWidth: Int, pHeight: Int,
open class ContainerWidget(
pX: Int, pY: Int,
pWidth: Int, pHeight: Int,
private val pTilt: Float,
pComponent: Component,
private val childrenWidgets: MutableMap<AbstractWidget, Double>
) : AbstractWidget(pWidth, pHeight, pX, pY, pComponent) {
private val childrenWidgets: MutableMap<AbstractWidget, Pair<Double, String?>>
) : AbstractWidget(pX, pY, pWidth, pHeight, pComponent) {
private val associationMap: MutableMap<String, AbstractWidget> = mutableMapOf()

internal object Serializer : KSerializer<ContainerWidget> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("ContainerWidget") {
element<Int>("width")
element<Int>("height")
element<Int>("x")
element<Int>("y")
element<Int>("width")
element<Int>("height")
element<Int>("tilt")
element<Component>("component")
element<List<AbstractWidget>>("widgets")
Expand All @@ -50,10 +51,10 @@ class ContainerWidget(
require(decoder is JsonDecoder)
val element = decoder.decodeJsonElement() as JsonObject
return ContainerWidget(
decoder.json.decodeFromJsonElement(element["width"]!!),
decoder.json.decodeFromJsonElement(element["height"]!!),
decoder.json.decodeFromJsonElement(element["x"]!!),
decoder.json.decodeFromJsonElement(element["y"]!!),
decoder.json.decodeFromJsonElement(element["width"]!!),
decoder.json.decodeFromJsonElement(element["height"]!!),
decoder.json.decodeFromJsonElement(element["tilt"]!!),
decoder.json.decodeFromJsonElement(element["component"]!!),
decoder.json.decodeFromJsonElement(element["widgets"]!!),
Expand All @@ -63,16 +64,20 @@ class ContainerWidget(
override fun serialize(encoder: Encoder, value: ContainerWidget) {
require(encoder is JsonEncoder)
encoder.encodeJsonElement(buildJsonObject {
put("width", json.encodeToJsonElement(value.width))
put("height", json.encodeToJsonElement(value.height))
put("x", json.encodeToJsonElement(value.x))
put("y", json.encodeToJsonElement(value.y))
put("width", json.encodeToJsonElement(value.width))
put("height", json.encodeToJsonElement(value.height))
put("component", json.encodeToJsonElement(value.message))
putJsonArray("widgets") { value.childrenWidgets.forEach { add(json.encodeToJsonElement(it)) } }
})
}
}

init {
childrenWidgets.forEach { (widget, pair) -> pair.second?.let { associationMap[it] = widget } }
}

/**
* Adds a widget to this container.
* @return This container.
Expand All @@ -81,31 +86,30 @@ class ContainerWidget(
* @author Miko Elbrecht
* @since 1.0
*/
fun addWidget(pWidget: AbstractWidget, pZIndex: Double): ContainerWidget = this.also {
childrenWidgets[pWidget] = pZIndex
fun addWidget(pWidget: AbstractWidget, pZIndex: Double, pTag: String): ContainerWidget = this.also {
childrenWidgets[pWidget] = pZIndex to pTag
associationMap[pTag] = pWidget
}

fun getTaggedWidget(pTag: String) = associationMap[pTag] ?: throw NoSuchElementException("No widget with tag $pTag")

override fun renderWidget(pGuiGraphics: GuiGraphics, pMouseX: Int, pMouseY: Int, pPartialTick: Float) {
val pose = pGuiGraphics.pose()
childrenWidgets.forEach { (widget, z) ->

childrenWidgets.forEach { (widget, pair) ->
pose.pushPose()
pose.translate(this.x + widget.x.toDouble(), this.y + widget.y.toDouble(), z)
val translateX = this.x + widget.x.toDouble()
val translateY = this.y + widget.y.toDouble()
pose.translate(translateX, translateY, pair.first)
pose.mulPoseMatrix(Matrix4f().rotateZ(pTilt))
widget.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick)
pose.popPose()
}
}
val mouseX = (pMouseX - translateX).roundToInt()
val mouseY = (pMouseY - translateY).roundToInt()

// does this run every game tick or frame tick??
fun tick() {
childrenWidgets.forEach { (widget, _) ->
if (widget is EditBox) widget.tick()
}
}
widget.render(pGuiGraphics, mouseX, mouseY, pPartialTick)

override fun updateWidgetNarration(pNarrationElementOutput: NarrationElementOutput) {
pNarrationElementOutput.add(NarratedElementType.TITLE, "w43")
pose.popPose()
}
}

override fun clicked(pMouseX: Double, pMouseY: Double): Boolean = false
override fun updateWidgetNarration(pNarrationElementOutput: NarrationElementOutput) {}
}
Loading

0 comments on commit cc232ec

Please sign in to comment.