hud: add support for colored text

This commit is contained in:
Lukas 2021-07-02 19:08:25 +02:00
parent f2c37d5a0a
commit ad9f8cade5
3 changed files with 28 additions and 13 deletions

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2021 Moritz Zwerger
* Copyright (C) 2021 Moritz Zwerger, Lukas Eisenhauer
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -59,6 +59,7 @@ class BaseComponent : ChatComponent {
ChatColors.VALUES.getOrNull(Character.digit(formattingChar, 16))?.let {
push()
currentColor = it
} ?: ChatFormattingCodes.getChatFormattingCodeByChar(formattingChar)?.let {
push()

View File

@ -35,10 +35,10 @@ class HUDImageElement: HUDElement {
tint = ChatColors.WHITE
}
constructor(position: HUDElementPosition, size: HUDElementVec2, z: Int, texture: TextureLike): super(position, size, z) {
constructor(position: HUDElementPosition, size: HUDElementVec2, z: Int, texture: TextureLike, tint: RGBColor?): super(position, size, z) {
textureName = null
this.texture = texture
tint = ChatColors.WHITE
this.tint = tint ?: ChatColors.WHITE
}
override fun init(hudRenderer: HUDRenderer) {

View File

@ -15,7 +15,9 @@
package de.bixilon.minosoft.gui.rendering.hud.elements.text
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.RGBColor
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.gui.rendering.font.Font
import de.bixilon.minosoft.gui.rendering.hud.HUDMenus
@ -49,15 +51,28 @@ class HUDTextElement : HUDElement {
}
private fun renderChatComponent(chatComponent: ChatComponent) {
val chars = chatComponent.message.toCharArray()
elements.clear()
val newLinePositions = addChars(chars)
val newLinePositions = mutableListOf<Int>()
addChatComponent(chatComponent, newLinePositions)
newLinePositions += elements.size
adjustPositionsForLineBreaks(newLinePositions)
}
private fun addChars(chars: CharArray): MutableList<Int> {
private fun addChatComponent(chatComponent: ChatComponent, newLinePositions: MutableList<Int>) {
when (chatComponent) {
is BaseComponent -> {
for (part in chatComponent.parts) {
addChatComponent(part, newLinePositions)
}
}
is TextComponent -> {
addChars(chatComponent.message.toCharArray(), chatComponent.color, newLinePositions)
}
}
}
private fun addChars(chars: CharArray, color: RGBColor?, newLinePositions: MutableList<Int>): MutableList<Int> {
var lastElement: HUDElement? = null
val newLinePositions = mutableListOf<Int>()
val maxRight = getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_RIGHT).x
val bottomLeftPosition = getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_LEFT).toVec2
for (char in chars) {
@ -76,7 +91,7 @@ class HUDTextElement : HUDElement {
val newElement = if (char == ' ') {
HUDSpacerElement(elementPosition, elementSize, z)
} else {
HUDImageElement(elementPosition, elementSize, z, fontChar)
HUDImageElement(elementPosition, elementSize, z, fontChar, tint = color)
}
elements += newElement
newElement.init(hudRenderer)
@ -91,7 +106,6 @@ class HUDTextElement : HUDElement {
elements[relevantIndex].position = HUDElementPosition(HUDElementVec2(bottomLeftPosition, HUDElementPositionUnits.PIXELS), HUDElementPositionAnchors.BOTTOM_LEFT)
}
}
newLinePositions += elements.size
return newLinePositions
}
@ -114,13 +128,13 @@ class HUDTextElement : HUDElement {
private fun adjustPositionsForLineBreaks(newLinePositions: MutableList<Int>) {
var y = when (alignment) {
HUDElementPositionAnchors.TOP_LEFT, HUDElementPositionAnchors.BOTTOM_LEFT -> getPositionAtAnchor(HUDElementPositionAnchors.TOP_LEFT).y
HUDElementPositionAnchors.TOP_RIGHT, HUDElementPositionAnchors.BOTTOM_RIGHT -> getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_RIGHT).y - (newLinePositions.size-2) * (Font.CHAR_HEIGHT+1) * Minosoft.getConfig().config.game.hud.scale.toInt()
HUDElementPositionAnchors.TOP_RIGHT, HUDElementPositionAnchors.BOTTOM_RIGHT -> getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_RIGHT).y - (newLinePositions.size - 2) * (Font.CHAR_HEIGHT + 1) * Minosoft.getConfig().config.game.hud.scale.toInt()
else -> TODO()
}
val left = getPositionAtAnchor(HUDElementPositionAnchors.TOP_LEFT).x
val right = glm.min(hudRenderer.renderWindow.screenDimensions.x, getPositionAtAnchor(HUDElementPositionAnchors.BOTTOM_RIGHT).x)
for (i in 0 until newLinePositions.size-1) {
elements[newLinePositions[i]].position = alignment.textAlignmentTransform.invoke(left, right, y, elements[newLinePositions[i+1] - 1])
for (i in 0 until newLinePositions.lastIndex) {
elements[newLinePositions[i]].position = alignment.textAlignmentTransform.invoke(left, right, y, elements[newLinePositions[i + 1] - 1])
y += ((Font.CHAR_HEIGHT + 1) * Minosoft.getConfig().config.game.hud.scale).toInt()
}
}
@ -132,7 +146,7 @@ class HUDTextElement : HUDElement {
}
override fun prepare(matrix: Mat4) {
renderChatComponent(TextComponent(contents))
renderChatComponent(BaseComponent(null, contents))
for (element in elements) {
element.prepare(matrix)
}