From 8b5c9d3cb65a6e3f56184391e5241dd2a12404ae Mon Sep 17 00:00:00 2001 From: "Simon E.W" Date: Mon, 11 Mar 2024 22:38:37 +0100 Subject: [PATCH] Add support for different padding on all 4 sides --- .../voidui/rendering/Renderer.kt | 9 +++ .../com/neptuneclient/voidui/ui/Component.kt | 6 +- .../com/neptuneclient/voidui/ui/Drawable.kt | 5 +- .../voidui/ui/ReactiveComponent.kt | 5 +- .../voidui/ui/StaticComponent.kt | 6 +- .../voidui/ui/elements/Element.kt | 5 +- .../neptuneclient/voidui/ui/elements/Text.kt | 12 +++- .../voidui/ui/objects/EdgeInsets.kt | 57 +++++++++++++++++++ .../voidui/tests/MockRenderer.kt | 5 ++ .../voidui/tests/TestRenderer.kt | 6 ++ .../com/neptuneclient/voidui/tests/tests.kt | 7 ++- 11 files changed, 109 insertions(+), 14 deletions(-) create mode 100644 src/main/kotlin/com/neptuneclient/voidui/ui/objects/EdgeInsets.kt diff --git a/src/main/kotlin/com/neptuneclient/voidui/rendering/Renderer.kt b/src/main/kotlin/com/neptuneclient/voidui/rendering/Renderer.kt index 3c1e859..e03865c 100644 --- a/src/main/kotlin/com/neptuneclient/voidui/rendering/Renderer.kt +++ b/src/main/kotlin/com/neptuneclient/voidui/rendering/Renderer.kt @@ -78,4 +78,13 @@ interface Renderer { text(x.toFloat(), y.toFloat(), text, font, color) } + /** + * Returns the bounds of the given text with the given font. + * + * @param text text to measure + * @param font font of the text + * @return the width and height of the text + */ + fun getTextBounds(text: String, font: Font): Pair + } \ No newline at end of file diff --git a/src/main/kotlin/com/neptuneclient/voidui/ui/Component.kt b/src/main/kotlin/com/neptuneclient/voidui/ui/Component.kt index a0ef534..53a4af8 100644 --- a/src/main/kotlin/com/neptuneclient/voidui/ui/Component.kt +++ b/src/main/kotlin/com/neptuneclient/voidui/ui/Component.kt @@ -1,5 +1,7 @@ package com.neptuneclient.voidui.ui +import com.neptuneclient.voidui.ui.objects.EdgeInsets + /** * Components are a small reusable chunk of drawables. Syntactically they are very similar to screens, but instead of being * displayed on the screen, you can use them just like elements within other parts of your UI. @@ -14,8 +16,8 @@ sealed class Component( width: Int? = null, height: Int? = null, - margin: Int? = null, - padding: Int? = null, + margin: EdgeInsets = EdgeInsets.zero, + padding: EdgeInsets = EdgeInsets.zero, val children: MutableList? = null ) : Drawable(x, y, width, height, margin, padding) { diff --git a/src/main/kotlin/com/neptuneclient/voidui/ui/Drawable.kt b/src/main/kotlin/com/neptuneclient/voidui/ui/Drawable.kt index d89cca7..f35c19c 100644 --- a/src/main/kotlin/com/neptuneclient/voidui/ui/Drawable.kt +++ b/src/main/kotlin/com/neptuneclient/voidui/ui/Drawable.kt @@ -1,6 +1,7 @@ package com.neptuneclient.voidui.ui import com.neptuneclient.voidui.VoidUI +import com.neptuneclient.voidui.ui.objects.EdgeInsets /** * The base class for anything which represents an object in the UI. @@ -11,8 +12,8 @@ abstract class Drawable( var width: Int? = null, var height: Int? = null, - var margin: Int? = null, - var padding: Int? = null + var margin: EdgeInsets = EdgeInsets.zero, + var padding: EdgeInsets = EdgeInsets.zero ) { /** diff --git a/src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt b/src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt index 9d74a3c..0a85b45 100644 --- a/src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt +++ b/src/main/kotlin/com/neptuneclient/voidui/ui/ReactiveComponent.kt @@ -1,5 +1,6 @@ package com.neptuneclient.voidui.ui +import com.neptuneclient.voidui.ui.objects.EdgeInsets import kotlin.properties.Delegates /** @@ -11,8 +12,8 @@ abstract class ReactiveComponent( width: Int? = null, height: Int? = null, - margin: Int? = null, - padding: Int? = null, + margin: EdgeInsets = EdgeInsets.zero, + padding: EdgeInsets = EdgeInsets.zero, children: MutableList? = null ) : Component(x, y, width, height, margin, padding, children) { diff --git a/src/main/kotlin/com/neptuneclient/voidui/ui/StaticComponent.kt b/src/main/kotlin/com/neptuneclient/voidui/ui/StaticComponent.kt index d39d707..4d63aff 100644 --- a/src/main/kotlin/com/neptuneclient/voidui/ui/StaticComponent.kt +++ b/src/main/kotlin/com/neptuneclient/voidui/ui/StaticComponent.kt @@ -1,5 +1,7 @@ package com.neptuneclient.voidui.ui +import com.neptuneclient.voidui.ui.objects.EdgeInsets + /** * @see Component */ @@ -9,8 +11,8 @@ abstract class StaticComponent( width: Int? = null, height: Int? = null, - margin: Int? = null, - padding: Int? = null, + margin: EdgeInsets = EdgeInsets.zero, + padding: EdgeInsets = EdgeInsets.zero, children: MutableList? = null ) : Component(x, y, width, height, margin, padding, children) \ No newline at end of file diff --git a/src/main/kotlin/com/neptuneclient/voidui/ui/elements/Element.kt b/src/main/kotlin/com/neptuneclient/voidui/ui/elements/Element.kt index 7f60105..690aba1 100644 --- a/src/main/kotlin/com/neptuneclient/voidui/ui/elements/Element.kt +++ b/src/main/kotlin/com/neptuneclient/voidui/ui/elements/Element.kt @@ -2,6 +2,7 @@ package com.neptuneclient.voidui.ui.elements import com.neptuneclient.voidui.rendering.Renderer import com.neptuneclient.voidui.ui.Drawable +import com.neptuneclient.voidui.ui.objects.EdgeInsets /** * Elements are the core building blocks of the library. They can not be created by the user and do not have children. @@ -13,8 +14,8 @@ sealed class Element( width: Int? = null, height: Int? = null, - margin: Int? = null, - padding: Int? = null + margin: EdgeInsets = EdgeInsets.zero, + padding: EdgeInsets = EdgeInsets.zero ) : Drawable(x, y, width, height, margin, padding) { abstract fun render() diff --git a/src/main/kotlin/com/neptuneclient/voidui/ui/elements/Text.kt b/src/main/kotlin/com/neptuneclient/voidui/ui/elements/Text.kt index 3fb48f3..49986cc 100644 --- a/src/main/kotlin/com/neptuneclient/voidui/ui/elements/Text.kt +++ b/src/main/kotlin/com/neptuneclient/voidui/ui/elements/Text.kt @@ -1,5 +1,6 @@ package com.neptuneclient.voidui.ui.elements +import com.neptuneclient.voidui.ui.objects.EdgeInsets import com.neptuneclient.voidui.utils.Font import java.awt.Color @@ -7,15 +8,22 @@ class Text( val text: String, val font: Font, val color: Color, + val backgroundColor: Color = Color(0, 0, 0, 0), x: Int? = null, y: Int? = null, - margin: Int? = null -) : Element(x, y, null, null, margin) { + margin: EdgeInsets = EdgeInsets.zero, + padding: EdgeInsets = EdgeInsets.zero +) : Element(x, y, null, null, margin, padding) { override fun render() { draw { + val (width, height) = getTextBounds(text, font) + val rectX = x!! - padding.left + val rectY = y!! - height - padding.top + rectangle(rectX, rectY, padding.horizontal + width, padding.vertical + height, backgroundColor) text(x!!, y!!, text, font, color) + rectangle(x!!, y!!, 1, 1, Color(255, 0, 0)) } } diff --git a/src/main/kotlin/com/neptuneclient/voidui/ui/objects/EdgeInsets.kt b/src/main/kotlin/com/neptuneclient/voidui/ui/objects/EdgeInsets.kt new file mode 100644 index 0000000..819fa36 --- /dev/null +++ b/src/main/kotlin/com/neptuneclient/voidui/ui/objects/EdgeInsets.kt @@ -0,0 +1,57 @@ +package com.neptuneclient.voidui.ui.objects + +data class EdgeInsets( + val left: Float, + val top: Float, + val right: Float, + val bottom: Float, +) { + companion object { + @JvmStatic + fun all(value: Float) = EdgeInsets(value, value, value, value) + @JvmStatic + fun only( + left: Float = 0f, + top: Float = 0f, + right: Float = 0f, + bottom: Float = 0f + ) = EdgeInsets(left, top, right, bottom) + @JvmStatic + fun symmetric( + vertical: Float = 0f, + horizontal: Float = 0f + ) = EdgeInsets(horizontal, vertical, horizontal, vertical) + val zero = EdgeInsets(0f, 0f, 0f, 0f) + } + + val horizontal get() = left + right + val vertical get() = top + bottom + + operator fun plus(other: EdgeInsets) = EdgeInsets( + left + other.left, + top + other.top, + right + other.right, + bottom + other.bottom + ) + + operator fun minus(other: EdgeInsets) = EdgeInsets( + left - other.left, + top - other.top, + right - other.right, + bottom - other.bottom + ) + + operator fun times(other: EdgeInsets) = EdgeInsets( + left * other.left, + top * other.top, + right * other.right, + bottom * other.bottom + ) + + operator fun div(other: EdgeInsets) = EdgeInsets( + left / other.left, + top / other.top, + right / other.right, + bottom / other.bottom + ) +} \ No newline at end of file diff --git a/src/test/kotlin/com/neptuneclient/voidui/tests/MockRenderer.kt b/src/test/kotlin/com/neptuneclient/voidui/tests/MockRenderer.kt index 15d2077..2c94b76 100644 --- a/src/test/kotlin/com/neptuneclient/voidui/tests/MockRenderer.kt +++ b/src/test/kotlin/com/neptuneclient/voidui/tests/MockRenderer.kt @@ -28,4 +28,9 @@ class MockRenderer: Renderer { override fun text(x: Float, y: Float, text: String, font: Font, color: Color) { println("text") } + + override fun getTextBounds(text: String, font: Font): Pair { + println("getTextBounds") + return Pair(0f, 0f) + } } \ No newline at end of file diff --git a/src/test/kotlin/com/neptuneclient/voidui/tests/TestRenderer.kt b/src/test/kotlin/com/neptuneclient/voidui/tests/TestRenderer.kt index 68c934b..0fb5fab 100644 --- a/src/test/kotlin/com/neptuneclient/voidui/tests/TestRenderer.kt +++ b/src/test/kotlin/com/neptuneclient/voidui/tests/TestRenderer.kt @@ -2,6 +2,7 @@ package com.neptuneclient.voidui.tests import com.neptuneclient.voidui.rendering.Renderer import com.neptuneclient.voidui.utils.Font +import org.lwjgl.BufferUtils import org.lwjgl.glfw.GLFW import org.lwjgl.nanovg.NVGColor import org.lwjgl.nanovg.NanoVG @@ -10,6 +11,7 @@ import org.lwjgl.opengl.GL import org.lwjgl.opengl.GL11 import org.lwjgl.system.MemoryStack import java.awt.Color +import java.nio.FloatBuffer import kotlin.math.max class TestRenderer : Renderer { @@ -146,4 +148,8 @@ class TestRenderer : Renderer { NanoVG.nvgClosePath(vg) } } + + override fun getTextBounds(text: String, font: Font): Pair { + TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/src/test/kotlin/com/neptuneclient/voidui/tests/tests.kt b/src/test/kotlin/com/neptuneclient/voidui/tests/tests.kt index 269f5a3..bfd158b 100644 --- a/src/test/kotlin/com/neptuneclient/voidui/tests/tests.kt +++ b/src/test/kotlin/com/neptuneclient/voidui/tests/tests.kt @@ -2,6 +2,7 @@ package com.neptuneclient.voidui.tests import com.neptuneclient.voidui.VoidUI import com.neptuneclient.voidui.ui.elements.Text +import com.neptuneclient.voidui.ui.objects.EdgeInsets import com.neptuneclient.voidui.utils.Font import org.junit.jupiter.api.Test import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable @@ -24,14 +25,16 @@ class FontTest() { y = 100, text = "Hello World!", font = font, - color = Color.WHITE + color = Color.WHITE, + padding = EdgeInsets.all(50f), + backgroundColor = Color.BLUE, ) text.void = void val renderer = void.renderer as TestRenderer while (!GLFW.glfwWindowShouldClose(renderer.window)) { renderer.beginFrame() - renderer.roundedRectangle(0f, 0f, 100f, 100f, 20f, Color.RED) +// renderer.roundedRectangle(0f, 0f, 100f, 100f, 20f, Color.RED) text.render() renderer.endFrame() }