Label improvements
Add shadow, line wrapping, line maximum
This commit is contained in:
parent
cb66900cb5
commit
f29e690208
|
@ -44,6 +44,8 @@ class TestCacaoScreen: CacaoScreen() {
|
|||
}
|
||||
})
|
||||
|
||||
val label = addView(Label("test ".repeat(100), maxLines = 5))
|
||||
|
||||
solver.dsl {
|
||||
stack.topAnchor equalTo 0
|
||||
stack.centerXAnchor equalTo this@apply.centerXAnchor
|
||||
|
@ -51,9 +53,11 @@ class TestCacaoScreen: CacaoScreen() {
|
|||
purple.centerXAnchor equalTo blue.centerXAnchor
|
||||
purple.centerYAnchor equalTo blue.centerYAnchor
|
||||
// purple.widthAnchor equalTo 50
|
||||
}
|
||||
|
||||
layout()
|
||||
label.topAnchor equalTo 0
|
||||
label.leftAnchor equalTo 0
|
||||
label.widthAnchor equalTo 100
|
||||
}
|
||||
|
||||
|
||||
// val red = addView(View().apply {
|
||||
|
|
|
@ -86,7 +86,7 @@ class Window {
|
|||
* Creates the internal constraints used by the window.
|
||||
* If overridden, the super-class method must be called.
|
||||
*/
|
||||
protected open fun createInternalConstraints() {
|
||||
protected fun createInternalConstraints() {
|
||||
solver.dsl {
|
||||
leftAnchor equalTo 0
|
||||
topAnchor equalTo 0
|
||||
|
|
|
@ -6,6 +6,7 @@ import net.shadowfacts.cacao.geometry.Point
|
|||
import net.shadowfacts.cacao.geometry.Size
|
||||
import net.shadowfacts.cacao.util.Color
|
||||
import net.shadowfacts.cacao.util.RenderHelper
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* A simple View that displays text. Allows for controlling the color and shadow of the text. Label cannot be used
|
||||
|
@ -13,14 +14,29 @@ import net.shadowfacts.cacao.util.RenderHelper
|
|||
*
|
||||
* @author shadowfacts
|
||||
* @param text The text of this label.
|
||||
* @param shadow Whether the text should be rendered with a shadow or not.
|
||||
* @param maxLines The maximum number of lines of text to render.
|
||||
* `0` means that there is no line limit and all lines will be rendered.
|
||||
* When using a non-zero [maxLines] value, the [intrinsicContentSize] of the Label still assumes all
|
||||
* content on one line. So, constraints must be provided to calculate the actual width to use for line
|
||||
* wrapping.
|
||||
*/
|
||||
class Label(text: String): View() {
|
||||
class Label(
|
||||
text: String,
|
||||
val shadow: Boolean = true,
|
||||
val maxLines: Int = 0,
|
||||
val wrappingMode: WrappingMode = WrappingMode.WRAP
|
||||
): View() {
|
||||
|
||||
companion object {
|
||||
private val textRenderer: TextRenderer
|
||||
get() = MinecraftClient.getInstance().textRenderer
|
||||
}
|
||||
|
||||
enum class WrappingMode {
|
||||
WRAP, NO_WRAP
|
||||
}
|
||||
|
||||
/**
|
||||
* The text of this label. Mutating this field will update the intrinsic content size and trigger a layout.
|
||||
*/
|
||||
|
@ -28,9 +44,20 @@ class Label(text: String): View() {
|
|||
set(value) {
|
||||
field = value
|
||||
updateIntrinsicContentSize()
|
||||
window.layout()
|
||||
}
|
||||
private lateinit var lines: List<String>
|
||||
|
||||
var textColor = Color.WHITE
|
||||
set(value) {
|
||||
field = value
|
||||
textColorARGB = value.argb
|
||||
}
|
||||
private var textColorARGB: Int = textColor.argb
|
||||
|
||||
private val drawFunc by lazy {
|
||||
if (shadow) textRenderer::drawWithShadow else textRenderer::draw
|
||||
}
|
||||
|
||||
override fun wasAdded() {
|
||||
super.wasAdded()
|
||||
|
@ -47,7 +74,34 @@ class Label(text: String): View() {
|
|||
}
|
||||
|
||||
override fun drawContent(mouse: Point, delta: Float) {
|
||||
textRenderer.draw(text, 0f, 0f, textColor.argb)
|
||||
if (!this::lines.isInitialized) {
|
||||
computeLines()
|
||||
}
|
||||
|
||||
for (i in 0 until lines.size) {
|
||||
val y = i * textRenderer.fontHeight
|
||||
drawFunc(lines[i], 0f, y.toFloat(), textColorARGB)
|
||||
}
|
||||
}
|
||||
|
||||
override fun didLayout() {
|
||||
super.didLayout()
|
||||
|
||||
computeLines()
|
||||
}
|
||||
|
||||
private fun computeLines() {
|
||||
var lines = text.split("\n")
|
||||
if (wrappingMode == WrappingMode.WRAP) {
|
||||
lines = lines.flatMap {
|
||||
val maxWidth = bounds.width.toInt()
|
||||
textRenderer.wrapStringToWidthAsList(it, maxWidth)
|
||||
}
|
||||
}
|
||||
if (0 < maxLines && maxLines < lines.size) {
|
||||
lines = lines.dropLast(lines.size - maxLines)
|
||||
}
|
||||
this.lines = lines
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue