From d66f892d9e4d19e295fec6ecb44ee557e188a58b Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 9 Sep 2022 17:53:45 +0700 Subject: [PATCH] Inventory rows height test --- .../ru/dbotthepony/mc/otm/client/Ext.kt | 65 ++++++++++++++ .../mc/otm/client/render/SkinElement.kt | 33 ++++---- .../mc/otm/client/render/Widgets.kt | 15 ++++ .../client/screen/ExoSuitInventoryScreen.kt | 79 ++++++++++++++---- .../otm/client/screen/panels/ButtonPanel.kt | 28 ++++--- .../screen/panels/DiscreteScrollBarPanel.kt | 8 +- .../client/screen/panels/HeightControls.kt | 79 ++++++++++++++++++ .../textures/gui/widgets.png | Bin 3126 -> 3267 bytes .../textures/gui/widgets.xcf | 4 +- 9 files changed, 260 insertions(+), 51 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets.kt create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/HeightControls.kt diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/Ext.kt index 4103e8d04..4e45b1e5e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/Ext.kt @@ -4,6 +4,10 @@ import net.minecraft.client.Minecraft import net.minecraft.client.gui.Font import net.minecraft.client.resources.sounds.SimpleSoundInstance import net.minecraft.sounds.SoundEvents +import org.lwjgl.glfw.GLFW +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.DoubleBuffer inline val minecraft: Minecraft get() = Minecraft.getInstance() inline val font: Font get() = minecraft.font @@ -11,3 +15,64 @@ inline val font: Font get() = minecraft.font fun playGuiClickSound() { minecraft.soundManager.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0f)) } + +fun setMousePos(x: Double, y: Double) { + GLFW.glfwSetCursorPos(minecraft.window.window, x, y) +} + +private val cursorXPosBuf = ByteBuffer.allocateDirect(8).also { it.order(ByteOrder.LITTLE_ENDIAN) }.asDoubleBuffer() +private val cursorYPosBuf = ByteBuffer.allocateDirect(8).also { it.order(ByteOrder.LITTLE_ENDIAN) }.asDoubleBuffer() + +data class MousePos(val x: Double, val y: Double) { + fun set() { + setMousePos(x, y) + } + + fun move(x: Double = 0.0, y: Double = 0.0) { + GLFW.glfwSetCursorPos(minecraft.window.window, this.x + x, this.y + y) + } + + fun move(x: Float = 0.0f, y: Float = 0.0f) { + GLFW.glfwSetCursorPos(minecraft.window.window, this.x + x, this.y + y) + } + + fun moveScaled(x: Double = 0.0, y: Double = 0.0) { + GLFW.glfwSetCursorPos(minecraft.window.window, this.x + x * minecraft.window.guiScale, this.y + y * minecraft.window.guiScale) + } + + fun moveScaled(x: Float = 0.0f, y: Float = 0.0f) { + GLFW.glfwSetCursorPos(minecraft.window.window, this.x + x * minecraft.window.guiScale, this.y + y * minecraft.window.guiScale) + } +} + +val mousePos: MousePos get() { + cursorXPosBuf.position(0) + cursorYPosBuf.position(0) + + GLFW.glfwGetCursorPos(minecraft.window.window, cursorXPosBuf, cursorYPosBuf) + + cursorXPosBuf.position(0) + cursorYPosBuf.position(0) + + return MousePos(cursorXPosBuf.get(), cursorYPosBuf.get()) +} + +fun moveMousePos(x: Double = 0.0, y: Double = 0.0) { + val (currentX, currentY) = mousePos + GLFW.glfwSetCursorPos(minecraft.window.window, currentX + x, currentY + y) +} + +fun moveMousePos(x: Float = 0.0f, y: Float = 0.0f) { + val (currentX, currentY) = mousePos + GLFW.glfwSetCursorPos(minecraft.window.window, currentX + x, currentY + y) +} + +fun moveMousePosScaled(x: Double = 0.0, y: Double = 0.0) { + val (currentX, currentY) = mousePos + GLFW.glfwSetCursorPos(minecraft.window.window, currentX + x * minecraft.window.guiScale, currentY + y * minecraft.window.guiScale) +} + +fun moveMousePosScaled(x: Float = 0.0f, y: Float = 0.0f) { + val (currentX, currentY) = mousePos + GLFW.glfwSetCursorPos(minecraft.window.window, currentX + x * minecraft.window.guiScale, currentY + y * minecraft.window.guiScale) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SkinElement.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SkinElement.kt index 3eb4cc711..97435aaee 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SkinElement.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/SkinElement.kt @@ -6,7 +6,7 @@ import net.minecraft.resources.ResourceLocation import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty @Suppress("unused") -class SkinGrid( +data class SkinGrid( val texture: ResourceLocation, val width: Float, val height: Float, @@ -92,14 +92,15 @@ fun ResourceLocation.vLine( ) = SkinElement(this, x, y, 1f, height, textureWidth, textureHeight) @Suppress("unused") -class SkinElement @JvmOverloads constructor( +data class SkinElement @JvmOverloads constructor( val texture: ResourceLocation, val x: Float, val y: Float, val width: Float, val height: Float, val imageWidth: Float = 256f, - val imageHeight: Float = 256f + val imageHeight: Float = 256f, + val winding: UVWindingOrder = UVWindingOrder.NORMAL ) { init { require(x >= 0f) { "Invalid x $x" } @@ -117,7 +118,7 @@ class SkinElement @JvmOverloads constructor( y: Float = 0f, width: Float = this.width, height: Float = this.height, - winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1 + winding: UVWindingOrder = this.winding ) { RenderSystem.setShaderTexture(0, texture) RenderSystem.enableBlend() @@ -133,7 +134,7 @@ class SkinElement @JvmOverloads constructor( y: Double = 0.0, width: Double = this.width.toDouble(), height: Double = this.height.toDouble(), - winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1 + winding: UVWindingOrder = this.winding ) = render(stack, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), winding) @JvmOverloads @@ -143,7 +144,7 @@ class SkinElement @JvmOverloads constructor( y: Float = 0f, width: Float = this.width, height: Float = this.height, - winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1 + winding: UVWindingOrder = this.winding ) { RenderSystem.setShaderTexture(0, texture) RenderSystem.enableBlend() @@ -159,7 +160,7 @@ class SkinElement @JvmOverloads constructor( y: Double = 0.0, width: Double = this.width.toDouble(), height: Double = this.height.toDouble(), - winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1 + winding: UVWindingOrder = this.winding ) = renderPartial(stack, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), winding) @JvmOverloads @@ -168,7 +169,7 @@ class SkinElement @JvmOverloads constructor( x: Float = 0f, y: Float = 0f, width: Float = this.width, - winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1, + winding: UVWindingOrder = this.winding ) { render(stack, x, y, width = width, winding = winding) } @@ -179,7 +180,7 @@ class SkinElement @JvmOverloads constructor( x: Double, y: Double = 0.0, width: Double = this.width.toDouble(), - winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1, + winding: UVWindingOrder = this.winding, ) = renderWidth(stack, x.toFloat(), y.toFloat(), width.toFloat(), winding) @JvmOverloads @@ -188,7 +189,7 @@ class SkinElement @JvmOverloads constructor( x: Float = 0f, y: Float = 0f, height: Float = this.height, - winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1, + winding: UVWindingOrder = this.winding, ) { render(stack, x, y, height = height, winding = winding) } @@ -199,7 +200,7 @@ class SkinElement @JvmOverloads constructor( x: Double, y: Double = 0.0, height: Double = this.height.toDouble(), - winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1, + winding: UVWindingOrder = this.winding, ) = renderHieght(stack, x.toFloat(), y.toFloat(), height.toFloat(), winding) private val u0 = this.x / imageWidth @@ -214,7 +215,7 @@ class SkinElement @JvmOverloads constructor( y: Float = 0f, width: Float = this.width, height: Float = this.height, - winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1 + winding: UVWindingOrder = UVWindingOrder.NORMAL ) { val winded = winding.translate(u0, v0, u1, v1) @@ -235,7 +236,7 @@ class SkinElement @JvmOverloads constructor( y: Double = 0.0, width: Double = this.width.toDouble(), height: Double = this.height.toDouble(), - winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1 + winding: UVWindingOrder = UVWindingOrder.NORMAL ) = renderRaw(stack, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), winding) @JvmOverloads @@ -245,7 +246,7 @@ class SkinElement @JvmOverloads constructor( y: Float = 0f, width: Float = this.width, height: Float = this.height, - winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1 + winding: UVWindingOrder = UVWindingOrder.NORMAL ) { val u1 = (this.x + width) / imageWidth val v1 = (this.y + height) / imageHeight @@ -269,11 +270,11 @@ class SkinElement @JvmOverloads constructor( y: Double = 0.0, width: Double = this.width.toDouble(), height: Double = this.height.toDouble(), - winding: UVWindingOrder = UVWindingOrder.U0_V0_U1_V1 + winding: UVWindingOrder = UVWindingOrder.NORMAL ) = renderRawPartial(stack, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), winding) } -class StretchingRectangleElement( +data class StretchingRectangleElement( val topLeft: SkinElement, val topRight: SkinElement, val bottomLeft: SkinElement, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets.kt new file mode 100644 index 000000000..ab9cbb6be --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Widgets.kt @@ -0,0 +1,15 @@ +package ru.dbotthepony.mc.otm.client.render + +object Widgets { + val SLOT = WidgetLocation.WIDGETS.element(0f, 0f, 18f, 18f) + + val ARROW_UP_BUTTON_IDLE = WidgetLocation.WIDGETS.element(0f, 18f, 18f, 6f) + val ARROW_UP_BUTTON_HOVERED = WidgetLocation.WIDGETS.element(0f, 18f + 6f, 18f, 6f) + val ARROW_UP_BUTTON_PRESSED = WidgetLocation.WIDGETS.element(0f, 18f + 6f * 2f, 18f, 6f) + val ARROW_UP_BUTTON_DISABLED = WidgetLocation.WIDGETS.element(0f, 18f + 6f * 3f, 18f, 6f) + + val ARROW_DOWN_BUTTON_IDLE = ARROW_UP_BUTTON_IDLE.copy(winding = UVWindingOrder.FLIP) + val ARROW_DOWN_BUTTON_HOVERED = ARROW_UP_BUTTON_HOVERED.copy(winding = UVWindingOrder.FLIP) + val ARROW_DOWN_BUTTON_PRESSED = ARROW_UP_BUTTON_PRESSED.copy(winding = UVWindingOrder.FLIP) + val ARROW_DOWN_BUTTON_DISABLED = ARROW_UP_BUTTON_DISABLED.copy(winding = UVWindingOrder.FLIP) +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExoSuitInventoryScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExoSuitInventoryScreen.kt index 59e066909..c0350dffa 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExoSuitInventoryScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExoSuitInventoryScreen.kt @@ -3,10 +3,14 @@ package ru.dbotthepony.mc.otm.client.screen import com.mojang.blaze3d.platform.InputConstants import com.mojang.blaze3d.vertex.PoseStack import net.minecraft.client.gui.screens.inventory.InventoryScreen +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.render.Widgets18 import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.client.render.element import ru.dbotthepony.mc.otm.client.screen.panels.* +import ru.dbotthepony.mc.otm.client.setMousePos import ru.dbotthepony.mc.otm.client.shouldOpenVanillaInventory import ru.dbotthepony.mc.otm.menu.ExoSuitInventoryMenu import ru.dbotthepony.mc.otm.network.ExoSuitMenuOpen @@ -15,25 +19,59 @@ import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak @MouseTweaksDisableWheelTweak class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen(menu, TranslatableComponent("otm.gui.exosuit")) { + var inventoryRows = 3 + set(value) { + val newValue = value.coerceAtLeast(3).coerceAtMost(6) + val old = field + + if (field != newValue) { + field = newValue + + if (mainFrame != null) { + updateInventoryRows(old) + } + } + } + + private lateinit var mainInventoryLine: EditablePanel + private lateinit var scrollPanel: DiscreteScrollBarPanel + + private fun updateInventoryRows(old: Int) { + mainFrame!!.height = FRAME_BASE_HEIGHT + inventoryRows * AbstractSlotPanel.SIZE + mainInventoryLine.height = AbstractSlotPanel.SIZE * inventoryRows + + for (i in scrollPanel.scroll until scrollPanel.scroll + old) { + getInventorySlotsRow(i).visible = false + } + + for (i in scrollPanel.scroll until scrollPanel.scroll + inventoryRows) { + getInventorySlotsRow(i).also { + it.parent = mainInventoryLine + it.y = AbstractSlotPanel.SIZE * (i - scrollPanel.scroll) + it.visible = true + } + } + + scrollPanel.scroll = scrollPanel.scroll + } + override fun makeMainFrame(): FramePanel> { - val frame = FramePanel(this, width = 200f, height = 180f, title = this.title) + val frame = FramePanel(this, width = 200f, height = FRAME_BASE_HEIGHT + inventoryRows * AbstractSlotPanel.SIZE, title = this.title) val toolbeltLine = EditablePanel(this, frame, height = 18f) toolbeltLine.dock = Dock.BOTTOM toolbeltLine.setDockMargin(top = 3f) - var mainInventoryLine: EditablePanel<*>? = null - - val scrollPanel = DiscreteScrollBarPanel(this, null, maxScroll = { ((menu.playerCombinedInventorySlots.size - 27) + 8) / 9 }, + scrollPanel = DiscreteScrollBarPanel(this, null, maxScroll = { ((menu.playerCombinedInventorySlots.size - inventoryRows * 9) + 8) / 9 }, scrollCallback = { _, old, new -> - for (i in old .. old + 2) { + for (i in old until old + inventoryRows) { getInventorySlotsRow(i).visible = false } - for (i in new .. new + 2) { + for (i in new until new + inventoryRows) { val row = getInventorySlotsRow(i) row.visible = true row.y = (i - new) * AbstractSlotPanel.SIZE @@ -43,14 +81,13 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen(this@ExoSuitInventoryScreen, frame, height = 18f * 3f) { + mainInventoryLine = object : EditablePanel(this@ExoSuitInventoryScreen, frame, height = AbstractSlotPanel.SIZE * inventoryRows) { override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean { return scrollPanel.mouseScrolledInner(x, y, scroll) } } + scrollPanel.scroll = menu.lastScroll scrollPanel.parent = mainInventoryLine mainInventoryLine.dock = Dock.BOTTOM @@ -63,7 +100,7 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen( + object : EditablePanel( this@ExoSuitInventoryScreen, craftingCanvas, x = craftingSlotsCanvas.width, @@ -132,15 +169,27 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen 3) + }.also { + it.controlStatus = HeightControls.Status.of(inventoryRows < 6, inventoryRows > 3) + } + return frame } @@ -153,5 +202,7 @@ class ExoSuitInventoryScreen(menu: ExoSuitInventoryMenu) : MatteryScreen>( +open class ButtonPanel( screen: S, parent: EditablePanel<*>?, x: Float = 0f, @@ -42,6 +42,10 @@ open class ButtonPanel>( 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 @@ -62,7 +66,7 @@ open class ButtonPanel>( pressed = false if (isHovered) { - callback?.run() + onClick(button) } return true @@ -113,7 +117,7 @@ open class ButtonPanel>( } @Suppress("PropertyName") -abstract class RectangleButtonPanel>( +abstract class RectangleButtonPanel( screen: S, parent: EditablePanel<*>?, x: Float = 0f, @@ -124,7 +128,7 @@ abstract class RectangleButtonPanel>( ) : EditablePanel(screen, parent, x, y, width, height) { protected var pressed = false - protected open fun click(clickButton: Int) { + protected open fun onClick(clickButton: Int) { onPress?.invoke(clickButton) } @@ -175,7 +179,7 @@ abstract class RectangleButtonPanel>( pressed = false if (isHovered) { - click(button) + onClick(button) } } @@ -185,7 +189,7 @@ abstract class RectangleButtonPanel>( } } -abstract class EnumRectangleButtonPanel, T : Enum>( +abstract class EnumRectangleButtonPanel>( screen: S, parent: EditablePanel<*>?, x: Float = 0f, @@ -293,7 +297,7 @@ abstract class EnumRectangleButtonPanel, T : return super.mouseReleasedInner(x, y, button) } - override fun click(clickButton: Int) { + override fun onClick(clickButton: Int) { when (clickButton) { InputConstants.MOUSE_BUTTON_LEFT -> { prop.set(prop.get().next(enum.enumConstants)) @@ -354,7 +358,7 @@ abstract class EnumRectangleButtonPanel, T : } } -open class LargeRectangleButtonPanel>( +open class LargeRectangleButtonPanel( screen: S, parent: EditablePanel<*>?, x: Float = 0f, @@ -385,7 +389,7 @@ open class LargeRectangleButtonPanel>( } } -open class LargeEnumRectangleButtonPanel, T : Enum>( +open class LargeEnumRectangleButtonPanel>( screen: S, parent: EditablePanel<*>?, x: Float = 0f, @@ -407,7 +411,7 @@ open class LargeEnumRectangleButtonPanel, T : } } -open class SmallRectangleButtonPanel>( +open class SmallRectangleButtonPanel( screen: S, parent: EditablePanel<*>?, x: Float = 0f, @@ -438,7 +442,7 @@ open class SmallRectangleButtonPanel>( } } -open class SmallEnumRectangleButtonPanel, T : Enum>( +open class SmallEnumRectangleButtonPanel>( screen: S, parent: EditablePanel<*>?, x: Float = 0f, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/DiscreteScrollBarPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/DiscreteScrollBarPanel.kt index 31b18b3d3..07a7598cb 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/DiscreteScrollBarPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/DiscreteScrollBarPanel.kt @@ -95,13 +95,7 @@ open class DiscreteScrollBarPanel @JvmOverloads constructor( return } - val newValue = if (value < 0) { - 0 - } else if (value > maxScroll.invoke(this)) { - maxScroll.invoke(this) - } else { - value - } + val newValue = value.coerceAtLeast(0).coerceAtMost(maxScroll.invoke(this)) if (newValue != field) { val old = field diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/HeightControls.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/HeightControls.kt new file mode 100644 index 000000000..23e4c781b --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/HeightControls.kt @@ -0,0 +1,79 @@ +package ru.dbotthepony.mc.otm.client.screen.panels + +import com.mojang.blaze3d.platform.InputConstants +import net.minecraft.client.gui.screens.Screen +import ru.dbotthepony.mc.otm.client.render.SkinElement +import ru.dbotthepony.mc.otm.client.render.Widgets + +open class HeightControls( + screen: S, + parent: EditablePanel<*>?, + x: Float = 0f, + y: Float = 0f, + val callback: (isIncrease: Boolean) -> Status +) : BackgroundPanel(screen, parent, x, y, WIDTH, HEIGHT) { + enum class Status(val canIncrease: Boolean, val canDecrease: Boolean) { + NONE(false, false), + INCREASE(true, false), + DECREASE(false, true), + EITHER(true, true); + + companion object { + fun of(canIncrease: Boolean, canDecrease: Boolean): Status { + return if (canIncrease && canDecrease) { + EITHER + } else if (canIncrease) { + INCREASE + } else if (canDecrease) { + DECREASE + } else { + NONE + } + } + } + } + + var controlStatus: Status = Status.EITHER + set(value) { + if (field == value) + return + + field = value + increase.isDisabled = !value.canIncrease + decrease.isDisabled = !value.canDecrease + } + + open inner class Control(val isIncrease: Boolean) : RectangleButtonPanel(screen, this@HeightControls, width = BUTTON_WIDTH, height = BUTTON_HEIGHT) { + override val PRESSED: SkinElement = if (isIncrease) Widgets.ARROW_DOWN_BUTTON_PRESSED else Widgets.ARROW_UP_BUTTON_PRESSED + override val HOVERED: SkinElement = if (isIncrease) Widgets.ARROW_DOWN_BUTTON_HOVERED else Widgets.ARROW_UP_BUTTON_HOVERED + override val IDLE: SkinElement = if (isIncrease) Widgets.ARROW_DOWN_BUTTON_IDLE else Widgets.ARROW_UP_BUTTON_IDLE + override val DISABLED: SkinElement = if (isIncrease) Widgets.ARROW_DOWN_BUTTON_DISABLED else Widgets.ARROW_UP_BUTTON_DISABLED + + init { + dock = Dock.TOP + dockBottom = 2f + } + + override fun onClick(clickButton: Int) { + if (clickButton == InputConstants.MOUSE_BUTTON_LEFT) { + this@HeightControls.onClick(isIncrease) + } else if (clickButton == InputConstants.MOUSE_BUTTON_RIGHT) { + this@HeightControls.onClick(!isIncrease) + } + } + } + + val decrease = Control(false) + val increase = Control(true) + + open fun onClick(isIncrease: Boolean) { + controlStatus = callback.invoke(isIncrease) + } + + companion object { + const val BUTTON_WIDTH = 18f + const val BUTTON_HEIGHT = 6f + const val WIDTH = BUTTON_WIDTH + 4f + const val HEIGHT = BUTTON_HEIGHT * 2f + 8f + } +} diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.png index 97c810a1de313a1ea3e6c09f0871b552cda9384e..78b52f14e10c769a799011e4ca7e4e15f4c117f1 100644 GIT binary patch delta 3089 zcmaJ@i8s`X7yr)Km$AGWqpZm*qZozA(u@~nd7;Qwwvdn|Wam4~)ALKTD5PbkMZ#FK zg;`3Pm_!*Q#%QP^>tGnm%>4BG1Agb8d(U0YJ)d*#J?DOIlWNDVTe@I&*zx184#$sc z$HYco47(fx0D8C6Z(G}UVAMPP-5T}bQkFU9!7tf;Sub;*xz|anIG%fQR;s`W{m(v_ z!}Z)}<32HqL3O{z*~Cg*rM7ei*4*MKveo`SA}3jc3s&ayw6@fnZHZV{l<~lf(d-T(Y?PUvf$hmd8Q?k2Osr2k#u+#SXYLKRI4-Kzd z^mjGPDE8wsDE!WZlnBRSmSlIym?2fgEc`ET28m10Li0)@L9LO53Gqd=n5Pfjzg)~1 z|9r^Dhc7+Fk~FM7SJEzZejdQNvB6BD#+BH2`0##BMDMp46_uAzQr~bE1~cJ07zbNI%x}tehYzARzvXlBLBO_y^wZ|De1pu-X2U{EWq;GRfn~1$b8o;7RPA-g0Jrek& z&#CatA2EunZ1rz0wXU`7{;`4}OqM_zluo zKVzerY;vH>_*q@B1I52SA|kjqiMAnPiAc#Q1quoZu?MH8rt~CnHmxZwm%z>;+nOP| zvT|r>=tOk)M6?sK^p_dz-;VP1!u&?pD>vQ_4|`WFRBA>KPaLs6rhL_}2!TL=Vg0MG zx|iK(Bpqzg=Y_Q(Bh~Yr+%5cp(z|pALZr6J2uEVF9XR;sBgSMBU9)+fo7^0DKh$Km zo$b4^F+Z|ZhDK_c;)}eF#lQ;#Fm zOrxfq)N_SCg7|Y!$%tjTQW32tC^~w<0{M>5bwATm&byxTuwQrA&MWLmjn7*MnE(aV;AxkgO>GUrA((26&(OTz^ zcy5}$4%!o}f6MQ8IY#no!L!#rYkrE5o&bHTe0iC{?J7ewdqPGhD{IKt7s#8{SJ0^* ze;TPPEYpin5mH{KWmZy1?Gy@YgXMZGO05E`ppPYy9CH1uf!&E>v9_%nHB*G2cXf6r z44G9yz0N`Tt0U1147u`oX|Pf5%Zm_HqMcVPC_lb*n9Uc)zXnIs zSlI5(+t*joE{QOAz_d5e5sAm+X%*cg`z9n_Wi8Fl9-LcP;8Yjf4)C8-rM{iF5$pl6 zdettRGev}Q-x}b{_wRx8yp-H59evL0g2Los$Kb(6!9H5lVM3XR#Z{#e4Q(FiYrBMF zFPPUJ3IdeN(;k7&jg3op()^IeA}}@8-phcy^h_mCVGP~R%#=KfxdPWdxqK9`^o88T z1%M!WLm(Voet58;c0FS4QU5KzB|+kev5D z1J0g6rztOkqJ=D7;d3YMqgIngW+eRz$jOhqQwHv5zsj%ETXzpt{bW)2h6;BFI_0UA zj)c<^uCK+5&n39~N)*czCfhHa81FB0DbjCiGiQ2UVrW zyu7lGj+*XgbR0ps1_3Z9cH46c7A0({{L>nOAMp}!*0PCd6JsZV{%?gdkGN#NVxH z#&JD-9xO50cnz+s4|)K&Hw3SbLBp|>&qG?8nnxU~5+ko^ClaB071+Yq=k^62q7-$) zbZ+Qg8gNXswOpDI+dq=h*4Ifyf3NR^V{Xtz3}D2G2?@IkcW@+BPu2) zCK?5|%&OkUxh*2_PSA6|hrDS9+Xy!c__Bt&^B4GSE*Y@fuGJXJP(R8N(wLOi!>%2{ zxAxjqFa%*m9LT{Pi^$SXW6OTz6RhWQuH+*%JQn*9mfZ?o^~I{}g>+_P-KSxfuS)dU zX=MzquncjZw6)`C!1Wp7XEN0O$1n8F%1re-!3<<_w1=^B_l$m_B;{D1T&qvtSqWG0 zlCfCKhMiS%c0Nl^DUY?I{WhFB#(=B+S?Dd=u(&9RH8OGc<~g~WLoO^bVIEGj>#*u z-VkI|IR<`K!zw5$8eDT|hGRnPK*Cd}z7;aC@B){B>aVH*3g>oHyANRLS0ri~1K6%C z?Veml9ua6qU?a2 zo{+y)#6Nn7>u047>q46SAa^~)w@)=Q$r_tjz0T3tCHAtvo|3j+?*aZ{jz;$`kNujF z1)6;z4?PZKUaN$bxu+<`kmn_5!zKD^2V9V)qcglHA4Sw#b)dBZu<%hNm?*_qODpw6 zE7aeHWByI&KbV)%=1(_4r^2nVdQAC-7PMDx*pk}z{rZdLhkdni2&*tCmXpR)Auxoc zm+iE@xT+Yl?UjJ#?sIXQ!5aIabQmmmhhI*XASm{p@B|8^=7z+IZ$Ku$Onl9h z9p7A_n1%QL^Z*9#W2-pO=XxsTANn6g3(`9nxB!Yg`xbMzB1PP%I7<)XDAvV?w=^{%Ne&{Tlx9+#j=#-8xz|G&Fj? z{dyNa^_{j5rIvSMjs{%o2qfoenQ$HoS_4cAD}KkC@{-d>?qD2|rpR404Tqn7etA{y zs+!38>y&tHwXRWH@OdI@fp*CxTtLFTp;l&B^>>9}n2@jE#kFOq`TMbL#p2G+&TMdU z@?G?;xVwycH6vvMo$UJ#d(^OWt-{moXjup85 z+Jvnpa9&IplUl`%ROQc5SPND%Y3o0VjKxUmlUd+$i|N;mC|E+x+@I~qRcUpU@Y+FM zj~VMDOvvfQmu(ZtZ|JUq{aIQUOY$M{%q0XK4GOIq{|1u%7CoDbaDI!&;})1F7889} zQI7it0uWoZY}o+cH>jz=9yqlXr{(1aRocRok@@W0>>|Z~I|8F3?l15j1gZ(NG}KE& U(2H2n_7@2_*g4x){}qt+UkXk1VgLXD delta 2887 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 diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf index 1048cb96b..6e9c51aa9 100644 --- a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf +++ b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d1107b9cc8a1a50c4a167b9c8926ed9780a42280eaa97f8ae431f22ff9f34129 -size 53271 +oid sha256:855cbab0d60bb6bb8f606a07e47054aec1e3a493a0976cdb31a5518042656280 +size 55647