refactor TextElement

does improve the gui api a lot, still a lot of things broken
This commit is contained in:
Bixilon 2023-06-13 23:45:13 +02:00
parent 025505074e
commit 72ebb2303d
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
38 changed files with 234 additions and 232 deletions

View File

@ -5,7 +5,7 @@ import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.gui.rendering.font.manager.FontManager
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextLineInfo
import de.bixilon.minosoft.gui.rendering.font.renderer.element.LineRenderInfo
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextOffset
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderInfo
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
@ -29,7 +29,7 @@ class ChatComponentRendererTest {
private fun TextRenderInfo.assert(
lineIndex: Int? = null,
lines: List<TextLineInfo>? = null,
lines: List<LineRenderInfo>? = null,
size: Vec2? = null,
cutOff: Boolean = false,
) {
@ -53,7 +53,7 @@ class ChatComponentRendererTest {
val info = render(TextComponent("b"))
info.assert(
lineIndex = 0,
lines = listOf(TextLineInfo(BaseComponent(TextComponent("b")), 0.5f)),
lines = listOf(LineRenderInfo(BaseComponent(TextComponent("b")), 0.5f)),
size = Vec2(0.5f, 11.0f),
)
}
@ -62,7 +62,7 @@ class ChatComponentRendererTest {
val info = render(TextComponent("bc"))
info.assert(
lineIndex = 0,
lines = listOf(TextLineInfo(BaseComponent(TextComponent("bc")), 2.5f)),
lines = listOf(LineRenderInfo(BaseComponent(TextComponent("bc")), 2.5f)),
size = Vec2(2.5f, 11.0f), // b + spacing + c
)
}
@ -71,7 +71,7 @@ class ChatComponentRendererTest {
val info = render(TextComponent("bcd"))
info.assert(
lineIndex = 0,
lines = listOf(TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f)),
lines = listOf(LineRenderInfo(BaseComponent(TextComponent("bcd")), 5.0f)),
size = Vec2(5.0f, 11.0f),
)
}
@ -81,8 +81,8 @@ class ChatComponentRendererTest {
info.assert(
lineIndex = 1,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(TextComponent("ef")), 5.5f),
LineRenderInfo(BaseComponent(TextComponent("bcd")), 5.0f),
LineRenderInfo(BaseComponent(TextComponent("ef")), 5.5f),
),
size = Vec2(5.5f, 22.0f),
)
@ -93,9 +93,9 @@ class ChatComponentRendererTest {
info.assert(
lineIndex = 2,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(TextComponent("ef")), 5.5f),
TextLineInfo(BaseComponent(TextComponent("g")), 3.0f),
LineRenderInfo(BaseComponent(TextComponent("bcd")), 5.0f),
LineRenderInfo(BaseComponent(TextComponent("ef")), 5.5f),
LineRenderInfo(BaseComponent(TextComponent("g")), 3.0f),
),
size = Vec2(5.5f, 33.0f),
)
@ -106,7 +106,7 @@ class ChatComponentRendererTest {
info.assert(
lineIndex = 0,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
LineRenderInfo(BaseComponent(TextComponent("bcd")), 5.0f),
),
size = Vec2(5.0f, 11.0f),
)
@ -117,8 +117,8 @@ class ChatComponentRendererTest {
info.assert(
lineIndex = 1,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(TextComponent("ef")), 5.5f),
LineRenderInfo(BaseComponent(TextComponent("bcd")), 5.0f),
LineRenderInfo(BaseComponent(TextComponent("ef")), 5.5f),
),
size = Vec2(5.5f, 23.0f),
)
@ -129,9 +129,9 @@ class ChatComponentRendererTest {
info.assert(
lineIndex = 2,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(TextComponent("ef")), 5.5f),
TextLineInfo(BaseComponent(TextComponent("g")), 3.0f),
LineRenderInfo(BaseComponent(TextComponent("bcd")), 5.0f),
LineRenderInfo(BaseComponent(TextComponent("ef")), 5.5f),
LineRenderInfo(BaseComponent(TextComponent("g")), 3.0f),
),
size = Vec2(5.5f, 35.0f),
)
@ -142,9 +142,9 @@ class ChatComponentRendererTest {
info.assert(
lineIndex = 2,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(TextComponent("ef")), 5.5f),
TextLineInfo(BaseComponent(TextComponent("g")), 3.0f),
LineRenderInfo(BaseComponent(TextComponent("bcd")), 5.0f),
LineRenderInfo(BaseComponent(TextComponent("ef")), 5.5f),
LineRenderInfo(BaseComponent(TextComponent("g")), 3.0f),
),
size = Vec2(5.5f, 73.0f),
)
@ -155,7 +155,7 @@ class ChatComponentRendererTest {
info.assert(
lineIndex = 1,
lines = listOf(
TextLineInfo(BaseComponent(), 0.0f),
LineRenderInfo(BaseComponent(), 0.0f),
),
size = Vec2(0.0f, 11.0f),
)
@ -166,8 +166,8 @@ class ChatComponentRendererTest {
info.assert(
lineIndex = 1,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("b")), 0.5f),
TextLineInfo(BaseComponent(TextComponent("b")), 0.5f),
LineRenderInfo(BaseComponent(TextComponent("b")), 0.5f),
LineRenderInfo(BaseComponent(TextComponent("b")), 0.5f),
),
size = Vec2(0.5f, 22.0f),
)
@ -178,9 +178,9 @@ class ChatComponentRendererTest {
info.assert(
lineIndex = 2,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(), 0.0f),
TextLineInfo(BaseComponent(TextComponent("efgh")), 14.0f),
LineRenderInfo(BaseComponent(TextComponent("bcd")), 5.0f),
LineRenderInfo(BaseComponent(), 0.0f),
LineRenderInfo(BaseComponent(TextComponent("efgh")), 14.0f),
),
size = Vec2(14f, 33.0f),
)
@ -221,7 +221,7 @@ class ChatComponentRendererTest {
info.assert(
lineIndex = 0,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
LineRenderInfo(BaseComponent(TextComponent("bcd")), 5.0f),
),
size = Vec2(5.0f, 11.0f),
cutOff = true,
@ -233,7 +233,7 @@ class ChatComponentRendererTest {
info.assert(
lineIndex = 0,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
LineRenderInfo(BaseComponent(TextComponent("bcd")), 5.0f),
),
size = Vec2(5.0f, 11.0f),
cutOff = true,
@ -245,8 +245,8 @@ class ChatComponentRendererTest {
info.assert(
lineIndex = 1,
lines = listOf(
TextLineInfo(BaseComponent(TextComponent("bcd")), 5.0f),
TextLineInfo(BaseComponent(TextComponent("efgh")), 14.0f),
LineRenderInfo(BaseComponent(TextComponent("bcd")), 5.0f),
LineRenderInfo(BaseComponent(TextComponent("efgh")), 14.0f),
),
size = Vec2(14.0f, 22.0f),
cutOff = true,
@ -269,7 +269,7 @@ class ChatComponentRendererTest {
info.assert(
lineIndex = 1,
lines = listOf(TextLineInfo()),
lines = listOf(LineRenderInfo()),
size = Vec2(0.0f, 11.0f),
)
}

View File

@ -23,5 +23,6 @@ data class CharSpacing(
companion object {
val DEFAULT = CharSpacing()
val VERTICAL = CharSpacing(0.0f, 0.0f)
}
}

View File

@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.font.renderer.element
import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.TextComponent
data class TextLineInfo(
data class LineRenderInfo(
val text: BaseComponent = BaseComponent(),
var width: Float = 0.0f,
) {

View File

@ -58,7 +58,7 @@ class TextOffset(
this.offset.y += height
this.offset.x = initial.x
info.lines += TextLineInfo()
info.lines += LineRenderInfo()
info.lineIndex++
return true

View File

@ -19,20 +19,20 @@ import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
class TextRenderInfo(
val maxSize: Vec2,
) {
val lines: MutableList<TextLineInfo> = mutableListOf()
val lines: MutableList<LineRenderInfo> = mutableListOf()
var lineIndex: Int = 0
var size = Vec2.EMPTY
var cutOff = false
fun update(offset: TextOffset, properties: TextRenderProperties, width: Float): TextLineInfo {
fun update(offset: TextOffset, properties: TextRenderProperties, width: Float): LineRenderInfo {
size.x = maxOf(offset.offset.x - offset.initial.x + width, size.x)
val line: TextLineInfo
val line: LineRenderInfo
if (lineIndex == 0 && lines.isEmpty()) {
// first char of all lines
line = TextLineInfo()
line = LineRenderInfo()
lines += line
size.y = properties.lineHeight
} else {
@ -43,4 +43,8 @@ class TextRenderInfo(
return line
}
fun rewind() {
lineIndex = 0
}
}

View File

@ -37,7 +37,7 @@ abstract class AbstractButtonElement(
text: Any,
disabled: Boolean = false,
) : Element(guiRenderer) {
protected val textElement = TextElement(guiRenderer, text, background = false, parent = this)
protected val textElement = TextElement(guiRenderer, text, background = null, parent = this)
protected abstract val disabledAtlas: AtlasElement?
protected abstract val normalAtlas: AtlasElement?
protected abstract val hoveredAtlas: AtlasElement?

View File

@ -37,7 +37,7 @@ open class SwitchElement(
parent: Element?,
var onChange: (state: Boolean) -> Unit,
) : AbstractCheckboxElement(guiRenderer) {
protected val textElement = TextElement(guiRenderer, text, background = false).apply { this.parent = this@SwitchElement }
protected val textElement = TextElement(guiRenderer, text, background = null).apply { this.parent = this@SwitchElement }
private val disabledAtlas = guiRenderer.atlasManager["minosoft:switch_disabled"]
private val normalAtlas = guiRenderer.atlasManager["minosoft:switch_normal"]
private val hoveredAtlas = guiRenderer.atlasManager["minosoft:switch_hovered"]

View File

@ -22,6 +22,8 @@ import de.bixilon.minosoft.data.registries.item.stack.StackableItem
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.font.renderer.element.CharSpacing
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
@ -42,7 +44,7 @@ class RawItemElement(
stack: ItemStack?,
parent: Element?,
) : Element(guiRenderer) {
private val countText = TextElement(guiRenderer, "", background = false, noBorder = true)
private val countText = TextElement(guiRenderer, "", background = null, properties = TextRenderProperties(charSpacing = CharSpacing.VERTICAL))
var _stack: ItemStack? = null
set(value) {

View File

@ -13,15 +13,16 @@
package de.bixilon.minosoft.gui.rendering.gui.elements.text
import de.bixilon.minosoft.data.text.EmptyComponent
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
class AutoTextElement(
guiRenderer: GUIRenderer,
var interval: Int,
alignment: HorizontalAlignments = HorizontalAlignments.LEFT,
properties: TextRenderProperties = TextRenderProperties.DEFAULT,
private val updater: () -> Any,
) : TextElement(guiRenderer, "", alignment) {
) : TextElement(guiRenderer, EmptyComponent, properties = properties) {
private var remainingTicks = 0
init {

View File

@ -16,11 +16,12 @@ package de.bixilon.minosoft.gui.rendering.gui.elements.text
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.primitive.BooleanUtil.decide
import de.bixilon.kutil.time.TimeUtil
import de.bixilon.kutil.time.TimeUtil.millis
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
@ -33,19 +34,16 @@ class FadingTextElement(
var fadeInTime: Long = 100,
var stayTime: Long = 1000,
var fadeOutTime: Long = 100,
fontAlignment: HorizontalAlignments = HorizontalAlignments.LEFT,
background: Boolean = true,
backgroundColor: RGBColor = RenderConstants.TEXT_BACKGROUND_COLOR,
noBorder: Boolean = false,
background: RGBColor? = RenderConstants.TEXT_BACKGROUND_COLOR,
parent: Element? = null,
scale: Float = 1.0f,
) : TextElement(guiRenderer = guiRenderer, text = text, fontAlignment = fontAlignment, background = background, backgroundColor = backgroundColor, noBorder = noBorder, parent, scale), Pollable {
properties: TextRenderProperties,
) : TextElement(guiRenderer = guiRenderer, text = text, background = background, parent, properties), Pollable {
override var cacheEnabled: Boolean
get() {
if (hidden || !super.cacheEnabled) {
return false
}
val time = TimeUtil.millis
val time = millis()
return (time >= fadeInEndTime) && (time < fadeOutStartTime)
}
set(value) {
@ -79,7 +77,7 @@ class FadingTextElement(
}
fun show() {
val time = TimeUtil.millis
val time = millis()
if (time in (fadeInEndTime + 1) until fadeOutStartTime) {
fadeOutStartTime = time + stayTime
} else {
@ -96,7 +94,7 @@ class FadingTextElement(
return
}
// ToDo: Eventually fade out when fading in
val time = TimeUtil.millis
val time = millis()
fadeInStartTime = -1L
fadeInEndTime = -1L
fadeOutStartTime = time
@ -111,7 +109,7 @@ class FadingTextElement(
if (hidden) {
return false
}
val hidden = TimeUtil.millis > fadeOutEndTime
val hidden = millis() > fadeOutEndTime
if (this.hidden != hidden) {
this.hidden = hidden
return true
@ -123,7 +121,7 @@ class FadingTextElement(
if (hidden) {
return
}
val time = TimeUtil.millis
val time = millis()
if (time > fadeOutEndTime) {
return
}

View File

@ -14,11 +14,8 @@
package de.bixilon.minosoft.gui.rendering.gui.elements.text
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
interface Labeled {
var text: Any
val chatComponent: ChatComponent
val fontAlignment: HorizontalAlignments
}

View File

@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.gui.elements.text
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.cast.CastUtil.unsafeNull
import de.bixilon.kutil.primitive.BooleanUtil.decide
import de.bixilon.kutil.exception.Broken
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.EmptyComponent
@ -24,14 +24,12 @@ import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.font.renderer.component.ChatComponentRenderer
import de.bixilon.minosoft.gui.rendering.font.renderer.element.CharSpacing
import de.bixilon.minosoft.gui.rendering.font.renderer.element.LineRenderInfo
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextOffset
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderInfo
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.font.types.font.Font
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments.Companion.getOffset
import de.bixilon.minosoft.gui.rendering.gui.input.mouse.MouseActions
import de.bixilon.minosoft.gui.rendering.gui.input.mouse.MouseButtons
@ -39,29 +37,23 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.system.window.CursorShapes
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.MAX
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
import de.bixilon.minosoft.gui.rendering.util.vec.vec4.Vec4iUtil.offset
import de.bixilon.minosoft.util.KUtil.charCount
open class TextElement(
guiRenderer: GUIRenderer,
text: Any,
override var fontAlignment: HorizontalAlignments = HorizontalAlignments.LEFT,
background: Boolean = true,
var backgroundColor: RGBColor = RenderConstants.TEXT_BACKGROUND_COLOR,
noBorder: Boolean = false,
background: RGBColor? = RenderConstants.TEXT_BACKGROUND_COLOR,
parent: Element? = null,
scale: Float = 1.0f,
shadow: Boolean = true,
properties: TextRenderProperties = TextRenderProperties.DEFAULT,
) : Element(guiRenderer, text.charCount * 6 * GUIMesh.GUIMeshStruct.FLOATS_PER_VERTEX), Labeled {
private var activeElement: TextComponent? = null
lateinit var info: TextRenderInfo
private set
// ToDo: Reapply if backgroundColor or fontAlignment changes
var scale: Float = scale
var background: RGBColor? = background
set(value) {
if (field == value) {
return
@ -69,35 +61,14 @@ open class TextElement(
field = value
cacheUpToDate = false
}
var background: Boolean = background
var properties: TextRenderProperties = properties
set(value) {
if (field == value) {
return
}
field = value
cacheUpToDate = false
}
var shadow: Boolean = shadow
set(value) {
if (field == value) {
return
}
field = value
cacheUpToDate = false
}
var noBorder: Boolean = noBorder
@Synchronized set(value) {
if (field == value) {
return
}
field = value
applyNoBorder()
forceApply()
}
var charHeight: Int = 0
private set
var charMargin: Int = 0
private set
override var size: Vec2i
get() = super.size
@ -109,7 +80,7 @@ open class TextElement(
field = value
}
private var emptyMessage: Boolean = true
private var empty: Boolean = true
var _chatComponent: ChatComponent = unsafeNull()
set(value) {
@ -117,20 +88,8 @@ open class TextElement(
return
}
field = value
emptyMessage = value is EmptyComponent || value.message.isEmpty()
val prefSize = Vec2i.EMPTY
if (!emptyMessage) {
val info = TextRenderInfo(Vec2.MAX)
val properties = TextRenderProperties(
alignment = fontAlignment,
charBaseHeight = charHeight.toFloat(),
charSpacing = CharSpacing(charMargin.toFloat(), charMargin.toFloat()),
scale = scale,
shadow = shadow,
)
ChatComponentRenderer.render(TextOffset(), context.font, properties, info, null, null, value)
}
_prefSize = prefSize
empty = value is EmptyComponent || value.message.isEmpty()
updatePrefSize(value)
}
override var chatComponent: ChatComponent
@ -142,66 +101,70 @@ open class TextElement(
init {
this._parent = parent
applyNoBorder()
this._chatComponent = ChatComponent.of(text)
forceSilentApply()
}
private fun applyNoBorder() {
charHeight = (noBorder.decide(Font.CHAR_HEIGHT, Font.TOTAL_CHAR_HEIGHT) * scale).toInt()
charMargin = (noBorder.decide(0, Font.CHAR_MARGIN) * scale).toInt()
private fun updatePrefSize(text: ChatComponent) {
var prefSize = Vec2.EMPTY
if (!empty) {
val info = TextRenderInfo(Vec2.MAX)
ChatComponentRenderer.render(TextOffset(), context.font, properties, info, null, null, text)
prefSize = info.size
}
_prefSize = Vec2i(prefSize)
}
override fun forceSilentApply() {
private fun updateText(text: ChatComponent) {
val info = TextRenderInfo(Vec2(maxSize))
val properties = TextRenderProperties(
alignment = fontAlignment,
charBaseHeight = charHeight.toFloat(),
charSpacing = CharSpacing(charMargin.toFloat(), charMargin.toFloat()),
scale = scale,
shadow = shadow,
)
if (!emptyMessage) {
ChatComponentRenderer.render(TextOffset(), context.font, properties, info, null, null, chatComponent)
info.lineIndex = 0
if (!empty) {
ChatComponentRenderer.render(TextOffset(), context.font, properties, info, null, null, text)
info.rewind()
}
this.info = info
this.cacheUpToDate = false
_size = Vec2i(info.size)
}
override fun onChildChange(child: Element) = error("A TextElement can not have a child!")
override fun forceSilentApply() {
updateText(this._chatComponent)
this.cacheUpToDate = false
}
override fun onChildChange(child: Element) = Broken("A TextElement can not have a child!")
private fun GUIVertexConsumer.renderBackground(color: RGBColor, properties: TextRenderProperties, info: TextRenderInfo, offset: Vec2, options: GUIVertexOptions?) {
val start = Vec2()
val end = Vec2()
val lineHeight = properties.lineHeight
for ((index, line) in info.lines.withIndex()) {
start.x = offset.x + properties.alignment.getOffset(line.width, info.size.x)
start.y = offset.y + (index * lineHeight) + (maxOf(index - 1, 0) * properties.lineSpacing)
end.x = start.x + line.width
end.y = start.y + lineHeight
addQuad(start, end, context.textureManager.whiteTexture, color, options)
}
}
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
if (emptyMessage) {
return
}
val initialOffset = offset + margin.offset
if (empty) return
val info = this.info
val properties = this.properties
val initialOffset = Vec2(offset + margin.offset)
if (background) {
for ((line, info) in info.lines.withIndex()) {
val start = initialOffset + Vec2i(fontAlignment.getOffset(size.x.toFloat(), info.width), line * charHeight)
consumer.addQuad(start, start + Vec2i(info.width + charMargin, charHeight), context.textureManager.whiteTexture, backgroundColor, options)
}
}
this.background?.let { consumer.renderBackground(it, properties, info, initialOffset, options) }
var vertices = ChatComponentRenderer.calculatePrimitiveCount(chatComponent) * consumer.order.size * GUIMesh.GUIMeshStruct.FLOATS_PER_VERTEX
if (shadow) {
if (properties.shadow) {
vertices *= 2
}
consumer.ensureSize(vertices)
val properties = TextRenderProperties(
alignment = fontAlignment,
charBaseHeight = charHeight.toFloat(),
charSpacing = CharSpacing(charMargin.toFloat(), charMargin.toFloat()),
scale = scale,
shadow = shadow,
)
ChatComponentRenderer.render(TextOffset(Vec2(initialOffset)), context.font, properties, info, consumer, options, chatComponent)
info.lineIndex = 0
info.rewind()
}
override fun onMouseAction(position: Vec2i, button: MouseButtons, action: MouseActions, count: Int): Boolean {
@ -224,7 +187,7 @@ open class TextElement(
}
override fun onMouseMove(position: Vec2i, absolute: Vec2i): Boolean {
val pair = getTextComponentAt(position)
val pair = getTextComponentAt(Vec2(position))
if (activeElement != pair?.first) {
val activeElement = activeElement
@ -234,9 +197,9 @@ open class TextElement(
} else {
context.window.cursorShape = CursorShapes.HAND
}
return (activeElement?.hoverEvent?.onMouseLeave(guiRenderer) ?: false) || (pair?.first?.hoverEvent?.onMouseEnter(guiRenderer, pair.second, absolute) ?: false)
return (activeElement?.hoverEvent?.onMouseLeave(guiRenderer) ?: false) || (pair?.first?.hoverEvent?.onMouseEnter(guiRenderer, Vec2i(pair.second), absolute) ?: false)
}
return pair?.first?.hoverEvent?.onMouseMove(guiRenderer, pair.second, absolute) ?: false
return pair?.first?.hoverEvent?.onMouseMove(guiRenderer, Vec2i(pair.second), absolute) ?: false
}
override fun onMouseLeave(): Boolean {
@ -254,28 +217,48 @@ open class TextElement(
activeElement = null
}
private fun getTextComponentAt(position: Vec2i): Pair<TextComponent, Vec2i>? {
val offset = Vec2i(position)
val line = info.lines.getOrNull(offset.y / charHeight) ?: return null
offset.y = offset.y % charHeight
private fun TextRenderInfo.getLineAt(lineHeight: Float, lineSpacing: Float, offset: Float): Pair<LineRenderInfo, Float>? {
var offset = offset
val cutText = TextElement(guiRenderer, line.text, fontAlignment, false, backgroundColor, noBorder, parent, scale)
cutText._prefMaxSize = Vec2i(offset.x, charHeight)
cutText.forceSilentApply()
for ((index, line) in info.lines.withIndex()) {
if (offset in 0.0f..lineHeight) {
return Pair(line, offset)
}
offset -= lineHeight
if (index > 0) {
offset -= lineSpacing
}
}
return null
}
@Deprecated("int")
private fun getTextComponentAt(position: Vec2i): Pair<TextComponent, Vec2i>? = getTextComponentAt(Vec2(position))?.let { Pair(it.first, Vec2i(it.second)) }
private fun getTextComponentAt(position: Vec2): Pair<TextComponent, Vec2>? {
val offset = Vec2(position)
val info = this.info
val properties = this.properties
val (line, yOffset) = info.getLineAt(properties.lineHeight, properties.lineSpacing, offset.y) ?: return null
offset.y = yOffset
val line0 = cutText.info.lines.getOrNull(0) ?: return null
val cutInfo = TextRenderInfo(Vec2(offset.x, properties.lineHeight))
val cut = ChatComponentRenderer.render(TextOffset(), context.font, properties, cutInfo, null, null, line.text)
val line0 = cutInfo.lines.getOrNull(0) ?: return null
val message = line0.text.message
var charToCheck = message.length
if (line0.width < offset.x && charToCheck < line.text.message.length) {
if (cut) {
// last char got cut off
charToCheck++
}
val text = line.text.getTextAt(charToCheck)
offset.x -= line0.width.toInt() // ToDo: Not 100% correct
offset.x -= line0.width // TODO: the cut part of the last char is missing
offset.x += fontAlignment.getOffset(size.x, line.width.toInt())
offset.x += properties.alignment.getOffset(info.size.x, line.width)
return Pair(text, offset)
}

View File

@ -118,7 +118,7 @@ open class TextFlowElement(
}
// ToDo: Cache lines
val textElement = TextElement(guiRenderer, message.text, background = false, parent = this)
val textElement = TextElement(guiRenderer, message.text, background = null, parent = this)
val lines = textElement.info.lines
val lineIterator = lines.reversed().iterator()
@ -143,7 +143,7 @@ open class TextFlowElement(
if (visibleLines.size >= maxLines) {
break
}
val lineElement = TextElement(guiRenderer, line.text, background = false)
val lineElement = TextElement(guiRenderer, line.text, background = null)
textSize = textSize.max(lineElement.size)
visibleLines += TextFlowLineElement(lineElement, message)
}

View File

@ -19,10 +19,9 @@ import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.font.types.font.Font
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ColorElement
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
import de.bixilon.minosoft.gui.rendering.gui.input.ModifierKeys
@ -33,14 +32,10 @@ import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
class MarkTextElement(
guiRenderer: GUIRenderer,
text: Any,
fontAlignment: HorizontalAlignments = HorizontalAlignments.LEFT,
background: Boolean = true,
backgroundColor: RGBColor = RenderConstants.TEXT_BACKGROUND_COLOR,
noBorder: Boolean = false,
background: RGBColor? = RenderConstants.TEXT_BACKGROUND_COLOR,
parent: Element? = null,
scale: Float = 1.0f,
shadow: Boolean = true,
) : TextElement(guiRenderer, text, fontAlignment, background, backgroundColor, noBorder, parent, scale, shadow) {
properties: TextRenderProperties = TextRenderProperties.DEFAULT,
) : TextElement(guiRenderer, text, background, parent, properties) {
var markStartPosition = 0
var markEndPosition = 0
@ -80,17 +75,17 @@ class MarkTextElement(
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
if (markStartPosition >= 0) {
val message = chatComponent.message // ToDo: This does not include formatting
val preMark = TextElement(guiRenderer, message.substring(0, markStartPosition), scale = scale, parent = _parent)
val mark = TextElement(guiRenderer, message.substring(markStartPosition, markEndPosition), scale = scale, parent = _parent)
val preMark = TextElement(guiRenderer, message.substring(0, markStartPosition), properties = properties, parent = _parent)
val mark = TextElement(guiRenderer, message.substring(markStartPosition, markEndPosition), properties = properties, parent = _parent)
val markOffset = Vec2i(preMark.info.lines.lastOrNull()?.width ?: 0, preMark.size.y)
if (markOffset.y > 0 && (preMark.info.lines.lastOrNull()?.width ?: 0.0f) <= (info.lines.lastOrNull()?.width ?: 0.0f)) {
markOffset.y -= (Font.TOTAL_CHAR_HEIGHT * scale).toInt()
markOffset.y -= (properties.lineHeight * properties.scale).toInt()
}
for (line in mark.info.lines) {
ColorElement(guiRenderer, size = Vec2i(line.width, Font.TOTAL_CHAR_HEIGHT * scale), color = ChatColors.DARK_BLUE).render(offset + markOffset, consumer, options)
ColorElement(guiRenderer, size = Vec2i(line.width, (properties.lineHeight * properties.scale).toInt()), color = ChatColors.DARK_BLUE).render(offset + markOffset, consumer, options)
markOffset.x = 0
markOffset.y += (Font.TOTAL_CHAR_HEIGHT * scale).toInt()
markOffset.y += (properties.lineHeight * properties.scale).toInt()
}
}
@ -107,11 +102,13 @@ class MarkTextElement(
}
mark(0, chatComponent.message.length)
}
KeyCodes.KEY_C -> {
if (controlDown) {
copy()
}
}
KeyCodes.KEY_ESCAPE -> unmark()
else -> return super.onKey(key, type)
}

View File

@ -17,7 +17,9 @@ import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.string.StringUtil.codePointAtOrNull
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.font.types.font.Font
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
@ -41,14 +43,13 @@ open class TextInputElement(
val cursorStyles: TextCursorStyles = TextCursorStyles.CLICKED,
var editable: Boolean = true,
var onChangeCallback: () -> Unit = {},
val background: Boolean = true,
shadow: Boolean = true,
scale: Float = 1.0f,
val background: RGBColor? = null,
properties: TextRenderProperties = TextRenderProperties.DEFAULT,
val cutAtSize: Boolean = false,
parent: Element? = null,
) : Element(guiRenderer) {
protected val cursor = ColorElement(guiRenderer, size = Vec2i(minOf(1.0f, scale), Font.TOTAL_CHAR_HEIGHT * scale))
protected val textElement = MarkTextElement(guiRenderer, "", background = false, parent = this, scale = scale, shadow = shadow)
protected val cursor = ColorElement(guiRenderer, size = Vec2i(minOf(1.0f, properties.scale), properties.lineHeight * properties.scale))
protected val textElement = MarkTextElement(guiRenderer, "", background = null, parent = this, properties = properties)
protected val backgroundElement = ColorElement(guiRenderer, Vec2i.EMPTY, RenderConstants.TEXT_BACKGROUND_COLOR)
protected var cursorOffset: Vec2i = Vec2i.EMPTY
val _value = StringBuffer(256)
@ -74,7 +75,7 @@ open class TextInputElement(
}
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
if (background) {
if (background != null) {
backgroundElement.render(offset, consumer, options)
}
textElement.render(offset, consumer, options)
@ -142,9 +143,9 @@ open class TextInputElement(
val preCursorText = if (_pointer == value.length) {
textElement
} else {
TextElement(guiRenderer, value.substring(0, _pointer), scale = textElement.scale, parent = this)
TextElement(guiRenderer, value.substring(0, _pointer), properties = textElement.properties, parent = this)
}
Vec2i(preCursorText.info.lines.lastOrNull()?.width ?: 0, maxOf(preCursorText.info.lines.size - 1, 0) * preCursorText.charHeight)
Vec2i(preCursorText.info.lines.lastOrNull()?.width ?: 0, maxOf(preCursorText.info.lines.size - 1, 0) * preCursorText.properties.lineHeight)
}
cacheUpToDate = false
}
@ -332,7 +333,7 @@ open class TextInputElement(
if (action != MouseActions.PRESS) {
return true
}
val leftText = TextElement(guiRenderer, value, background = false)
val leftText = TextElement(guiRenderer, value, background = null)
leftText.prefMaxSize = Vec2i(position.x, size.y)
var pointer = 0
var heightLeft = position.y

View File

@ -24,6 +24,8 @@ import de.bixilon.minosoft.commands.util.CommandReader
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.text.mark.TextCursorStyles
@ -44,12 +46,11 @@ class NodeTextInputElement(
cursorStyles: TextCursorStyles = TextCursorStyles.CLICKED,
editable: Boolean = true,
onChange: () -> Unit = {},
background: Boolean = true,
shadow: Boolean = true,
scale: Float = 1.0f,
background: RGBColor? = null,
cutAtSize: Boolean = false,
parent: Element? = null,
) : TextInputElement(guiRenderer, value, maxLength, cursorStyles, editable, onChange, background, shadow, scale, cutAtSize, parent) {
properties: TextRenderProperties = TextRenderProperties.DEFAULT,
) : TextInputElement(guiRenderer, value, maxLength, cursorStyles, editable, onChange, background, properties, cutAtSize, parent) {
private var showError = false
private val errorElement = NodeErrorElement(guiRenderer, Vec2i.EMPTY)
private val suggestions = NodeSuggestionsElement(guiRenderer, Vec2i.EMPTY, this)

View File

@ -32,7 +32,7 @@ class ItemInfoPopper(
position: Vec2i,
val stack: ItemStack,
) : MouseTrackedPopper(guiRenderer, position) {
private val textElement = TextElement(guiRenderer, "", background = false, parent = this)
private val textElement = TextElement(guiRenderer, "", background = null, parent = this)
init {
forceSilentApply()

View File

@ -26,7 +26,7 @@ open class TextPopper(
position: Vec2i,
text: Any,
) : MouseTrackedPopper(guiRenderer, position) {
protected val textElement = TextElement(guiRenderer, text, background = false, parent = this)
protected val textElement = TextElement(guiRenderer, text, background = null, parent = this)
init {
forceSilentApply()

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.gui.gui.screen
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.registries.misc.event.world.handler.win.WinGameEvent
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments.Companion.getOffset
@ -28,8 +29,8 @@ import de.bixilon.minosoft.protocol.packets.c2s.play.ClientActionC2SP
class CreditsScreen(
guiRenderer: GUIRenderer,
) : Screen(guiRenderer) {
private val headerElement = TextElement(guiRenderer, "Minecraft", background = false, scale = 3.0f, parent = this)
private val textElement = TextElement(guiRenderer, "Ähm, yes. This is not yet implemented -/-\nI don't know how to make moving text in the current gui system.\nI am so sorry...", background = false, parent = this)
private val headerElement = TextElement(guiRenderer, "Minecraft", background = null, properties = TextRenderProperties(scale = 3.0f), parent = this)
private val textElement = TextElement(guiRenderer, "Ähm, yes. This is not yet implemented -/-\nI don't know how to make moving text in the current gui system.\nI am so sorry...", background = null, parent = this)
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {

View File

@ -24,6 +24,7 @@ import de.bixilon.minosoft.data.entities.block.sign.SignSides
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
import de.bixilon.minosoft.data.registries.blocks.types.pixlyzer.entity.sign.SignBlock
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.font.types.font.Font
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
@ -57,10 +58,10 @@ class SignEditorScreen(
val blockState: BlockState? = guiRenderer.connection.world[blockPosition],
val blockEntity: SignBlockEntity? = guiRenderer.connection.world.getBlockEntity(blockPosition).nullCast(),
) : Screen(guiRenderer), AbstractLayout<Element> {
private val headerElement = TextElement(guiRenderer, "Edit sign message", background = false, scale = 3.0f, parent = this)
private val positionElement = TextElement(guiRenderer, "at $blockPosition", background = false, parent = this)
private val headerElement = TextElement(guiRenderer, "Edit sign message", background = null, properties = TextRenderProperties(scale = 3.0f), parent = this)
private val positionElement = TextElement(guiRenderer, "at $blockPosition", background = null, parent = this)
private val backgroundElement = ImageElement(guiRenderer, getTexture(), uvStart = SIGN_UV_START, uvEnd = SIGN_UV_END, size = BACKGROUND_SIZE)
private val lines = Array(SignBlockEntity.LINES) { TextInputElement(guiRenderer, blockEntity?.lines?.get(it)?.message ?: "", SIGN_MAX_CHARS, scale = TEXT_SCALE, background = false, cutAtSize = true, parent = this) }
private val lines = Array(SignBlockEntity.LINES) { TextInputElement(guiRenderer, blockEntity?.lines?.get(it)?.message ?: "", SIGN_MAX_CHARS, properties = TextRenderProperties(scale = TEXT_SCALE), background = null, cutAtSize = true, parent = this) }
private val doneButton = ButtonElement(guiRenderer, "Done") { guiRenderer.gui.pop() }.apply { size = Vec2i(BACKGROUND_SIZE.x, size.y);parent = this@SignEditorScreen }
private val lengthLimitSwitch = SwitchElement(guiRenderer, "Limit length", guiRenderer.connection.profiles.gui.sign.limitLength, parent = this) { guiRenderer.connection.profiles.gui.sign.limitLength = it; forceSilentApply() }
override var activeElement: Element? = null

View File

@ -41,7 +41,7 @@ class EnchantmentButtonElement(
override val disabledAtlas = guiRenderer.atlasManager["enchanting_table_card_disabled"]
override val normalAtlas = guiRenderer.atlasManager["enchanting_table_card_normal"]
override val hoveredAtlas = guiRenderer.atlasManager["enchanting_table_card_hovered"]
private val levelText = TextElement(guiRenderer, ChatComponent.EMPTY, background = false)
private val levelText = TextElement(guiRenderer, ChatComponent.EMPTY, background = null)
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
super.forceRender(offset, consumer, options)

View File

@ -17,6 +17,7 @@ import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasArea
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
@ -41,7 +42,7 @@ class ContainerText(
return null
}
text.setFallbackColor(DEFAULT_TEXT_COLOR)
val textElement = TextElement(guiRenderer, text, background = false, shadow = false)
val textElement = TextElement(guiRenderer, text, background = null, properties = TextRenderProperties(shadow = false))
textElement.prefMaxSize = area.size
return ContainerText(textElement, area.start)

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.gui.gui.screen.menu.confirmation
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.input.button.ButtonElement
@ -46,8 +47,8 @@ abstract class AbstractConfirmationMenu(
}
protected fun initButtons() {
add(TextElement(guiRenderer, text, HorizontalAlignments.CENTER, false, scale = 1.5f))
add(TextElement(guiRenderer, subtext, HorizontalAlignments.CENTER, false))
add(TextElement(guiRenderer, text, background = null, properties = TextRenderProperties(HorizontalAlignments.CENTER, scale = 1.5f)))
add(TextElement(guiRenderer, subtext, background = null, properties = TextRenderProperties(HorizontalAlignments.CENTER)))
add(SpacerElement(guiRenderer, Vec2i(0, 30)))
for (button in createButtons()) {

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.gui.gui.screen.menu.debug
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.input.button.ButtonElement
@ -28,7 +29,7 @@ class DebugMenu(guiRenderer: GUIRenderer) : Menu(guiRenderer) {
private val connection = guiRenderer.connection
init {
add(TextElement(guiRenderer, "Debug options", HorizontalAlignments.CENTER, false))
add(TextElement(guiRenderer, "Debug options", properties = TextRenderProperties(HorizontalAlignments.CENTER)))
add(SpacerElement(guiRenderer, Vec2i(0, 10)))
add(ButtonElement(guiRenderer, "Switch to next gamemode") { connection.util.typeChat("/gamemode ${connection.player.gamemode.next().name.lowercase()}") })
add(ButtonElement(guiRenderer, "Hack to next gamemode") {

View File

@ -19,6 +19,7 @@ import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager
import de.bixilon.minosoft.data.language.LanguageUtil.i18n
import de.bixilon.minosoft.gui.eros.Eros
import de.bixilon.minosoft.gui.eros.util.JavaFXUtil
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.input.button.ButtonElement
@ -34,7 +35,7 @@ import de.bixilon.minosoft.terminal.RunConfiguration
class PauseMenu(guiRenderer: GUIRenderer) : Menu(guiRenderer) {
init {
add(TextElement(guiRenderer, RunConfiguration.APPLICATION_NAME, HorizontalAlignments.CENTER, false, scale = 3.0f))
add(TextElement(guiRenderer, RunConfiguration.APPLICATION_NAME, properties = TextRenderProperties(HorizontalAlignments.CENTER, scale = 3.0f)))
add(SpacerElement(guiRenderer, Vec2i(0, 20)))
add(ButtonElement(guiRenderer, "menu.pause.back_to_game".i18n()) { guiRenderer.gui.pause(false) })
add(ButtonElement(guiRenderer, "menu.pause.options.debug".i18n()) { guiRenderer.gui.push(DebugMenu) })

View File

@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.gui.gui.screen.menu.pause
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.input.button.ButtonElement
@ -32,7 +33,7 @@ class RespawnMenu(guiRenderer: GUIRenderer) : Menu(guiRenderer) {
init {
background.tint = RGBColor(0xFF, 0x00, 0x00, 0x7F)
add(TextElement(guiRenderer, "You died!", HorizontalAlignments.CENTER, false, scale = 3.0f))
add(TextElement(guiRenderer, "You died!", background = null, properties = TextRenderProperties(HorizontalAlignments.CENTER, scale = 3.0f)))
add(SpacerElement(guiRenderer, Vec2i(0, 20)))
if (guiRenderer.connection.world.hardcore) {
add(TextElement(guiRenderer, "This world is hardcore, you cannot respawn!"))

View File

@ -37,7 +37,7 @@ class BossbarElement(
private var color: BossbarColors = bossbar.color
private var notches: BossbarNotches = bossbar.notches
private val titleElement = TextElement(guiRenderer, text = bossbar.title, background = false, parent = this)
private val titleElement = TextElement(guiRenderer, text = bossbar.title, background = null, parent = this)
private lateinit var progress: BossbarProgressElement
init {

View File

@ -20,6 +20,8 @@ import de.bixilon.minosoft.data.container.equipment.EquipmentSlots
import de.bixilon.minosoft.data.container.stack.ItemStack
import de.bixilon.minosoft.data.entities.entities.player.Arms
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.font.renderer.element.CharSpacing
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
@ -46,10 +48,10 @@ class HotbarElement(guiRenderer: GUIRenderer) : Element(guiRenderer), LayoutedEl
val offhand = HotbarOffhandElement(guiRenderer)
private var renderOffhand = false
val hoverText = FadingTextElement(guiRenderer, text = "", fadeInTime = 300, stayTime = 3000, fadeOutTime = 500, background = false, noBorder = true)
val hoverText = FadingTextElement(guiRenderer, text = "", fadeInTime = 300, stayTime = 3000, fadeOutTime = 500, background = null, properties = TextRenderProperties(charSpacing = CharSpacing.VERTICAL))
private var hoverTextShown = false
private val itemText = FadingTextElement(guiRenderer, text = "", fadeInTime = 300, stayTime = 1500, fadeOutTime = 500, background = false, noBorder = true)
private val itemText = FadingTextElement(guiRenderer, text = "", fadeInTime = 300, stayTime = 1500, fadeOutTime = 500, background = null, properties = TextRenderProperties(charSpacing = CharSpacing.VERTICAL))
private var lastItemStackNameShown: ItemStack? = null
private var lastItemSlot = -1
private var itemTextShown = true

View File

@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.font.types.font.Font
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
@ -61,7 +62,7 @@ class HotbarExperienceBarElement(guiRenderer: GUIRenderer) : Element(guiRenderer
if (level > 0) {
// level
val text = TextElement(guiRenderer, TextComponent(level).apply { color = RenderConstants.EXPERIENCE_BAR_LEVEL_COLOR }, fontAlignment = HorizontalAlignments.CENTER, false)
val text = TextElement(guiRenderer, TextComponent(level).apply { color = RenderConstants.EXPERIENCE_BAR_LEVEL_COLOR }, properties = TextRenderProperties(HorizontalAlignments.CENTER, shadow = false))
text.render(offset + Vec2i(HorizontalAlignments.CENTER.getOffset(size.x, text.size.x), -Font.CHAR_HEIGHT + 1), consumer, options)
}

View File

@ -33,6 +33,7 @@ import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
import de.bixilon.minosoft.data.world.chunk.light.SectionLight
import de.bixilon.minosoft.gui.rendering.entity.EntityRenderer
import de.bixilon.minosoft.gui.rendering.events.ResizeWindowEvent
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
@ -195,8 +196,8 @@ class DebugHUDElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Layouted
private fun initRight(): Element {
val layout = RowLayout(guiRenderer, HorizontalAlignments.RIGHT)
layout.margin = Vec4i(2)
layout += TextElement(guiRenderer, "Java ${Runtime.version()} ${System.getProperty("sun.arch.data.model")}bit", HorizontalAlignments.RIGHT)
layout += TextElement(guiRenderer, "OS ${SystemInformation.OS_TEXT}", HorizontalAlignments.RIGHT)
layout += TextElement(guiRenderer, "Java ${Runtime.version()} ${System.getProperty("sun.arch.data.model")}bit", properties = Companion.RIGHT)
layout += TextElement(guiRenderer, "OS ${SystemInformation.OS_TEXT}", properties = Companion.RIGHT)
layout += LineSpacerElement(guiRenderer)
@ -217,39 +218,39 @@ class DebugHUDElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Layouted
layout += LineSpacerElement(guiRenderer)
layout += TextElement(guiRenderer, "CPU ${SystemInformation.PROCESSOR_TEXT}", HorizontalAlignments.RIGHT)
layout += TextElement(guiRenderer, "CPU ${SystemInformation.PROCESSOR_TEXT}", properties = Companion.RIGHT)
layout += TextElement(guiRenderer, "Memory ${SystemInformation.SYSTEM_MEMORY.formatBytes()}")
layout += LineSpacerElement(guiRenderer)
layout += TextElement(guiRenderer, "Display <?>", HorizontalAlignments.RIGHT).apply {
layout += TextElement(guiRenderer, "Display <?>", properties = Companion.RIGHT).apply {
guiRenderer.context.connection.events.listen<ResizeWindowEvent> {
text = "Display ${it.size.x.format()}x${it.size.y.format()}"
}
}
context.renderSystem.apply {
layout += TextElement(guiRenderer, "GPU $gpuType", HorizontalAlignments.RIGHT)
layout += TextElement(guiRenderer, "Version $version", HorizontalAlignments.RIGHT)
layout += TextElement(guiRenderer, "GPU $gpuType", properties = Companion.RIGHT)
layout += TextElement(guiRenderer, "Version $version", properties = Companion.RIGHT)
}
MinosoftProperties.git?.let {
layout += LineSpacerElement(guiRenderer)
MinosoftPropertiesLoader.apply {
layout += TextElement(guiRenderer, "Git ${it.commitShort}/${it.branch}", HorizontalAlignments.RIGHT)
layout += TextElement(guiRenderer, "Git ${it.commitShort}/${it.branch}", properties = Companion.RIGHT)
}
}
layout += LineSpacerElement(guiRenderer)
layout += TextElement(guiRenderer, "${connection.events.size.format()}x listeners", HorizontalAlignments.RIGHT)
layout += TextElement(guiRenderer, "${connection.events.size.format()}x listeners", properties = Companion.RIGHT)
layout += LineSpacerElement(guiRenderer)
context.connection.camera.target.apply {
layout += AutoTextElement(guiRenderer, 1, HorizontalAlignments.RIGHT) {
layout += AutoTextElement(guiRenderer, 1, properties = Companion.RIGHT) {
// ToDo: Tags
target ?: "No target"
}
@ -332,6 +333,8 @@ class DebugHUDElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Layouted
KeyActions.STICKY to setOf(KeyCodes.KEY_F3),
)
private val RIGHT = TextRenderProperties(HorizontalAlignments.RIGHT)
override fun build(guiRenderer: GUIRenderer): LayoutedGUIElement<DebugHUDElement> {
return LayoutedGUIElement(DebugHUDElement(guiRenderer)).apply { enabled = false }
}

View File

@ -31,8 +31,8 @@ class ScoreboardScoreElement(
val score: ScoreboardScore,
parent: Element?,
) : Element(guiRenderer) {
private val nameElement = TextElement(guiRenderer, "", background = false, parent = this)
private val scoreElement = TextElement(guiRenderer, "", background = false, parent = this)
private val nameElement = TextElement(guiRenderer, "", background = null, parent = this)
private val scoreElement = TextElement(guiRenderer, "", background = null, parent = this)
init {
nameElement.prefMaxSize = Vec2i(-1, ScoreboardSideElement.SCORE_HEIGHT)

View File

@ -45,7 +45,7 @@ import de.bixilon.minosoft.util.KUtil.toResourceLocation
class ScoreboardSideElement(guiRenderer: GUIRenderer) : Element(guiRenderer), LayoutedElement, Initializable, AsyncDrawable {
private val backgroundElement = ColorElement(guiRenderer, size = Vec2i.EMPTY, color = RenderConstants.TEXT_BACKGROUND_COLOR)
private val nameBackgroundElement = ColorElement(guiRenderer, size = Vec2i.EMPTY, color = RenderConstants.TEXT_BACKGROUND_COLOR)
private val nameElement = TextElement(guiRenderer, "", background = false, parent = this)
private val nameElement = TextElement(guiRenderer, "", background = null, parent = this)
private val scores: LockMap<ScoreboardScore, ScoreboardScoreElement> = lockMapOf()
override val layoutOffset: Vec2i

View File

@ -23,6 +23,7 @@ import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.atlas.AtlasElement
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
@ -45,8 +46,8 @@ import java.util.*
import java.util.concurrent.locks.ReentrantLock
class TabListElement(guiRenderer: GUIRenderer) : Element(guiRenderer), LayoutedElement, Initializable, AsyncDrawable {
val header = TextElement(guiRenderer, "", background = false, fontAlignment = HorizontalAlignments.CENTER, parent = this)
val footer = TextElement(guiRenderer, "", background = false, fontAlignment = HorizontalAlignments.CENTER, parent = this)
val header = TextElement(guiRenderer, "", background = null, properties = TextRenderProperties(HorizontalAlignments.CENTER), parent = this)
val footer = TextElement(guiRenderer, "", background = null, properties = TextRenderProperties(HorizontalAlignments.CENTER), parent = this)
private val background = ColorElement(guiRenderer, Vec2i.EMPTY, color = RGBColor(0, 0, 0, 120))

View File

@ -53,7 +53,7 @@ class TabListEntryElement(
private val skinElement = DynamicImageElement(guiRenderer, null, uvStart = Vec2(0.125), uvEnd = Vec2(0.25), size = Vec2i(8, 8), parent = this)
// private val skinElement = ImageElement(guiRenderer, guiRenderer.context.textureManager.steveTexture, uvStart = Vec2(0.125), uvEnd = Vec2(0.25), size = Vec2i(512, 512))
private val nameElement = TextElement(guiRenderer, "", background = false, parent = this)
private val nameElement = TextElement(guiRenderer, "", background = null, parent = this)
private lateinit var pingElement: AtlasImageElement
private var displayName: ChatComponent = item.tabDisplayName

View File

@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements.title
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.time.TimeUtil.millis
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments
@ -36,8 +37,8 @@ import java.lang.Integer.max
// ToDo: Remove subtitle when hidden
class TitleElement(guiRenderer: GUIRenderer) : Element(guiRenderer), LayoutedElement, Initializable {
val title = FadingTextElement(guiRenderer, "", background = false, scale = 4.0f, parent = this)
val subtitle = FadingTextElement(guiRenderer, "", background = false, scale = 2.0f, parent = this)
val title = FadingTextElement(guiRenderer, "", background = null, properties = TextRenderProperties(scale = 4.0f), parent = this)
val subtitle = FadingTextElement(guiRenderer, "", background = null, properties = TextRenderProperties(scale = 2.0f), parent = this)
var fadeInTime = 0L
set(value) {
title.fadeInTime = value

View File

@ -17,6 +17,7 @@ import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.registries.identified.Identified
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
@ -54,13 +55,13 @@ abstract class WawlaElement(protected val wawla: WawlaHUDElement) : Element(wawl
protected fun createNameElement(translationKey: ResourceLocation?): TextElement {
val name = wawla.context.connection.language.forceTranslate(translationKey)
name.setFallbackColor(ChatColors.WHITE)
return TextElement(guiRenderer, name, background = false, scale = 1.2f)
return TextElement(guiRenderer, name, background = null, properties = TextRenderProperties(scale = 1.2f))
}
protected fun createIdentifierElement(item: Identified): TextElement? {
if (!wawla.profile.identifier) {
return null
}
return TextElement(guiRenderer, item.identifier.format(), background = false, scale = 0.8f)
return TextElement(guiRenderer, item.identifier.format(), background = null, properties = TextRenderProperties(scale = 1.2f))
}
}

View File

@ -48,7 +48,7 @@ class BlockWawlaElement(wawla: WawlaHUDElement, val target: BlockTarget) : Wawla
if (namespace == Namespaces.DEFAULT) {
return null
}
return TextElement(guiRenderer, TextComponent(namespace).color(ChatColors.BLUE), background = false)
return TextElement(guiRenderer, TextComponent(namespace).color(ChatColors.BLUE), background = null)
}
private fun createAdditionalInformation(): TextElement? {
@ -69,6 +69,6 @@ class BlockWawlaElement(wawla: WawlaHUDElement, val target: BlockTarget) : Wawla
component.setFallbackColor(ChatColors.GRAY)
return TextElement(guiRenderer, component, background = false)
return TextElement(guiRenderer, component, background = null)
}
}

View File

@ -26,6 +26,7 @@ import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.ChatComponentUtil.removeTrailingNewlines
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.wawla.WawlaElement
@ -50,7 +51,7 @@ class EntityWawlaElement(wawla: WawlaHUDElement, private val target: EntityTarge
val name = target.entity.additional.tabDisplayName
if (name.length > 0) {
name.setFallbackColor(ChatColors.WHITE)
return TextElement(guiRenderer, name, background = false, scale = 1.2f)
return TextElement(guiRenderer, name, background = null, properties = TextRenderProperties(scale = 1.2f))
}
}
return createNameElement(target.entity.type.translationKey)
@ -61,7 +62,7 @@ class EntityWawlaElement(wawla: WawlaHUDElement, private val target: EntityTarge
if (namespace == Namespaces.DEFAULT) {
return null
}
return TextElement(guiRenderer, TextComponent(namespace).color(ChatColors.BLUE), background = false)
return TextElement(guiRenderer, TextComponent(namespace).color(ChatColors.BLUE), background = null)
}
private fun createBaseInformation(): TextElement? {
@ -82,7 +83,7 @@ class EntityWawlaElement(wawla: WawlaHUDElement, private val target: EntityTarge
component.setFallbackColor(ChatColors.GRAY)
return TextElement(guiRenderer, component, background = false)
return TextElement(guiRenderer, component, background = null)
}
private fun createAdditionalInformation(): TextElement? {
@ -95,6 +96,6 @@ class EntityWawlaElement(wawla: WawlaHUDElement, private val target: EntityTarge
text.setFallbackColor(ChatColors.GRAY)
return TextElement(guiRenderer, text, background = false)
return TextElement(guiRenderer, text, background = null)
}
}