NetworkedStringInput
This commit is contained in:
parent
1842074d9e
commit
117e59e028
@ -5,6 +5,7 @@ import net.minecraft.world.entity.player.Inventory
|
|||||||
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
|
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.TextInputPanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.TextInputPanel
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.input.NetworkedStringInputPanel
|
||||||
import ru.dbotthepony.mc.otm.menu.HoloSignMenu
|
import ru.dbotthepony.mc.otm.menu.HoloSignMenu
|
||||||
import ru.dbotthepony.mc.otm.milliTime
|
import ru.dbotthepony.mc.otm.milliTime
|
||||||
|
|
||||||
@ -12,27 +13,9 @@ class HoloSignScreen(menu: HoloSignMenu, inventory: Inventory, title: Component)
|
|||||||
override fun makeMainFrame(): FramePanel<MatteryScreen<*>> {
|
override fun makeMainFrame(): FramePanel<MatteryScreen<*>> {
|
||||||
val frame = FramePanel(this, null, 0f, 0f, 200f, 200f, getTitle())
|
val frame = FramePanel(this, null, 0f, 0f, 200f, 200f, getTitle())
|
||||||
|
|
||||||
object : TextInputPanel<HoloSignScreen>(this@HoloSignScreen, frame) {
|
val input = NetworkedStringInputPanel(this, frame, backend = menu.text)
|
||||||
init {
|
input.dock = Dock.FILL
|
||||||
dock = Dock.FILL
|
input.multiLine = true
|
||||||
multiLine = true
|
|
||||||
}
|
|
||||||
|
|
||||||
private var lastChanges = 0L
|
|
||||||
|
|
||||||
override fun onTextChanged(old: String, new: String) {
|
|
||||||
lastChanges = milliTime + 1000L
|
|
||||||
menu.textInput.input(new)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun tick() {
|
|
||||||
super.tick()
|
|
||||||
|
|
||||||
if (milliTime >= lastChanges) {
|
|
||||||
text = menu.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
|
@ -138,9 +138,10 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
|
|
||||||
var cursorLine = 0
|
var cursorLine = 0
|
||||||
var cursorCharacter = 0
|
var cursorCharacter = 0
|
||||||
var textColor = RGBAColor.WHITE
|
open var textColor = RGBAColor.WHITE
|
||||||
var cursorColor = RGBAColor.GREEN
|
open var cursorColor = RGBAColor.GREEN
|
||||||
var backgroundColor = RGBAColor.BLACK
|
open var backgroundColor = RGBAColor.BLACK
|
||||||
|
open var isActive = true
|
||||||
|
|
||||||
private var oldText = ArrayList<String>()
|
private var oldText = ArrayList<String>()
|
||||||
private var textCache: String? = null
|
private var textCache: String? = null
|
||||||
@ -626,7 +627,7 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun keyPressedInternal(key: Int, scancode: Int, mods: Int): Boolean {
|
override fun keyPressedInternal(key: Int, scancode: Int, mods: Int): Boolean {
|
||||||
if (key == InputConstants.KEY_ESCAPE) {
|
if (key == InputConstants.KEY_ESCAPE || !isActive) {
|
||||||
killFocus()
|
killFocus()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -967,6 +968,11 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun charTypedInternal(codepoint: Char, mods: Int): Boolean {
|
override fun charTypedInternal(codepoint: Char, mods: Int): Boolean {
|
||||||
|
if (!isActive) {
|
||||||
|
killFocus()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
wipeSelection()
|
wipeSelection()
|
||||||
|
|
||||||
if (!multiLine)
|
if (!multiLine)
|
||||||
@ -1117,6 +1123,9 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
protected set
|
protected set
|
||||||
|
|
||||||
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
||||||
|
if (!isActive)
|
||||||
|
return true
|
||||||
|
|
||||||
selections.clear()
|
selections.clear()
|
||||||
requestFocus()
|
requestFocus()
|
||||||
|
|
||||||
|
@ -23,6 +23,6 @@ open class CheckBoxInputPanel<out S : Screen> @JvmOverloads constructor(
|
|||||||
set(value) {}
|
set(value) {}
|
||||||
|
|
||||||
override fun onClick() {
|
override fun onClick() {
|
||||||
widget.userInput(!checked, minecraft.player)
|
widget.input(!checked, minecraft.player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.client.screen.panels.input
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.screens.Screen
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
|
import ru.dbotthepony.mc.otm.client.screen.panels.TextInputPanel
|
||||||
|
import ru.dbotthepony.mc.otm.menu.input.AbstractNetworkedInput
|
||||||
|
import ru.dbotthepony.mc.otm.menu.input.NetworkedStringInput
|
||||||
|
import ru.dbotthepony.mc.otm.milliTime
|
||||||
|
|
||||||
|
open class NetworkedStringInputPanel<out S : Screen>(
|
||||||
|
screen: S,
|
||||||
|
parent: EditablePanel<*>?,
|
||||||
|
val backend: AbstractNetworkedInput<String>,
|
||||||
|
x: Float = 0f,
|
||||||
|
y: Float = 0f,
|
||||||
|
width: Float = 60f,
|
||||||
|
height: Float = 11f,
|
||||||
|
) : TextInputPanel<S>(screen, parent, x, y, width, height) {
|
||||||
|
override var isActive: Boolean
|
||||||
|
get() = backend.checkClient()
|
||||||
|
set(value) {}
|
||||||
|
|
||||||
|
override fun onFocusChanged(new: Boolean, old: Boolean) {
|
||||||
|
super.onFocusChanged(new, old)
|
||||||
|
|
||||||
|
if (new && !backend.checkClient()) {
|
||||||
|
killFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var lastChanges = 0L
|
||||||
|
|
||||||
|
override fun onTextChanged(old: String, new: String) {
|
||||||
|
lastChanges = milliTime + 1000L
|
||||||
|
backend.clientInput(new)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tick() {
|
||||||
|
super.tick()
|
||||||
|
|
||||||
|
if (milliTime >= lastChanges) {
|
||||||
|
text = backend.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import net.minecraft.world.entity.player.Inventory
|
|||||||
import net.minecraft.world.inventory.Slot
|
import net.minecraft.world.inventory.Slot
|
||||||
import ru.dbotthepony.mc.otm.block.entity.decorative.HoloSignBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.decorative.HoloSignBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.core.util.BinaryStringCodec
|
import ru.dbotthepony.mc.otm.core.util.BinaryStringCodec
|
||||||
|
import ru.dbotthepony.mc.otm.menu.input.NetworkedStringInput
|
||||||
import ru.dbotthepony.mc.otm.registry.MMenus
|
import ru.dbotthepony.mc.otm.registry.MMenus
|
||||||
|
|
||||||
class HoloSignMenu @JvmOverloads constructor(
|
class HoloSignMenu @JvmOverloads constructor(
|
||||||
@ -11,20 +12,8 @@ class HoloSignMenu @JvmOverloads constructor(
|
|||||||
inventory: Inventory,
|
inventory: Inventory,
|
||||||
tile: HoloSignBlockEntity? = null
|
tile: HoloSignBlockEntity? = null
|
||||||
) : MatteryMenu(MMenus.HOLO_SIGN, containerId, inventory, tile) {
|
) : MatteryMenu(MMenus.HOLO_SIGN, containerId, inventory, tile) {
|
||||||
var text by mSynchronizer.string(name = "text")
|
val text = if (tile != null) NetworkedStringInput(this, tile::text) else NetworkedStringInput(this).asClient()
|
||||||
|
|
||||||
val textInput = PlayerInput(BinaryStringCodec) {
|
|
||||||
if (tile is HoloSignBlockEntity)
|
|
||||||
tile.text = it
|
|
||||||
}
|
|
||||||
|
|
||||||
override val storageSlots: Collection<Slot>
|
override val storageSlots: Collection<Slot>
|
||||||
get() = listOf()
|
get() = listOf()
|
||||||
|
|
||||||
override fun broadcastChanges() {
|
|
||||||
super.broadcastChanges()
|
|
||||||
|
|
||||||
if (tile is HoloSignBlockEntity)
|
|
||||||
text = tile.text
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import ru.dbotthepony.mc.otm.compat.curios.isCurioSlot
|
|||||||
import ru.dbotthepony.mc.otm.container.ItemFilter
|
import ru.dbotthepony.mc.otm.container.ItemFilter
|
||||||
import ru.dbotthepony.mc.otm.container.ItemFilterNetworkSlot
|
import ru.dbotthepony.mc.otm.container.ItemFilterNetworkSlot
|
||||||
import ru.dbotthepony.mc.otm.core.util.BigDecimalValueCodec
|
import ru.dbotthepony.mc.otm.core.util.BigDecimalValueCodec
|
||||||
|
import ru.dbotthepony.mc.otm.core.util.BinaryStringCodec
|
||||||
import ru.dbotthepony.mc.otm.core.util.BooleanValueCodec
|
import ru.dbotthepony.mc.otm.core.util.BooleanValueCodec
|
||||||
import ru.dbotthepony.mc.otm.core.util.IStreamCodec
|
import ru.dbotthepony.mc.otm.core.util.IStreamCodec
|
||||||
import ru.dbotthepony.mc.otm.core.util.NullValueCodec
|
import ru.dbotthepony.mc.otm.core.util.NullValueCodec
|
||||||
@ -123,6 +124,7 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
|
|||||||
|
|
||||||
fun bigDecimalInput(allowSpectators: Boolean = false, handler: (BigDecimal) -> Unit) = PlayerInput(BigDecimalValueCodec, allowSpectators, handler)
|
fun bigDecimalInput(allowSpectators: Boolean = false, handler: (BigDecimal) -> Unit) = PlayerInput(BigDecimalValueCodec, allowSpectators, handler)
|
||||||
fun booleanInput(allowSpectators: Boolean = false, handler: (Boolean) -> Unit) = PlayerInput(BooleanValueCodec, allowSpectators, handler)
|
fun booleanInput(allowSpectators: Boolean = false, handler: (Boolean) -> Unit) = PlayerInput(BooleanValueCodec, allowSpectators, handler)
|
||||||
|
fun stringInput(allowSpectators: Boolean = false, handler: (String) -> Unit) = PlayerInput(BinaryStringCodec, allowSpectators, handler)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* inventory + exosuit + hotbar (in this order)
|
* inventory + exosuit + hotbar (in this order)
|
||||||
|
@ -23,7 +23,8 @@ class StorageBusMenu @JvmOverloads constructor(
|
|||||||
busFilterState = NetworkedBooleanInput(this, tile.filter::isWhitelist)
|
busFilterState = NetworkedBooleanInput(this, tile.filter::isWhitelist)
|
||||||
} else {
|
} else {
|
||||||
busFilterSlots = addFilterSlots(StorageBusBlockEntity.MAX_FILTERS)
|
busFilterSlots = addFilterSlots(StorageBusBlockEntity.MAX_FILTERS)
|
||||||
busFilterState = NetworkedBooleanInput(this).asClient()
|
busFilterState = NetworkedBooleanInput(this)
|
||||||
|
busFilterState.asClient()
|
||||||
}
|
}
|
||||||
|
|
||||||
addInventorySlots()
|
addInventorySlots()
|
||||||
|
@ -23,7 +23,8 @@ class StorageExporterMenu @JvmOverloads constructor(
|
|||||||
busFilterState = NetworkedBooleanInput(this, tile.filter::isWhitelist)
|
busFilterState = NetworkedBooleanInput(this, tile.filter::isWhitelist)
|
||||||
} else {
|
} else {
|
||||||
busFilterSlots = addFilterSlots(StorageExporterBlockEntity.MAX_FILTERS)
|
busFilterSlots = addFilterSlots(StorageExporterBlockEntity.MAX_FILTERS)
|
||||||
busFilterState = NetworkedBooleanInput(this).asClient()
|
busFilterState = NetworkedBooleanInput(this)
|
||||||
|
busFilterState.asClient()
|
||||||
}
|
}
|
||||||
|
|
||||||
addInventorySlots()
|
addInventorySlots()
|
||||||
|
@ -23,7 +23,8 @@ class StorageImporterMenu @JvmOverloads constructor(
|
|||||||
busFilterState = NetworkedBooleanInput(this, tile.filter::isWhitelist)
|
busFilterState = NetworkedBooleanInput(this, tile.filter::isWhitelist)
|
||||||
} else {
|
} else {
|
||||||
busFilterSlots = addFilterSlots(StorageImporterBlockEntity.MAX_FILTERS)
|
busFilterSlots = addFilterSlots(StorageImporterBlockEntity.MAX_FILTERS)
|
||||||
busFilterState = NetworkedBooleanInput(this).asClient()
|
busFilterState = NetworkedBooleanInput(this)
|
||||||
|
busFilterState.asClient()
|
||||||
}
|
}
|
||||||
|
|
||||||
addInventorySlots()
|
addInventorySlots()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package ru.dbotthepony.mc.otm.menu.input
|
package ru.dbotthepony.mc.otm.menu.input
|
||||||
|
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import ru.dbotthepony.mc.otm.client.minecraft
|
||||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||||
import kotlin.reflect.KMutableProperty0
|
import kotlin.reflect.KMutableProperty0
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ abstract class AbstractNetworkedInput<V> {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun userInput(newValue: V, ply: Player? = null) {
|
fun input(newValue: V, ply: Player? = null) {
|
||||||
if (isClient) {
|
if (isClient) {
|
||||||
input.checkedInput(newValue, ply)
|
input.checkedInput(newValue, ply)
|
||||||
} else {
|
} else {
|
||||||
@ -50,4 +51,13 @@ abstract class AbstractNetworkedInput<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clientInput(newValue: V) {
|
||||||
|
if (isClient) {
|
||||||
|
input.checkedInput(newValue, minecraft.player)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkClient(): Boolean {
|
||||||
|
return input.allowSpectators || minecraft.player?.isSpectator == false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,6 @@ class NetworkedBooleanInput(menu: MatteryMenu) : AbstractNetworkedInput<Boolean>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun switchValue(ply: Player? = null) {
|
fun switchValue(ply: Player? = null) {
|
||||||
userInput(!value, ply)
|
input(!value, ply)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.menu.input
|
||||||
|
|
||||||
|
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||||
|
import kotlin.reflect.KMutableProperty0
|
||||||
|
|
||||||
|
class NetworkedStringInput(menu: MatteryMenu) : AbstractNetworkedInput<String>() {
|
||||||
|
override val input = menu.stringInput { consumer?.invoke(it.replace('\u0000', ' ')) }
|
||||||
|
override val value by menu.mSynchronizer.string(getter = { supplier?.invoke() ?: "" })
|
||||||
|
|
||||||
|
constructor(menu: MatteryMenu, state: KMutableProperty0<String>) : this(menu) {
|
||||||
|
with(state)
|
||||||
|
}
|
||||||
|
}
|
@ -171,6 +171,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|||||||
fun fraction(getter: () -> Decimal, name: String = nextFieldName()) = ComputedField(getter, ImpreciseFractionValueCodec, name)
|
fun fraction(getter: () -> Decimal, name: String = nextFieldName()) = ComputedField(getter, ImpreciseFractionValueCodec, name)
|
||||||
fun bigDecimal(getter: () -> BigDecimal, name: String = nextFieldName()) = ComputedField(getter, BigDecimalValueCodec, name)
|
fun bigDecimal(getter: () -> BigDecimal, name: String = nextFieldName()) = ComputedField(getter, BigDecimalValueCodec, name)
|
||||||
fun item(getter: () -> ItemStack, name: String = nextFieldName()) = ComputedField(getter, ItemStackValueCodec, name)
|
fun item(getter: () -> ItemStack, name: String = nextFieldName()) = ComputedField(getter, ItemStackValueCodec, name)
|
||||||
|
fun string(getter: () -> String, name: String = nextFieldName()) = ComputedField(getter, BinaryStringCodec, name)
|
||||||
|
|
||||||
fun byte(getter: KProperty0<Byte>, name: String = nextFieldName()) = ComputedField(getter, ByteValueCodec, name)
|
fun byte(getter: KProperty0<Byte>, name: String = nextFieldName()) = ComputedField(getter, ByteValueCodec, name)
|
||||||
fun bool(getter: KProperty0<Boolean>, name: String = nextFieldName()) = ComputedField(getter, BooleanValueCodec, name)
|
fun bool(getter: KProperty0<Boolean>, name: String = nextFieldName()) = ComputedField(getter, BooleanValueCodec, name)
|
||||||
@ -185,6 +186,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|||||||
fun fraction(getter: KProperty0<Decimal>, name: String = nextFieldName()) = ComputedField(getter, ImpreciseFractionValueCodec, name)
|
fun fraction(getter: KProperty0<Decimal>, name: String = nextFieldName()) = ComputedField(getter, ImpreciseFractionValueCodec, name)
|
||||||
fun bigDecimal(getter: KProperty0<BigDecimal>, name: String = nextFieldName()) = ComputedField(getter, BigDecimalValueCodec, name)
|
fun bigDecimal(getter: KProperty0<BigDecimal>, name: String = nextFieldName()) = ComputedField(getter, BigDecimalValueCodec, name)
|
||||||
fun item(getter: KProperty0<ItemStack>, name: String = nextFieldName()) = ComputedField(getter, ItemStackValueCodec, name)
|
fun item(getter: KProperty0<ItemStack>, name: String = nextFieldName()) = ComputedField(getter, ItemStackValueCodec, name)
|
||||||
|
fun string(getter: KProperty0<String>, name: String = nextFieldName()) = ComputedField(getter, BinaryStringCodec, name)
|
||||||
|
|
||||||
fun byte(getter: Supplier<Byte>, name: String = nextFieldName()) = ComputedField(getter::get, ByteValueCodec, name)
|
fun byte(getter: Supplier<Byte>, name: String = nextFieldName()) = ComputedField(getter::get, ByteValueCodec, name)
|
||||||
fun bool(getter: Supplier<Boolean>, name: String = nextFieldName()) = ComputedField(getter::get, BooleanValueCodec, name)
|
fun bool(getter: Supplier<Boolean>, name: String = nextFieldName()) = ComputedField(getter::get, BooleanValueCodec, name)
|
||||||
@ -199,6 +201,7 @@ class FieldSynchronizer(private val callback: Runnable, private val alwaysCallCa
|
|||||||
fun fraction(getter: Supplier<Decimal>, name: String = nextFieldName()) = ComputedField(getter::get, ImpreciseFractionValueCodec, name)
|
fun fraction(getter: Supplier<Decimal>, name: String = nextFieldName()) = ComputedField(getter::get, ImpreciseFractionValueCodec, name)
|
||||||
fun bigDecimal(getter: Supplier<BigDecimal>, name: String = nextFieldName()) = ComputedField(getter::get, BigDecimalValueCodec, name)
|
fun bigDecimal(getter: Supplier<BigDecimal>, name: String = nextFieldName()) = ComputedField(getter::get, BigDecimalValueCodec, name)
|
||||||
fun item(getter: Supplier<ItemStack>, name: String = nextFieldName()) = ComputedField(getter::get, ItemStackValueCodec, name)
|
fun item(getter: Supplier<ItemStack>, name: String = nextFieldName()) = ComputedField(getter::get, ItemStackValueCodec, name)
|
||||||
|
fun string(getter: Supplier<String>, name: String = nextFieldName()) = ComputedField(getter::get, BinaryStringCodec, name)
|
||||||
|
|
||||||
fun <T : Enum<T>> enum(type: Class<T>, getter: () -> T, name: String = nextFieldName()) = ComputedField(getter, EnumValueCodec(type), name)
|
fun <T : Enum<T>> enum(type: Class<T>, getter: () -> T, name: String = nextFieldName()) = ComputedField(getter, EnumValueCodec(type), name)
|
||||||
inline fun <reified T : Enum<T>> enum(noinline getter: () -> T, name: String = nextFieldName()) = ComputedField(getter, EnumValueCodec(T::class.java), name)
|
inline fun <reified T : Enum<T>> enum(noinline getter: () -> T, name: String = nextFieldName()) = ComputedField(getter, EnumValueCodec(T::class.java), name)
|
||||||
|
Loading…
Reference in New Issue
Block a user