Add WIP buttons and scrollbars to clickboxes

This commit is contained in:
Username404-59 2021-05-01 15:55:23 +02:00
parent c23ad38d54
commit 09536ddbb1
Signed by: Username404-59
GPG Key ID: 7AB361FBB257A5D1
4 changed files with 158 additions and 36 deletions

View File

@ -3,14 +3,33 @@ package fr.username404.snowygui
import fr.username404.snowygui.gui.Element
import fr.username404.snowygui.gui.SnowyScreen
import fr.username404.snowygui.gui.elements.ClickBox
import fr.username404.snowygui.gui.elements.ClickButton
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import net.minecraft.network.chat.TranslatableComponent
object ClickGui: SnowyScreen() {
private var GuiDragging: Boolean = false
override val components: MutableSet<Element> = mutableSetOf(
ClickBox(4.0, 4.0, TranslatableComponent("snowy.clickbox.misc")),
ClickBox(90.0, 4.0, TranslatableComponent("snowy.clickbox.rendering"))
ClickBox(4.0, 4.0, TranslatableComponent("snowy.clickbox.misc"), mutableListOf(
ClickButton(color = 0x6C9E9D),
ClickButton(color = 0x6C9E9D)
)),
ClickBox(90.0, 4.0, TranslatableComponent("snowy.clickbox.rendering"), mutableListOf(
ClickButton(color = 0x6C9E9D),
ClickButton(color = 0x6C9E9D)
))
)
private inline fun boxContext(args: (ClickBox) -> Unit) = components.filterIsInstance<ClickBox>().forEach(args)
override fun mouseClicked(d: Double, e: Double, i: Int): Boolean { boxContext { it.buttons.forEach { elem -> elem.mouseClicked(d, e, i) } }; return false }
override fun mouseReleased(d: Double, e: Double, i: Int): Boolean { boxContext { it.buttons.forEach { elem -> elem.mouseReleased(d, e, i) } }; return false }
override fun mouseScrolled(d: Double, e: Double, f: Double): Boolean {
boxContext {
it.scrollBar.height // TODO Implement scrolling
}
return false
}
override fun mouseDragged(d: Double, e: Double, i: Int, f: Double, g: Double): Boolean {
if (i == 0) {
components.forEach {
@ -21,6 +40,6 @@ object ClickGui: SnowyScreen() {
} else GuiDragging = false
}
}
return false
return super.mouseDragged(d, e, i, f, g)
}
}

View File

@ -1,15 +1,23 @@
package fr.username404.snowygui.gui
import com.mojang.blaze3d.vertex.BufferBuilder
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.Tesselator
import com.mojang.blaze3d.vertex.VertexConsumer
import com.mojang.blaze3d.vertex.*
import fr.username404.snowygui.Snowy
import org.lwjgl.opengl.GL20
fun interface Renderable {
companion object Rendering {
@JvmStatic val tessellator: Tesselator = Tesselator.getInstance()
@JvmStatic val buffer: BufferBuilder = tessellator.builder
fun ColoredElement.defaultRectFunc() {
with(buffer) {
begin(GL20.GL_QUADS, DefaultVertexFormat.POSITION_COLOR)
vertex(x, y + height, 0.0).colorEnd()
vertex(x + width, y + height, 0.0).colorEnd()
vertex(x + width, y, 0.0).colorEnd()
vertex(x, y, 0.0).colorEnd()
tessellator.end()
}
}
}
fun render(poseStack: PoseStack?)
}
@ -18,7 +26,7 @@ abstract class Element(
@JvmField val xOrigin: Double, @JvmField val yOrigin: Double,
val width: Int, val height: Int
): Renderable {
var x = xOrigin; var y = yOrigin
open var x = xOrigin; open var y = yOrigin
internal fun withinBounds(coordinateX: Double, coordinateY: Double): Boolean =
((coordinateX >= this.x) && (coordinateX <= (this.x + this.width))) and ((coordinateY >= this.y) && (coordinateY <= (this.y + this.height)))
companion object {
@ -44,7 +52,7 @@ abstract class Element(
var hidden: Boolean = false; protected set
}
abstract class ColoredElement(x: Double, y: Double, width: Int, height: Int, private val color: Int, private val opacity: Float) : Element(x, y, width, height) {
abstract class ColoredElement(x: Double, y: Double, width: Int, height: Int, protected open var color: Int, protected var opacity: Float) : Element(x, y, width, height) {
companion object {
const val TransparentColor: Int = -0x1
@JvmStatic protected fun VertexConsumer.colorIt(color: Int, opacity: Float = 1F): VertexConsumer {
@ -53,7 +61,7 @@ abstract class ColoredElement(x: Double, y: Double, width: Int, height: Int, pri
}
}
}
protected fun VertexConsumer.colorEnd(color: Int = this@ColoredElement.color) = colorIt(color, opacity).endVertex()
internal fun VertexConsumer.colorEnd(color: Int = this@ColoredElement.color) = colorIt(color, opacity).endVertex()
}
fun hextoRGB(hex: Int): MutableList<Float> {

View File

@ -5,44 +5,82 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.PoseStack
import fr.username404.snowygui.gui.ColoredElement
import fr.username404.snowygui.gui.Renderable.Rendering.buffer
import fr.username404.snowygui.gui.Renderable.Rendering.defaultRectFunc
import fr.username404.snowygui.gui.Renderable.Rendering.tessellator
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import net.minecraft.client.Minecraft
import net.minecraft.network.chat.TranslatableComponent
import org.lwjgl.opengl.GL20
class ClickBox(x: Double, y: Double, private val name: TranslatableComponent? = null): ColoredElement(x, y, 80, 10, 0x6C9E9D, 0.5F) {
class ClickBox(
x: Double, y: Double,
private val name: TranslatableComponent? = null,
val buttons: MutableCollection<ClickButton> = mutableListOf()
): ColoredElement(x, y, 80, 10, 0x6C9E9D, 0.5F) {
@JvmField
val scrollBar: ColoredElement = object: ColoredElement(
(x + width), y + height + 3,
color = color, width = 3, height = 74,
opacity = 0.75F
) {
override fun render(poseStack: PoseStack?) {
RenderSystem.disableTexture()
RenderSystem.enableBlend()
RenderSystem.defaultBlendFunc()
defaultRectFunc()
RenderSystem.disableBlend()
RenderSystem.enableTexture()
}
}
private companion object {
const val inclination: Double = 2.5
}
override fun render(poseStack: PoseStack?) {
RenderSystem.disableTexture()
RenderSystem.enableBlend()
RenderSystem.defaultBlendFunc()
with(buffer) {
begin(GL20.GL_POLYGON, DefaultVertexFormat.POSITION_COLOR)
// Render the header:
vertex(x, y + height, 0.0).colorEnd()
vertex(x + width + inclination, y + height, 0.0).colorEnd()
vertex(x + width, y, 0.0).colorEnd()
vertex(x + inclination, y, 0.0).colorEnd()
runBlocking {
RenderSystem.disableTexture()
RenderSystem.enableBlend()
RenderSystem.defaultBlendFunc()
with(buffer) {
begin(GL20.GL_POLYGON, DefaultVertexFormat.POSITION_COLOR)
// Render the header:
vertex(x, y + height, 0.0).colorEnd()
vertex(x + width + inclination, y + height, 0.0).colorEnd()
vertex(x + width, y, 0.0).colorEnd()
vertex(x + inclination, y, 0.0).colorEnd()
// Render the box:
val fullHeight = (y + height) + 80
vertex(x, fullHeight, 0.0).colorEnd()
vertex(x + width + inclination, fullHeight, 0.0).colorEnd()
vertex(x + width + inclination, y + height, 0.0).colorEnd()
tessellator.end()
// Render the box:
val currentHeight = (y + height) + 80.0
vertex(x, currentHeight, 0.0).colorEnd()
vertex(x + width + inclination, currentHeight, 0.0).colorEnd()
vertex(x + width + inclination, y + height, 0.0).colorEnd()
tessellator.end()
begin(GL20.GL_LINES, DefaultVertexFormat.POSITION_COLOR)
vertex(x + inclination, y + height, 0.0).colorEnd(0xF2F2FC)
vertex(x + width, y + height, 0.0).colorEnd(0xF2F2FC)
tessellator.end()
}
RenderSystem.enableTexture()
RenderSystem.disableBlend()
begin(GL20.GL_LINES, DefaultVertexFormat.POSITION_COLOR)
vertex(x + inclination, y + height, 0.0).colorEnd(0xF2F2FC)
vertex(x + width, y + height, 0.0).colorEnd(0xF2F2FC)
tessellator.end()
}
RenderSystem.enableTexture()
RenderSystem.disableBlend()
if ((name != null) && (poseStack != null)) {
Minecraft.getInstance().font.draw(poseStack, name.string, x.toFloat() + 5, y.toFloat() + 1.5F, TransparentColor)
val renderButtons = if (buttons.isNotEmpty()) launch {
scrollBar.apply {
x = this@ClickBox.x + this@ClickBox.width - 3
y = this@ClickBox.y + this@ClickBox.height + 3
}.display(poseStack)
buttons.forEachIndexed { num, it ->
it.apply {
it.x = this@ClickBox.x + 3
it.y = this@ClickBox.y + 5 + height + (num * 9)
}.display(poseStack)
}
} else null
if ((name != null) && (poseStack != null)) {
Minecraft.getInstance().font.draw(poseStack, name.string, x.toFloat() + 5, y.toFloat() + 1.5F, TransparentColor)
renderButtons?.join()
}
}
}
}

View File

@ -0,0 +1,57 @@
package fr.username404.snowygui.gui.elements
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack
import fr.username404.snowygui.gui.ColoredElement
import fr.username404.snowygui.gui.Renderable.Rendering.defaultRectFunc
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import net.minecraft.client.gui.components.events.GuiEventListener
class ClickButton(
x: Double = 0.0, y: Double = 0.0,
width: Int = 73, height: Int = 8,
color: Int, private val kind: Type = Type.TOGGLE,
val action: (() -> Unit)? = null
): ColoredElement(x, y, width, height, color, 0.60F), GuiEventListener {
companion object {
enum class Type {
TOGGLE,
CLICK
}
internal var lightningFactor: Float = 0.33F
}
fun execAction() {
runBlocking {
action?.let {
launch {
it.invoke()
}
}
}
}
private var wasWithinBounds: Boolean = false
private var toggled: Boolean = false
private fun lightUp() { opacity += lightningFactor }
private fun lightDown() { opacity -= lightningFactor }
override fun mouseClicked(d: Double, e: Double, i: Int): Boolean {
wasWithinBounds = withinBounds(d, e).also { if (it) lightUp() }
return false
}
override fun mouseReleased(d: Double, e: Double, i: Int): Boolean {
if (wasWithinBounds) {
lightDown()
execAction()
}
return false
}
override fun render(poseStack: PoseStack?) {
RenderSystem.disableTexture()
RenderSystem.enableBlend()
defaultRectFunc()
RenderSystem.enableTexture()
RenderSystem.disableBlend()
}
}