Get button classes in line

This commit is contained in:
DBotThePony 2023-01-30 21:35:11 +07:00
parent 52a2e845fa
commit 862eba0234
Signed by: DBot
GPG Key ID: DCC23B5715498507
12 changed files with 164 additions and 177 deletions

View File

@ -37,8 +37,7 @@ class MatterBottlerScreen(menu: MatterBottlerMenu, inventory: Inventory, title:
progress = ProgressGaugePanel(this, frame, menu.progressWidget, 90f, PROGRESS_ARROW_TOP)
if (minecraft?.player?.isSpectator != true) {
val mode = ButtonPanel(this, frame, 46f, 69f, 100f, 20f, TranslatableComponent("otm.matter_bottler.switch_mode"))
mode.bind { menu.workFlow.switchValue() }
ButtonPanel(this, frame, 46f, 69f, 100f, 20f, TranslatableComponent("otm.matter_bottler.switch_mode"), onPress = menu.workFlow::switchValue)
}
return frame

View File

@ -157,7 +157,7 @@ class MatterPanelScreen(
}
if (minecraft?.player?.isSpectator != true) {
ButtonPanel(this@MatterPanelScreen, frame, width = 80f, label = TranslatableComponent("otm.container.matter_panel.cancel_task"), onPress = {
ButtonPanel(this@MatterPanelScreen, frame, width = 80f, label = TranslatableComponent("otm.container.matter_panel.cancel_task"), onPress = Runnable {
menu.requestTaskCancel(task.id)
frame.remove()
}).also {
@ -259,32 +259,32 @@ class MatterPanelScreen(
}
}
ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 8), onPress = { input.increase(8) }).also {
ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 8), onPress = Runnable { input.increase(8) }).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}
ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 64), onPress = { input.increase(64) }).also {
ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 64), onPress = Runnable { input.increase(64) }).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}
ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 256), onPress = { input.increase(256) }).also {
ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.container.matter_panel.increase_by", 256), onPress = Runnable { input.increase(256) }).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}
ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 8), onPress = { input.increase(-8) }).also {
ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 8), onPress = Runnable { input.increase(-8) }).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}
ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 64), onPress = { input.increase(-64) }).also {
ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 64), onPress = Runnable { input.increase(-64) }).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}
ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 256), onPress = { input.increase(-256) }).also {
ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.container.matter_panel.decrease_by", 256), onPress = Runnable { input.increase(-256) }).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}

View File

@ -0,0 +1,68 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import com.mojang.blaze3d.platform.InputConstants
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.screen.panels.EditablePanel
import java.util.function.IntConsumer
import java.util.function.IntPredicate
abstract class AbstractButtonPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = 10f,
height: Float = 10f,
) : EditablePanel<S>(screen, parent, x, y, width, height), IntPredicate {
var isPressed = false
protected set
open var isDisabled = false
set(value) {
if (field != value) {
if (!value) {
isPressed = false
grabMouseInput = false
}
field = value
}
}
override fun test(value: Int): Boolean {
return value == InputConstants.MOUSE_BUTTON_LEFT
}
protected abstract fun onClick(mouseButton: Int)
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
if (isDisabled || isPressed || !test(button)) {
return true
}
if (!tryToGrabMouseInput()) {
return true
}
isPressed = true
playGuiClickSound()
return true
}
override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean {
if (!isPressed || !test(button)) {
return true
}
grabMouseInput = false
isPressed = false
if (isHovered) {
onClick(button)
}
return true
}
}

View File

@ -20,12 +20,10 @@ abstract class BooleanRectangleButtonPanel<out S : Screen>(
val skinElementInactive: AbstractMatterySprite? = 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 onClick(mouseButton: Int) {
val newValue = !prop.value
prop.value = newValue
onChange?.invoke(newValue)
}
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {

View File

@ -9,6 +9,7 @@ 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.math.RGBAColor
import java.util.function.IntConsumer
open class ButtonPanel<out S : Screen>(
screen: S,
@ -17,9 +18,10 @@ open class ButtonPanel<out S : Screen>(
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)
var label: Component,
var onPress: IntConsumer? = null
) : AbstractButtonPanel<S>(screen, parent, x, y, width, height) {
constructor(screen: S, parent: EditablePanel<*>?, label: Component, onPress: IntConsumer? = null) : this(screen, parent, x = 0f, label = label, onPress = onPress)
constructor(
screen: S,
@ -30,75 +32,28 @@ open class ButtonPanel<out S : Screen>(
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
}
) : this(screen, parent, x, y, width, height, label, onPress = IntConsumer { onPress.run() })
var textColor = RGBAColor.WHITE
var isDisabled = false
set(value) {
if (field != value) {
if (!value) {
pressed = false
grabMouseInput = false
}
override fun onClick(mouseButton: Int) {
onPress?.accept(mouseButton)
}
field = value
}
}
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
protected fun renderStretchableBackground(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
if (isDisabled) {
Widgets18.BUTTON_DISABLED_STRETCHABLE.render(stack, width = width, height = height)
} else if (pressed) {
} else if (isPressed) {
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)
}
}
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
renderStretchableBackground(stack, mouseX, mouseY, partialTick)
font.drawAligned(stack, label, TextAlign.CENTER_CENTER, width / 2f, height / 2f, textColor.toInt())
}

View File

@ -1,8 +1,10 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.client.gui.screens.Screen
import net.minecraft.world.entity.player.Player
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.core.GetterSetter
import ru.dbotthepony.mc.otm.core.value
import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback
@ -15,7 +17,7 @@ open class CheckBoxInputPanel<out S : Screen> @JvmOverloads constructor(
width: Float = REGULAR_DIMENSIONS + 120f,
height: Float = REGULAR_DIMENSIONS
) : CheckBoxPanel<S>(screen, parent, x, y, width, height) {
override var checked: Boolean
override var isChecked: Boolean
get() = widget.value
set(value) {}
@ -23,7 +25,7 @@ open class CheckBoxInputPanel<out S : Screen> @JvmOverloads constructor(
get() = !widget.test(minecraft.player)
set(value) {}
override fun onClick() {
widget.accept(!checked)
override fun onClick(mouseButton: Int) {
widget.accept(!isChecked)
}
}

View File

@ -2,11 +2,13 @@ package ru.dbotthepony.mc.otm.client.screen.panels.button
import com.mojang.blaze3d.platform.InputConstants
import com.mojang.blaze3d.vertex.PoseStack
import it.unimi.dsi.fastutil.booleans.BooleanConsumer
import net.minecraft.client.gui.screens.Screen
import ru.dbotthepony.mc.otm.client.playGuiClickSound
import ru.dbotthepony.mc.otm.client.render.AbstractMatterySprite
import ru.dbotthepony.mc.otm.client.render.WidgetLocation
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.core.TextComponent
open class CheckBoxPanel<out S : Screen> @JvmOverloads constructor(
screen: S,
@ -14,34 +16,42 @@ open class CheckBoxPanel<out S : Screen> @JvmOverloads constructor(
x: Float = 0f,
y: Float = 0f,
width: Float = REGULAR_DIMENSIONS,
height: Float = REGULAR_DIMENSIONS
) : EditablePanel<S>(screen, parent, x, y, width, height) {
open var checked = false
open var isDisabled = false
protected var isPressed = false
height: Float = REGULAR_DIMENSIONS,
var onPress: BooleanConsumer? = null
) : AbstractButtonPanel<S>(screen, parent, x, y, width, height) {
open var isChecked = false
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
open val IDLE_UNCHECKED: AbstractMatterySprite = Companion.IDLE_UNCHECKED
open val IDLE_CHECKED: AbstractMatterySprite = Companion.IDLE_CHECKED
open val HOVERED_UNCHECKED: AbstractMatterySprite = Companion.HOVERED_UNCHECKED
open val HOVERED_CHECKED: AbstractMatterySprite = Companion.HOVERED_CHECKED
open val PRESSED_UNCHECKED: AbstractMatterySprite = Companion.PRESSED_UNCHECKED
open val PRESSED_CHECKED: AbstractMatterySprite = Companion.PRESSED_CHECKED
open val DISABLED_UNCHECKED: AbstractMatterySprite = Companion.DISABLED_UNCHECKED
open val DISABLED_CHECKED: AbstractMatterySprite = Companion.DISABLED_CHECKED
protected fun renderCheckboxBackground(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
if (isDisabled) {
if (checked) {
if (isChecked) {
DISABLED_CHECKED.render(stack, width = width, height = height)
} else {
DISABLED_UNCHECKED.render(stack, width = width, height = height)
}
} else {
if (isPressed) {
if (checked) {
if (isChecked) {
PRESSED_CHECKED.render(stack, width = width, height = height)
} else {
PRESSED_UNCHECKED.render(stack, width = width, height = height)
}
} else if (isHovered) {
if (checked) {
if (isChecked) {
HOVERED_CHECKED.render(stack, width = width, height = height)
} else {
HOVERED_UNCHECKED.render(stack, width = width, height = height)
}
} else {
if (checked) {
if (isChecked) {
IDLE_CHECKED.render(stack, width = width, height = height)
} else {
IDLE_UNCHECKED.render(stack, width = width, height = height)
@ -50,31 +60,13 @@ open class CheckBoxPanel<out S : Screen> @JvmOverloads constructor(
}
}
protected open fun onClick() {
checked = !checked
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
renderCheckboxBackground(stack, mouseX, mouseY, partialTick)
}
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
if (!isDisabled && button == InputConstants.MOUSE_BUTTON_LEFT) {
grabMouseInput = true
isPressed = true
playGuiClickSound()
}
return true
}
override fun mouseReleasedInner(x: Double, y: Double, button: Int): Boolean {
if (isPressed && button == InputConstants.MOUSE_BUTTON_LEFT) {
if (isHovered) {
onClick()
}
isPressed = false
grabMouseInput = false
}
return true
override fun onClick(mouseButton: Int) {
isChecked = !isChecked
onPress?.accept(isChecked)
}
companion object {

View File

@ -5,6 +5,8 @@ import net.minecraft.client.gui.screens.Screen
import ru.dbotthepony.mc.otm.client.playGuiClickSound
import ru.dbotthepony.mc.otm.client.render.AbstractMatterySprite
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.core.TextComponent
import java.util.function.IntConsumer
@Suppress("PropertyName")
abstract class RectangleButtonPanel<out S : Screen>(
@ -14,35 +16,21 @@ abstract class RectangleButtonPanel<out S : Screen>(
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)
}
var onPress: IntConsumer? = null,
) : AbstractButtonPanel<S>(screen, parent, x, y, width, height) {
abstract val PRESSED: AbstractMatterySprite
abstract val HOVERED: AbstractMatterySprite
abstract val IDLE: AbstractMatterySprite
abstract val DISABLED: AbstractMatterySprite
var isDisabled = false
set(value) {
if (field != value) {
if (!value) {
pressed = false
grabMouseInput = false
}
override fun onClick(mouseButton: Int) {
onPress?.accept(mouseButton)
}
field = value
}
}
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
protected fun renderSquareButton(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
if (isDisabled) {
DISABLED.render(stack, 0f, 0f, width, height)
} else if (pressed) {
} else if (isPressed) {
PRESSED.render(stack, 0f, 0f, width, height)
} else if (isHovered) {
HOVERED.render(stack, 0f, 0f, width, height)
@ -51,31 +39,7 @@ abstract class RectangleButtonPanel<out S : Screen>(
}
}
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
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
renderSquareButton(stack, mouseX, mouseY, partialTick)
}
}

View File

@ -44,22 +44,16 @@ open class QueryUserPanel<out S: Screen>(
this.height = height + bottom.height + PADDING + PADDING_TOP + 4f
ButtonPanel(screen, bottom, width = font.width(TranslatableComponent("otm.gui.cancel")) + 12f, label = TranslatableComponent("otm.gui.cancel")).also {
it.bind {
onCancel?.run()
this.remove()
}
it.dock = Dock.RIGHT
}
ButtonPanel(screen, bottom, width = font.width(TranslatableComponent("otm.gui.cancel")) + 12f, label = TranslatableComponent("otm.gui.cancel"), onPress = Runnable {
onCancel?.run()
this.remove()
}).dock = Dock.RIGHT
if (onConfirm != null) {
ButtonPanel(screen, bottom, width = font.width(TranslatableComponent("otm.gui.confirm")) + 12f, label = TranslatableComponent("otm.gui.confirm")).also {
it.bind {
onConfirm.run()
this.remove()
}
ButtonPanel(screen, bottom, width = font.width(TranslatableComponent("otm.gui.confirm")) + 12f, label = TranslatableComponent("otm.gui.confirm"), onPress = Runnable {
onConfirm.run()
this.remove()
}).also {
it.dock = Dock.RIGHT
it.dockRight = 2f
}

View File

@ -643,12 +643,10 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
researchCanvas.parent = research
val bottom = EditablePanel(this, research, 0f, 0f, 0f, 20f)
val close = ButtonPanel(this, bottom, 0f, 0f, 90f, 20f, TranslatableComponent("otm.container.matter_panel.close"))
val close = ButtonPanel(this, bottom, 0f, 0f, 90f, 20f, TranslatableComponent("otm.container.matter_panel.close"), onPress = Runnable { research!!.remove() })
bottom.dock = Dock.BOTTOM
close.dock = Dock.RIGHT
close.bind { research!!.remove() }
bottom.setDockMargin(0f, 0f, 4f, 4f)
researchCanvas.setDockMargin(4f, 4f, 4f, 4f)

View File

@ -81,10 +81,9 @@ class EnergyCounterScreen(menu: EnergyCounterMenu, inventory: Inventory, title:
label.setDockMargin(4f, 0f, 0f, 0f)
if (!menu.ply.isSpectator) {
val button = ButtonPanel(this, frame, 0f, 0f, 0f, 20f, TranslatableComponent("block.overdrive_that_matters.energy_counter.switch"))
val button = ButtonPanel(this, frame, 0f, 0f, 0f, 20f, TranslatableComponent("block.overdrive_that_matters.energy_counter.switch"), onPress = Runnable { menu.switchDirection.input(null) })
button.dock = Dock.TOP
button.setDockMargin(4f, 0f, 4f, 0f)
button.bind { menu.switchDirection.input(null) }
}
val infoPanels = frame.fetchChildren()

View File

@ -14,7 +14,25 @@ import kotlin.reflect.KMutableProperty0
*
* Getting and setting values should ONLY be done clientside
*/
interface IPlayerInputWithFeedback<V> : GetterSetter<V>, Predicate<Player?>
interface IPlayerInputWithFeedback<V> : GetterSetter<V>, Predicate<Player?> {
companion object {
fun <V> of(getterSetter: GetterSetter<V>): IPlayerInputWithFeedback<V> {
return object : IPlayerInputWithFeedback<V>, GetterSetter<V> by getterSetter {
override fun test(t: Player?): Boolean {
return true
}
}
}
fun <V> validPlayer(getterSetter: GetterSetter<V>): IPlayerInputWithFeedback<V> {
return object : IPlayerInputWithFeedback<V>, GetterSetter<V> by getterSetter {
override fun test(t: Player?): Boolean {
return t != null
}
}
}
}
}
/**
* Represents Server to Client synchronization and Client to Server input