Compare commits

..

2 Commits

Author SHA1 Message Date
174f840226
Finish remaking UI rendering
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2026-02-06 01:35:50 +01:00
a20a2d2d8c
Fix box width
Signed-off-by: Username404-59 <w.iron.zombie@gmail.com>
2026-02-06 00:16:01 +01:00
3 changed files with 109 additions and 25 deletions

View File

@ -6,6 +6,7 @@ import fr.username404.snowygui.gui.SnowyScreen
import fr.username404.snowygui.gui.elements.ClickBox import fr.username404.snowygui.gui.elements.ClickBox
import net.minecraft.client.input.MouseButtonEvent import net.minecraft.client.input.MouseButtonEvent
import org.lwjgl.glfw.GLFW import org.lwjgl.glfw.GLFW
import kotlin.math.roundToInt
object ClickGui: SnowyScreen() { object ClickGui: SnowyScreen() {
override val components = mutableSetOf<Element>() override val components = mutableSetOf<Element>()
@ -18,8 +19,8 @@ object ClickGui: SnowyScreen() {
private var draggingBox: String? = null private var draggingBox: String? = null
private inline fun currentBoxContext(args: ClickBox.() -> Unit): Unit? = draggingBox?.run { boxContext { if (name.string == draggingBox) args() } } private inline fun currentBoxContext(args: ClickBox.() -> Unit): Unit? = draggingBox?.run { boxContext { if (name.string == draggingBox) args() } }
private var offsetX: Double = 0.0; private var offsetX: Double = 0.0
private var offsetY: Double = 0.0; private var offsetY: Double = 0.0
override fun mouseClicked(event: MouseButtonEvent, isDoubleClick: Boolean): Boolean { override fun mouseClicked(event: MouseButtonEvent, isDoubleClick: Boolean): Boolean {
if (event.input() == GLFW.GLFW_MOUSE_BUTTON_LEFT) { if (event.input() == GLFW.GLFW_MOUSE_BUTTON_LEFT) {
clickBoxes.find { it.isWithinBounds(event.x, event.y) }?.let { draggingBox = it.name.string } clickBoxes.find { it.isWithinBounds(event.x, event.y) }?.let { draggingBox = it.name.string }
@ -36,8 +37,12 @@ object ClickGui: SnowyScreen() {
override fun mouseDragged(event: MouseButtonEvent, mouseX: Double, mouseY: Double): Boolean { override fun mouseDragged(event: MouseButtonEvent, mouseX: Double, mouseY: Double): Boolean {
if (event.input() == GLFW.GLFW_MOUSE_BUTTON_LEFT) { if (event.input() == GLFW.GLFW_MOUSE_BUTTON_LEFT) {
currentBoxContext { currentBoxContext {
x = (event.x + offsetX).coerceIn(0.0..this@ClickGui.width - width.toDouble()) val targetX = (event.x + offsetX).coerceIn(0.0..this@ClickGui.width - width.toDouble())
y = (event.y + offsetY).coerceIn(0.0..this@ClickGui.height - height.toDouble()) val targetY = (event.y + offsetY).coerceIn(0.0..this@ClickGui.height - height.toDouble())
// Snap to integer pixels => stable spacing
x = targetX.roundToInt().toDouble()
y = targetY.roundToInt().toDouble()
} }
} }
return super.mouseDragged(event, mouseX, mouseY) return super.mouseDragged(event, mouseX, mouseY)

View File

@ -12,6 +12,8 @@ import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.GuiGraphics
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.util.ARGB import net.minecraft.util.ARGB
import kotlin.math.floor
import kotlin.math.roundToInt
import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.ApiStatus
import java.util.TreeSet import java.util.TreeSet
import kotlin.collections.LinkedHashSet import kotlin.collections.LinkedHashSet
@ -73,13 +75,17 @@ class ClickBox(
} }
override fun render(guiGraphics: GuiGraphics?) { override fun render(guiGraphics: GuiGraphics?) {
val xi = floor(x).toInt()
val yi = floor(y).toInt()
// Header // Header
RenderingUtil.drawRectangle( RenderingUtil.drawSlantedHeader(
guiGraphics = guiGraphics, guiGraphics = guiGraphics,
x = x, x = xi,
y = y, y = yi,
height = height,
width = width, width = width,
height = height,
slantTop = inclination,
color = color, color = color,
opacity = opacity opacity = opacity
) )
@ -87,10 +93,10 @@ class ClickBox(
// Body // Body
RenderingUtil.drawRectangle( RenderingUtil.drawRectangle(
guiGraphics = guiGraphics, guiGraphics = guiGraphics,
x = x, x = xi.toDouble(),
y = (y + height), y = (yi + height).toDouble(),
height = clickboxHeightOffset, height = clickboxHeightOffset,
width = width, width = width + inclination.roundToInt(),
color = color, color = color,
opacity = opacity opacity = opacity
) )
@ -98,24 +104,36 @@ class ClickBox(
// Separator line // Separator line
RenderingUtil.hLine( RenderingUtil.hLine(
guiGraphics = guiGraphics, guiGraphics = guiGraphics,
x1 = (x + 0).toInt(), x1 = (xi + inclination).toInt(),
x2 = (x + width).toInt(), x2 = (xi + width),
y = (y + height).toInt(), y = (yi + height),
rgb = Colors.WHITE_LINES.hexValue, rgb = Colors.WHITE_LINES.hexValue,
opacity = 1f opacity = 1f
) )
if (buttons.isNotEmpty()) { if (buttons.isNotEmpty()) {
val barWidth = 3
val leftPadding = 3
val gapToBar = 1
buttonsProgressBar.apply { buttonsProgressBar.apply {
this.x = this@ClickBox.x + this@ClickBox.width - 3 this.width = barWidth
this.x = this@ClickBox.x + this@ClickBox.width - barWidth
this.y = this@ClickBox.y + this@ClickBox.height + 3 this.y = this@ClickBox.y + this@ClickBox.height + 3
}.display(guiGraphics) }.display(guiGraphics)
val buttonWidth = (this@ClickBox.width - leftPadding - barWidth - gapToBar).coerceAtLeast(10)
buttons.forEachIndexed { num, button -> buttons.forEachIndexed { num, button ->
val fullHeight = (y + height.toDouble())..(this.y + height + clickboxHeightOffset) val fullHeight = (y + height.toDouble())..(this.y + height + clickboxHeightOffset)
button.also { button.also {
it.x = this.x + 3 it.x = this.x + leftPadding
it.y = this.y + 3 + height + (((num + 1) - barStage) * 9) it.y = this.y + 3 + height + (((num + 1) - barStage) * 9)
it.hidden = if ((num + 1) <= 8) ((it.y) !in fullHeight) else ((it.y + it.height) !in fullHeight)
it.width = buttonWidth
it.hidden =
if ((num + 1) <= 8) ((it.y) !in fullHeight)
else ((it.y + it.height) !in fullHeight)
}.display(guiGraphics) }.display(guiGraphics)
} }
} }
@ -124,8 +142,9 @@ class ClickBox(
guiGraphics?.drawString( guiGraphics?.drawString(
this, this,
Component.nullToEmpty(name.string), Component.nullToEmpty(name.string),
(x + 5).toInt(), (y + 2).toInt(), (xi + 5 + (inclination / 2f)).toInt(),
ARGB.opaque(Colors.TRANSPARENT.hexValue), (yi + 2),
ARGB.opaque(Colors.WHITE.hexValue),
false false
) )
} }

View File

@ -4,6 +4,10 @@ import com.mojang.blaze3d.opengl.GlStateManager
import fr.username404.snowygui.gui.feature.Colors import fr.username404.snowygui.gui.feature.Colors
import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.GuiGraphics
import net.minecraft.util.ARGB import net.minecraft.util.ARGB
import kotlin.math.ceil
import kotlin.math.floor
import kotlin.math.max
import kotlin.math.min
object RenderingUtil { object RenderingUtil {
fun prepareDraw() = GlStateManager._enableBlend() fun prepareDraw() = GlStateManager._enableBlend()
@ -27,18 +31,74 @@ object RenderingUtil {
color: Int = Colors.TRANSPARENT(), color: Int = Colors.TRANSPARENT(),
opacity: Float = 1F opacity: Float = 1F
) { ) {
if (guiGraphics == null) return
val x1 = floor(x).toInt()
val y1 = floor(y).toInt()
val x2 = ceil(x + width).toInt()
val y2 = ceil(y + height).toInt()
prepareDraw() prepareDraw()
guiGraphics?.fill( guiGraphics.fill(x1, y1, x2, y2, argbFromRgb(color, opacity))
x.toInt(), y.toInt(), endDraw()
(x + width).toInt(), (y + height).toInt(), }
argbFromRgb(color, opacity)
) fun drawSlantedHeader(
guiGraphics: GuiGraphics?,
x: Int,
y: Int,
width: Int,
height: Int,
slantTop: Float,
color: Int,
opacity: Float
) {
if (guiGraphics == null) return
if (width <= 0 || height <= 0) return
val slant = slantTop.toDouble()
val baseArgb = argbFromRgb(color, opacity)
prepareDraw()
for (dy in 0 until height) {
val t = if (height == 1) 0.0 else dy.toDouble() / (height - 1).toDouble()
val leftF = x + slant * (1.0 - t)
val rightF = x + width + slant * t
val left = min(leftF, rightF)
val right = max(leftF, rightF)
val lx = floor(left).toInt()
val rx = floor(right).toInt()
val yy = y + dy
val midStart = lx + 1
val midEnd = rx
if (midEnd > midStart) {
guiGraphics.fill(midStart, yy, midEnd, yy + 1, baseArgb)
}
val leftFrac = (left - floor(left)).toFloat().coerceIn(0f, 1f)
val rightFrac = (right - floor(right)).toFloat().coerceIn(0f, 1f)
val leftAlpha = (1f - leftFrac) * opacity
val rightAlpha = rightFrac * opacity
if (leftAlpha > 0f) guiGraphics.fill(lx, yy, lx + 1, yy + 1, argbFromRgb(color, leftAlpha))
if (rightAlpha > 0f) guiGraphics.fill(rx, yy, rx + 1, yy + 1, argbFromRgb(color, rightAlpha))
if (rx <= lx) {
guiGraphics.fill(lx, yy, lx + 1, yy + 1, baseArgb)
}
}
endDraw() endDraw()
} }
fun hLine(guiGraphics: GuiGraphics?, x1: Int, x2: Int, y: Int, rgb: Int, opacity: Float = 1f) { fun hLine(guiGraphics: GuiGraphics?, x1: Int, x2: Int, y: Int, rgb: Int, opacity: Float = 1f) {
if (guiGraphics == null) return
prepareDraw() prepareDraw()
guiGraphics?.hLine(x1, x2, y, argbFromRgb(rgb, opacity)) guiGraphics.hLine(x1, x2, y, argbFromRgb(rgb, opacity))
endDraw() endDraw()
} }
} }