Energy counter limit input using panel instead of widget
This commit is contained in:
parent
064fbd0f36
commit
b80da0e214
@ -13,6 +13,7 @@ import net.minecraft.client.gui.navigation.ScreenRectangle
|
|||||||
import net.minecraft.client.gui.screens.Screen
|
import net.minecraft.client.gui.screens.Screen
|
||||||
import net.minecraft.client.renderer.Rect2i
|
import net.minecraft.client.renderer.Rect2i
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.util.RandomSource
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import ru.dbotthepony.mc.otm.SystemTime
|
import ru.dbotthepony.mc.otm.SystemTime
|
||||||
import ru.dbotthepony.mc.otm.client.CursorType
|
import ru.dbotthepony.mc.otm.client.CursorType
|
||||||
@ -134,6 +135,14 @@ open class EditablePanel<out S : Screen>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val random: RandomSource by lazy {
|
||||||
|
if (screen is MatteryScreen<*>) {
|
||||||
|
screen.menu.random
|
||||||
|
} else {
|
||||||
|
RandomSource.create()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bigger values means lesser priority while docking, rendering and processing inputs.
|
* Bigger values means lesser priority while docking, rendering and processing inputs.
|
||||||
*/
|
*/
|
||||||
|
@ -200,6 +200,10 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
snapshotTimer = null
|
snapshotTimer = null
|
||||||
redo.clear()
|
redo.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isFocusedThis && snapshotTimer == null) {
|
||||||
|
idleCallback?.invoke()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun pushbackSnapshot() {
|
private fun pushbackSnapshot() {
|
||||||
@ -1062,6 +1066,8 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
return characterFilter?.acceptsCharacter(codepoint, mods, index) ?: true
|
return characterFilter?.acceptsCharacter(codepoint, mods, index) ?: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected var rejectCharacterTimer: Long? = null
|
||||||
|
|
||||||
override fun charTypedInternal(codepoint: Char, mods: Int): Boolean {
|
override fun charTypedInternal(codepoint: Char, mods: Int): Boolean {
|
||||||
if (!isActive) {
|
if (!isActive) {
|
||||||
killFocus()
|
killFocus()
|
||||||
@ -1087,6 +1093,7 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
|
|
||||||
if (!acceptsCharacter(codepoint, mods, index)) {
|
if (!acceptsCharacter(codepoint, mods, index)) {
|
||||||
playGuiClickSound()
|
playGuiClickSound()
|
||||||
|
rejectCharacterTimer = milliTime + SHAKE_MILLIS
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1145,6 +1152,19 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
|
|
||||||
val selectedLine = this[cursorLine]
|
val selectedLine = this[cursorLine]
|
||||||
|
|
||||||
|
val shakeX: Float
|
||||||
|
val shakeY: Float
|
||||||
|
|
||||||
|
if (rejectCharacterTimer != null && rejectCharacterTimer!! > milliTime) {
|
||||||
|
val strength = (rejectCharacterTimer!! - milliTime).toFloat() / SHAKE_MILLIS.toFloat()
|
||||||
|
shakeX = (random.nextFloat() - 0.5f) * strength
|
||||||
|
shakeY = (random.nextFloat() - 0.5f) * strength
|
||||||
|
} else {
|
||||||
|
rejectCharacterTimer = null
|
||||||
|
shakeX = 0f
|
||||||
|
shakeY = 0f
|
||||||
|
}
|
||||||
|
|
||||||
if (selectedLine != null) {
|
if (selectedLine != null) {
|
||||||
val w = width(selectedLine, end = cursorRow) - scrollPixels
|
val w = width(selectedLine, end = cursorRow) - scrollPixels
|
||||||
|
|
||||||
@ -1162,14 +1182,14 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
stack.pushPose()
|
stack.pushPose()
|
||||||
stack.translate(-scrollPixels, 0f, 0f)
|
stack.translate(-scrollPixels, 0f, 0f)
|
||||||
|
|
||||||
var y = topPadding
|
var y = topPadding + shakeY
|
||||||
|
|
||||||
if (lines.isEmpty() || lines.size == 1 && lines[0] == "") {
|
if (lines.isEmpty() || lines.size == 1 && lines[0] == "") {
|
||||||
graphics.draw(
|
graphics.draw(
|
||||||
font = font,
|
font = font,
|
||||||
text = placeholder,
|
text = placeholder,
|
||||||
gravity = RenderGravity.TOP_LEFT,
|
gravity = RenderGravity.TOP_LEFT,
|
||||||
x = dockPadding.left,
|
x = dockPadding.left + shakeX,
|
||||||
y = y,
|
y = y,
|
||||||
color = placeholderColor
|
color = placeholderColor
|
||||||
)
|
)
|
||||||
@ -1182,7 +1202,7 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
graphics.draw(
|
graphics.draw(
|
||||||
text = line,
|
text = line,
|
||||||
gravity = RenderGravity.TOP_LEFT,
|
gravity = RenderGravity.TOP_LEFT,
|
||||||
x = dockPadding.left,
|
x = dockPadding.left + shakeX,
|
||||||
y = y,
|
y = y,
|
||||||
color = textColor
|
color = textColor
|
||||||
)
|
)
|
||||||
@ -1190,7 +1210,7 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
if (selection != null && selection.isValid) {
|
if (selection != null && selection.isValid) {
|
||||||
val (before, selected) = selection.sub(line)
|
val (before, selected) = selection.sub(line)
|
||||||
|
|
||||||
var x = dockPadding.left
|
var x = dockPadding.left + shakeX
|
||||||
|
|
||||||
if (before.isNotEmpty()) {
|
if (before.isNotEmpty()) {
|
||||||
x += font.width(before).toFloat()
|
x += font.width(before).toFloat()
|
||||||
@ -1233,16 +1253,16 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
graphics.draw(
|
graphics.draw(
|
||||||
text = "_",
|
text = "_",
|
||||||
gravity = RenderGravity.TOP_LEFT,
|
gravity = RenderGravity.TOP_LEFT,
|
||||||
x = dockPadding.left + (if (activeLine == null) 0f else font.width(activeLine).toFloat()),
|
x = dockPadding.left + (if (activeLine == null) 0f else font.width(activeLine).toFloat()) + shakeX,
|
||||||
y = topPadding + (cursorLine - scrollLines) * (font.lineHeight + rowSpacing),
|
y = topPadding + (cursorLine - scrollLines) * (font.lineHeight + rowSpacing) + shakeY,
|
||||||
color = cursorColor
|
color = cursorColor
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
graphics.draw(
|
graphics.draw(
|
||||||
text = "|",
|
text = "|",
|
||||||
gravity = RenderGravity.TOP_LEFT,
|
gravity = RenderGravity.TOP_LEFT,
|
||||||
x = dockPadding.left + font.width(activeLine.substring(0, cursorRow)).toFloat() - 1f,
|
x = dockPadding.left + font.width(activeLine.substring(0, cursorRow)).toFloat() - 1f + shakeX,
|
||||||
y = topPadding + (cursorLine - scrollLines) * (font.lineHeight + rowSpacing),
|
y = topPadding + shakeY + (cursorLine - scrollLines) * (font.lineHeight + rowSpacing),
|
||||||
color = cursorColor
|
color = cursorColor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1393,11 +1413,16 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected var changeCallback: ((new: String, old: String) -> Unit)? = null
|
protected var changeCallback: ((new: String, old: String) -> Unit)? = null
|
||||||
|
protected var idleCallback: (() -> Unit)? = null
|
||||||
|
|
||||||
fun onTextChange(callback: (new: String, old: String) -> Unit) {
|
fun onTextChange(callback: (new: String, old: String) -> Unit) {
|
||||||
changeCallback = callback
|
changeCallback = callback
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onIdle(callback: () -> Unit) {
|
||||||
|
idleCallback = callback
|
||||||
|
}
|
||||||
|
|
||||||
private enum class CharType {
|
private enum class CharType {
|
||||||
SPACES {
|
SPACES {
|
||||||
override fun contains(input: Char): Boolean {
|
override fun contains(input: Char): Boolean {
|
||||||
@ -1446,6 +1471,7 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
const val SHAKE_MILLIS = 600L
|
||||||
val NEWLINES = Regex("\r?\n")
|
val NEWLINES = Regex("\r?\n")
|
||||||
private val BUFFER = DynamicBufferSource()
|
private val BUFFER = DynamicBufferSource()
|
||||||
|
|
||||||
|
@ -34,9 +34,11 @@ import ru.dbotthepony.mc.otm.client.screen.widget.WideProfiledPowerGaugePanel
|
|||||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||||
import ru.dbotthepony.kommons.math.RGBAColor
|
import ru.dbotthepony.kommons.math.RGBAColor
|
||||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||||
|
import ru.dbotthepony.mc.otm.core.RandomSource2Generator
|
||||||
import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu
|
import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu
|
||||||
import ru.dbotthepony.mc.otm.network.AndroidResearchRequestPacket
|
import ru.dbotthepony.mc.otm.network.AndroidResearchRequestPacket
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.random.RandomGenerator
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
@ -440,8 +442,8 @@ private class AndroidResearchButton(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private enum class PreviewScrollers(
|
private enum class PreviewScrollers(
|
||||||
val init: (EditablePanel<*>, Random) -> Unit,
|
val init: (EditablePanel<*>, RandomGenerator) -> Unit,
|
||||||
val scroll: (EditablePanel<*>, Random) -> Boolean
|
val scroll: (EditablePanel<*>, RandomGenerator) -> Boolean
|
||||||
) {
|
) {
|
||||||
LEFT_TO_RIGHT(
|
LEFT_TO_RIGHT(
|
||||||
init = { it, random ->
|
init = { it, random ->
|
||||||
@ -499,8 +501,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
|
|||||||
val rows = Int2ObjectOpenHashMap<EditablePanel<AndroidStationScreen>>()
|
val rows = Int2ObjectOpenHashMap<EditablePanel<AndroidStationScreen>>()
|
||||||
|
|
||||||
val canvas = object : DraggableCanvasPanel<AndroidStationScreen>(this@AndroidStationScreen, null) {
|
val canvas = object : DraggableCanvasPanel<AndroidStationScreen>(this@AndroidStationScreen, null) {
|
||||||
private val random = Random()
|
private var scroller: PreviewScrollers = PreviewScrollers.entries.let { it[random.nextInt(it.size)] }
|
||||||
private var scroller: PreviewScrollers = PreviewScrollers.values().let { it[random.nextInt(it.size)] }
|
|
||||||
private var firstTick = false
|
private var firstTick = false
|
||||||
|
|
||||||
override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
|
override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||||
@ -522,14 +523,14 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
|
|||||||
|
|
||||||
if (isPreview && !layoutInvalidated) {
|
if (isPreview && !layoutInvalidated) {
|
||||||
if (firstTick) {
|
if (firstTick) {
|
||||||
scroller.init.invoke(this, random)
|
scroller.init.invoke(this, RandomSource2Generator(random))
|
||||||
}
|
}
|
||||||
|
|
||||||
val status = scroller.scroll.invoke(this, random)
|
val status = scroller.scroll.invoke(this, RandomSource2Generator(random))
|
||||||
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
scroller = PreviewScrollers.values().let { it[random.nextInt(it.size)] }
|
scroller = PreviewScrollers.entries.let { it[random.nextInt(it.size)] }
|
||||||
scroller.init.invoke(this, random)
|
scroller.init.invoke(this, RandomSource2Generator(random))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
|
|||||||
import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls
|
import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.input.NetworkNumberInputPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.input.NetworkNumberInputPanel
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.input.TextInputPanel
|
||||||
|
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.util.formatPower
|
import ru.dbotthepony.mc.otm.core.util.formatPower
|
||||||
import ru.dbotthepony.mc.otm.menu.tech.EnergyCounterMenu
|
import ru.dbotthepony.mc.otm.menu.tech.EnergyCounterMenu
|
||||||
|
|
||||||
@ -85,9 +87,28 @@ class EnergyCounterScreen(menu: EnergyCounterMenu, inventory: Inventory, title:
|
|||||||
it.dockTop = 10f
|
it.dockTop = 10f
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkNumberInputPanel(this, limitsTab.canvas, widget = menu.maxIOInput, networkValue = menu::maxIO).also {
|
TextInputPanel(this, limitsTab.canvas).also {
|
||||||
it.dock = Dock.TOP
|
it.dock = Dock.TOP
|
||||||
it.dockTop = 4f
|
it.dockTop = 4f
|
||||||
|
|
||||||
|
it.allowNumbersAndSign()
|
||||||
|
it.onTextChange { new, old ->
|
||||||
|
try {
|
||||||
|
var value = Decimal(new)
|
||||||
|
|
||||||
|
if (value < Decimal.ZERO)
|
||||||
|
value = Decimal.MINUS_ONE
|
||||||
|
|
||||||
|
if (value != menu.maxIOInput)
|
||||||
|
menu.maxIOInput.accept(value)
|
||||||
|
} catch (err: NumberFormatException) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it.onIdle {
|
||||||
|
it.text = menu.maxIO.toString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
makeDeviceControls(this, frame, redstoneConfig = menu.redstone)
|
makeDeviceControls(this, frame, redstoneConfig = menu.redstone)
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.core
|
||||||
|
|
||||||
|
import net.minecraft.util.RandomSource
|
||||||
|
import java.util.random.RandomGenerator
|
||||||
|
|
||||||
|
class RandomSource2Generator(private val parent: RandomSource) : RandomGenerator {
|
||||||
|
override fun nextLong(): Long {
|
||||||
|
return parent.nextLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextInt(): Int {
|
||||||
|
return parent.nextInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextFloat(): Float {
|
||||||
|
return parent.nextFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextDouble(): Double {
|
||||||
|
return parent.nextDouble()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextBoolean(): Boolean {
|
||||||
|
return parent.nextBoolean()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextGaussian(): Double {
|
||||||
|
return parent.nextGaussian()
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf
|
|||||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload
|
||||||
import net.minecraft.resources.ResourceLocation
|
import net.minecraft.resources.ResourceLocation
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
import net.minecraft.util.RandomSource
|
||||||
import net.minecraft.world.Container
|
import net.minecraft.world.Container
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
@ -78,6 +79,7 @@ abstract class MatteryMenu(
|
|||||||
val mSynchronizer = Syncher()
|
val mSynchronizer = Syncher()
|
||||||
val synchronizerRemote = mSynchronizer.Remote()
|
val synchronizerRemote = mSynchronizer.Remote()
|
||||||
val player: Player get() = inventory.player
|
val player: Player get() = inventory.player
|
||||||
|
val random: RandomSource = RandomSource.create()
|
||||||
|
|
||||||
private val _playerInventorySlots = ArrayList<InventorySlot>()
|
private val _playerInventorySlots = ArrayList<InventorySlot>()
|
||||||
private val _playerHotbarSlots = ArrayList<InventorySlot>()
|
private val _playerHotbarSlots = ArrayList<InventorySlot>()
|
||||||
|
Loading…
Reference in New Issue
Block a user