Fix terminal search field not unfocusing when REI focused
This commit is contained in:
parent
c5ede3bd62
commit
ef9aa9e958
|
@ -1,5 +1,7 @@
|
||||||
package net.shadowfacts.phycon.plugin.rei
|
package net.shadowfacts.phycon.plugin.rei
|
||||||
|
|
||||||
|
import dev.architectury.event.EventResult
|
||||||
|
import dev.architectury.event.events.client.ClientScreenInputEvent
|
||||||
import me.shedaniel.math.Rectangle
|
import me.shedaniel.math.Rectangle
|
||||||
import me.shedaniel.rei.api.client.REIRuntime
|
import me.shedaniel.rei.api.client.REIRuntime
|
||||||
import me.shedaniel.rei.api.client.plugins.REIClientPlugin
|
import me.shedaniel.rei.api.client.plugins.REIClientPlugin
|
||||||
|
@ -15,15 +17,17 @@ object PhyConPluginClient: ClientModInitializer, REIClientPlugin {
|
||||||
const val MODID = "phycon_rei"
|
const val MODID = "phycon_rei"
|
||||||
|
|
||||||
override fun onInitializeClient() {
|
override fun onInitializeClient() {
|
||||||
AbstractTerminalScreen.registerClickHandler { mouseX, mouseY, button ->
|
ClientScreenInputEvent.MOUSE_RELEASED_PRE.register { client, screen, mouseX, mouseY, button ->
|
||||||
REIRuntime.getInstance().searchTextField?.also {
|
if (screen is AbstractTerminalScreen<*, *>) {
|
||||||
if (it.isFocused) {
|
REIRuntime.getInstance().searchTextField?.also {
|
||||||
this.terminalVC.searchField.resignFirstResponder()
|
if (it.isFocused) {
|
||||||
} else {
|
screen.terminalVC.searchField.resignFirstResponder()
|
||||||
this.terminalVC.searchField.becomeFirstResponder()
|
} else {
|
||||||
|
screen.terminalVC.searchField.becomeFirstResponder()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
null
|
EventResult.pass()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package net.shadowfacts.phycon.mixin.client;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import net.shadowfacts.cacao.AbstractCacaoScreen;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
@Mixin(MinecraftClient.class)
|
||||||
|
public class MixinMinecraftClient {
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "setScreen(Lnet/minecraft/client/gui/screen/Screen;)V",
|
||||||
|
at = @At(value = "FIELD", target = "Lnet/minecraft/client/MinecraftClient;currentScreen:Lnet/minecraft/client/gui/screen/Screen;", opcode = Opcodes.PUTFIELD, shift = At.Shift.AFTER)
|
||||||
|
)
|
||||||
|
private void setScreen(Screen screen, CallbackInfo ci) {
|
||||||
|
if (screen instanceof AbstractCacaoScreen) {
|
||||||
|
((AbstractCacaoScreen)screen).screenWillAppear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -14,4 +14,6 @@ interface AbstractCacaoScreen {
|
||||||
|
|
||||||
fun removeWindow(window: Window)
|
fun removeWindow(window: Window)
|
||||||
|
|
||||||
|
fun screenWillAppear()
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package net.shadowfacts.cacao
|
package net.shadowfacts.cacao
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
import net.minecraft.client.gui.screen.ingame.HandledScreen
|
import net.minecraft.client.gui.screen.ingame.HandledScreen
|
||||||
import net.minecraft.client.util.math.MatrixStack
|
import net.minecraft.client.util.math.MatrixStack
|
||||||
import net.minecraft.entity.player.PlayerInventory
|
import net.minecraft.entity.player.PlayerInventory
|
||||||
|
@ -29,10 +30,16 @@ open class CacaoHandledScreen<Handler: ScreenHandler>(
|
||||||
|
|
||||||
override val windows: List<Window> = _windows
|
override val windows: List<Window> = _windows
|
||||||
|
|
||||||
|
private var hasAppeared = false
|
||||||
|
|
||||||
|
|
||||||
override fun <T: Window> addWindow(window: T, index: Int): T {
|
override fun <T: Window> addWindow(window: T, index: Int): T {
|
||||||
if (window is ScreenHandlerWindow && window.screenHandler != handler) {
|
if (window is ScreenHandlerWindow && window.screenHandler != handler) {
|
||||||
throw RuntimeException("Adding ScreenHandlerWindow to CacaoHandledScreen with different screen handler is not supported")
|
throw RuntimeException("Adding ScreenHandlerWindow to CacaoHandledScreen with different screen handler is not supported")
|
||||||
}
|
}
|
||||||
|
if (hasAppeared) {
|
||||||
|
window.viewController.viewWillAppear()
|
||||||
|
}
|
||||||
|
|
||||||
_windows.add(index, window)
|
_windows.add(index, window)
|
||||||
|
|
||||||
|
@ -54,6 +61,12 @@ open class CacaoHandledScreen<Handler: ScreenHandler>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun screenWillAppear() {
|
||||||
|
windows.forEach {
|
||||||
|
it.viewController.viewWillAppear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
@ -66,7 +79,8 @@ open class CacaoHandledScreen<Handler: ScreenHandler>(
|
||||||
super.onClose()
|
super.onClose()
|
||||||
|
|
||||||
windows.forEach {
|
windows.forEach {
|
||||||
// todo: VC callbacks
|
it.viewController.viewWillDisappear()
|
||||||
|
it.viewController.viewDidDisappear()
|
||||||
|
|
||||||
it.firstResponder = null
|
it.firstResponder = null
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package net.shadowfacts.cacao
|
package net.shadowfacts.cacao
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient
|
||||||
import net.minecraft.client.gui.screen.Screen
|
import net.minecraft.client.gui.screen.Screen
|
||||||
import net.minecraft.client.util.math.MatrixStack
|
import net.minecraft.client.util.math.MatrixStack
|
||||||
import net.minecraft.sound.SoundEvents
|
import net.minecraft.sound.SoundEvents
|
||||||
|
@ -32,6 +33,8 @@ open class CacaoScreen(title: Text = LiteralText("CacaoScreen")): Screen(title),
|
||||||
*/
|
*/
|
||||||
override val windows: List<Window> = _windows
|
override val windows: List<Window> = _windows
|
||||||
|
|
||||||
|
private var hasAppeared = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the given window to this screen's window list at the given position.
|
* Adds the given window to this screen's window list at the given position.
|
||||||
*
|
*
|
||||||
|
@ -40,6 +43,10 @@ open class CacaoScreen(title: Text = LiteralText("CacaoScreen")): Screen(title),
|
||||||
* @return The window that was added, as a convenience.
|
* @return The window that was added, as a convenience.
|
||||||
*/
|
*/
|
||||||
override fun <T: Window> addWindow(window: T, index: Int): T {
|
override fun <T: Window> addWindow(window: T, index: Int): T {
|
||||||
|
if (hasAppeared) {
|
||||||
|
window.viewController.viewWillAppear()
|
||||||
|
}
|
||||||
|
|
||||||
_windows.add(index, window)
|
_windows.add(index, window)
|
||||||
|
|
||||||
window.screen = this
|
window.screen = this
|
||||||
|
@ -66,8 +73,14 @@ open class CacaoScreen(title: Text = LiteralText("CacaoScreen")): Screen(title),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun init() {
|
override fun screenWillAppear() {
|
||||||
super.init()
|
windows.forEach {
|
||||||
|
it.viewController.viewWillAppear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun resize(client: MinecraftClient, width: Int, height: Int) {
|
||||||
|
super.resize(client, width, height)
|
||||||
|
|
||||||
windows.forEach {
|
windows.forEach {
|
||||||
it.resize(width, height)
|
it.resize(width, height)
|
||||||
|
@ -78,7 +91,8 @@ open class CacaoScreen(title: Text = LiteralText("CacaoScreen")): Screen(title),
|
||||||
super.onClose()
|
super.onClose()
|
||||||
|
|
||||||
windows.forEach {
|
windows.forEach {
|
||||||
// todo: VC callbacks
|
it.viewController.viewWillDisappear()
|
||||||
|
it.viewController.viewDidDisappear()
|
||||||
|
|
||||||
// resign the current first responder (if any)
|
// resign the current first responder (if any)
|
||||||
it.firstResponder = null
|
it.firstResponder = null
|
||||||
|
|
|
@ -147,11 +147,6 @@ class TabViewController<T: TabViewController.Tab>(
|
||||||
currentTabController.viewWillAppear()
|
currentTabController.viewWillAppear()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun viewDidAppear() {
|
|
||||||
super.viewDidAppear()
|
|
||||||
currentTabController.viewDidAppear()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun viewWillDisappear() {
|
override fun viewWillDisappear() {
|
||||||
super.viewWillDisappear()
|
super.viewWillDisappear()
|
||||||
currentTabController.viewWillDisappear()
|
currentTabController.viewWillDisappear()
|
||||||
|
@ -225,7 +220,6 @@ class TabViewController<T: TabViewController.Tab>(
|
||||||
embedChild(currentTabController, tabVCContainer)
|
embedChild(currentTabController, tabVCContainer)
|
||||||
currentTabController.didMoveTo(this)
|
currentTabController.didMoveTo(this)
|
||||||
currentTabController.viewWillAppear()
|
currentTabController.viewWillAppear()
|
||||||
currentTabController.viewDidAppear()
|
|
||||||
|
|
||||||
onTabChange?.invoke(currentTab)
|
onTabChange?.invoke(currentTab)
|
||||||
|
|
||||||
|
|
|
@ -122,12 +122,12 @@ abstract class ViewController {
|
||||||
children.forEach(ViewController::viewWillAppear)
|
children.forEach(ViewController::viewWillAppear)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Called immediately after the VC's view has first been displayed on screen.
|
// * Called immediately after the VC's view has first been displayed on screen.
|
||||||
*/
|
// */
|
||||||
open fun viewDidAppear() {
|
// open fun viewDidAppear() {
|
||||||
children.forEach(ViewController::viewDidAppear)
|
// children.forEach(ViewController::viewDidAppear)
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before the view will disappear from the screen, either because the VC has been removed from it's parent/screen
|
* Called before the view will disappear from the screen, either because the VC has been removed from it's parent/screen
|
||||||
|
|
|
@ -4,7 +4,6 @@ import com.mojang.blaze3d.systems.RenderSystem
|
||||||
import net.minecraft.client.MinecraftClient
|
import net.minecraft.client.MinecraftClient
|
||||||
import net.minecraft.client.gui.DrawableHelper
|
import net.minecraft.client.gui.DrawableHelper
|
||||||
import net.minecraft.client.gui.Element
|
import net.minecraft.client.gui.Element
|
||||||
import net.minecraft.client.gui.widget.TextFieldWidget
|
|
||||||
import net.minecraft.client.render.GameRenderer
|
import net.minecraft.client.render.GameRenderer
|
||||||
import net.minecraft.client.render.Tessellator
|
import net.minecraft.client.render.Tessellator
|
||||||
import net.minecraft.client.render.VertexConsumerProvider
|
import net.minecraft.client.render.VertexConsumerProvider
|
||||||
|
@ -13,7 +12,6 @@ import net.minecraft.entity.player.PlayerInventory
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.screen.slot.Slot
|
import net.minecraft.screen.slot.Slot
|
||||||
import net.minecraft.screen.slot.SlotActionType
|
import net.minecraft.screen.slot.SlotActionType
|
||||||
import net.minecraft.text.LiteralText
|
|
||||||
import net.minecraft.text.Text
|
import net.minecraft.text.Text
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
import net.shadowfacts.cacao.CacaoHandledScreen
|
import net.shadowfacts.cacao.CacaoHandledScreen
|
||||||
|
@ -23,7 +21,6 @@ import net.shadowfacts.phycon.networking.C2STerminalRequestItem
|
||||||
import net.shadowfacts.phycon.networking.C2STerminalUpdateDisplayedItems
|
import net.shadowfacts.phycon.networking.C2STerminalUpdateDisplayedItems
|
||||||
import java.math.RoundingMode
|
import java.math.RoundingMode
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
import java.util.LinkedList
|
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
|
@ -38,14 +35,6 @@ abstract class AbstractTerminalScreen<BE: AbstractTerminalBlockEntity, T: Abstra
|
||||||
val terminalBackgroundHeight: Int,
|
val terminalBackgroundHeight: Int,
|
||||||
): CacaoHandledScreen<T>(handler, playerInv, title) {
|
): CacaoHandledScreen<T>(handler, playerInv, title) {
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val clickHandlers = LinkedList<AbstractTerminalScreen<*, *>.(Double, Double, Int) -> Boolean?>()
|
|
||||||
|
|
||||||
fun registerClickHandler(handler: AbstractTerminalScreen<*, *>.(Double, Double, Int) -> Boolean?) {
|
|
||||||
clickHandlers.add(handler)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract val backgroundTexture: Identifier
|
abstract val backgroundTexture: Identifier
|
||||||
|
|
||||||
val terminalVC: AbstractTerminalViewController<*, *, *>
|
val terminalVC: AbstractTerminalViewController<*, *, *>
|
||||||
|
@ -160,17 +149,6 @@ abstract class AbstractTerminalScreen<BE: AbstractTerminalBlockEntity, T: Abstra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
|
|
||||||
for (handler in clickHandlers) {
|
|
||||||
val res = handler(mouseX, mouseY, button)
|
|
||||||
if (res != null) {
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.mouseClicked(mouseX, mouseY, button)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMouseClick(slot: Slot?, invSlot: Int, clickData: Int, type: SlotActionType?) {
|
override fun onMouseClick(slot: Slot?, invSlot: Int, clickData: Int, type: SlotActionType?) {
|
||||||
super.onMouseClick(slot, invSlot, clickData, type)
|
super.onMouseClick(slot, invSlot, clickData, type)
|
||||||
|
|
||||||
|
@ -191,12 +169,11 @@ abstract class AbstractTerminalScreen<BE: AbstractTerminalBlockEntity, T: Abstra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val fakeFocusedElement = TextFieldWidget(textRenderer, 0, 0, 0, 0, LiteralText(""))
|
override fun setFocused(element: Element?) {
|
||||||
override fun getFocused(): Element? {
|
super.setFocused(element)
|
||||||
return if (windows.last().firstResponder != null) {
|
// so that when something else (e.g., REI) steals focus and calls setFocused(null) on us, any first responder resigns
|
||||||
fakeFocusedElement
|
if (element == null) {
|
||||||
} else {
|
windows.last().firstResponder?.resignFirstResponder()
|
||||||
null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,6 @@ abstract class AbstractTerminalViewController<BE: AbstractTerminalBlockEntity, S
|
||||||
handler = ::searchFieldChanged
|
handler = ::searchFieldChanged
|
||||||
drawBackground = false
|
drawBackground = false
|
||||||
}
|
}
|
||||||
searchField.becomeFirstResponder()
|
|
||||||
|
|
||||||
scrollTrack = view.addSubview(ScrollTrackView(::scrollPositionChanged))
|
scrollTrack = view.addSubview(ScrollTrackView(::scrollPositionChanged))
|
||||||
|
|
||||||
|
@ -137,6 +136,12 @@ abstract class AbstractTerminalViewController<BE: AbstractTerminalBlockEntity, S
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun viewWillAppear() {
|
||||||
|
super.viewWillAppear()
|
||||||
|
|
||||||
|
searchField.becomeFirstResponder()
|
||||||
|
}
|
||||||
|
|
||||||
private fun searchFieldChanged(field: TextField) {
|
private fun searchFieldChanged(field: TextField) {
|
||||||
screen.searchQuery = field.text
|
screen.searchQuery = field.text
|
||||||
screen.requestUpdatedItems()
|
screen.requestUpdatedItems()
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
{
|
{
|
||||||
"required": true,
|
"required": true,
|
||||||
"package": "net.shadowfacts.phycon.mixin.client",
|
"package": "net.shadowfacts.phycon.mixin.client",
|
||||||
"compatibilityLevel": "JAVA_8",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"MixinHandledScreen",
|
"MixinHandledScreen",
|
||||||
|
"MixinMinecraftClient",
|
||||||
"TextFieldWidgetAccessor"
|
"TextFieldWidgetAccessor"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"required": true,
|
"required": true,
|
||||||
"package": "net.shadowfacts.phycon.mixin",
|
"package": "net.shadowfacts.phycon.mixin",
|
||||||
"compatibilityLevel": "JAVA_8",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
|
|
Loading…
Reference in New Issue