Split buttons panel file
This commit is contained in:
parent
a53438e1f9
commit
b2181819ca
@ -18,7 +18,7 @@ import ru.dbotthepony.mc.otm.client.screen.ExoSuitInventoryScreen
|
|||||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.AbstractSlotPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.AbstractSlotPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.DiscreteScrollBarPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.DiscreteScrollBarPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.LargeRectangleButtonPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.buttons.LargeRectangleButtonPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.Panel2Widget
|
import ru.dbotthepony.mc.otm.client.screen.panels.Panel2Widget
|
||||||
import ru.dbotthepony.mc.otm.compat.InventoryScrollPacket
|
import ru.dbotthepony.mc.otm.compat.InventoryScrollPacket
|
||||||
import ru.dbotthepony.mc.otm.compat.cos.isCosmeticArmorScreen
|
import ru.dbotthepony.mc.otm.compat.cos.isCosmeticArmorScreen
|
||||||
|
@ -1,25 +1,21 @@
|
|||||||
package ru.dbotthepony.mc.otm.client.screen
|
package ru.dbotthepony.mc.otm.client.screen
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.InputConstants
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
import net.minecraft.client.gui.screens.inventory.InventoryScreen
|
import net.minecraft.client.gui.screens.inventory.InventoryScreen
|
||||||
import ru.dbotthepony.mc.otm.client.mousePos
|
import ru.dbotthepony.mc.otm.client.mousePos
|
||||||
import ru.dbotthepony.mc.otm.client.moveMousePos
|
|
||||||
import ru.dbotthepony.mc.otm.client.moveMousePosScaled
|
import ru.dbotthepony.mc.otm.client.moveMousePosScaled
|
||||||
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
||||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.client.render.element
|
import ru.dbotthepony.mc.otm.client.render.element
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.buttons.LargeRectangleButtonPanel
|
||||||
import ru.dbotthepony.mc.otm.client.setMousePos
|
import ru.dbotthepony.mc.otm.client.setMousePos
|
||||||
import ru.dbotthepony.mc.otm.client.shouldOpenVanillaInventory
|
import ru.dbotthepony.mc.otm.client.shouldOpenVanillaInventory
|
||||||
import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleButton
|
|
||||||
import ru.dbotthepony.mc.otm.compat.curios.curiosSlots
|
|
||||||
import ru.dbotthepony.mc.otm.core.maxScrollDivision
|
import ru.dbotthepony.mc.otm.core.maxScrollDivision
|
||||||
import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu
|
import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu
|
||||||
import ru.dbotthepony.mc.otm.network.ExoSuitMenuOpen
|
import ru.dbotthepony.mc.otm.network.ExoSuitMenuOpen
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
|
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
|
||||||
import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak
|
import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak
|
||||||
import kotlin.math.cos
|
|
||||||
|
|
||||||
@MouseTweaksDisableWheelTweak
|
@MouseTweaksDisableWheelTweak
|
||||||
class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuitInventoryMenu>(menu, TranslatableComponent("otm.gui.exosuit")) {
|
class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen<ExoSuitInventoryMenu>(menu, TranslatableComponent("otm.gui.exosuit")) {
|
||||||
|
@ -13,6 +13,7 @@ import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorPlayerSettings
|
|||||||
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
|
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
|
||||||
import ru.dbotthepony.mc.otm.client.render.Widgets8
|
import ru.dbotthepony.mc.otm.client.render.Widgets8
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.buttons.SmallEnumRectangleButtonPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
import ru.dbotthepony.mc.otm.client.screen.widget.WidePowerGaugePanel
|
||||||
import ru.dbotthepony.mc.otm.core.asGetterSetter
|
import ru.dbotthepony.mc.otm.core.asGetterSetter
|
||||||
|
@ -1,546 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.client.screen.panels
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.InputConstants
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack
|
|
||||||
import net.minecraft.ChatFormatting
|
|
||||||
import net.minecraft.client.gui.screens.Screen
|
|
||||||
import net.minecraft.network.chat.Component
|
|
||||||
import ru.dbotthepony.mc.otm.client.playGuiClickSound
|
|
||||||
import ru.dbotthepony.mc.otm.core.TextComponent
|
|
||||||
import ru.dbotthepony.mc.otm.client.render.*
|
|
||||||
import ru.dbotthepony.mc.otm.core.GetterSetter
|
|
||||||
import ru.dbotthepony.mc.otm.core.RGBAColor
|
|
||||||
import ru.dbotthepony.mc.otm.core.next
|
|
||||||
import ru.dbotthepony.mc.otm.core.prev
|
|
||||||
import ru.dbotthepony.mc.otm.core.value
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
import kotlin.reflect.KMutableProperty0
|
|
||||||
|
|
||||||
open class ButtonPanel<out S : Screen>(
|
|
||||||
screen: S,
|
|
||||||
parent: EditablePanel<*>?,
|
|
||||||
x: Float = 0f,
|
|
||||||
y: Float = 0f,
|
|
||||||
width: Float = 40f,
|
|
||||||
height: Float = HEIGHT,
|
|
||||||
var label: Component
|
|
||||||
) : EditablePanel<S>(screen, parent, x, y, width, height) {
|
|
||||||
constructor(screen: S, parent: EditablePanel<*>?, label: Component) : this(screen, parent, x = 0f, label = label)
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
screen: S,
|
|
||||||
parent: EditablePanel<*>?,
|
|
||||||
x: Float = 0f,
|
|
||||||
y: Float = 0f,
|
|
||||||
width: Float = 40f,
|
|
||||||
height: Float = HEIGHT,
|
|
||||||
label: Component,
|
|
||||||
onPress: Runnable
|
|
||||||
) : this(screen, parent, x, y, width, height, label) {
|
|
||||||
this.callback = onPress
|
|
||||||
}
|
|
||||||
|
|
||||||
protected var callback: Runnable? = null
|
|
||||||
protected var pressed = false
|
|
||||||
|
|
||||||
protected open fun onClick(button: Int) {
|
|
||||||
callback?.run()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
|
||||||
if (isDisabled || pressed) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tryToGrabMouseInput()) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
pressed = true
|
|
||||||
playGuiClickSound()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean {
|
|
||||||
if (!pressed) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
grabMouseInput = false
|
|
||||||
pressed = false
|
|
||||||
|
|
||||||
if (isHovered) {
|
|
||||||
onClick(button)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun bind(runnable: Runnable) {
|
|
||||||
callback = runnable
|
|
||||||
}
|
|
||||||
|
|
||||||
var textColor = RGBAColor.WHITE
|
|
||||||
|
|
||||||
var isDisabled = false
|
|
||||||
set(value) {
|
|
||||||
if (field != value) {
|
|
||||||
if (!value) {
|
|
||||||
pressed = false
|
|
||||||
grabMouseInput = false
|
|
||||||
}
|
|
||||||
|
|
||||||
field = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
|
||||||
if (isDisabled) {
|
|
||||||
Widgets18.BUTTON_DISABLED_STRETCHABLE.render(stack, width = width, height = height)
|
|
||||||
} else if (pressed) {
|
|
||||||
Widgets18.BUTTON_PRESSED_STRETCHABLE.render(stack, width = width, height = height)
|
|
||||||
} else if (isHovered) {
|
|
||||||
Widgets18.BUTTON_HOVERED_STRETCHABLE.render(stack, width = width, height = height)
|
|
||||||
} else {
|
|
||||||
Widgets18.BUTTON_IDLE_STRETCHABLE.render(stack, width = width, height = height)
|
|
||||||
}
|
|
||||||
|
|
||||||
font.drawAligned(stack, label, TextAlign.CENTER_CENTER, width / 2f, height / 2f, textColor.toInt())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun sizeToContents() {
|
|
||||||
super.sizeToContents()
|
|
||||||
|
|
||||||
height = height.coerceAtLeast(HEIGHT).coerceAtLeast(font.lineHeight.toFloat() + 2f)
|
|
||||||
width = width.coerceAtLeast(HEIGHT).coerceAtLeast(font.width(label) + 4f)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val HEIGHT = 18f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("PropertyName")
|
|
||||||
abstract class RectangleButtonPanel<out S : Screen>(
|
|
||||||
screen: S,
|
|
||||||
parent: EditablePanel<*>?,
|
|
||||||
x: Float = 0f,
|
|
||||||
y: Float = 0f,
|
|
||||||
width: Float,
|
|
||||||
height: Float,
|
|
||||||
val onPress: ((clickButton: Int) -> Unit)? = null,
|
|
||||||
) : EditablePanel<S>(screen, parent, x, y, width, height) {
|
|
||||||
protected var pressed = false
|
|
||||||
|
|
||||||
protected open fun onClick(clickButton: Int) {
|
|
||||||
onPress?.invoke(clickButton)
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract val PRESSED: AbstractSkinElement
|
|
||||||
abstract val HOVERED: AbstractSkinElement
|
|
||||||
abstract val IDLE: AbstractSkinElement
|
|
||||||
abstract val DISABLED: AbstractSkinElement
|
|
||||||
|
|
||||||
var isDisabled = false
|
|
||||||
set(value) {
|
|
||||||
if (field != value) {
|
|
||||||
if (!value) {
|
|
||||||
pressed = false
|
|
||||||
grabMouseInput = false
|
|
||||||
}
|
|
||||||
|
|
||||||
field = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
|
||||||
if (isDisabled) {
|
|
||||||
DISABLED.render(stack, 0f, 0f, width, height)
|
|
||||||
} else if (pressed) {
|
|
||||||
PRESSED.render(stack, 0f, 0f, width, height)
|
|
||||||
} else if (isHovered) {
|
|
||||||
HOVERED.render(stack, 0f, 0f, width, height)
|
|
||||||
} else {
|
|
||||||
IDLE.render(stack, 0f, 0f, width, height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
|
||||||
if (!isDisabled) {
|
|
||||||
if (!pressed) {
|
|
||||||
playGuiClickSound()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tryToGrabMouseInput()) {
|
|
||||||
pressed = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean {
|
|
||||||
if (!isDisabled && pressed) {
|
|
||||||
pressed = false
|
|
||||||
|
|
||||||
if (isHovered) {
|
|
||||||
onClick(button)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
grabMouseInput = false
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class EnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
|
|
||||||
screen: S,
|
|
||||||
parent: EditablePanel<*>?,
|
|
||||||
x: Float = 0f,
|
|
||||||
y: Float = 0f,
|
|
||||||
width: Float,
|
|
||||||
height: Float,
|
|
||||||
val enum: Class<T>,
|
|
||||||
val prop: GetterSetter<T>,
|
|
||||||
val defaultValue: T,
|
|
||||||
val onChange: ((newValue: T) -> Unit)? = null,
|
|
||||||
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height, null) {
|
|
||||||
private var building = true
|
|
||||||
|
|
||||||
protected val enumMapping = EnumMap<T, Pair<AbstractSkinElement, UVWindingOrder>>(enum)
|
|
||||||
protected val tooltipMapping = EnumMap<T, Component>(enum)
|
|
||||||
|
|
||||||
fun addTooltip(value: T, component: Component): EnumRectangleButtonPanel<S, T> {
|
|
||||||
check(tooltipMapping.put(value, component) == null) { "Already has mapping for $value" }
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
var mainTooltip: Component? = null
|
|
||||||
set(value) {
|
|
||||||
if (field != null) {
|
|
||||||
throw UnsupportedOperationException("Write once only")
|
|
||||||
}
|
|
||||||
|
|
||||||
field = value
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isFullyDefined(): Boolean {
|
|
||||||
for (value in enum.enumConstants) {
|
|
||||||
if (enumMapping[value] == null) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
val missingValues: List<T> get() {
|
|
||||||
val missing = ArrayList<T>()
|
|
||||||
|
|
||||||
for (value in enum.enumConstants) {
|
|
||||||
if (enumMapping[value] == null) {
|
|
||||||
missing.add(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return missing
|
|
||||||
}
|
|
||||||
|
|
||||||
fun add(value: T, skinElement: AbstractSkinElement, winding: UVWindingOrder = UVWindingOrder.NORMAL): EnumRectangleButtonPanel<S, T> {
|
|
||||||
return add(value, skinElement to winding)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun add(value: T, skinElement: AbstractSkinElement, component: Component, winding: UVWindingOrder = UVWindingOrder.NORMAL): EnumRectangleButtonPanel<S, T> {
|
|
||||||
return add(value, component, skinElement to winding)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun add(value: T, component: Component, skinElement: AbstractSkinElement, winding: UVWindingOrder = UVWindingOrder.NORMAL): EnumRectangleButtonPanel<S, T> {
|
|
||||||
return add(value, component, skinElement to winding)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun add(value: T, pair: Pair<AbstractSkinElement, UVWindingOrder>): EnumRectangleButtonPanel<S, T> {
|
|
||||||
check(building) { "Not building" }
|
|
||||||
check(enumMapping.put(value, pair) == null) { "Already has mapping for $value" }
|
|
||||||
|
|
||||||
if (enumMapping.size == enum.enumConstants.size) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun add(value: T, component: Component, pair: Pair<AbstractSkinElement, UVWindingOrder>): EnumRectangleButtonPanel<S, T> {
|
|
||||||
addTooltip(value, component)
|
|
||||||
return add(value, pair)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun finish(): EnumRectangleButtonPanel<S, T> {
|
|
||||||
check(building) { "Not building" }
|
|
||||||
check(isFullyDefined()) {
|
|
||||||
"Not all enums having their mapping defined, missing are: ${missingValues.joinToString(", ")}"
|
|
||||||
}
|
|
||||||
|
|
||||||
building = false
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
|
||||||
check(!building) { "Still building this button!" }
|
|
||||||
super.innerRender(stack, mouseX, mouseY, partialTick)
|
|
||||||
val pair = checkNotNull(enumMapping[prop.get()]) { "HOW" }
|
|
||||||
pair.first.render(stack, 0f, 0f, width, height, pair.second)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
|
||||||
check(!building) { "Still building this button!" }
|
|
||||||
return super.mouseClickedInner(x, y, button)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean {
|
|
||||||
check(!building) { "Still building this button!" }
|
|
||||||
return super.mouseReleasedInner(x, y, button)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onClick(clickButton: Int) {
|
|
||||||
when (clickButton) {
|
|
||||||
InputConstants.MOUSE_BUTTON_LEFT -> {
|
|
||||||
prop.value = prop.value.next(enum.enumConstants)
|
|
||||||
onChange?.invoke(prop.get())
|
|
||||||
}
|
|
||||||
|
|
||||||
InputConstants.MOUSE_BUTTON_RIGHT -> {
|
|
||||||
prop.value = prop.value.prev(enum.enumConstants)
|
|
||||||
onChange?.invoke(prop.get())
|
|
||||||
}
|
|
||||||
|
|
||||||
InputConstants.MOUSE_BUTTON_MIDDLE -> {
|
|
||||||
if (prop.get() != defaultValue) {
|
|
||||||
prop.value = defaultValue
|
|
||||||
onChange?.invoke(prop.get())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun innerRenderTooltips(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
|
|
||||||
if (!isHovered && !isGrabbingMouseInput()) {
|
|
||||||
return super.innerRenderTooltips(stack, mouseX, mouseY, partialTick)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mainTooltip == null && tooltipMapping.size == 0) {
|
|
||||||
return super.innerRenderTooltips(stack, mouseX, mouseY, partialTick)
|
|
||||||
}
|
|
||||||
|
|
||||||
val listing = ArrayList<Component>()
|
|
||||||
|
|
||||||
if (mainTooltip != null) {
|
|
||||||
listing.add(mainTooltip!!)
|
|
||||||
listing.add(SPACE)
|
|
||||||
}
|
|
||||||
|
|
||||||
for ((key, value) in tooltipMapping) {
|
|
||||||
if (key == prop.get()) {
|
|
||||||
listing.add(value.copy().withStyle(ChatFormatting.WHITE))
|
|
||||||
} else {
|
|
||||||
listing.add(value.copy().withStyle(ChatFormatting.GRAY))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
screen.renderComponentTooltip(
|
|
||||||
stack,
|
|
||||||
listing,
|
|
||||||
mouseX.toInt(),
|
|
||||||
mouseY.toInt(),
|
|
||||||
font
|
|
||||||
)
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val SPACE = TextComponent("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class BooleanRectangleButtonPanel<out S : Screen>(
|
|
||||||
screen: S,
|
|
||||||
parent: EditablePanel<*>?,
|
|
||||||
x: Float = 0f,
|
|
||||||
y: Float = 0f,
|
|
||||||
width: Float,
|
|
||||||
height: Float,
|
|
||||||
val prop: GetterSetter<Boolean>,
|
|
||||||
val skinElementActive: AbstractSkinElement? = null,
|
|
||||||
val skinElementInactive: AbstractSkinElement? = null,
|
|
||||||
val onChange: ((newValue: Boolean) -> Unit)? = null,
|
|
||||||
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height, null) {
|
|
||||||
override fun onClick(clickButton: Int) {
|
|
||||||
if (clickButton == InputConstants.MOUSE_BUTTON_LEFT) {
|
|
||||||
val newValue = !prop.value
|
|
||||||
prop.value = newValue
|
|
||||||
onChange?.invoke(newValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
|
||||||
super.innerRender(stack, mouseX, mouseY, partialTick)
|
|
||||||
|
|
||||||
if (prop.value) {
|
|
||||||
skinElementActive?.render(stack, width = width, height = height)
|
|
||||||
} else {
|
|
||||||
skinElementInactive?.render(stack, width = width, height = height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open class LargeRectangleButtonPanel<out S : Screen>(
|
|
||||||
screen: S,
|
|
||||||
parent: EditablePanel<*>?,
|
|
||||||
x: Float = 0f,
|
|
||||||
y: Float = 0f,
|
|
||||||
width: Float = SIZE,
|
|
||||||
height: Float = SIZE,
|
|
||||||
onPress: ((clickButton: Int) -> Unit)? = null,
|
|
||||||
val skinElement: AbstractSkinElement? = null,
|
|
||||||
val skinElementWinding: UVWindingOrder? = null,
|
|
||||||
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height, onPress) {
|
|
||||||
final override val IDLE = Widgets18.BUTTON_IDLE
|
|
||||||
final override val HOVERED = Widgets18.BUTTON_HOVERED
|
|
||||||
final override val PRESSED = Widgets18.BUTTON_PRESSED
|
|
||||||
final override val DISABLED = Widgets18.BUTTON_DISABLED
|
|
||||||
|
|
||||||
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
|
||||||
super.innerRender(stack, mouseX, mouseY, partialTick)
|
|
||||||
|
|
||||||
if (skinElementWinding != null) {
|
|
||||||
skinElement?.render(stack, width = width, height = height, winding = skinElementWinding)
|
|
||||||
} else {
|
|
||||||
skinElement?.render(stack, width = width, height = height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val SIZE = 18f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open class LargeEnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
|
|
||||||
screen: S,
|
|
||||||
parent: EditablePanel<*>?,
|
|
||||||
x: Float = 0f,
|
|
||||||
y: Float = 0f,
|
|
||||||
width: Float = SIZE,
|
|
||||||
height: Float = SIZE,
|
|
||||||
enum: Class<T>,
|
|
||||||
prop: GetterSetter<T>,
|
|
||||||
defaultValue: T,
|
|
||||||
onChange: ((newValue: T) -> Unit)? = null,
|
|
||||||
) : EnumRectangleButtonPanel<S, T>(screen, parent, x, y, width, height, enum, prop, defaultValue, onChange) {
|
|
||||||
final override val IDLE = Widgets18.BUTTON_IDLE
|
|
||||||
final override val HOVERED = Widgets18.BUTTON_HOVERED
|
|
||||||
final override val PRESSED = Widgets18.BUTTON_PRESSED
|
|
||||||
final override val DISABLED = Widgets18.BUTTON_DISABLED
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val SIZE = 18f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open class LargeBooleanRectangleButtonPanel<out S : Screen>(
|
|
||||||
screen: S,
|
|
||||||
parent: EditablePanel<*>?,
|
|
||||||
x: Float = 0f,
|
|
||||||
y: Float = 0f,
|
|
||||||
width: Float = SIZE,
|
|
||||||
height: Float = SIZE,
|
|
||||||
prop: GetterSetter<Boolean>,
|
|
||||||
skinElementActive: AbstractSkinElement? = null,
|
|
||||||
skinElementInactive: AbstractSkinElement? = null,
|
|
||||||
onChange: ((newValue: Boolean) -> Unit)? = null,
|
|
||||||
) : BooleanRectangleButtonPanel<S>(screen, parent, x, y, width, height, prop, skinElementActive, skinElementInactive, onChange) {
|
|
||||||
final override val IDLE = Widgets18.BUTTON_IDLE
|
|
||||||
final override val HOVERED = Widgets18.BUTTON_HOVERED
|
|
||||||
final override val PRESSED = Widgets18.BUTTON_PRESSED
|
|
||||||
final override val DISABLED = Widgets18.BUTTON_DISABLED
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val SIZE = 18f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open class SmallRectangleButtonPanel<out S : Screen>(
|
|
||||||
screen: S,
|
|
||||||
parent: EditablePanel<*>?,
|
|
||||||
x: Float = 0f,
|
|
||||||
y: Float = 0f,
|
|
||||||
width: Float = SIZE,
|
|
||||||
height: Float = SIZE,
|
|
||||||
onPress: ((clickButton: Int) -> Unit)? = null,
|
|
||||||
val skinElement: SkinElement? = null,
|
|
||||||
val skinElementWinding: UVWindingOrder? = null,
|
|
||||||
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height, onPress) {
|
|
||||||
final override val IDLE = Widgets8.BUTTON_IDLE
|
|
||||||
final override val HOVERED = Widgets8.BUTTON_HOVERED
|
|
||||||
final override val PRESSED = Widgets8.BUTTON_PRESSED
|
|
||||||
final override val DISABLED = Widgets8.BUTTON_DISABLED
|
|
||||||
|
|
||||||
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
|
||||||
super.innerRender(stack, mouseX, mouseY, partialTick)
|
|
||||||
|
|
||||||
if (skinElementWinding != null) {
|
|
||||||
skinElement?.render(stack, width = width, height = height, winding = skinElementWinding)
|
|
||||||
} else {
|
|
||||||
skinElement?.render(stack, width = width, height = height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val SIZE = 8f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open class SmallEnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
|
|
||||||
screen: S,
|
|
||||||
parent: EditablePanel<*>?,
|
|
||||||
x: Float = 0f,
|
|
||||||
y: Float = 0f,
|
|
||||||
width: Float = SIZE,
|
|
||||||
height: Float = SIZE,
|
|
||||||
enum: Class<T>,
|
|
||||||
prop: GetterSetter<T>,
|
|
||||||
defaultValue: T,
|
|
||||||
onChange: ((newValue: T) -> Unit)? = null,
|
|
||||||
) : EnumRectangleButtonPanel<S, T>(screen, parent, x, y, width, height, enum, prop, defaultValue, onChange) {
|
|
||||||
final override val IDLE = Widgets8.BUTTON_IDLE
|
|
||||||
final override val HOVERED = Widgets8.BUTTON_HOVERED
|
|
||||||
final override val PRESSED = Widgets8.BUTTON_PRESSED
|
|
||||||
final override val DISABLED = Widgets8.BUTTON_DISABLED
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val SIZE = 8f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open class SmallBooleanRectangleButtonPanel<out S : Screen>(
|
|
||||||
screen: S,
|
|
||||||
parent: EditablePanel<*>?,
|
|
||||||
x: Float = 0f,
|
|
||||||
y: Float = 0f,
|
|
||||||
width: Float = SIZE,
|
|
||||||
height: Float = SIZE,
|
|
||||||
prop: GetterSetter<Boolean>,
|
|
||||||
skinElementActive: AbstractSkinElement? = null,
|
|
||||||
skinElementInactive: AbstractSkinElement? = null,
|
|
||||||
onChange: ((newValue: Boolean) -> Unit)? = null,
|
|
||||||
) : BooleanRectangleButtonPanel<S>(screen, parent, x, y, width, height, prop, skinElementActive, skinElementInactive, onChange) {
|
|
||||||
final override val IDLE = Widgets8.BUTTON_IDLE
|
|
||||||
final override val HOVERED = Widgets8.BUTTON_HOVERED
|
|
||||||
final override val PRESSED = Widgets8.BUTTON_PRESSED
|
|
||||||
final override val DISABLED = Widgets8.BUTTON_DISABLED
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val SIZE = 8f
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,6 +10,7 @@ import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
|||||||
import ru.dbotthepony.mc.otm.client.render.Widgets8
|
import ru.dbotthepony.mc.otm.client.render.Widgets8
|
||||||
import ru.dbotthepony.mc.otm.client.render.element
|
import ru.dbotthepony.mc.otm.client.render.element
|
||||||
import ru.dbotthepony.mc.otm.client.screen.ExoSuitInventoryScreen
|
import ru.dbotthepony.mc.otm.client.screen.ExoSuitInventoryScreen
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.buttons.SmallBooleanRectangleButtonPanel
|
||||||
import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleRenderButton
|
import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleRenderButton
|
||||||
import ru.dbotthepony.mc.otm.compat.cos.isCosmeticArmorLoaded
|
import ru.dbotthepony.mc.otm.compat.cos.isCosmeticArmorLoaded
|
||||||
import ru.dbotthepony.mc.otm.core.asGetterOnly
|
import ru.dbotthepony.mc.otm.core.asGetterOnly
|
||||||
|
@ -3,8 +3,8 @@ package ru.dbotthepony.mc.otm.client.screen.panels
|
|||||||
import com.mojang.blaze3d.platform.InputConstants
|
import com.mojang.blaze3d.platform.InputConstants
|
||||||
import net.minecraft.client.gui.screens.Screen
|
import net.minecraft.client.gui.screens.Screen
|
||||||
import ru.dbotthepony.mc.otm.client.render.AbstractSkinElement
|
import ru.dbotthepony.mc.otm.client.render.AbstractSkinElement
|
||||||
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
|
||||||
import ru.dbotthepony.mc.otm.client.render.Widgets
|
import ru.dbotthepony.mc.otm.client.render.Widgets
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.buttons.RectangleButtonPanel
|
||||||
|
|
||||||
open class HeightControls<out S : Screen>(
|
open class HeightControls<out S : Screen>(
|
||||||
screen: S,
|
screen: S,
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client.screen.panels.buttons
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.InputConstants
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
|
import net.minecraft.client.gui.screens.Screen
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.AbstractSkinElement
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
|
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||||
|
import ru.dbotthepony.mc.otm.core.value
|
||||||
|
|
||||||
|
abstract class BooleanRectangleButtonPanel<out S : Screen>(
|
||||||
|
screen: S,
|
||||||
|
parent: EditablePanel<*>?,
|
||||||
|
x: Float = 0f,
|
||||||
|
y: Float = 0f,
|
||||||
|
width: Float,
|
||||||
|
height: Float,
|
||||||
|
val prop: GetterSetter<Boolean>,
|
||||||
|
val skinElementActive: AbstractSkinElement? = null,
|
||||||
|
val skinElementInactive: AbstractSkinElement? = null,
|
||||||
|
val onChange: ((newValue: Boolean) -> Unit)? = null,
|
||||||
|
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height, null) {
|
||||||
|
override fun onClick(clickButton: Int) {
|
||||||
|
if (clickButton == InputConstants.MOUSE_BUTTON_LEFT) {
|
||||||
|
val newValue = !prop.value
|
||||||
|
prop.value = newValue
|
||||||
|
onChange?.invoke(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||||
|
super.innerRender(stack, mouseX, mouseY, partialTick)
|
||||||
|
|
||||||
|
if (prop.value) {
|
||||||
|
skinElementActive?.render(stack, width = width, height = height)
|
||||||
|
} else {
|
||||||
|
skinElementInactive?.render(stack, width = width, height = height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,115 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client.screen.panels.buttons
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
|
import net.minecraft.client.gui.screens.Screen
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import ru.dbotthepony.mc.otm.client.playGuiClickSound
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.TextAlign
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.drawAligned
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
|
import ru.dbotthepony.mc.otm.core.RGBAColor
|
||||||
|
|
||||||
|
open class ButtonPanel<out S : Screen>(
|
||||||
|
screen: S,
|
||||||
|
parent: EditablePanel<*>?,
|
||||||
|
x: Float = 0f,
|
||||||
|
y: Float = 0f,
|
||||||
|
width: Float = 40f,
|
||||||
|
height: Float = HEIGHT,
|
||||||
|
var label: Component
|
||||||
|
) : EditablePanel<S>(screen, parent, x, y, width, height) {
|
||||||
|
constructor(screen: S, parent: EditablePanel<*>?, label: Component) : this(screen, parent, x = 0f, label = label)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
screen: S,
|
||||||
|
parent: EditablePanel<*>?,
|
||||||
|
x: Float = 0f,
|
||||||
|
y: Float = 0f,
|
||||||
|
width: Float = 40f,
|
||||||
|
height: Float = HEIGHT,
|
||||||
|
label: Component,
|
||||||
|
onPress: Runnable
|
||||||
|
) : this(screen, parent, x, y, width, height, label) {
|
||||||
|
this.callback = onPress
|
||||||
|
}
|
||||||
|
|
||||||
|
protected var callback: Runnable? = null
|
||||||
|
protected var pressed = false
|
||||||
|
|
||||||
|
protected open fun onClick(button: Int) {
|
||||||
|
callback?.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
||||||
|
if (isDisabled || pressed) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tryToGrabMouseInput()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
pressed = true
|
||||||
|
playGuiClickSound()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean {
|
||||||
|
if (!pressed) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
grabMouseInput = false
|
||||||
|
pressed = false
|
||||||
|
|
||||||
|
if (isHovered) {
|
||||||
|
onClick(button)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bind(runnable: Runnable) {
|
||||||
|
callback = runnable
|
||||||
|
}
|
||||||
|
|
||||||
|
var textColor = RGBAColor.WHITE
|
||||||
|
|
||||||
|
var isDisabled = false
|
||||||
|
set(value) {
|
||||||
|
if (field != value) {
|
||||||
|
if (!value) {
|
||||||
|
pressed = false
|
||||||
|
grabMouseInput = false
|
||||||
|
}
|
||||||
|
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||||
|
if (isDisabled) {
|
||||||
|
Widgets18.BUTTON_DISABLED_STRETCHABLE.render(stack, width = width, height = height)
|
||||||
|
} else if (pressed) {
|
||||||
|
Widgets18.BUTTON_PRESSED_STRETCHABLE.render(stack, width = width, height = height)
|
||||||
|
} else if (isHovered) {
|
||||||
|
Widgets18.BUTTON_HOVERED_STRETCHABLE.render(stack, width = width, height = height)
|
||||||
|
} else {
|
||||||
|
Widgets18.BUTTON_IDLE_STRETCHABLE.render(stack, width = width, height = height)
|
||||||
|
}
|
||||||
|
|
||||||
|
font.drawAligned(stack, label, TextAlign.CENTER_CENTER, width / 2f, height / 2f, textColor.toInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun sizeToContents() {
|
||||||
|
super.sizeToContents()
|
||||||
|
|
||||||
|
height = height.coerceAtLeast(HEIGHT).coerceAtLeast(font.lineHeight.toFloat() + 2f)
|
||||||
|
width = width.coerceAtLeast(HEIGHT).coerceAtLeast(font.width(label) + 4f)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val HEIGHT = 18f
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,186 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client.screen.panels.buttons
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.InputConstants
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
|
import net.minecraft.ChatFormatting
|
||||||
|
import net.minecraft.client.gui.screens.Screen
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.AbstractSkinElement
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
|
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||||
|
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||||
|
import ru.dbotthepony.mc.otm.core.next
|
||||||
|
import ru.dbotthepony.mc.otm.core.prev
|
||||||
|
import ru.dbotthepony.mc.otm.core.value
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
abstract class EnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
|
||||||
|
screen: S,
|
||||||
|
parent: EditablePanel<*>?,
|
||||||
|
x: Float = 0f,
|
||||||
|
y: Float = 0f,
|
||||||
|
width: Float,
|
||||||
|
height: Float,
|
||||||
|
val enum: Class<T>,
|
||||||
|
val prop: GetterSetter<T>,
|
||||||
|
val defaultValue: T,
|
||||||
|
val onChange: ((newValue: T) -> Unit)? = null,
|
||||||
|
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height, null) {
|
||||||
|
private var building = true
|
||||||
|
|
||||||
|
protected val enumMapping = EnumMap<T, Pair<AbstractSkinElement, UVWindingOrder>>(enum)
|
||||||
|
protected val tooltipMapping = EnumMap<T, Component>(enum)
|
||||||
|
|
||||||
|
fun addTooltip(value: T, component: Component): EnumRectangleButtonPanel<S, T> {
|
||||||
|
check(tooltipMapping.put(value, component) == null) { "Already has mapping for $value" }
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
var mainTooltip: Component? = null
|
||||||
|
set(value) {
|
||||||
|
if (field != null) {
|
||||||
|
throw UnsupportedOperationException("Write once only")
|
||||||
|
}
|
||||||
|
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isFullyDefined(): Boolean {
|
||||||
|
for (value in enum.enumConstants) {
|
||||||
|
if (enumMapping[value] == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
val missingValues: List<T> get() {
|
||||||
|
val missing = ArrayList<T>()
|
||||||
|
|
||||||
|
for (value in enum.enumConstants) {
|
||||||
|
if (enumMapping[value] == null) {
|
||||||
|
missing.add(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return missing
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(value: T, skinElement: AbstractSkinElement, winding: UVWindingOrder = UVWindingOrder.NORMAL): EnumRectangleButtonPanel<S, T> {
|
||||||
|
return add(value, skinElement to winding)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(value: T, skinElement: AbstractSkinElement, component: Component, winding: UVWindingOrder = UVWindingOrder.NORMAL): EnumRectangleButtonPanel<S, T> {
|
||||||
|
return add(value, component, skinElement to winding)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(value: T, component: Component, skinElement: AbstractSkinElement, winding: UVWindingOrder = UVWindingOrder.NORMAL): EnumRectangleButtonPanel<S, T> {
|
||||||
|
return add(value, component, skinElement to winding)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(value: T, pair: Pair<AbstractSkinElement, UVWindingOrder>): EnumRectangleButtonPanel<S, T> {
|
||||||
|
check(building) { "Not building" }
|
||||||
|
check(enumMapping.put(value, pair) == null) { "Already has mapping for $value" }
|
||||||
|
|
||||||
|
if (enumMapping.size == enum.enumConstants.size) {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(value: T, component: Component, pair: Pair<AbstractSkinElement, UVWindingOrder>): EnumRectangleButtonPanel<S, T> {
|
||||||
|
addTooltip(value, component)
|
||||||
|
return add(value, pair)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun finish(): EnumRectangleButtonPanel<S, T> {
|
||||||
|
check(building) { "Not building" }
|
||||||
|
check(isFullyDefined()) {
|
||||||
|
"Not all enums having their mapping defined, missing are: ${missingValues.joinToString(", ")}"
|
||||||
|
}
|
||||||
|
|
||||||
|
building = false
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||||
|
check(!building) { "Still building this button!" }
|
||||||
|
super.innerRender(stack, mouseX, mouseY, partialTick)
|
||||||
|
val pair = checkNotNull(enumMapping[prop.get()]) { "HOW" }
|
||||||
|
pair.first.render(stack, 0f, 0f, width, height, pair.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
||||||
|
check(!building) { "Still building this button!" }
|
||||||
|
return super.mouseClickedInner(x, y, button)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean {
|
||||||
|
check(!building) { "Still building this button!" }
|
||||||
|
return super.mouseReleasedInner(x, y, button)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(clickButton: Int) {
|
||||||
|
when (clickButton) {
|
||||||
|
InputConstants.MOUSE_BUTTON_LEFT -> {
|
||||||
|
prop.value = prop.value.next(enum.enumConstants)
|
||||||
|
onChange?.invoke(prop.get())
|
||||||
|
}
|
||||||
|
|
||||||
|
InputConstants.MOUSE_BUTTON_RIGHT -> {
|
||||||
|
prop.value = prop.value.prev(enum.enumConstants)
|
||||||
|
onChange?.invoke(prop.get())
|
||||||
|
}
|
||||||
|
|
||||||
|
InputConstants.MOUSE_BUTTON_MIDDLE -> {
|
||||||
|
if (prop.get() != defaultValue) {
|
||||||
|
prop.value = defaultValue
|
||||||
|
onChange?.invoke(prop.get())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun innerRenderTooltips(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
|
||||||
|
if (!isHovered && !isGrabbingMouseInput()) {
|
||||||
|
return super.innerRenderTooltips(stack, mouseX, mouseY, partialTick)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mainTooltip == null && tooltipMapping.size == 0) {
|
||||||
|
return super.innerRenderTooltips(stack, mouseX, mouseY, partialTick)
|
||||||
|
}
|
||||||
|
|
||||||
|
val listing = ArrayList<Component>()
|
||||||
|
|
||||||
|
if (mainTooltip != null) {
|
||||||
|
listing.add(mainTooltip!!)
|
||||||
|
listing.add(SPACE)
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((key, value) in tooltipMapping) {
|
||||||
|
if (key == prop.get()) {
|
||||||
|
listing.add(value.copy().withStyle(ChatFormatting.WHITE))
|
||||||
|
} else {
|
||||||
|
listing.add(value.copy().withStyle(ChatFormatting.GRAY))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
screen.renderComponentTooltip(
|
||||||
|
stack,
|
||||||
|
listing,
|
||||||
|
mouseX.toInt(),
|
||||||
|
mouseY.toInt(),
|
||||||
|
font
|
||||||
|
)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val SPACE = TextComponent("")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client.screen.panels.buttons
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.screens.Screen
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.AbstractSkinElement
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
|
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||||
|
|
||||||
|
open class LargeBooleanRectangleButtonPanel<out S : Screen>(
|
||||||
|
screen: S,
|
||||||
|
parent: EditablePanel<*>?,
|
||||||
|
x: Float = 0f,
|
||||||
|
y: Float = 0f,
|
||||||
|
width: Float = SIZE,
|
||||||
|
height: Float = SIZE,
|
||||||
|
prop: GetterSetter<Boolean>,
|
||||||
|
skinElementActive: AbstractSkinElement? = null,
|
||||||
|
skinElementInactive: AbstractSkinElement? = null,
|
||||||
|
onChange: ((newValue: Boolean) -> Unit)? = null,
|
||||||
|
) : BooleanRectangleButtonPanel<S>(screen, parent, x, y, width, height, prop, skinElementActive, skinElementInactive, onChange) {
|
||||||
|
final override val IDLE = Widgets18.BUTTON_IDLE
|
||||||
|
final override val HOVERED = Widgets18.BUTTON_HOVERED
|
||||||
|
final override val PRESSED = Widgets18.BUTTON_PRESSED
|
||||||
|
final override val DISABLED = Widgets18.BUTTON_DISABLED
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val SIZE = 18f
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client.screen.panels.buttons
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.screens.Screen
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
|
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||||
|
|
||||||
|
open class LargeEnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
|
||||||
|
screen: S,
|
||||||
|
parent: EditablePanel<*>?,
|
||||||
|
x: Float = 0f,
|
||||||
|
y: Float = 0f,
|
||||||
|
width: Float = SIZE,
|
||||||
|
height: Float = SIZE,
|
||||||
|
enum: Class<T>,
|
||||||
|
prop: GetterSetter<T>,
|
||||||
|
defaultValue: T,
|
||||||
|
onChange: ((newValue: T) -> Unit)? = null,
|
||||||
|
) : EnumRectangleButtonPanel<S, T>(screen, parent, x, y, width, height, enum, prop, defaultValue, onChange) {
|
||||||
|
final override val IDLE = Widgets18.BUTTON_IDLE
|
||||||
|
final override val HOVERED = Widgets18.BUTTON_HOVERED
|
||||||
|
final override val PRESSED = Widgets18.BUTTON_PRESSED
|
||||||
|
final override val DISABLED = Widgets18.BUTTON_DISABLED
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val SIZE = 18f
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client.screen.panels.buttons
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
|
import net.minecraft.client.gui.screens.Screen
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.AbstractSkinElement
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
|
|
||||||
|
open class LargeRectangleButtonPanel<out S : Screen>(
|
||||||
|
screen: S,
|
||||||
|
parent: EditablePanel<*>?,
|
||||||
|
x: Float = 0f,
|
||||||
|
y: Float = 0f,
|
||||||
|
width: Float = SIZE,
|
||||||
|
height: Float = SIZE,
|
||||||
|
onPress: ((clickButton: Int) -> Unit)? = null,
|
||||||
|
val skinElement: AbstractSkinElement? = null,
|
||||||
|
val skinElementWinding: UVWindingOrder? = null,
|
||||||
|
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height, onPress) {
|
||||||
|
final override val IDLE = Widgets18.BUTTON_IDLE
|
||||||
|
final override val HOVERED = Widgets18.BUTTON_HOVERED
|
||||||
|
final override val PRESSED = Widgets18.BUTTON_PRESSED
|
||||||
|
final override val DISABLED = Widgets18.BUTTON_DISABLED
|
||||||
|
|
||||||
|
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||||
|
super.innerRender(stack, mouseX, mouseY, partialTick)
|
||||||
|
|
||||||
|
if (skinElementWinding != null) {
|
||||||
|
skinElement?.render(stack, width = width, height = height, winding = skinElementWinding)
|
||||||
|
} else {
|
||||||
|
skinElement?.render(stack, width = width, height = height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val SIZE = 18f
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client.screen.panels.buttons
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
|
import net.minecraft.client.gui.screens.Screen
|
||||||
|
import ru.dbotthepony.mc.otm.client.playGuiClickSound
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.AbstractSkinElement
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
|
|
||||||
|
@Suppress("PropertyName")
|
||||||
|
abstract class RectangleButtonPanel<out S : Screen>(
|
||||||
|
screen: S,
|
||||||
|
parent: EditablePanel<*>?,
|
||||||
|
x: Float = 0f,
|
||||||
|
y: Float = 0f,
|
||||||
|
width: Float,
|
||||||
|
height: Float,
|
||||||
|
val onPress: ((clickButton: Int) -> Unit)? = null,
|
||||||
|
) : EditablePanel<S>(screen, parent, x, y, width, height) {
|
||||||
|
protected var pressed = false
|
||||||
|
|
||||||
|
protected open fun onClick(clickButton: Int) {
|
||||||
|
onPress?.invoke(clickButton)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract val PRESSED: AbstractSkinElement
|
||||||
|
abstract val HOVERED: AbstractSkinElement
|
||||||
|
abstract val IDLE: AbstractSkinElement
|
||||||
|
abstract val DISABLED: AbstractSkinElement
|
||||||
|
|
||||||
|
var isDisabled = false
|
||||||
|
set(value) {
|
||||||
|
if (field != value) {
|
||||||
|
if (!value) {
|
||||||
|
pressed = false
|
||||||
|
grabMouseInput = false
|
||||||
|
}
|
||||||
|
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||||
|
if (isDisabled) {
|
||||||
|
DISABLED.render(stack, 0f, 0f, width, height)
|
||||||
|
} else if (pressed) {
|
||||||
|
PRESSED.render(stack, 0f, 0f, width, height)
|
||||||
|
} else if (isHovered) {
|
||||||
|
HOVERED.render(stack, 0f, 0f, width, height)
|
||||||
|
} else {
|
||||||
|
IDLE.render(stack, 0f, 0f, width, height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
||||||
|
if (!isDisabled) {
|
||||||
|
if (!pressed) {
|
||||||
|
playGuiClickSound()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tryToGrabMouseInput()) {
|
||||||
|
pressed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean {
|
||||||
|
if (!isDisabled && pressed) {
|
||||||
|
pressed = false
|
||||||
|
|
||||||
|
if (isHovered) {
|
||||||
|
onClick(button)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grabMouseInput = false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client.screen.panels.buttons
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.screens.Screen
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.*
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
|
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||||
|
|
||||||
|
open class SmallBooleanRectangleButtonPanel<out S : Screen>(
|
||||||
|
screen: S,
|
||||||
|
parent: EditablePanel<*>?,
|
||||||
|
x: Float = 0f,
|
||||||
|
y: Float = 0f,
|
||||||
|
width: Float = SIZE,
|
||||||
|
height: Float = SIZE,
|
||||||
|
prop: GetterSetter<Boolean>,
|
||||||
|
skinElementActive: AbstractSkinElement? = null,
|
||||||
|
skinElementInactive: AbstractSkinElement? = null,
|
||||||
|
onChange: ((newValue: Boolean) -> Unit)? = null,
|
||||||
|
) : BooleanRectangleButtonPanel<S>(screen, parent, x, y, width, height, prop, skinElementActive, skinElementInactive, onChange) {
|
||||||
|
final override val IDLE = Widgets8.BUTTON_IDLE
|
||||||
|
final override val HOVERED = Widgets8.BUTTON_HOVERED
|
||||||
|
final override val PRESSED = Widgets8.BUTTON_PRESSED
|
||||||
|
final override val DISABLED = Widgets8.BUTTON_DISABLED
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val SIZE = 8f
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client.screen.panels.buttons
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.screens.Screen
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.Widgets8
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
|
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||||
|
|
||||||
|
open class SmallEnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
|
||||||
|
screen: S,
|
||||||
|
parent: EditablePanel<*>?,
|
||||||
|
x: Float = 0f,
|
||||||
|
y: Float = 0f,
|
||||||
|
width: Float = SIZE,
|
||||||
|
height: Float = SIZE,
|
||||||
|
enum: Class<T>,
|
||||||
|
prop: GetterSetter<T>,
|
||||||
|
defaultValue: T,
|
||||||
|
onChange: ((newValue: T) -> Unit)? = null,
|
||||||
|
) : EnumRectangleButtonPanel<S, T>(screen, parent, x, y, width, height, enum, prop, defaultValue, onChange) {
|
||||||
|
final override val IDLE = Widgets8.BUTTON_IDLE
|
||||||
|
final override val HOVERED = Widgets8.BUTTON_HOVERED
|
||||||
|
final override val PRESSED = Widgets8.BUTTON_PRESSED
|
||||||
|
final override val DISABLED = Widgets8.BUTTON_DISABLED
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val SIZE = 8f
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client.screen.panels.buttons
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack
|
||||||
|
import net.minecraft.client.gui.screens.Screen
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
|
||||||
|
import ru.dbotthepony.mc.otm.client.render.Widgets8
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
|
|
||||||
|
open class SmallRectangleButtonPanel<out S : Screen>(
|
||||||
|
screen: S,
|
||||||
|
parent: EditablePanel<*>?,
|
||||||
|
x: Float = 0f,
|
||||||
|
y: Float = 0f,
|
||||||
|
width: Float = SIZE,
|
||||||
|
height: Float = SIZE,
|
||||||
|
onPress: ((clickButton: Int) -> Unit)? = null,
|
||||||
|
val skinElement: SkinElement? = null,
|
||||||
|
val skinElementWinding: UVWindingOrder? = null,
|
||||||
|
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height, onPress) {
|
||||||
|
final override val IDLE = Widgets8.BUTTON_IDLE
|
||||||
|
final override val HOVERED = Widgets8.BUTTON_HOVERED
|
||||||
|
final override val PRESSED = Widgets8.BUTTON_PRESSED
|
||||||
|
final override val DISABLED = Widgets8.BUTTON_DISABLED
|
||||||
|
|
||||||
|
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||||
|
super.innerRender(stack, mouseX, mouseY, partialTick)
|
||||||
|
|
||||||
|
if (skinElementWinding != null) {
|
||||||
|
skinElement?.render(stack, width = width, height = height, winding = skinElementWinding)
|
||||||
|
} else {
|
||||||
|
skinElement?.render(stack, width = width, height = height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val SIZE = 8f
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,6 @@ import com.mojang.blaze3d.vertex.PoseStack
|
|||||||
import lain.mods.cos.impl.ModObjects
|
import lain.mods.cos.impl.ModObjects
|
||||||
import lain.mods.cos.impl.client.PlayerRenderHandler
|
import lain.mods.cos.impl.client.PlayerRenderHandler
|
||||||
import lain.mods.cos.impl.client.gui.GuiCosArmorInventory
|
import lain.mods.cos.impl.client.gui.GuiCosArmorInventory
|
||||||
import lain.mods.cos.impl.client.gui.GuiCosArmorToggleButton
|
|
||||||
import lain.mods.cos.impl.network.packet.PacketSetSkinArmor
|
import lain.mods.cos.impl.network.packet.PacketSetSkinArmor
|
||||||
import net.minecraft.client.gui.screens.Screen
|
import net.minecraft.client.gui.screens.Screen
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
@ -20,9 +19,8 @@ import net.minecraftforge.fml.ModList
|
|||||||
import ru.dbotthepony.mc.otm.client.minecraft
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
import ru.dbotthepony.mc.otm.client.render.SkinElement
|
||||||
import ru.dbotthepony.mc.otm.client.render.element
|
import ru.dbotthepony.mc.otm.client.render.element
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.AbstractSlotPanel
|
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.RectangleButtonPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.buttons.RectangleButtonPanel
|
||||||
import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleButton.Companion.BUTTON_ACTIVE
|
import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleButton.Companion.BUTTON_ACTIVE
|
||||||
import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleButton.Companion.BUTTON_INACTIVE
|
import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleButton.Companion.BUTTON_INACTIVE
|
||||||
import ru.dbotthepony.mc.otm.container.awareStream
|
import ru.dbotthepony.mc.otm.container.awareStream
|
||||||
|
Loading…
Reference in New Issue
Block a user