Add REI sync mode for terminal search field

This commit is contained in:
Shadowfacts 2021-12-23 12:54:33 -05:00
parent b21a45fbbb
commit b2e794e5a4
14 changed files with 138 additions and 13 deletions

View File

@ -8,13 +8,19 @@ import me.shedaniel.rei.api.client.plugins.REIClientPlugin
import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry
import net.fabricmc.api.ClientModInitializer import net.fabricmc.api.ClientModInitializer
import net.minecraft.client.MinecraftClient import net.minecraft.client.MinecraftClient
import net.shadowfacts.phycon.PhysicalConnectivityClient
import net.shadowfacts.phycon.block.terminal.AbstractTerminalScreen import net.shadowfacts.phycon.block.terminal.AbstractTerminalScreen
import org.apache.logging.log4j.LogManager
import java.lang.invoke.MethodHandle
import java.lang.invoke.MethodHandles
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
object PhyConPluginClient: ClientModInitializer, REIClientPlugin { object PhyConPluginClient: ClientModInitializer, REIClientPlugin, AbstractTerminalScreen.SearchQueryListener {
const val MODID = "phycon_rei"
private val logger = LogManager.getLogger()
private var isHighlightingHandle: MethodHandle? = null
override fun onInitializeClient() { override fun onInitializeClient() {
ClientScreenInputEvent.MOUSE_RELEASED_PRE.register { client, screen, mouseX, mouseY, button -> ClientScreenInputEvent.MOUSE_RELEASED_PRE.register { client, screen, mouseX, mouseY, button ->
@ -29,6 +35,14 @@ object PhyConPluginClient: ClientModInitializer, REIClientPlugin {
} }
EventResult.pass() EventResult.pass()
} }
AbstractTerminalScreen.searchQueryListener = this
try {
val clazz = Class.forName("me.shedaniel.rei.impl.client.gui.widget.search.OverlaySearchField")
isHighlightingHandle = MethodHandles.publicLookup().findStaticGetter(clazz, "isHighlighting", Boolean::class.java)
} catch (e: ReflectiveOperationException) {
logger.warn("Unable to find OverlaySearchField.isHighlighting, highlight sync will be disabled", e)
}
} }
override fun registerScreens(registry: ScreenRegistry) { override fun registerScreens(registry: ScreenRegistry) {
@ -37,9 +51,37 @@ object PhyConPluginClient: ClientModInitializer, REIClientPlugin {
val view = screen.terminalVC.settingsView val view = screen.terminalVC.settingsView
val rect = view.convert(view.bounds, to = null) val rect = view.convert(view.bounds, to = null)
listOf( listOf(
Rectangle(rect.left.toInt(), rect.top.toInt(), 20, 20) Rectangle(rect.left.toInt(), rect.top.toInt(), view.bounds.width.toInt(), view.bounds.height.toInt())
) )
} }
} }
override fun terminalSearchQueryChanged(newValue: String) {
if (shouldSync()) {
REIRuntime.getInstance().searchTextField?.text = newValue
}
}
override fun requestTerminalSearchFieldUpdate(): String? {
return if (shouldSync()) {
REIRuntime.getInstance().searchTextField?.text
} else {
null
}
}
private fun shouldSync(): Boolean {
return when (PhysicalConnectivityClient.terminalSettings[PhyConPluginCommon.REI_SYNC_KEY]) {
REISyncMode.OFF -> false
REISyncMode.ON -> true
REISyncMode.HIGHLIGHT_ONLY -> {
if (isHighlightingHandle != null) {
isHighlightingHandle!!.invoke() as Boolean
} else {
false
}
}
}
}
} }

View File

@ -8,18 +8,30 @@ import me.shedaniel.rei.api.common.transfer.info.MenuInfoRegistry
import me.shedaniel.rei.api.common.transfer.info.simple.SimpleGridMenuInfo import me.shedaniel.rei.api.common.transfer.info.simple.SimpleGridMenuInfo
import me.shedaniel.rei.api.common.transfer.info.simple.SimpleMenuInfoProvider import me.shedaniel.rei.api.common.transfer.info.simple.SimpleMenuInfoProvider
import me.shedaniel.rei.api.common.transfer.info.stack.SlotAccessor import me.shedaniel.rei.api.common.transfer.info.stack.SlotAccessor
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.block.terminal.CraftingTerminalScreenHandler import net.shadowfacts.phycon.block.terminal.CraftingTerminalScreenHandler
import java.util.stream.IntStream import java.util.stream.IntStream
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
object PhyConPluginCommon: REIServerPlugin { object PhyConPluginCommon: REIServerPlugin, PhyConPlugin {
const val MODID = "phycon_rei"
lateinit var REI_SYNC_KEY: TerminalSettingKey<REISyncMode>
private set
override fun registerMenuInfo(registry: MenuInfoRegistry) { override fun registerMenuInfo(registry: MenuInfoRegistry) {
registry.register(CategoryIdentifier.of("minecraft", "plugins/crafting"), CraftingTerminalScreenHandler::class.java, SimpleMenuInfoProvider.of(::TerminalInfo)) registry.register(CategoryIdentifier.of("minecraft", "plugins/crafting"), CraftingTerminalScreenHandler::class.java, SimpleMenuInfoProvider.of(::TerminalInfo))
} }
override fun initializePhyCon(api: PhyConAPI) {
REI_SYNC_KEY = api.registerTerminalSetting(Identifier(MODID, "rei_sync"), REISyncMode.OFF)
}
class TerminalInfo<D: SimpleGridMenuDisplay>( class TerminalInfo<D: SimpleGridMenuDisplay>(
private val display: D, private val display: D,
): SimpleGridMenuInfo<CraftingTerminalScreenHandler, D> { ): SimpleGridMenuInfo<CraftingTerminalScreenHandler, D> {

View File

@ -0,0 +1,29 @@
package net.shadowfacts.phycon.plugin.rei
import net.minecraft.text.LiteralText
import net.minecraft.util.Identifier
import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.api.TerminalSetting
/**
* @author shadowfacts
*/
enum class REISyncMode: TerminalSetting {
OFF,
ON,
HIGHLIGHT_ONLY;
override fun getIconTexture() = Identifier(PhysicalConnectivity.MODID, "textures/gui/terminal.png")
override fun getUV() = when (this) {
OFF -> intArrayOf(0, 240)
ON -> intArrayOf(16, 240)
HIGHLIGHT_ONLY -> intArrayOf(32, 240)
}
override fun getTooltip() = when (this) {
OFF -> LiteralText("Don't sync with REI")
ON -> LiteralText("Sync with REI")
HIGHLIGHT_ONLY -> LiteralText("Sync in highlight mode")
}
}

View File

@ -28,6 +28,12 @@
"adapter": "kotlin", "adapter": "kotlin",
"value": "net.shadowfacts.phycon.plugin.rei.PhyConPluginCommon" "value": "net.shadowfacts.phycon.plugin.rei.PhyConPluginCommon"
} }
],
"phycon": [
{
"adapter": "kotlin",
"value": "net.shadowfacts.phycon.plugin.rei.PhyConPluginCommon"
}
] ]
}, },
"mixins": [ "mixins": [

View File

@ -1,10 +1,12 @@
package net.shadowfacts.phycon.api; package net.shadowfacts.phycon.api;
import org.jetbrains.annotations.NotNull;
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
public interface PhyConPlugin { public interface PhyConPlugin {
void initializePhyCon(PhyConAPI api); void initializePhyCon(@NotNull PhyConAPI api);
} }

View File

@ -11,4 +11,6 @@ public interface TerminalSettingKey<E extends Enum<E> & TerminalSetting> {
E getValue(); E getValue();
void setPriority(int priority);
} }

View File

@ -79,8 +79,8 @@ open class CacaoScreen(title: Text = LiteralText("CacaoScreen")): Screen(title),
} }
} }
override fun resize(client: MinecraftClient, width: Int, height: Int) { override fun init() {
super.resize(client, width, height) super.init()
windows.forEach { windows.forEach {
it.resize(width, height) it.resize(width, height)

View File

@ -16,6 +16,7 @@ object DefaultPlugin: PhyConPlugin {
override fun initializePhyCon(api: PhyConAPI) { override fun initializePhyCon(api: PhyConAPI) {
SORT_MODE = api.registerTerminalSetting(Identifier(PhysicalConnectivity.MODID, "sort"), SortMode.COUNT_HIGH_FIRST) SORT_MODE = api.registerTerminalSetting(Identifier(PhysicalConnectivity.MODID, "sort"), SortMode.COUNT_HIGH_FIRST)
SORT_MODE.setPriority(Int.MAX_VALUE)
} }
} }

View File

@ -35,12 +35,29 @@ abstract class AbstractTerminalScreen<BE: AbstractTerminalBlockEntity, T: Abstra
val terminalBackgroundHeight: Int, val terminalBackgroundHeight: Int,
): CacaoHandledScreen<T>(handler, playerInv, title) { ): CacaoHandledScreen<T>(handler, playerInv, title) {
interface SearchQueryListener {
fun terminalSearchQueryChanged(newValue: String)
fun requestTerminalSearchFieldUpdate(): String?
}
companion object {
var searchQueryListener: SearchQueryListener? = null
}
abstract val backgroundTexture: Identifier abstract val backgroundTexture: Identifier
val terminalVC: AbstractTerminalViewController<*, *, *> val terminalVC: AbstractTerminalViewController<*, *, *>
var amountVC: TerminalRequestAmountViewController? = null var amountVC: TerminalRequestAmountViewController? = null
private var prevSearchQuery = ""
var searchQuery = "" var searchQuery = ""
set(value) {
field = value
if (prevSearchQuery != value) {
searchQueryListener?.terminalSearchQueryChanged(value)
}
prevSearchQuery = value
}
var scrollPosition = 0.0 var scrollPosition = 0.0
init { init {
@ -147,6 +164,13 @@ abstract class AbstractTerminalScreen<BE: AbstractTerminalBlockEntity, T: Abstra
} else { } else {
terminalVC.searchField.tick() terminalVC.searchField.tick()
} }
val newSearchQuery = searchQueryListener?.requestTerminalSearchFieldUpdate()
if (newSearchQuery != null && searchQuery != newSearchQuery) {
searchQuery = newSearchQuery
terminalVC.searchField.text = newSearchQuery
requestUpdatedItems()
}
} }
override fun onMouseClick(slot: Slot?, invSlot: Int, clickData: Int, type: SlotActionType?) { override fun onMouseClick(slot: Slot?, invSlot: Int, clickData: Int, type: SlotActionType?) {

View File

@ -105,7 +105,7 @@ abstract class AbstractTerminalViewController<BE: AbstractTerminalBlockEntity, S
val settingsStack = view.addSubview(StackView(Axis.VERTICAL, spacing = 2.0)) val settingsStack = view.addSubview(StackView(Axis.VERTICAL, spacing = 2.0))
settingsView = settingsStack settingsView = settingsStack
TerminalSettings.allKeys.forEach { key -> TerminalSettings.allKeys.sortedByDescending { it.priority }.forEach { key ->
val button = SettingButton(key) val button = SettingButton(key)
button.handler = { settingsChanged() } button.handler = { settingsChanged() }
settingsStack.addArrangedSubview(button) settingsStack.addArrangedSubview(button)

View File

@ -18,7 +18,7 @@ class ScrollTrackView(
): View() { ): View() {
companion object { companion object {
private val THUMB = Texture(Identifier(PhysicalConnectivity.MODID, "textures/gui/terminal.png"), 52, 230) private val THUMB = Texture(Identifier(PhysicalConnectivity.MODID, "textures/gui/terminal.png"), 52, 224)
private const val THUMB_WIDTH = 12.0 private const val THUMB_WIDTH = 12.0
private const val THUMB_HEIGHT = 15.0 private const val THUMB_HEIGHT = 15.0
} }

View File

@ -17,9 +17,9 @@ enum class SortMode: TerminalSetting {
override fun getIconTexture() = Identifier(PhysicalConnectivity.MODID, "textures/gui/terminal.png") override fun getIconTexture() = Identifier(PhysicalConnectivity.MODID, "textures/gui/terminal.png")
override fun getUV() = when (this) { override fun getUV() = when (this) {
COUNT_HIGH_FIRST -> intArrayOf(0, 230) COUNT_HIGH_FIRST -> intArrayOf(0, 224)
COUNT_LOW_FIRST -> intArrayOf(16, 230) COUNT_LOW_FIRST -> intArrayOf(16, 224)
ALPHABETICAL -> intArrayOf(32, 230) ALPHABETICAL -> intArrayOf(32, 224)
} }
override fun getTooltip() = when (this) { override fun getTooltip() = when (this) {

View File

@ -19,7 +19,7 @@ class TerminalSettings {
get() = SETTINGS.values get() = SETTINGS.values
fun <E> register(id: Identifier, defaultValue: E): SettingKey<E> where E: Enum<E>, E: TerminalSetting { fun <E> register(id: Identifier, defaultValue: E): SettingKey<E> where E: Enum<E>, E: TerminalSetting {
val setting = SettingKey(id, defaultValue.javaClass) val setting = SettingKey(id, defaultValue.javaClass, 0)
SETTINGS[id] = setting SETTINGS[id] = setting
DEFAULTS[setting] = defaultValue DEFAULTS[setting] = defaultValue
return setting return setting
@ -34,7 +34,11 @@ class TerminalSettings {
class SettingKey<E>( class SettingKey<E>(
val id: Identifier, val id: Identifier,
val clazz: Class<E>, val clazz: Class<E>,
priority: Int,
): TerminalSettingKey<E> where E: Enum<E>, E: TerminalSetting { ): TerminalSettingKey<E> where E: Enum<E>, E: TerminalSetting {
var priority: Int = priority
private set
fun value(ordinal: Int): E? { fun value(ordinal: Int): E? {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return if (clazz.enumConstants.size <= ordinal) null return if (clazz.enumConstants.size <= ordinal) null
@ -43,6 +47,9 @@ class TerminalSettings {
override fun getID() = id override fun getID() = id
override fun getValue() = PhysicalConnectivityClient.terminalSettings[this] override fun getValue() = PhysicalConnectivityClient.terminalSettings[this]
override fun setPriority(priority: Int) {
this.priority = priority
}
} }
private val settings = mutableMapOf<TerminalSettingKey<*>, Enum<*>>() private val settings = mutableMapOf<TerminalSettingKey<*>, Enum<*>>()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 506 B

After

Width:  |  Height:  |  Size: 4.4 KiB