text wrapping

This commit is contained in:
Bixilon 2021-08-04 22:18:11 +02:00
parent 69ae387d0b
commit e70efd2c20
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
6 changed files with 87 additions and 15 deletions

View File

@ -20,9 +20,10 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import glm_.vec2.Vec2i
object BaseComponentRenderer : ChatComponentRenderer<BaseComponent> {
override fun render(offset: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: BaseComponent) {
override fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: BaseComponent) {
for (part in text.parts) {
ChatComponentRenderer.render(offset, z, element, renderWindow, consumer, part)
ChatComponentRenderer.render(initialOffset, offset, size, z, element, renderWindow, consumer, part)
}
}
}

View File

@ -23,15 +23,15 @@ import glm_.vec2.Vec2i
interface ChatComponentRenderer<T : ChatComponent> {
fun render(offset: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: T)
fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: T)
companion object : ChatComponentRenderer<ChatComponent> {
override fun render(offset: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: ChatComponent) {
override fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: ChatComponent) {
when (text) {
is BaseComponent -> BaseComponentRenderer.render(offset, z, element, renderWindow, consumer, text)
is TextComponent -> TextComponentRenderer.render(offset, z, element, renderWindow, consumer, text)
is BaseComponent -> BaseComponentRenderer.render(initialOffset, offset, size, z, element, renderWindow, consumer, text)
is TextComponent -> TextComponentRenderer.render(initialOffset, offset, size, z, element, renderWindow, consumer, text)
else -> TODO("Don't know how to render ${text::class.java}")
}
}

View File

@ -25,11 +25,53 @@ import glm_.vec2.Vec2i
object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
override fun render(offset: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: TextComponent) {
override fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, z: Int, element: LabeledElement, renderWindow: RenderWindow, consumer: GUIVertexConsumer, text: TextComponent) {
var first = true
/**
* @return If the text can't fit into the layout anymore
*/
fun wrap(): Boolean {
val yAdd = Font.CHAR_HEIGHT + Font.VERTICAL_SPACING
if (size.y + yAdd > element.maxSize.y) {
return true
}
offset.x = initialOffset.x
offset.y += yAdd
size.y += yAdd
return false
}
/**
* @return If the text can't fit into the layout anymore
*/
fun add(x: Int): Boolean {
if (offset.x - initialOffset.x + x > element.maxSize.x) {
if (wrap()) {
return true
}
} else {
offset.x += x
}
if (size.x < offset.x - initialOffset.x) {
size.x += x
}
return false
}
for (char in text.message.toCharArray()) {
if (char == '\n') {
offset.y += Font.CHAR_HEIGHT + Font.VERTICAL_SPACING
if (wrap()) {
return
}
continue
}
// skip wrapped spaces
if (offset.y != initialOffset.y && offset.x == initialOffset.x && char == ' ') {
continue
}
@ -37,17 +79,26 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
if (first) {
first = false
} else {
offset.x += Font.HORIZONTAL_SPACING
} else if (offset.x != initialOffset.x && add(Font.HORIZONTAL_SPACING)) {
return
}
val width = charData.calculateWidth(text)
if (offset.x == initialOffset.x && offset.x - initialOffset.x + width > element.maxSize.x) {
return
}
charData.render(offset, z, text, consumer)
offset.x += charData.calculateWidth(text)
if (add(width)) {
return
}
}
if (text.formatting.contains(PreChatFormattingCodes.ITALIC)) {
offset.x += CharData.ITALIC_OFFSET.ceil
val italicOffset = CharData.ITALIC_OFFSET.ceil
offset.x += italicOffset
size.x += italicOffset
}
}
}

View File

@ -19,8 +19,8 @@ import glm_.vec2.Vec2i
abstract class Element {
open var prepared: Boolean = false
open var minSize: Vec2i = Vec2i()
open var maxSize: Vec2i = Vec2i()
open var minSize: Vec2i = Vec2i(10, 10)
open var maxSize: Vec2i = Vec2i(50, 50)
open var size: Vec2i = Vec2i()

View File

@ -38,7 +38,7 @@ class TextElement(
override fun render(offset: Vec2i, z: Int, consumer: GUIVertexConsumer): Int {
ChatComponentRenderer.render(offset, z, this, renderWindow, consumer, textComponent)
ChatComponentRenderer.render(Vec2i(offset), offset, Vec2i(0, 0), z, this, renderWindow, consumer, textComponent)
return LAYERS
}

View File

@ -80,6 +80,26 @@ class HUDRenderer(
text.render(Vec2i(10, 10), 0, mesh)
}
val text2 = TextElement(
renderWindow = renderWindow,
text = TextComponent(
message = "Moritz\nist toll!!!",
color = ChatColors.BLUE,
formatting = mutableSetOf(
PreChatFormattingCodes.BOLD,
PreChatFormattingCodes.SHADOWED,
PreChatFormattingCodes.UNDERLINED,
PreChatFormattingCodes.ITALIC,
PreChatFormattingCodes.STRIKETHROUGH,
PreChatFormattingCodes.OBFUSCATED
),
),
)
if (!text2.prepared) {
text2.render(Vec2i(10, 60), 0, mesh)
}
mesh.load()