Color picker panel

This commit is contained in:
DBotThePony 2023-07-15 19:41:31 +07:00
parent 9394de61d9
commit 4daa0be19a
Signed by: DBot
GPG Key ID: DCC23B5715498507
7 changed files with 782 additions and 0 deletions

View File

@ -139,6 +139,8 @@ private fun misc(provider: MatteryLanguageProvider) {
gui("exopack.go_back", "Open vanilla inventory") gui("exopack.go_back", "Open vanilla inventory")
gui("exopack.go_in", "Open Exopack inventory") gui("exopack.go_in", "Open Exopack inventory")
gui("exopack.toggle_visibility", "Toggle Exopack visibility") gui("exopack.toggle_visibility", "Toggle Exopack visibility")
gui("exopack.change_color", "Customize Exopack color")
gui("exopack.change_color2", "Press Middle Mouse Button to remove color")
gui("exopack.probe1", "This little device feels unnatural to touch, it is almost certainly resilient to any possible attempt to break it open.") gui("exopack.probe1", "This little device feels unnatural to touch, it is almost certainly resilient to any possible attempt to break it open.")
gui("exopack.probe2", "There is fingerprint reader built into one of sides which gently glow when touched.") gui("exopack.probe2", "There is fingerprint reader built into one of sides which gently glow when touched.")
@ -664,6 +666,22 @@ private fun gui(provider: MatteryLanguageProvider) {
with(provider.english) { with(provider.english) {
gui("quicksearch", "Quick search...") gui("quicksearch", "Quick search...")
gui("color_picker", "Color Picker")
gui("color.short.red", "R")
gui("color.short.green", "G")
gui("color.short.blue", "B")
gui("color.short.hue", "H")
gui("color.short.saturation", "S")
gui("color.short.value", "V")
gui("color.full.red", "Red")
gui("color.full.green", "Green")
gui("color.full.blue", "Blue")
gui("color.full.hue", "Hue")
gui("color.full.saturation", "Saturation")
gui("color.full.value", "Value")
gui("item_monitor.refill_source.desc", "Controls from where to take items for slot auto refill") gui("item_monitor.refill_source.desc", "Controls from where to take items for slot auto refill")
gui("item_monitor.refill_source.system", "System only. Crafting grid will be auto refilled only from storage system. This is the behavior you see in AE2 and Refined Storage") gui("item_monitor.refill_source.system", "System only. Crafting grid will be auto refilled only from storage system. This is the behavior you see in AE2 and Refined Storage")
gui("item_monitor.refill_source.inventory", "Inventory only. Crafting grid will be auto refilled only from player's inventory") gui("item_monitor.refill_source.inventory", "Inventory only. Crafting grid will be auto refilled only from player's inventory")

View File

@ -147,6 +147,8 @@ private fun misc(provider: MatteryLanguageProvider) {
gui("exopack.go_back", "Открыть обычный инвентарь") gui("exopack.go_back", "Открыть обычный инвентарь")
gui("exopack.go_in", "Открыть инвентарь экзопака") gui("exopack.go_in", "Открыть инвентарь экзопака")
gui("exopack.toggle_visibility", "Переключить отображение Экзопака") gui("exopack.toggle_visibility", "Переключить отображение Экзопака")
gui("exopack.change_color", "Изменить окраску Экзопака")
gui("exopack.change_color2", "Нажмите среднюю кнопку мыши для сброса окраски")
gui("exopack.probe1", "Данное маленькое устройство необычно на ощупь, а так же неприступно для любых попыток вскрыть.") gui("exopack.probe1", "Данное маленькое устройство необычно на ощупь, а так же неприступно для любых попыток вскрыть.")
gui("exopack.probe2", "На одной из сторон данного устройства находится сканер отпечатка, который тускло загорается при касании.") gui("exopack.probe2", "На одной из сторон данного устройства находится сканер отпечатка, который тускло загорается при касании.")
@ -668,6 +670,22 @@ private fun gui(provider: MatteryLanguageProvider) {
with(provider.russian) { with(provider.russian) {
gui("quicksearch", "Быстрый поиск...") gui("quicksearch", "Быстрый поиск...")
gui("color_picker", "Выбор цвета")
gui("color.short.red", "К")
gui("color.short.green", "З")
gui("color.short.blue", "С")
gui("color.short.hue", "Ц")
gui("color.short.saturation", "Н")
gui("color.short.value", "Я")
gui("color.full.red", "Красный")
gui("color.full.green", "Зелёный")
gui("color.full.blue", "Синий")
gui("color.full.hue", "Цвет")
gui("color.full.saturation", "Насыщение")
gui("color.full.value", "Яркость")
gui("item_monitor.refill_source.desc", "Контролирует источник предметов для заполнения сетки создания") gui("item_monitor.refill_source.desc", "Контролирует источник предметов для заполнения сетки создания")
gui("item_monitor.refill_source.system", "Только система. Сетка создания будет заполняться только из системы предметов. Данный параметр соответствует поведению AE2 и Refined Storage") gui("item_monitor.refill_source.system", "Только система. Сетка создания будет заполняться только из системы предметов. Данный параметр соответствует поведению AE2 и Refined Storage")
gui("item_monitor.refill_source.inventory", "Только инвентарь. Сетка создания будет заполняться только из инвентаря игрока") gui("item_monitor.refill_source.inventory", "Только инвентарь. Сетка создания будет заполняться только из инвентаря игрока")

View File

@ -0,0 +1,746 @@
package ru.dbotthepony.mc.otm.client.screen.panels
import com.mojang.blaze3d.platform.InputConstants
import com.mojang.datafixers.util.Either
import it.unimi.dsi.fastutil.floats.FloatConsumer
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.screens.Screen
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.client.playGuiClickSound
import ru.dbotthepony.mc.otm.client.render.MatterySprite
import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.render.WidgetLocation
import ru.dbotthepony.mc.otm.client.render.renderRect
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.button.AbstractButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.input.TextInputPanel
import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.math.HSVColor
import ru.dbotthepony.mc.otm.core.math.RGBAColor
import java.util.function.Consumer
import kotlin.math.roundToInt
open class ColorBoxPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float,
y: Float,
width: Float = 64f,
height: Float = 64f,
protected val callback: Consumer<HSVColor>? = null,
) : EditablePanel<S>(screen, parent, x, y, width, height) {
var backgroundColor = RGBAColor.RED
private set
var markerPos = backgroundColor.toHSV()
protected set
fun setColor(color: Either<RGBAColor, HSVColor>) {
color.map(
{ markerPos = it.toHSV(); if (it.canRepresentHue()) backgroundColor = HSVColor(it.toHSV().hue, 1f, 1f).toRGBA() },
{ markerPos = it; backgroundColor = HSVColor(it.hue, 1f, 1f).toRGBA() })
}
var isPressed = false
private set
override fun shouldRenderTooltips(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
return super.shouldRenderTooltips(graphics, mouseX, mouseY, partialTick) || isPressed
}
protected open fun onPickedColor(color: HSVColor) {
callback?.accept(color)
}
protected fun pickColor(mouseX: Double, mouseY: Double) {
val (x, y) = screenToLocal(mouseX, mouseY)
val saturation = 1f - x.coerceIn(0f, width) / width
val value = 1f - y.coerceIn(0f, height) / height
markerPos = HSVColor(backgroundColor.toHSV().hue, saturation, value)
onPickedColor(markerPos)
}
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
if (button == InputConstants.MOUSE_BUTTON_LEFT) {
if (!isPressed) {
isPressed = true
grabMouseInput = true
pickColor(x, y)
playGuiClickSound()
}
return true
}
return super.mouseClickedInner(x, y, button)
}
override fun mouseDraggedInner(x: Double, y: Double, button: Int, xDelta: Double, yDelta: Double): Boolean {
if (isPressed && button == InputConstants.MOUSE_BUTTON_LEFT) {
pickColor(x, y)
return true
}
return super.mouseDraggedInner(x, y, button, xDelta, yDelta)
}
override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean {
if (button == InputConstants.MOUSE_BUTTON_LEFT) {
if (isPressed) {
isPressed = false
grabMouseInput = false
}
return true
}
return super.mouseReleasedInner(x, y, button)
}
override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
graphics.renderRect(0f, 0f, width, height, color = RGBAColor.WHITE)
GRADIENT_LEFT.render(graphics, 0f, 0f, width, height, color = backgroundColor)
GRADIENT_DOWN.render(graphics, 0f, 0f, width, height, color = RGBAColor.BLACK)
val x = (1f - markerPos.saturation) * width
val y = (1f - markerPos.value) * height
LINE_VERTICAL.render(graphics, x = x - 1f, height = height)
LINE_HORIZONTAL.render(graphics, y = y - 1f, width = width)
LINE_CROSS.render(graphics, x = x - 1f, y = y - 1f)
}
companion object {
val GRADIENT_UP = MatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/gradient_v.png"), 0f, 0f, 32f, 256f, 32f, 256f)
val GRADIENT_DOWN = GRADIENT_UP.copy(winding = UVWindingOrder.FLIP)
val GRADIENT_RIGHT = MatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/gradient_h.png"), 0f, 0f, 256f, 32f, 256f, 32f)
val GRADIENT_LEFT = GRADIENT_RIGHT.copy(winding = UVWindingOrder.FLOP)
val LINE_VERTICAL = WidgetLocation.MISC.sprite(36f, 0f, 3f, 3f)
val LINE_HORIZONTAL = WidgetLocation.MISC.sprite(36f, 3f, 3f, 3f)
val LINE_CROSS = WidgetLocation.MISC.sprite(36f, 6f, 3f, 3f)
}
}
abstract class AbstractColorWangPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = 40f,
height: Float = 10f,
protected val callback: Consumer<RGBAColor>? = null,
) : EditablePanel<S>(screen, parent, x, y, width, height) {
abstract val leftColor: RGBAColor
abstract val rightColor: RGBAColor
abstract val wangPosition: Float
abstract fun setColor(color: Either<RGBAColor, HSVColor>)
protected abstract fun onWangInput(newPosition: Float)
init {
scissor = true
}
var isPressed = false
private set
protected fun updateColor(mouseX: Double) {
onWangInput((screenToLocal(mouseX, 0.0).x / width).coerceIn(0f, 1f))
}
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
if (button == InputConstants.MOUSE_BUTTON_LEFT) {
if (!isPressed) {
isPressed = true
grabMouseInput = true
updateColor(x)
playGuiClickSound()
}
return true
}
return super.mouseClickedInner(x, y, button)
}
override fun mouseDraggedInner(x: Double, y: Double, button: Int, xDelta: Double, yDelta: Double): Boolean {
if (isPressed && button == InputConstants.MOUSE_BUTTON_LEFT) {
updateColor(x)
return true
}
return super.mouseDraggedInner(x, y, button, xDelta, yDelta)
}
override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean {
if (button == InputConstants.MOUSE_BUTTON_LEFT) {
if (isPressed) {
isPressed = false
grabMouseInput = false
}
return true
}
return super.mouseReleasedInner(x, y, button)
}
protected fun renderGradients(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
ColorBoxPanel.GRADIENT_RIGHT.render(graphics, 0f, 0f, width, height, color = rightColor)
ColorBoxPanel.GRADIENT_LEFT.render(graphics, 0f, 0f, width, height, color = leftColor)
}
protected fun renderWang(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
if (wangPosition in 0f .. 1f) {
ColorBoxPanel.LINE_VERTICAL.render(graphics, x = wangPosition * width - 1f, height = height)
}
}
override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
renderGradients(graphics, mouseX, mouseY, partialTick)
renderWang(graphics, mouseX, mouseY, partialTick)
}
}
open class RedColorWangPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = 40f,
height: Float = 10f,
callback: Consumer<RGBAColor>? = null,
) : AbstractColorWangPanel<S>(screen, parent, x, y, width, height, callback) {
override var leftColor: RGBAColor = RGBAColor.BLACK
protected set
override var rightColor: RGBAColor = RGBAColor.RED
protected set
override var wangPosition: Float = 0f
protected set
override fun onWangInput(newPosition: Float) {
val color = leftColor.copy(red = newPosition)
wangPosition = newPosition
callback?.accept(color)
}
override fun setColor(color: Either<RGBAColor, HSVColor>) {
@Suppress("name_shadowing")
val color = color.map({ it }, { it.toRGBA() })
leftColor = color.copy(red = 0f, alpha = 1f)
rightColor = color.copy(red = 1f, alpha = 1f)
wangPosition = color.red
}
}
open class GreenColorWangPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = 40f,
height: Float = 10f,
callback: Consumer<RGBAColor>? = null,
) : AbstractColorWangPanel<S>(screen, parent, x, y, width, height, callback) {
override var leftColor: RGBAColor = RGBAColor.BLACK
protected set
override var rightColor: RGBAColor = RGBAColor.GREEN
protected set
override var wangPosition: Float = 0f
protected set
override fun onWangInput(newPosition: Float) {
val color = leftColor.copy(green = newPosition)
wangPosition = newPosition
callback?.accept(color)
}
override fun setColor(color: Either<RGBAColor, HSVColor>) {
@Suppress("name_shadowing")
val color = color.map({ it }, { it.toRGBA() })
leftColor = color.copy(green = 0f, alpha = 1f)
rightColor = color.copy(green = 1f, alpha = 1f)
wangPosition = color.green
}
}
open class BlueColorWangPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = 40f,
height: Float = 10f,
callback: Consumer<RGBAColor>? = null,
) : AbstractColorWangPanel<S>(screen, parent, x, y, width, height, callback) {
override var leftColor: RGBAColor = RGBAColor.BLACK
protected set
override var rightColor: RGBAColor = RGBAColor.BLUE
protected set
override var wangPosition: Float = 0f
protected set
override fun onWangInput(newPosition: Float) {
val color = leftColor.copy(blue = newPosition)
wangPosition = newPosition
callback?.accept(color)
}
override fun setColor(color: Either<RGBAColor, HSVColor>) {
@Suppress("name_shadowing")
val color = color.map({ it }, { it.toRGBA() })
leftColor = color.copy(blue = 0f, alpha = 1f)
rightColor = color.copy(blue = 1f, alpha = 1f)
wangPosition = color.blue
}
}
open class HueWangPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = 40f,
height: Float = 10f,
protected val hueCallback: FloatConsumer? = null,
) : AbstractColorWangPanel<S>(screen, parent, x, y, width, height) {
override val leftColor: RGBAColor get() = RGBAColor.WHITE
override val rightColor: RGBAColor get() = RGBAColor.WHITE
override var wangPosition: Float = 1f
protected set
override fun setColor(color: Either<RGBAColor, HSVColor>) {
color.map(
{
if (it.canRepresentHue()) {
wangPosition = it.toHSV().hue / 360f
}
},
{
wangPosition = it.hue / 360f
}
)
}
override fun onWangInput(newPosition: Float) {
wangPosition = newPosition
hueCallback?.accept(newPosition * 360f)
}
override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
HSV_BAR.render(graphics, 0f, 0f, width, height)
renderWang(graphics, mouseX, mouseY, partialTick)
}
companion object {
val HSV_BAR = MatterySprite(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/hsv.png"), 0f, 0f, 256f, 16f, 256f, 16f)
}
}
open class SaturationWangPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = 40f,
height: Float = 10f,
protected val saturationCallback: FloatConsumer? = null,
) : AbstractColorWangPanel<S>(screen, parent, x, y, width, height) {
override var leftColor: RGBAColor = RGBAColor.WHITE
protected set
override var rightColor: RGBAColor = RGBAColor.WHITE
protected set
override var wangPosition: Float = 1f
protected set
override fun onWangInput(newPosition: Float) {
wangPosition = newPosition
saturationCallback?.accept(newPosition)
}
override fun setColor(color: Either<RGBAColor, HSVColor>) {
color.map(
{
val hsv = it.toHSV()
if (it.canRepresentHue()) {
leftColor = hsv.copy(saturation = 0f).toRGBA()
rightColor = hsv.copy(saturation = 1f).toRGBA()
} else {
leftColor = hsv.copy(hue = leftColor.toHSV().hue, saturation = 0f).toRGBA()
rightColor = hsv.copy(hue = rightColor.toHSV().hue, saturation = 1f).toRGBA()
}
wangPosition = hsv.saturation
},
{ hsv ->
leftColor = hsv.copy(saturation = 0f).toRGBA()
rightColor = hsv.copy(saturation = 1f).toRGBA()
wangPosition = hsv.saturation
}
)
}
}
open class ValueWangPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = 40f,
height: Float = 10f,
protected val valueCallback: FloatConsumer? = null,
) : AbstractColorWangPanel<S>(screen, parent, x, y, width, height) {
override var leftColor: RGBAColor = RGBAColor.BLACK
protected set
override var rightColor: RGBAColor = RGBAColor.WHITE
protected set
override var wangPosition: Float = 1f
protected set
override fun onWangInput(newPosition: Float) {
wangPosition = newPosition
valueCallback?.accept(newPosition)
}
override fun setColor(color: Either<RGBAColor, HSVColor>) {
color.map(
{
val hsv = it.toHSV()
if (it.canRepresentHue()) {
leftColor = hsv.copy(value = 0f).toRGBA()
rightColor = hsv.copy(value = 1f).toRGBA()
} else {
leftColor = hsv.copy(hue = leftColor.toHSV().hue, value = 0f).toRGBA()
rightColor = hsv.copy(hue = rightColor.toHSV().hue, value = 1f).toRGBA()
}
wangPosition = hsv.value
},
{ hsv ->
leftColor = hsv.copy(value = 0f).toRGBA()
rightColor = hsv.copy(value = 1f).toRGBA()
wangPosition = hsv.value
}
)
}
}
open class ColorPalettePanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = 64f,
height: Float = 64f,
protected val callback: Consumer<RGBAColor>? = null
) : EditablePanel<S>(screen, parent, x, y, width, height) {
open fun onColorChoose(color: RGBAColor) {
callback?.accept(color)
}
inner class Button(val color: RGBAColor) : AbstractButtonPanel<S>(screen, this@ColorPalettePanel, 0f, 0f, 8f, 8f) {
init {
tooltips.add(TextComponent("${color.redInt}, ${color.greenInt}, ${color.blueInt}"))
tooltips.add(TextComponent(color.toHexStringRGB()))
}
override fun onClick(mouseButton: Int) {
onColorChoose(color)
}
override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
graphics.renderRect(0f, 0f, width, height, color = RGBAColor.BLACK)
graphics.renderRect(1f, 1f, width - 2f, height - 2f, color = color)
}
override fun compareTo(other: EditablePanel<*>): Int {
return super.compareTo(other).let {
if (it != 0 || other !is Button)
it
else
color.compareTo(other.color)
}
}
}
override fun performLayout() {
super.performLayout()
var x = 0f
var y = 0f
for (children in visibleChildren) {
if (children is Button) {
if (x != 0f && x + children.width > width) {
y += 9f
x = 0f
}
children.x = x
children.y = y
x += 9f
}
}
}
}
open class ColorPickerPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = 164f,
height: Float = 118f,
val callback: Consumer<RGBAColor>? = null
) : EditablePanel<S>(screen, parent, x, y, width, height) {
open fun onColorChanged(color: RGBAColor) {
callback?.accept(color)
}
var currentColor: Either<RGBAColor, HSVColor> = Either.left(RGBAColor.WHITE)
protected set
fun setColor(color: Either<RGBAColor, HSVColor>) {
currentColor = color
hexInput.text = color.map({ it }, { it.toRGBA() }).toHexStringRGB()
updateWangs(color)
}
protected fun updateWangs(color: Either<RGBAColor, HSVColor>) {
box.setColor(color)
for (wang in wangs)
wang.update(color)
}
protected open fun onPaletteChoose(color: RGBAColor) {
setColor(Either.left(color))
onColorChanged(color)
}
protected open fun onColorBoxChoose(color: HSVColor) {
setColor(Either.right(color))
onColorChanged(color.toRGBA())
}
protected open fun onWangChoose(color: RGBAColor) {
setColor(Either.left(color))
onColorChanged(color)
}
protected open fun onHueChoose(hue: Float) {
val current = currentColor.map({ it.toHSV() }, { it })
val new = current.copy(hue = hue)
setColor(Either.right(new))
onColorChanged(new.toRGBA())
}
protected open fun onSaturationChoose(saturation: Float) {
val current = currentColor.map({ it.toHSV() }, { it })
val new = current.copy(saturation = saturation)
setColor(Either.right(new))
onColorChanged(new.toRGBA())
}
protected open fun onValueChoose(value: Float) {
val current = currentColor.map({ it.toHSV() }, { it })
val new = current.copy(value = value)
setColor(Either.right(new))
onColorChanged(new.toRGBA())
}
val topStrip = EditablePanel(screen, this, 0f, 0f, width = width, height = 70f)
val middleStrip = EditablePanel(screen, this)
val palette = ColorPalettePanel(screen, this, callback = { onPaletteChoose(it) })
val hexInput = object : TextInputPanel<S>(screen, middleStrip, width = 50f) {
init {
dock = Dock.RIGHT
}
override fun onFocusChanged() {
if (!isFocusedThis) {
val newColor = RGBAColor.fromHexStringRGB(text)
if (newColor == null) {
text = currentColor.map({ it }, { it.toRGBA() }).toHexStringRGB()
} else {
setColor(Either.left(newColor))
onColorChanged(newColor)
}
}
}
override fun acceptsCharacter(codepoint: Char, mods: Int): Boolean {
return RGBAColor.isHexCharacter(codepoint)
}
}
init {
topStrip.dock = Dock.TOP
middleStrip.dock = Dock.TOP
palette.dock = Dock.FILL
palette.dockTop = 2f
middleStrip.dockTop = 2f
for (color in paletteColors) {
palette.Button(color)
}
}
val box = ColorBoxPanel(screen, topStrip, 0f, 0f, width = 70f, height = 70f, callback = { onColorBoxChoose(it) })
val wangCanvas = EditablePanel(screen, topStrip, width = 80f)
inner class WangLine(label: String, val wang: AbstractColorWangPanel<S>, val text: (color: Either<RGBAColor, HSVColor>) -> Component?) {
val canvas = EditablePanel(screen, wangCanvas, height = 10f)
val label = Label(screen, canvas, width = 10f, text = TranslatableComponent("otm.gui.color.short.$label"))
val textLabel = Label(screen, canvas, width = 25f)
init {
this.wang.parent = canvas
this.wang.width = 45f
this.label.childrenOrder = 0
this.wang.childrenOrder = 1
this.textLabel.childrenOrder = 2
this.canvas.dock = Dock.TOP
this.canvas.dockTop = 2f
this.label.dock = Dock.LEFT
this.label.dockRight = 2f
this.wang.dock = Dock.LEFT
this.wang.dockRight = 2f
this.textLabel.dock = Dock.LEFT
this.textLabel.align = RenderGravity.CENTER_LEFT
this.label.tooltips.add(TranslatableComponent("otm.gui.color.full.$label"))
this.label.align = RenderGravity.CENTER_RIGHT
}
fun update(color: Either<RGBAColor, HSVColor>) {
wang.setColor(color)
text.invoke(color)?.let {
textLabel.text = it
}
}
}
val red = WangLine("red", RedColorWangPanel(screen, wangCanvas, callback = { onWangChoose(it) })) { TextComponent((it.map({ it }, { it.toRGBA() }).red * 255f).roundToInt().toString()) }
val green = WangLine("green", GreenColorWangPanel(screen, wangCanvas, callback = { onWangChoose(it) })) { TextComponent((it.map({ it }, { it.toRGBA() }).green * 255f).roundToInt().toString()) }
val blue = WangLine("blue", BlueColorWangPanel(screen, wangCanvas, callback = { onWangChoose(it) })) { TextComponent((it.map({ it }, { it.toRGBA() }).blue * 255f).roundToInt().toString()) }
val hue = WangLine("hue", HueWangPanel(screen, wangCanvas, hueCallback = { onHueChoose(it) })) { it.map({ if (it.canRepresentHue()) it.toHSV() else null }, { it })?.let { TextComponent(it.hue.roundToInt().toString()) } }
val saturation = WangLine("saturation", SaturationWangPanel(screen, wangCanvas, saturationCallback = { onSaturationChoose(it) })) { it.map({ if (it.canRepresentHue()) it.toHSV() else null }, { it })?.let { TextComponent((it.saturation * 100f).roundToInt().toString() + "%") } }
val value = WangLine("value", ValueWangPanel(screen, wangCanvas, valueCallback = { onValueChoose(it) })) { it.map({ if (it.canRepresentHue()) it.toHSV() else null }, { it })?.let { TextComponent((it.value * 100f).roundToInt().toString() + "%") } }
val wangs = listOf(red, green, blue, hue, saturation, value)
init {
box.dock = Dock.LEFT
wangCanvas.dock = Dock.RIGHT
red.canvas.dockTop = 0f
setColor(Either.right(HSVColor.WHITE))
}
companion object {
val paletteColors = listOf(
RGBAColor.rgb(0x9b59b6L), // Amethyst
RGBAColor.rgb(0x010101L), // Black
RGBAColor.rgb(0x0000ffL), // Blue
RGBAColor.rgb(0x8B4513L), // Brown
RGBAColor.rgb(0xe67e22L), // Carrot
RGBAColor.rgb(0xD2691EL), // Chocolate
RGBAColor.rgb(0xecf0f1L), // Clouds
RGBAColor.rgb(0xFF7F50L), // Coral
RGBAColor.rgb(0xDC143CL), // Crimson
RGBAColor.rgb(0x00FFFFL), // Cyan
RGBAColor.rgb(0x008B8BL), // DarkCyan
RGBAColor.rgb(0xBDB76BL), // DarkGold
RGBAColor.rgb(0xB8860BL), // DarkGoldenRod
RGBAColor.rgb(0x006400L), // DarkGreen
RGBAColor.rgb(0x16a085L), // DarkGreen
RGBAColor.rgb(0x8B008BL), // DarkMagenta
RGBAColor.rgb(0x556B2FL), // DarkOlive
RGBAColor.rgb(0xFF8C00L), // DarkOrange
RGBAColor.rgb(0x8B0000L), // DarkRed
RGBAColor.rgb(0xE9967AL), // DarkSalmon
RGBAColor.rgb(0x9400D3L), // DarkViolet
RGBAColor.rgb(0xFF1493L), // DeepPink
RGBAColor.rgb(0x00BFFFL), // DeepSkyBlue
RGBAColor.rgb(0x2ecc71L), // Emerald
RGBAColor.rgb(0xB22222L), // FireBrick
RGBAColor.rgb(0x228B22L), // ForestGreen
RGBAColor.rgb(0xFF00FFL), // Fuchsia
RGBAColor.rgb(0xDCDCDCL), // Gainsboro
RGBAColor.rgb(0xFFD700L), // Gold
RGBAColor.rgb(0xDAA520L), // GoldenRod
RGBAColor.rgb(0x00B000L), // Green
RGBAColor.rgb(0x808080L), // Grey
RGBAColor.rgb(0xFF69B4L), // HotPink
RGBAColor.rgb(0x4B0082L), // Indigo
RGBAColor.rgb(0xF0E68CL), // Khaki
RGBAColor.rgb(0xE6E6FAL), // Lavender
RGBAColor.rgb(0xFF9FF7L), // LavenderRose
RGBAColor.rgb(0xD3D3D3L), // LightGrey
RGBAColor.rgb(0x87CEFAL), // LightSkyBlue
RGBAColor.rgb(0xFFFFE0L), // LightYellow
RGBAColor.rgb(0x00ff00L), // Lime
RGBAColor.rgb(0x32CD32L), // LimeGreen
RGBAColor.rgb(0xBA55D3L), // MediumOrchid
RGBAColor.rgb(0x9370DBL), // MediumPurple
RGBAColor.rgb(0x7B68EEL), // MediumSlateBlue
RGBAColor.rgb(0x808000L), // Olive
RGBAColor.rgb(0x6B8E23L), // OliveGreen
RGBAColor.rgb(0xFFA500L), // Orange
RGBAColor.rgb(0xDA70D6L), // Orchid
RGBAColor.rgb(0xDB7093L), // PaleVioletRed
RGBAColor.rgb(0xCD853FL), // Peru
RGBAColor.rgb(0xFFC0CBL), // Pink
RGBAColor.rgb(0xB0E0E6L), // PowderBlue
RGBAColor.rgb(0xd35400L), // Pumpkin
RGBAColor.rgb(0x800080L), // Purple
RGBAColor.rgb(0xff0000L), // Red
RGBAColor.rgb(0x4169E1L), // RoyalBlue
RGBAColor.rgb(0xFA8072L), // Salmon
RGBAColor.rgb(0xF4A460L), // SandyBrown
RGBAColor.rgb(0x2E8B57L), // SeaGreen
RGBAColor.rgb(0xA0522DL), // Sienna
RGBAColor.rgb(0xbdc3c7L), // Silver
RGBAColor.rgb(0x87CEEBL), // SkyBlue
RGBAColor.rgb(0x708090L), // SlateGrey
RGBAColor.rgb(0x4682B4L), // SteelBlue
RGBAColor.rgb(0xf1c40fL), // SunFlower
RGBAColor.rgb(0x008080L), // Teal
RGBAColor.rgb(0xD8BFD8L), // Thistle
RGBAColor.rgb(0xEE82EEL), // Violet
)
fun <S : MatteryScreen<*>> frame(screen: S, callback: Consumer<RGBAColor>, color: RGBAColor = RGBAColor.RED, title: Component? = TranslatableComponent("otm.gui.color_picker")): FramePanel<S> {
return FramePanel.padded(screen, 164f, 118f, title).also {
ColorPickerPanel(screen, it, 0f, 0f, callback = callback).also {
it.dock = Dock.FILL
it.setColor(Either.left(color))
}
screen.addPanel(it)
it.toScreenCenter()
it.behaveAsWindow()
it.popup()
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB