From 6901ba1b465ab3bd205fcbb39b12e147242f5230 Mon Sep 17 00:00:00 2001 From: Zywl <86253343+opZywl@users.noreply.github.com> Date: Mon, 6 Jan 2025 21:14:04 -0300 Subject: [PATCH] feat: ColorValue for RGBColors --- .../net/ccbluex/liquidbounce/config/Value.kt | 67 ++++++++ .../clickgui/style/styles/BlackStyle.kt | 155 ++++++++++++++++-- .../style/styles/LiquidBounceStyle.kt | 134 +++++++++++++++ .../client/clickgui/style/styles/NullStyle.kt | 138 ++++++++++++++++ .../clickgui/style/styles/SlowlyStyle.kt | 142 ++++++++++++++++ .../liquidbounce/utils/render/RenderUtils.kt | 25 +++ 6 files changed, 649 insertions(+), 12 deletions(-) diff --git a/src/main/java/net/ccbluex/liquidbounce/config/Value.kt b/src/main/java/net/ccbluex/liquidbounce/config/Value.kt index 7df1c2378e3..a111a2165b5 100644 --- a/src/main/java/net/ccbluex/liquidbounce/config/Value.kt +++ b/src/main/java/net/ccbluex/liquidbounce/config/Value.kt @@ -16,6 +16,7 @@ import net.ccbluex.liquidbounce.utils.client.ClientUtils.LOGGER import net.ccbluex.liquidbounce.utils.kotlin.RandomUtils.nextFloat import net.ccbluex.liquidbounce.utils.kotlin.RandomUtils.nextInt import net.minecraft.client.gui.FontRenderer +import java.awt.Color import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty @@ -378,6 +379,72 @@ open class ListValue( } } +class ColorValue( + name: String, + defaultColor: Color, + var rainbow: Boolean = false, + var showPicker: Boolean = false +) : Value(name, defaultColor) { + + var hue = 0f + var saturation = 1f + var brightness = 1f + var alpha = 1f + + init { + changeValue(defaultColor) + } + + fun getColor(): Color { + val base = Color.getHSBColor(hue, saturation, brightness) + val finalAlpha = (alpha * 255).toInt().coerceIn(0, 255) + return Color(base.red, base.green, base.blue, finalAlpha) + } + + fun setColor(color: Color) { + set(color) + } + + override fun onInit(value: Color) { + val r = value.red + val g = value.green + val b = value.blue + val a = value.alpha + val hsb = Color.RGBtoHSB(r, g, b, null) + hue = hsb[0] + saturation = hsb[1] + brightness = hsb[2] + alpha = a / 255f + } + + override fun onChange(oldValue: Color, newValue: Color): Color { + val r = newValue.red + val g = newValue.green + val b = newValue.blue + val a = newValue.alpha + val hsb = Color.RGBtoHSB(r, g, b, null) + hue = hsb[0] + saturation = hsb[1] + brightness = hsb[2] + alpha = a / 255f + return newValue + } + + override fun toJsonF(): JsonElement? { + val argbHex = "#%08X".format(value.rgb) + return JsonPrimitive(argbHex) + } + + override fun fromJsonF(element: JsonElement): Color? { + if (element.isJsonPrimitive) { + val raw = element.asString.removePrefix("#") + val argb = raw.toLongOrNull(16)?.toInt() + if (argb != null) return Color(argb, true) + } + return null + } +} + fun int( name: String, value: Int, diff --git a/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/BlackStyle.kt b/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/BlackStyle.kt index cdc30a6179a..8552bd013b8 100644 --- a/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/BlackStyle.kt +++ b/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/BlackStyle.kt @@ -5,6 +5,7 @@ */ package net.ccbluex.liquidbounce.ui.client.clickgui.style.styles +import net.ccbluex.liquidbounce.config.* import net.ccbluex.liquidbounce.features.module.modules.render.ClickGUI.scale import net.ccbluex.liquidbounce.ui.client.clickgui.ClickGui.clamp import net.ccbluex.liquidbounce.ui.client.clickgui.Panel @@ -17,10 +18,11 @@ import net.ccbluex.liquidbounce.utils.block.BlockUtils.getBlockName import net.ccbluex.liquidbounce.utils.extensions.component1 import net.ccbluex.liquidbounce.utils.extensions.component2 import net.ccbluex.liquidbounce.utils.extensions.lerpWith +import net.ccbluex.liquidbounce.utils.render.ColorUtils +import net.ccbluex.liquidbounce.utils.render.RenderUtils import net.ccbluex.liquidbounce.utils.render.RenderUtils.drawBorderedRect import net.ccbluex.liquidbounce.utils.render.RenderUtils.drawFilledCircle import net.ccbluex.liquidbounce.utils.render.RenderUtils.drawRect -import net.ccbluex.liquidbounce.config.* import net.minecraft.client.gui.ScaledResolution import net.minecraft.util.StringUtils import net.minecraftforge.fml.relauncher.Side @@ -247,10 +249,8 @@ object BlackStyle : Style() { ) ) - // Keep changing this slider until mouse is unpressed. sliderValueHeld = value - // Stop rendering and interacting only when this event was triggered by a mouse click. if (mouseButton == 0) return true } @@ -288,10 +288,8 @@ object BlackStyle : Style() { .coerceIn(value.range) ) - // Keep changing this slider until mouse is unpressed. sliderValueHeld = value - // Stop rendering and interacting only when this event was triggered by a mouse click. if (mouseButton == 0) return true } @@ -331,10 +329,8 @@ object BlackStyle : Style() { value.setFirst(value.lerpWith(percentage).coerceIn(value.minimum, slider2)) } else value.setLast(value.lerpWith(percentage).coerceIn(slider1, value.maximum)) - // Keep changing this slider until mouse is unpressed. sliderValueHeld = value - // Stop rendering and interacting only when this event was triggered by a mouse click. if (mouseButton == 0) return true } @@ -383,10 +379,8 @@ object BlackStyle : Style() { value.setFirst(value.lerpWith(percentage).coerceIn(value.minimum, slider2)) } else value.setLast(value.lerpWith(percentage).coerceIn(slider1, value.maximum)) - // Keep changing this slider until mouse is unpressed. sliderValueHeld = value - // Stop rendering and interacting only when this event was triggered by a mouse click. if (mouseButton == 0) return true } @@ -415,9 +409,7 @@ object BlackStyle : Style() { font35.drawString(displayString, minX + 2, yPos + 2, Color.WHITE.rgb) if (mouseButton != null && mouseX in minX..maxX && mouseY in yPos..yPos + 12) { - // Cycle to next font when left-clicked, previous when right-clicked. - if (mouseButton == 0) value.next() - else value.previous() + if (mouseButton == 0) value.next() else value.previous() clickSound() return true } @@ -425,6 +417,141 @@ object BlackStyle : Style() { yPos += 11 } + is ColorValue -> { + val colorValue = value + + val currentColor = if (colorValue.rainbow) { + ColorUtils.rainbow() + } else { + colorValue.get() + } + + val previewSize = 10 + val previewX1 = moduleElement.x + moduleElement.width + 4 + val previewY1 = yPos + 2 + val previewX2 = previewX1 + previewSize + val previewY2 = previewY1 + previewSize + + drawRect(previewX1, previewY1, previewX2, previewY2, currentColor.rgb) + + if (mouseButton == 0 && mouseX in previewX1..previewX2 && mouseY in previewY1..previewY2) { + colorValue.showPicker = !colorValue.showPicker + clickSound() + return true + } + + if (!colorValue.showPicker) { + yPos += (previewSize + 6) + return false + } + + if (!colorValue.rainbow) { + val hsb = Color.RGBtoHSB(currentColor.red, currentColor.green, currentColor.blue, null) + var hue = hsb[0] + var saturation = hsb[1] + var brightness = hsb[2] + + val colorPickerWidth = 75 + val colorPickerHeight = 50 + val hueSliderWidth = 7 + val hueSliderHeight = 50 + + val startX = previewX1 + val startY = previewY1 + previewSize + 4 + + font35.drawStringWithShadow( + "Color", + (startX + 1).toFloat(), + (startY - 10).toFloat(), + 0xFFFFFFFF.toInt() + ) + + for (px in 0 until colorPickerWidth) { + for (py in 0 until colorPickerHeight) { + val localS = px / colorPickerWidth.toFloat() + val localB = 1.0f - (py / colorPickerHeight.toFloat()) + val rgb = Color.HSBtoRGB(hue, localS, localB) + drawRect(startX + px, startY + py, startX + px + 1, startY + py + 1, rgb) + } + } + + val markerX = startX + (saturation * colorPickerWidth).toInt() + val markerY = startY + ((1.0f - brightness) * colorPickerHeight).toInt() + RenderUtils.drawBorderedRectRGB( + markerX - 2, markerY - 2, + markerX + 3, markerY + 3, + 1.0f, + 0xFFFFFFFF.toInt(), + 0x00000000 + ) + + val hueSliderX = startX + colorPickerWidth + 5 + val hueSliderY = startY + for (i in 0 until hueSliderHeight) { + val localHue = i / hueSliderHeight.toFloat() + val rgb = Color.HSBtoRGB(localHue, 1.0f, 1.0f) + drawRect(hueSliderX, hueSliderY + i, hueSliderX + hueSliderWidth, hueSliderY + i + 1, rgb) + } + + val hueMarkerY = hueSliderY + (hue * hueSliderHeight).toInt() + RenderUtils.drawBorderedRectRGB( + hueSliderX - 1, hueMarkerY - 1, + hueSliderX + hueSliderWidth + 1, hueMarkerY + 2, + 1.0f, + 0xFFFFFFFF.toInt(), + 0x00000000 + ) + + val inColorPicker = + (mouseX in startX until (startX + colorPickerWidth)) && + (mouseY in startY until (startY + colorPickerHeight)) + + val inHueSlider = + (mouseX in hueSliderX until (hueSliderX + hueSliderWidth)) && + (mouseY in hueSliderY until (hueSliderY + hueSliderHeight)) + + if ((mouseButton == 0 || sliderValueHeld == colorValue) && (inColorPicker || inHueSlider)) { + if (inColorPicker) { + val newS = ((mouseX - startX) / colorPickerWidth.toFloat()).coerceIn(0f, 1f) + val newB = (1.0f - ((mouseY - startY) / colorPickerHeight.toFloat())).coerceIn(0f, 1f) + saturation = newS + brightness = newB + } + if (inHueSlider) { + val newH = ((mouseY - hueSliderY) / hueSliderHeight.toFloat()).coerceIn(0f, 1f) + hue = newH + } + + sliderValueHeld = colorValue + + if (mouseButton == 0) { + return true + } + } + + val finalRGB = Color.HSBtoRGB(hue, saturation, brightness) + val finalColor = Color(finalRGB) + colorValue.set(finalColor) + + val previewSubSize = 6 + drawRect( + startX + 75, + startY - 10, + startX + 75 + previewSubSize, + startY - 10 + previewSubSize, + finalColor.rgb + ) + + yPos += colorPickerHeight + previewSize + 6 + } else { + yPos += previewSize + 15 + } + + if (mouseButton == -1) { + sliderValueHeld = null + } + } + else -> { val text = value.name + "§f: " + value.get() @@ -443,6 +570,10 @@ object BlackStyle : Style() { } } + if (mouseButton == -1) { + sliderValueHeld = null + } + return false } } \ No newline at end of file diff --git a/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/LiquidBounceStyle.kt b/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/LiquidBounceStyle.kt index 8b709459d1b..450a90af266 100644 --- a/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/LiquidBounceStyle.kt +++ b/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/LiquidBounceStyle.kt @@ -21,6 +21,7 @@ import net.ccbluex.liquidbounce.utils.extensions.lerpWith import net.ccbluex.liquidbounce.utils.render.RenderUtils.drawBorderedRect import net.ccbluex.liquidbounce.utils.render.RenderUtils.drawRect import net.ccbluex.liquidbounce.config.* +import net.ccbluex.liquidbounce.utils.render.RenderUtils import net.minecraft.client.gui.ScaledResolution import net.minecraft.util.StringUtils import net.minecraftforge.fml.relauncher.Side @@ -388,6 +389,139 @@ object LiquidBounceStyle : Style() { yPos += 11 } + is ColorValue -> { + val colorValue = value + + val currentColor = if (colorValue.rainbow) { + colorValue.get() + } else { + colorValue.get() + } + + val previewSize = 10 + val previewX1 = moduleElement.x + moduleElement.width + 4 + val previewY1 = yPos + 2 + val previewX2 = previewX1 + previewSize + val previewY2 = previewY1 + previewSize + + drawRect(previewX1, previewY1, previewX2, previewY2, currentColor.rgb) + + if (mouseButton == 0 && mouseX in previewX1..previewX2 && mouseY in previewY1..previewY2) { + colorValue.showPicker = !colorValue.showPicker + clickSound() + return true + } + + if (!colorValue.showPicker) { + yPos += previewSize + 6 + return false + + if (!colorValue.rainbow) { + val hsb = Color.RGBtoHSB(currentColor.red, currentColor.green, currentColor.blue, null) + var hue = hsb[0] + var saturation = hsb[1] + var brightness = hsb[2] + + val colorPickerWidth = 75 + val colorPickerHeight = 50 + val hueSliderWidth = 7 + val hueSliderHeight = 50 + + val startX = previewX1 + val startY = previewY1 + previewSize + 4 + + drawRect(startX - 2, startY - 12, startX + colorPickerWidth + hueSliderWidth + 10, startY + colorPickerHeight + 2, Color(30, 30, 30, 160).rgb) + + font35.drawStringWithShadow( + "Color", + (startX + 1).toFloat(), + (startY - 10).toFloat(), + 0xFFFFFFFF.toInt() + ) + + for (px in 0 until colorPickerWidth) { + for (py in 0 until colorPickerHeight) { + val localS = px / colorPickerWidth.toFloat() + val localB = 1.0f - (py / colorPickerHeight.toFloat()) + val rgb = Color.HSBtoRGB(hue, localS, localB) + drawRect(startX + px, startY + py, startX + px + 1, startY + py + 1, rgb) + } + } + + val markerX = startX + (saturation * colorPickerWidth).toInt() + val markerY = startY + ((1.0f - brightness) * colorPickerHeight).toInt() + RenderUtils.drawBorderedRectRGB( + markerX - 2, markerY - 2, + markerX + 3, markerY + 3, + 1.0f, + 0xFFFFFFFF.toInt(), + 0x00000000 + ) + + val hueSliderX = startX + colorPickerWidth + 5 + val hueSliderY = startY + for (i in 0 until hueSliderHeight) { + val localHue = i / hueSliderHeight.toFloat() + val rgb = Color.HSBtoRGB(localHue, 1.0f, 1.0f) + drawRect(hueSliderX, hueSliderY + i, hueSliderX + hueSliderWidth, hueSliderY + i + 1, rgb) + } + + val hueMarkerY = hueSliderY + (hue * hueSliderHeight).toInt() + RenderUtils.drawBorderedRectRGB( + hueSliderX - 1, hueMarkerY - 1, + hueSliderX + hueSliderWidth + 1, hueMarkerY + 2, + 1.0f, + 0xFFFFFFFF.toInt(), + 0x00000000 + ) + + val inColorPicker = mouseX in startX until (startX + colorPickerWidth) && mouseY in startY until (startY + colorPickerHeight) + val inHueSlider = mouseX in hueSliderX..(hueSliderX + hueSliderWidth) && mouseY in hueSliderY..(hueSliderY + hueSliderHeight) + + if ((mouseButton == 0 || sliderValueHeld == colorValue) && (inColorPicker || inHueSlider)) { + if (inColorPicker) { + val newS = ((mouseX - startX) / colorPickerWidth.toFloat()).coerceIn(0f, 1f) + val newB = (1.0f - ((mouseY - startY) / colorPickerHeight.toFloat())).coerceIn(0f, 1f) + saturation = newS + brightness = newB + } + if (inHueSlider) { + val newH = ((mouseY - hueSliderY) / hueSliderHeight.toFloat()).coerceIn(0f, 1f) + hue = newH + } + + sliderValueHeld = colorValue + + if (mouseButton == 0) { + return true + } + } + + val finalRGB = Color.HSBtoRGB(hue, saturation, brightness) + val finalColor = Color(finalRGB) + colorValue.set(finalColor) + + val previewSubSize = 6 + drawRect( + startX + 75, + startY - 10, + startX + 75 + previewSubSize, + startY - 10 + previewSubSize, + finalColor.rgb + ) + + yPos += colorPickerHeight + previewSize + 8 + } else { + // Se for rainbow + yPos += previewSize + 15 + } + + if (mouseButton == -1) { + sliderValueHeld = null + } + } + } + else -> { val text = value.name + "§f: §c" + value.get() diff --git a/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/NullStyle.kt b/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/NullStyle.kt index 792b667a766..128df361980 100644 --- a/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/NullStyle.kt +++ b/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/NullStyle.kt @@ -21,6 +21,7 @@ import net.ccbluex.liquidbounce.utils.extensions.lerpWith import net.ccbluex.liquidbounce.utils.render.RenderUtils.drawBorderedRect import net.ccbluex.liquidbounce.utils.render.RenderUtils.drawRect import net.ccbluex.liquidbounce.config.* +import net.ccbluex.liquidbounce.utils.render.RenderUtils import net.minecraft.client.gui.ScaledResolution import net.minecraft.util.StringUtils import net.minecraftforge.fml.relauncher.Side @@ -380,6 +381,143 @@ object NullStyle : Style() { yPos += 11 } + is ColorValue -> { + val colorValue = value + + val currentColor = if (colorValue.rainbow) { + colorValue.get() + } else { + colorValue.get() + } + + val previewSize = 10 + val previewX1 = moduleElement.x + moduleElement.width + 4 + val previewY1 = yPos + 2 + val previewX2 = previewX1 + previewSize + val previewY2 = previewY1 + previewSize + + drawRect(previewX1, previewY1, previewX2, previewY2, currentColor.rgb) + + // Abrir/fechar + if (mouseButton == 0 && mouseX in previewX1..previewX2 && mouseY in previewY1..previewY2) { + colorValue.showPicker = !colorValue.showPicker + clickSound() + return true + } + + if (!colorValue.showPicker) { + yPos += previewSize + 6 + return false + } + + if (!colorValue.rainbow) { + val hsb = Color.RGBtoHSB(currentColor.red, currentColor.green, currentColor.blue, null) + var hue = hsb[0] + var saturation = hsb[1] + var brightness = hsb[2] + + val colorPickerWidth = 75 + val colorPickerHeight = 50 + val hueSliderWidth = 7 + val hueSliderHeight = 50 + + val startX = previewX1 + val startY = previewY1 + previewSize + 4 + + drawRect(startX - 2, startY - 12, startX + colorPickerWidth + hueSliderWidth + 10, startY + colorPickerHeight + 2, Int.MIN_VALUE) + + font35.drawStringWithShadow( + "Color", + (startX + 1).toFloat(), + (startY - 10).toFloat(), + 0xFFFFFFFF.toInt() + ) + + // Quadrado de S/B + for (px in 0 until colorPickerWidth) { + for (py in 0 until colorPickerHeight) { + val localS = px / colorPickerWidth.toFloat() + val localB = 1.0f - (py / colorPickerHeight.toFloat()) + val rgb = Color.HSBtoRGB(hue, localS, localB) + drawRect(startX + px, startY + py, startX + px + 1, startY + py + 1, rgb) + } + } + + // Marcador S/B + val markerX = startX + (saturation * colorPickerWidth).toInt() + val markerY = startY + ((1.0f - brightness) * colorPickerHeight).toInt() + RenderUtils.drawBorderedRectRGB( + markerX - 2, markerY - 2, + markerX + 3, markerY + 3, + 1.0f, + 0xFFFFFFFF.toInt(), + 0x00000000 + ) + + // Hue + val hueSliderX = startX + colorPickerWidth + 5 + val hueSliderY = startY + for (i in 0 until hueSliderHeight) { + val localHue = i / hueSliderHeight.toFloat() + val rgb = Color.HSBtoRGB(localHue, 1.0f, 1.0f) + drawRect(hueSliderX, hueSliderY + i, hueSliderX + hueSliderWidth, hueSliderY + i + 1, rgb) + } + + val hueMarkerY = hueSliderY + (hue * hueSliderHeight).toInt() + RenderUtils.drawBorderedRectRGB( + hueSliderX - 1, hueMarkerY - 1, + hueSliderX + hueSliderWidth + 1, hueMarkerY + 2, + 1.0f, + 0xFFFFFFFF.toInt(), + 0x00000000 + ) + + val inColorPicker = mouseX in startX until (startX + colorPickerWidth) && mouseY in startY until (startY + colorPickerHeight) + val inHueSlider = mouseX in hueSliderX..(hueSliderX + hueSliderWidth) && mouseY in hueSliderY..(hueSliderY + hueSliderHeight) + + if ((mouseButton == 0 || sliderValueHeld == colorValue) && (inColorPicker || inHueSlider)) { + if (inColorPicker) { + val newS = ((mouseX - startX) / colorPickerWidth.toFloat()).coerceIn(0f, 1f) + val newB = (1.0f - ((mouseY - startY) / colorPickerHeight.toFloat())).coerceIn(0f, 1f) + saturation = newS + brightness = newB + } + if (inHueSlider) { + val newH = ((mouseY - hueSliderY) / hueSliderHeight.toFloat()).coerceIn(0f, 1f) + hue = newH + } + + sliderValueHeld = colorValue + + if (mouseButton == 0) { + return true + } + } + + val finalRGB = Color.HSBtoRGB(hue, saturation, brightness) + val finalColor = Color(finalRGB) + colorValue.set(finalColor) + + // Preview final + val previewSubSize = 6 + drawRect( + startX + 75, + startY - 10, + startX + 75 + previewSubSize, + startY - 10 + previewSubSize, + finalColor.rgb + ) + + yPos += colorPickerHeight + previewSize + 8 + } else { + yPos += previewSize + 15 + } + + if (mouseButton == -1) { + sliderValueHeld = null + } + } + else -> { val text = value.name + "§f: §c" + value.get() diff --git a/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/SlowlyStyle.kt b/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/SlowlyStyle.kt index 626bf699b67..920e1041f9d 100644 --- a/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/SlowlyStyle.kt +++ b/src/main/java/net/ccbluex/liquidbounce/ui/client/clickgui/style/styles/SlowlyStyle.kt @@ -21,6 +21,7 @@ import net.ccbluex.liquidbounce.utils.render.RenderUtils.drawBorderedRect import net.ccbluex.liquidbounce.utils.render.RenderUtils.drawFilledCircle import net.ccbluex.liquidbounce.utils.render.RenderUtils.drawRect import net.ccbluex.liquidbounce.config.* +import net.ccbluex.liquidbounce.utils.render.RenderUtils import net.minecraft.client.gui.ScaledResolution import net.minecraft.util.StringUtils import net.minecraftforge.fml.relauncher.Side @@ -418,6 +419,147 @@ object SlowlyStyle : Style() { yPos += 11 } + is ColorValue -> { + val colorValue = value + + val currentColor = if (colorValue.rainbow) { + colorValue.get() + } else { + colorValue.get() + } + + val previewSize = 10 + val previewX1 = moduleElement.x + moduleElement.width + 4 + val previewY1 = yPos + 2 + val previewX2 = previewX1 + previewSize + val previewY2 = previewY1 + previewSize + + drawRect(previewX1, previewY1, previewX2, previewY2, currentColor.rgb) + + if (mouseButton == 0 && mouseX in previewX1..previewX2 && mouseY in previewY1..previewY2) { + colorValue.showPicker = !colorValue.showPicker + clickSound() + return true + } + + if (!colorValue.showPicker) { + yPos += (previewSize + 6) + return false + } + + if (!colorValue.rainbow) { + val hsb = Color.RGBtoHSB(currentColor.red, currentColor.green, currentColor.blue, null) + var hue = hsb[0] + var saturation = hsb[1] + var brightness = hsb[2] + + val colorPickerWidth = 75 + val colorPickerHeight = 50 + val hueSliderWidth = 7 + val hueSliderHeight = 50 + + val startX = previewX1 + val startY = previewY1 + previewSize + 4 + + drawBorderedRect( + startX - 3f, + (startY - 12).toFloat(), + (startX + colorPickerWidth + hueSliderWidth + 10).toFloat(), + (startY + colorPickerHeight + 2).toFloat(), + 3f, + Color(42, 57, 79).rgb, + Color(54, 71, 96).rgb + ) + + font35.drawStringWithShadow( + "Color", + (startX + 1).toFloat(), + (startY - 10).toFloat(), + Color.WHITE.rgb + ) + + for (px in 0 until colorPickerWidth) { + for (py in 0 until colorPickerHeight) { + val localS = px / colorPickerWidth.toFloat() + val localB = 1.0f - (py / colorPickerHeight.toFloat()) + val rgb = Color.HSBtoRGB(hue, localS, localB) + drawRect(startX + px, startY + py, startX + px + 1, startY + py + 1, rgb) + } + } + + val markerX = startX + (saturation * colorPickerWidth).toInt() + val markerY = startY + ((1.0f - brightness) * colorPickerHeight).toInt() + RenderUtils.drawBorderedRectRGB( + markerX - 2, markerY - 2, + markerX + 3, markerY + 3, + 1.0f, + 0xFFFFFFFF.toInt(), + 0x00000000 + ) + + val hueSliderX = startX + colorPickerWidth + 5 + val hueSliderY = startY + for (i in 0 until hueSliderHeight) { + val localHue = i / hueSliderHeight.toFloat() + val rgb = Color.HSBtoRGB(localHue, 1.0f, 1.0f) + drawRect(hueSliderX, hueSliderY + i, hueSliderX + hueSliderWidth, hueSliderY + i + 1, rgb) + } + + val hueMarkerY = hueSliderY + (hue * hueSliderHeight).toInt() + RenderUtils.drawBorderedRectRGB( + hueSliderX - 1, hueMarkerY - 1, + hueSliderX + hueSliderWidth + 1, hueMarkerY + 2, + 1.0f, + 0xFFFFFFFF.toInt(), + 0x00000000 + ) + + val inColorPicker = mouseX in startX..(startX + colorPickerWidth) && mouseY in startY..(startY + colorPickerHeight) + val inHueSlider = mouseX in hueSliderX..(hueSliderX + hueSliderWidth) && mouseY in hueSliderY..(hueSliderY + hueSliderHeight) + + if ((mouseButton == 0 || sliderValueHeld == colorValue) && (inColorPicker || inHueSlider)) { + if (inColorPicker) { + val newS = ((mouseX - startX) / colorPickerWidth.toFloat()).coerceIn(0f, 1f) + val newB = (1.0f - ((mouseY - startY) / colorPickerHeight.toFloat())).coerceIn(0f, 1f) + saturation = newS + brightness = newB + } + if (inHueSlider) { + val newH = ((mouseY - hueSliderY) / hueSliderHeight.toFloat()).coerceIn(0f, 1f) + hue = newH + } + + sliderValueHeld = colorValue + + if (mouseButton == 0) { + return true + } + } + + val finalRGB = Color.HSBtoRGB(hue, saturation, brightness) + val finalColor = Color(finalRGB) + colorValue.set(finalColor) + + // Preview final + val previewSubSize = 6 + drawRect( + startX + 75, + startY - 10, + startX + 75 + previewSubSize, + startY - 10 + previewSubSize, + finalColor.rgb + ) + + yPos += colorPickerHeight + previewSize + 8 + } else { + yPos += previewSize + 15 + } + + if (mouseButton == -1) { + sliderValueHeld = null + } + } + else -> { val text = value.name + "§f: " + value.get() diff --git a/src/main/java/net/ccbluex/liquidbounce/utils/render/RenderUtils.kt b/src/main/java/net/ccbluex/liquidbounce/utils/render/RenderUtils.kt index 4d5eab89914..ea86bc461e1 100644 --- a/src/main/java/net/ccbluex/liquidbounce/utils/render/RenderUtils.kt +++ b/src/main/java/net/ccbluex/liquidbounce/utils/render/RenderUtils.kt @@ -607,6 +607,31 @@ object RenderUtils : MinecraftInstance { drawBorder(x, y, x2, y2, width, borderColor) } + fun drawBorderedRectRGB(x: Int, y: Int, x2: Int, y2: Int, width: Float, color1: Int, color2: Int) { + drawRect(x, y, x2, y2, color2) + glEnable(GL_BLEND) + glDisable(GL_TEXTURE_2D) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_LINE_SMOOTH) + + glColor(color1) + glLineWidth(width) + glBegin(1) + glVertex2d(x.toDouble(), y.toDouble()) + glVertex2d(x.toDouble(), y2.toDouble()) + glVertex2d(x2.toDouble(), y2.toDouble()) + glVertex2d(x2.toDouble(), y.toDouble()) + glVertex2d(x.toDouble(), y.toDouble()) + glVertex2d(x2.toDouble(), y.toDouble()) + glVertex2d(x.toDouble(), y2.toDouble()) + glVertex2d(x2.toDouble(), y2.toDouble()) + glEnd() + + glEnable(GL_TEXTURE_2D) + glDisable(GL_BLEND) + glDisable(GL_LINE_SMOOTH) + } + fun drawRoundedBorderRect( x: Float, y: Float, x2: Float, y2: Float, width: Float, color1: Int, color2: Int, radius: Float ) {