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 * 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. * 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 { ChatColors.VALUES.getOrNull(Character.digit(formattingChar, 16))?.let {
push() push()
currentColor = it
} ?: ChatFormattingCodes.getChatFormattingCodeByChar(formattingChar)?.let { } ?: ChatFormattingCodes.getChatFormattingCodeByChar(formattingChar)?.let {
push() push()

View File

@ -35,10 +35,10 @@ class HUDImageElement: HUDElement {
tint = ChatColors.WHITE 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 textureName = null
this.texture = texture this.texture = texture
tint = ChatColors.WHITE this.tint = tint ?: ChatColors.WHITE
} }
override fun init(hudRenderer: HUDRenderer) { override fun init(hudRenderer: HUDRenderer) {

View File

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