mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-16 10:55:01 -04:00
text wrapping
This commit is contained in:
parent
69ae387d0b
commit
e70efd2c20
@ -20,9 +20,10 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
|||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
|
|
||||||
object BaseComponentRenderer : ChatComponentRenderer<BaseComponent> {
|
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) {
|
for (part in text.parts) {
|
||||||
ChatComponentRenderer.render(offset, z, element, renderWindow, consumer, part)
|
ChatComponentRenderer.render(initialOffset, offset, size, z, element, renderWindow, consumer, part)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,15 +23,15 @@ import glm_.vec2.Vec2i
|
|||||||
|
|
||||||
interface ChatComponentRenderer<T : ChatComponent> {
|
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> {
|
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) {
|
when (text) {
|
||||||
is BaseComponent -> BaseComponentRenderer.render(offset, z, element, renderWindow, consumer, text)
|
is BaseComponent -> BaseComponentRenderer.render(initialOffset, offset, size, z, element, renderWindow, consumer, text)
|
||||||
is TextComponent -> TextComponentRenderer.render(offset, 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}")
|
else -> TODO("Don't know how to render ${text::class.java}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,53 @@ import glm_.vec2.Vec2i
|
|||||||
|
|
||||||
object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
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
|
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()) {
|
for (char in text.message.toCharArray()) {
|
||||||
if (char == '\n') {
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,17 +79,26 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
|||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false
|
first = false
|
||||||
} else {
|
} else if (offset.x != initialOffset.x && add(Font.HORIZONTAL_SPACING)) {
|
||||||
offset.x += 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)
|
charData.render(offset, z, text, consumer)
|
||||||
|
|
||||||
offset.x += charData.calculateWidth(text)
|
if (add(width)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text.formatting.contains(PreChatFormattingCodes.ITALIC)) {
|
if (text.formatting.contains(PreChatFormattingCodes.ITALIC)) {
|
||||||
offset.x += CharData.ITALIC_OFFSET.ceil
|
val italicOffset = CharData.ITALIC_OFFSET.ceil
|
||||||
|
offset.x += italicOffset
|
||||||
|
size.x += italicOffset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ import glm_.vec2.Vec2i
|
|||||||
abstract class Element {
|
abstract class Element {
|
||||||
open var prepared: Boolean = false
|
open var prepared: Boolean = false
|
||||||
|
|
||||||
open var minSize: Vec2i = Vec2i()
|
open var minSize: Vec2i = Vec2i(10, 10)
|
||||||
open var maxSize: Vec2i = Vec2i()
|
open var maxSize: Vec2i = Vec2i(50, 50)
|
||||||
open var size: Vec2i = Vec2i()
|
open var size: Vec2i = Vec2i()
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ class TextElement(
|
|||||||
|
|
||||||
|
|
||||||
override fun render(offset: Vec2i, z: Int, consumer: GUIVertexConsumer): Int {
|
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
|
return LAYERS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,26 @@ class HUDRenderer(
|
|||||||
text.render(Vec2i(10, 10), 0, mesh)
|
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()
|
mesh.load()
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user