Add terminal settings API
This commit is contained in:
parent
e41c9e3ccb
commit
28e14ae8bf
|
@ -34,8 +34,8 @@ object PhyConPlugin: ClientModInitializer, REIPluginV0 {
|
|||
override fun registerBounds(helper: DisplayHelper) {
|
||||
BaseBoundsHandler.getInstance().registerExclusionZones(TerminalScreen::class.java) {
|
||||
val screen = MinecraftClient.getInstance().currentScreen as TerminalScreen
|
||||
val button = screen.terminalVC.sortMode
|
||||
val rect = button.convert(button.bounds, to = null)
|
||||
val view = screen.terminalVC.settingsView
|
||||
val rect = view.convert(view.bounds, to = null)
|
||||
listOf(
|
||||
Rectangle(rect.left.toInt(), rect.top.toInt(), 20, 20)
|
||||
)
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package net.shadowfacts.phycon.api;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
public interface PhyConAPI {
|
||||
|
||||
@NotNull
|
||||
<E extends Enum<E> & TerminalSetting> TerminalSettingKey<E> registerTerminalSetting(Identifier id, E defaultValue);
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package net.shadowfacts.phycon.api;
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
public interface PhyConPlugin {
|
||||
|
||||
void initializePhyCon(PhyConAPI api);
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package net.shadowfacts.phycon.api;
|
||||
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
public interface TerminalSetting {
|
||||
|
||||
Identifier getIconTexture();
|
||||
|
||||
int[] getUV();
|
||||
|
||||
@Nullable Text getTooltip();
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package net.shadowfacts.phycon.api;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
public interface TerminalSettingKey<E extends Enum<E> & TerminalSetting> {
|
||||
|
||||
Identifier getID();
|
||||
|
||||
E getValue();
|
||||
|
||||
}
|
|
@ -11,10 +11,12 @@ import net.shadowfacts.cacao.util.texture.Texture
|
|||
*
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class TextureView(var texture: Texture): View() {
|
||||
class TextureView(var texture: Texture?): View() {
|
||||
|
||||
override fun drawContent(matrixStack: MatrixStack, mouse: Point, delta: Float) {
|
||||
RenderHelper.draw(matrixStack, bounds, texture)
|
||||
texture?.also {
|
||||
RenderHelper.draw(matrixStack, bounds, it)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package net.shadowfacts.phycon
|
||||
|
||||
import net.minecraft.util.Identifier
|
||||
import net.shadowfacts.phycon.api.PhyConAPI
|
||||
import net.shadowfacts.phycon.api.PhyConPlugin
|
||||
import net.shadowfacts.phycon.api.TerminalSettingKey
|
||||
import net.shadowfacts.phycon.util.SortMode
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
object DefaultPlugin: PhyConPlugin {
|
||||
|
||||
lateinit var SORT_MODE: TerminalSettingKey<SortMode>
|
||||
private set
|
||||
|
||||
override fun initializePhyCon(api: PhyConAPI) {
|
||||
SORT_MODE = api.registerTerminalSetting(Identifier(PhysicalConnectivity.MODID, "sort"), SortMode.COUNT_HIGH_FIRST)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package net.shadowfacts.phycon
|
||||
|
||||
import net.minecraft.util.Identifier
|
||||
import net.shadowfacts.phycon.api.PhyConAPI
|
||||
import net.shadowfacts.phycon.api.TerminalSetting
|
||||
import net.shadowfacts.phycon.api.TerminalSettingKey
|
||||
import net.shadowfacts.phycon.util.TerminalSettings
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
object PhyConAPIImpl: PhyConAPI {
|
||||
|
||||
override fun <E> registerTerminalSetting(id: Identifier, defaultValue: E): TerminalSettingKey<E> where E: Enum<E>, E: TerminalSetting? {
|
||||
return TerminalSettings.register(id, defaultValue)
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,8 @@ package net.shadowfacts.phycon
|
|||
|
||||
import net.fabricmc.api.ModInitializer
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking
|
||||
import net.fabricmc.loader.api.FabricLoader
|
||||
import net.shadowfacts.phycon.api.PhyConPlugin
|
||||
import net.shadowfacts.phycon.init.PhyBlockEntities
|
||||
import net.shadowfacts.phycon.init.PhyBlocks
|
||||
import net.shadowfacts.phycon.init.PhyItems
|
||||
|
@ -27,6 +29,10 @@ object PhysicalConnectivity: ModInitializer {
|
|||
registerGlobalReceiver(C2STerminalRequestItem)
|
||||
registerGlobalReceiver(C2STerminalUpdateDisplayedItems)
|
||||
registerGlobalReceiver(C2SConfigureDevice)
|
||||
|
||||
for (it in FabricLoader.getInstance().getEntrypoints("phycon", PhyConPlugin::class.java)) {
|
||||
it.initializePhyCon(PhyConAPIImpl)
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerGlobalReceiver(receiver: ServerReceiver) {
|
||||
|
|
|
@ -14,12 +14,15 @@ import net.shadowfacts.phycon.client.PhyExtendedModelProvider
|
|||
import net.shadowfacts.phycon.client.PhyModelProvider
|
||||
import net.shadowfacts.phycon.networking.ClientReceiver
|
||||
import net.shadowfacts.phycon.networking.S2CTerminalUpdateDisplayedItems
|
||||
import net.shadowfacts.phycon.util.TerminalSettings
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
object PhysicalConnectivityClient: ClientModInitializer {
|
||||
|
||||
val terminalSettings = TerminalSettings()
|
||||
|
||||
var screenMaterial: RenderMaterial? = null
|
||||
private set
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
package net.shadowfacts.phycon.block.terminal
|
||||
|
||||
import net.minecraft.client.util.math.MatrixStack
|
||||
import net.shadowfacts.cacao.geometry.Point
|
||||
import net.shadowfacts.cacao.geometry.Size
|
||||
import net.shadowfacts.cacao.util.EnumHelper
|
||||
import net.shadowfacts.cacao.util.MouseButton
|
||||
import net.shadowfacts.cacao.util.texture.Texture
|
||||
import net.shadowfacts.cacao.view.TextureView
|
||||
import net.shadowfacts.cacao.view.button.AbstractButton
|
||||
import net.shadowfacts.phycon.PhysicalConnectivityClient
|
||||
import net.shadowfacts.phycon.api.TerminalSetting
|
||||
import net.shadowfacts.phycon.util.TerminalSettings
|
||||
import java.util.EnumMap
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class SettingButton<E>(
|
||||
val key: TerminalSettings.SettingKey<E>,
|
||||
): AbstractButton<SettingButton<E>>(
|
||||
TextureView(null).apply {
|
||||
intrinsicContentSize = Size(16.0, 16.0)
|
||||
},
|
||||
padding = 2.0
|
||||
) where E: Enum<E>, E: TerminalSetting {
|
||||
|
||||
private val textureCache = EnumMap<E, Texture>(key.clazz)
|
||||
|
||||
private val textureView: TextureView
|
||||
get() = content as TextureView
|
||||
|
||||
init {
|
||||
updateTexture()
|
||||
}
|
||||
|
||||
private fun updateTexture() {
|
||||
textureView.texture = textureCache.getOrPut(key.value) {
|
||||
val uv = key.value.uv
|
||||
Texture(key.value.iconTexture, uv[0], uv[1])
|
||||
}
|
||||
}
|
||||
|
||||
override fun mouseClicked(point: Point, mouseButton: MouseButton): Boolean {
|
||||
if (!disabled) {
|
||||
val newValue = when (mouseButton) {
|
||||
MouseButton.LEFT -> EnumHelper.next(key.value)
|
||||
MouseButton.RIGHT -> EnumHelper.previous(key.value)
|
||||
else -> {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
PhysicalConnectivityClient.terminalSettings[key] = newValue
|
||||
|
||||
updateTexture()
|
||||
}
|
||||
|
||||
return super.mouseClicked(point, mouseButton)
|
||||
}
|
||||
|
||||
override fun draw(matrixStack: MatrixStack, mouse: Point, delta: Float) {
|
||||
super.draw(matrixStack, mouse, delta)
|
||||
|
||||
if (mouse in bounds) {
|
||||
key.value.tooltip?.also {
|
||||
window!!.drawTooltip(listOf(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package net.shadowfacts.phycon.block.terminal
|
||||
|
||||
import net.minecraft.util.Identifier
|
||||
import net.shadowfacts.cacao.geometry.Point
|
||||
import net.shadowfacts.cacao.geometry.Size
|
||||
import net.shadowfacts.cacao.util.EnumHelper
|
||||
import net.shadowfacts.cacao.util.MouseButton
|
||||
import net.shadowfacts.cacao.util.texture.Texture
|
||||
import net.shadowfacts.cacao.view.TextureView
|
||||
import net.shadowfacts.cacao.view.button.AbstractButton
|
||||
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||
import net.shadowfacts.phycon.util.SortMode
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class SortModeButton(
|
||||
initialValue: SortMode,
|
||||
): AbstractButton<SortModeButton>(
|
||||
TextureView(TEXTURES[initialValue]!!).apply {
|
||||
intrinsicContentSize = Size(16.0, 16.0)
|
||||
}
|
||||
) {
|
||||
|
||||
companion object {
|
||||
private val ID = Identifier(PhysicalConnectivity.MODID, "textures/gui/terminal.png")
|
||||
private val TEXTURES = mapOf(
|
||||
SortMode.COUNT_HIGH_FIRST to Texture(ID, 0, 230),
|
||||
SortMode.COUNT_LOW_FIRST to Texture(ID, 16, 230),
|
||||
SortMode.ALPHABETICAL to Texture(ID, 32, 230),
|
||||
)
|
||||
}
|
||||
|
||||
private val textureView: TextureView
|
||||
get() = content as TextureView
|
||||
|
||||
var value: SortMode = initialValue
|
||||
set(value) {
|
||||
field = value
|
||||
textureView.texture = TEXTURES[value]!!
|
||||
}
|
||||
|
||||
override fun mouseClicked(point: Point, mouseButton: MouseButton): Boolean {
|
||||
if (!disabled) {
|
||||
value = when (mouseButton) {
|
||||
MouseButton.LEFT -> EnumHelper.next(value)
|
||||
MouseButton.RIGHT -> EnumHelper.previous(value)
|
||||
else -> {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.mouseClicked(point, mouseButton)
|
||||
}
|
||||
|
||||
}
|
|
@ -57,6 +57,7 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL),
|
|||
private var observers = 0
|
||||
val cachedNetItems = ItemStackCollections.intMap()
|
||||
|
||||
// todo: multiple players could have the terminal open simultaneously
|
||||
var netItemObserver: WeakReference<NetItemObserver>? = null
|
||||
|
||||
init {
|
||||
|
@ -117,7 +118,9 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL),
|
|||
|
||||
private fun updateAndSync() {
|
||||
updateNetItems()
|
||||
// syncs the internal buffer to the client
|
||||
sync()
|
||||
// syncs the open container (if any) to the client
|
||||
netItemObserver?.get()?.netItemsChanged()
|
||||
}
|
||||
|
||||
|
@ -153,14 +156,6 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL),
|
|||
finishable.forEach(::stackLocateRequestCompleted)
|
||||
}
|
||||
|
||||
fun addObserver() {
|
||||
observers++
|
||||
}
|
||||
|
||||
fun removeObserver() {
|
||||
observers--
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
|
||||
|
@ -171,10 +166,6 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL),
|
|||
|
||||
if (counter % 20 == 0L && !world!!.isClient) {
|
||||
beginInsertions()
|
||||
|
||||
if (observers > 0) {
|
||||
updateAndSync()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,7 +188,6 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL),
|
|||
}
|
||||
player.openHandledScreen(factory)
|
||||
}
|
||||
addObserver()
|
||||
}
|
||||
|
||||
fun requestItem(stack: ItemStack, amount: Int = stack.count) {
|
||||
|
|
|
@ -53,7 +53,6 @@ class TerminalScreen(handler: TerminalScreenHandler, playerInv: PlayerInventory,
|
|||
|
||||
var searchQuery = ""
|
||||
var scrollPosition = 0.0
|
||||
var sortMode = SortMode.COUNT_HIGH_FIRST
|
||||
|
||||
init {
|
||||
backgroundWidth = 252
|
||||
|
@ -72,7 +71,7 @@ class TerminalScreen(handler: TerminalScreenHandler, playerInv: PlayerInventory,
|
|||
|
||||
fun requestUpdatedItems() {
|
||||
val player = MinecraftClient.getInstance().player!!
|
||||
player.networkHandler.sendPacket(C2STerminalUpdateDisplayedItems(handler.terminal, searchQuery, sortMode, scrollPosition.toFloat()))
|
||||
player.networkHandler.sendPacket(C2STerminalUpdateDisplayedItems(handler.terminal, searchQuery, scrollPosition.toFloat()))
|
||||
}
|
||||
|
||||
private fun showRequestAmountDialog(stack: ItemStack) {
|
||||
|
|
|
@ -10,11 +10,13 @@ import net.minecraft.screen.ScreenHandler
|
|||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.registry.Registry
|
||||
import net.shadowfacts.phycon.DefaultPlugin
|
||||
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||
import net.shadowfacts.phycon.init.PhyBlocks
|
||||
import net.shadowfacts.phycon.init.PhyScreens
|
||||
import net.shadowfacts.phycon.networking.S2CTerminalUpdateDisplayedItems
|
||||
import net.shadowfacts.phycon.util.SortMode
|
||||
import net.shadowfacts.phycon.util.TerminalSettings
|
||||
import net.shadowfacts.phycon.util.copyWithCount
|
||||
import java.lang.ref.WeakReference
|
||||
import kotlin.math.ceil
|
||||
|
@ -25,7 +27,11 @@ import kotlin.math.roundToInt
|
|||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val terminal: TerminalBlockEntity): ScreenHandler(PhyScreens.TERMINAL, syncId),
|
||||
class TerminalScreenHandler(
|
||||
syncId: Int,
|
||||
val playerInv: PlayerInventory,
|
||||
val terminal: TerminalBlockEntity,
|
||||
): ScreenHandler(PhyScreens.TERMINAL, syncId),
|
||||
TerminalBlockEntity.NetItemObserver {
|
||||
|
||||
companion object {
|
||||
|
@ -36,8 +42,7 @@ class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val ter
|
|||
|
||||
private val fakeInv = FakeInventory(this)
|
||||
private var searchQuery: String = ""
|
||||
var sortMode = SortMode.COUNT_HIGH_FIRST
|
||||
private set
|
||||
private var settings = TerminalSettings()
|
||||
var totalEntries = 0
|
||||
private set
|
||||
var scrollPosition = 0f
|
||||
|
@ -54,12 +59,17 @@ class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val ter
|
|||
private set
|
||||
|
||||
constructor(syncId: Int, playerInv: PlayerInventory, buf: PacketByteBuf):
|
||||
this(syncId, playerInv, PhyBlocks.TERMINAL.getBlockEntity(playerInv.player.world, buf.readBlockPos())!!)
|
||||
this(
|
||||
syncId,
|
||||
playerInv,
|
||||
PhyBlocks.TERMINAL.getBlockEntity(playerInv.player.world, buf.readBlockPos())!!
|
||||
)
|
||||
|
||||
init {
|
||||
if (!terminal.world!!.isClient) {
|
||||
assert(terminal.netItemObserver?.get() === null)
|
||||
terminal.netItemObserver = WeakReference(this)
|
||||
netItemsChanged()
|
||||
// intentionally don't call netItemsChanged immediately, we need to wait for the client to send us its settings
|
||||
}
|
||||
|
||||
// network
|
||||
|
@ -107,7 +117,7 @@ class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val ter
|
|||
totalEntries = filtered.size
|
||||
|
||||
val sorted =
|
||||
when (sortMode) {
|
||||
when (settings[DefaultPlugin.SORT_MODE]) {
|
||||
SortMode.COUNT_HIGH_FIRST -> filtered.sortedByDescending { it.intValue }
|
||||
SortMode.COUNT_LOW_FIRST -> filtered.sortedBy { it.intValue }
|
||||
SortMode.ALPHABETICAL -> filtered.sortedBy { it.key.name.string }
|
||||
|
@ -120,7 +130,7 @@ class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val ter
|
|||
|
||||
// itemEntries = sorted.map { Entry(it.key, it.intValue) }
|
||||
|
||||
(player as ServerPlayerEntity).networkHandler.sendPacket(S2CTerminalUpdateDisplayedItems(terminal, itemEntries, searchQuery, sortMode, scrollPosition, totalEntries))
|
||||
(player as ServerPlayerEntity).networkHandler.sendPacket(S2CTerminalUpdateDisplayedItems(terminal, itemEntries, searchQuery, settings, scrollPosition, totalEntries))
|
||||
}
|
||||
|
||||
fun totalRows(): Int {
|
||||
|
@ -139,18 +149,17 @@ class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val ter
|
|||
return currentScrollOffsetInRows() * 9
|
||||
}
|
||||
|
||||
fun sendUpdatedItemsToClient(player: ServerPlayerEntity, query: String, sortMode: SortMode, scrollPosition: Float) {
|
||||
fun sendUpdatedItemsToClient(player: ServerPlayerEntity, query: String, settings: TerminalSettings, scrollPosition: Float) {
|
||||
this.searchQuery = query
|
||||
this.sortMode = sortMode
|
||||
this.settings = settings
|
||||
this.scrollPosition = scrollPosition
|
||||
netItemsChanged()
|
||||
}
|
||||
|
||||
fun receivedUpdatedItemsFromServer(entries: List<Entry>, query: String, sortMode: SortMode, scrollPosition: Float, totalEntries: Int) {
|
||||
fun receivedUpdatedItemsFromServer(entries: List<Entry>, query: String, scrollPosition: Float, totalEntries: Int) {
|
||||
assert(playerInv.player.world.isClient)
|
||||
|
||||
this.searchQuery = query
|
||||
this.sortMode = sortMode
|
||||
this.scrollPosition = scrollPosition
|
||||
this.totalEntries = totalEntries
|
||||
itemEntries = entries
|
||||
|
@ -163,7 +172,7 @@ class TerminalScreenHandler(syncId: Int, val playerInv: PlayerInventory, val ter
|
|||
override fun close(player: PlayerEntity) {
|
||||
super.close(player)
|
||||
|
||||
terminal.removeObserver()
|
||||
terminal.netItemObserver = null
|
||||
}
|
||||
|
||||
override fun onSlotClick(slotId: Int, clickData: Int, actionType: SlotActionType, player: PlayerEntity): ItemStack {
|
||||
|
|
|
@ -2,15 +2,18 @@ package net.shadowfacts.phycon.block.terminal
|
|||
|
||||
import net.minecraft.text.TranslatableText
|
||||
import net.minecraft.util.math.MathHelper
|
||||
import net.shadowfacts.cacao.geometry.Axis
|
||||
import net.shadowfacts.cacao.geometry.Point
|
||||
import net.shadowfacts.cacao.util.Color
|
||||
import net.shadowfacts.cacao.util.MouseButton
|
||||
import net.shadowfacts.cacao.view.Label
|
||||
import net.shadowfacts.cacao.view.StackView
|
||||
import net.shadowfacts.cacao.view.View
|
||||
import net.shadowfacts.cacao.view.textfield.TextField
|
||||
import net.shadowfacts.cacao.viewcontroller.ViewController
|
||||
import net.shadowfacts.kiwidsl.dsl
|
||||
import net.shadowfacts.phycon.util.SortMode
|
||||
import net.shadowfacts.phycon.util.TerminalSettings
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
|
@ -22,7 +25,7 @@ class TerminalViewController(
|
|||
): ViewController() {
|
||||
|
||||
private lateinit var scrollTrack: ScrollTrackView
|
||||
lateinit var sortMode: SortModeButton
|
||||
lateinit var settingsView: View
|
||||
private set
|
||||
lateinit var searchField: TextField
|
||||
private set
|
||||
|
@ -84,8 +87,12 @@ class TerminalViewController(
|
|||
|
||||
scrollTrack = view.addSubview(ScrollTrackView(::scrollPositionChanged))
|
||||
|
||||
sortMode = view.addSubview(SortModeButton(SortMode.COUNT_HIGH_FIRST)).apply {
|
||||
handler = ::sortModeChanged
|
||||
val settingsStack = view.addSubview(StackView(Axis.VERTICAL, spacing = 2.0))
|
||||
settingsView = settingsStack
|
||||
TerminalSettings.allKeys.forEach { key ->
|
||||
val button = SettingButton(key)
|
||||
button.handler = { settingsChanged() }
|
||||
settingsStack.addArrangedSubview(button)
|
||||
}
|
||||
|
||||
view.solver.dsl {
|
||||
|
@ -108,10 +115,8 @@ class TerminalViewController(
|
|||
scrollTrack.bottomAnchor equalTo (network.bottomAnchor - 1)
|
||||
scrollTrack.widthAnchor equalTo 12
|
||||
|
||||
sortMode.leftAnchor equalTo pane.rightAnchor + 4
|
||||
sortMode.topAnchor equalTo pane.topAnchor
|
||||
sortMode.widthAnchor equalTo 20
|
||||
sortMode.heightAnchor equalTo 20
|
||||
settingsStack.leftAnchor equalTo (pane.rightAnchor + 4)
|
||||
settingsStack.topAnchor equalTo pane.topAnchor
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,8 +136,7 @@ class TerminalViewController(
|
|||
}
|
||||
}
|
||||
|
||||
private fun sortModeChanged(button: SortModeButton) {
|
||||
screen.sortMode = button.value
|
||||
private fun settingsChanged() {
|
||||
screen.requestUpdatedItems()
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,11 @@ import net.minecraft.server.network.ServerPlayNetworkHandler
|
|||
import net.minecraft.server.network.ServerPlayerEntity
|
||||
import net.minecraft.util.Identifier
|
||||
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||
import net.shadowfacts.phycon.PhysicalConnectivityClient
|
||||
import net.shadowfacts.phycon.block.terminal.TerminalBlockEntity
|
||||
import net.shadowfacts.phycon.block.terminal.TerminalScreenHandler
|
||||
import net.shadowfacts.phycon.util.SortMode
|
||||
import net.shadowfacts.phycon.util.TerminalSettings
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
|
@ -21,14 +23,14 @@ object C2STerminalUpdateDisplayedItems: ServerReceiver {
|
|||
|
||||
override val CHANNEL = Identifier(PhysicalConnectivity.MODID, "terminal_update_displayed")
|
||||
|
||||
operator fun invoke(terminal: TerminalBlockEntity, query: String, sortMode: SortMode, scrollPosition: Float): Packet<*> {
|
||||
operator fun invoke(terminal: TerminalBlockEntity, query: String, scrollPosition: Float): Packet<*> {
|
||||
val buf = PacketByteBufs.create()
|
||||
|
||||
buf.writeIdentifier(terminal.world!!.registryKey.value)
|
||||
buf.writeBlockPos(terminal.pos)
|
||||
|
||||
buf.writeString(query)
|
||||
buf.writeVarInt(sortMode.ordinal)
|
||||
buf.writeCompoundTag(PhysicalConnectivityClient.terminalSettings.toTag())
|
||||
buf.writeFloat(scrollPosition)
|
||||
|
||||
return ClientPlayNetworking.createC2SPacket(CHANNEL, buf)
|
||||
|
@ -38,7 +40,8 @@ object C2STerminalUpdateDisplayedItems: ServerReceiver {
|
|||
val dimID = buf.readIdentifier()
|
||||
val pos = buf.readBlockPos()
|
||||
val query = buf.readString()
|
||||
val sortMode = SortMode.values()[buf.readVarInt()]
|
||||
val settings = TerminalSettings()
|
||||
settings.fromTag(buf.readCompoundTag()!!)
|
||||
val scrollPosition = buf.readFloat()
|
||||
|
||||
server.execute {
|
||||
|
@ -46,7 +49,7 @@ object C2STerminalUpdateDisplayedItems: ServerReceiver {
|
|||
val screenHandler = player.currentScreenHandler
|
||||
if (screenHandler !is TerminalScreenHandler) return@execute
|
||||
if (screenHandler.terminal.pos != pos) return@execute
|
||||
screenHandler.sendUpdatedItemsToClient(player, query, sortMode, scrollPosition)
|
||||
screenHandler.sendUpdatedItemsToClient(player, query, settings, scrollPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,11 @@ import net.minecraft.client.MinecraftClient
|
|||
import net.minecraft.client.network.ClientPlayNetworkHandler
|
||||
import net.minecraft.network.Packet
|
||||
import net.minecraft.network.PacketByteBuf
|
||||
import net.shadowfacts.phycon.PhysicalConnectivityClient
|
||||
import net.shadowfacts.phycon.block.terminal.TerminalBlockEntity
|
||||
import net.shadowfacts.phycon.block.terminal.TerminalScreenHandler
|
||||
import net.shadowfacts.phycon.util.SortMode
|
||||
import net.shadowfacts.phycon.util.TerminalSettings
|
||||
import net.shadowfacts.phycon.util.readItemStackWithoutCount
|
||||
import net.shadowfacts.phycon.util.writeItemStackWithoutCount
|
||||
|
||||
|
@ -19,7 +21,7 @@ import net.shadowfacts.phycon.util.writeItemStackWithoutCount
|
|||
object S2CTerminalUpdateDisplayedItems: ClientReceiver {
|
||||
override val CHANNEL = C2STerminalUpdateDisplayedItems.CHANNEL
|
||||
|
||||
operator fun invoke(terminal: TerminalBlockEntity, entries: List<TerminalScreenHandler.Entry>, query: String, sortMode: SortMode, scrollPosition: Float, totalEntries: Int): Packet<*> {
|
||||
operator fun invoke(terminal: TerminalBlockEntity, entries: List<TerminalScreenHandler.Entry>, query: String, settings: TerminalSettings, scrollPosition: Float, totalEntries: Int): Packet<*> {
|
||||
val buf = PacketByteBufs.create()
|
||||
|
||||
buf.writeIdentifier(terminal.world!!.registryKey.value)
|
||||
|
@ -32,7 +34,7 @@ object S2CTerminalUpdateDisplayedItems: ClientReceiver {
|
|||
}
|
||||
|
||||
buf.writeString(query)
|
||||
buf.writeVarInt(sortMode.ordinal)
|
||||
buf.writeCompoundTag(settings.toTag())
|
||||
buf.writeFloat(scrollPosition)
|
||||
buf.writeInt(totalEntries)
|
||||
|
||||
|
@ -48,7 +50,7 @@ object S2CTerminalUpdateDisplayedItems: ClientReceiver {
|
|||
entries.add(TerminalScreenHandler.Entry(buf.readItemStackWithoutCount(), buf.readVarInt()))
|
||||
}
|
||||
val query = buf.readString()
|
||||
val sortMode = SortMode.values()[buf.readVarInt()]
|
||||
PhysicalConnectivityClient.terminalSettings.fromTag(buf.readCompoundTag()!!)
|
||||
val scrollPosition = buf.readFloat()
|
||||
val totalEntries = buf.readInt()
|
||||
|
||||
|
@ -57,7 +59,7 @@ object S2CTerminalUpdateDisplayedItems: ClientReceiver {
|
|||
val screenHandler = client.player!!.currentScreenHandler
|
||||
if (screenHandler !is TerminalScreenHandler) return@execute
|
||||
if (screenHandler.terminal.pos != pos) return@execute
|
||||
screenHandler.receivedUpdatedItemsFromServer(entries, query, sortMode, scrollPosition, totalEntries)
|
||||
screenHandler.receivedUpdatedItemsFromServer(entries, query, scrollPosition, totalEntries)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,17 +2,27 @@ package net.shadowfacts.phycon.util
|
|||
|
||||
import net.minecraft.text.LiteralText
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.Identifier
|
||||
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||
import net.shadowfacts.phycon.api.TerminalSetting
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
enum class SortMode: RotatableEnum {
|
||||
enum class SortMode: TerminalSetting {
|
||||
COUNT_HIGH_FIRST,
|
||||
COUNT_LOW_FIRST,
|
||||
ALPHABETICAL;
|
||||
|
||||
val tooltip: Text
|
||||
get() = when (this) {
|
||||
override fun getIconTexture() = Identifier(PhysicalConnectivity.MODID, "textures/gui/terminal.png")
|
||||
|
||||
override fun getUV() = when (this) {
|
||||
COUNT_HIGH_FIRST -> intArrayOf(0, 230)
|
||||
COUNT_LOW_FIRST -> intArrayOf(16, 230)
|
||||
ALPHABETICAL -> intArrayOf(32, 230)
|
||||
}
|
||||
|
||||
override fun getTooltip() = when (this) {
|
||||
COUNT_HIGH_FIRST -> LiteralText("Count, highest first")
|
||||
COUNT_LOW_FIRST -> LiteralText("Count, lowest first")
|
||||
ALPHABETICAL -> LiteralText("Name")
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package net.shadowfacts.phycon.util
|
||||
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.util.Identifier
|
||||
import net.shadowfacts.phycon.PhysicalConnectivityClient
|
||||
import net.shadowfacts.phycon.api.TerminalSettingKey
|
||||
import net.shadowfacts.phycon.api.TerminalSetting
|
||||
|
||||
/**
|
||||
* @author shadowfacts
|
||||
*/
|
||||
class TerminalSettings {
|
||||
|
||||
companion object {
|
||||
private val SETTINGS = mutableMapOf<Identifier, SettingKey<*>>()
|
||||
private val DEFAULTS = mutableMapOf<TerminalSettingKey<*>, Enum<*>>()
|
||||
|
||||
val allKeys: Collection<SettingKey<*>>
|
||||
get() = SETTINGS.values
|
||||
|
||||
fun <E> register(id: Identifier, defaultValue: E): SettingKey<E> where E: Enum<E>, E: TerminalSetting {
|
||||
val setting = SettingKey(id, defaultValue.javaClass)
|
||||
SETTINGS[id] = setting
|
||||
DEFAULTS[setting] = defaultValue
|
||||
return setting
|
||||
}
|
||||
|
||||
fun <E> getDefault(setting: TerminalSettingKey<E>): E where E: Enum<E>, E: TerminalSetting {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return DEFAULTS[setting] as E
|
||||
}
|
||||
}
|
||||
|
||||
class SettingKey<E>(
|
||||
val id: Identifier,
|
||||
val clazz: Class<E>,
|
||||
): TerminalSettingKey<E> where E: Enum<E>, E: TerminalSetting {
|
||||
fun value(ordinal: Int): E? {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return if (clazz.enumConstants.size <= ordinal) null
|
||||
else clazz.enumConstants[ordinal] as E
|
||||
}
|
||||
|
||||
override fun getID() = id
|
||||
override fun getValue() = PhysicalConnectivityClient.terminalSettings[this]
|
||||
}
|
||||
|
||||
private val settings = mutableMapOf<TerminalSettingKey<*>, Enum<*>>()
|
||||
|
||||
operator fun <E> get(key: TerminalSettingKey<E>): E where E: Enum<E>, E: TerminalSetting {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return settings[key] as? E ?: getDefault(key)
|
||||
}
|
||||
|
||||
operator fun <E> set(key: SettingKey<E>, value: E) where E: Enum<E>, E: TerminalSetting {
|
||||
settings[key] = value
|
||||
}
|
||||
|
||||
fun toTag(): CompoundTag {
|
||||
return CompoundTag().also {
|
||||
settings.forEach { (s, v) ->
|
||||
it.putInt(s.id.toString(), v.ordinal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun fromTag(tag: CompoundTag) {
|
||||
settings.clear()
|
||||
tag.keys.forEach { k ->
|
||||
val id = Identifier.tryParse(k) ?: return@forEach
|
||||
val setting = SETTINGS[id] ?: return@forEach
|
||||
setValueFromOrdinal(setting, tag.getInt(k))
|
||||
}
|
||||
}
|
||||
|
||||
private fun <E> setValueFromOrdinal(setting: SettingKey<E>, ordinal: Int) where E: Enum<E>, E: TerminalSetting {
|
||||
val value = setting.value(ordinal)
|
||||
if (value != null) {
|
||||
this[setting] = value
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -35,6 +35,12 @@
|
|||
"adapter": "kotlin",
|
||||
"value": "net.shadowfacts.phycon.PhysicalConnectivityClient"
|
||||
}
|
||||
],
|
||||
"phycon": [
|
||||
{
|
||||
"adapter": "kotlin",
|
||||
"value": "net.shadowfacts.phycon.DefaultPlugin"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
|
|
Loading…
Reference in New Issue