Un-hellish panel focus logic
This commit is contained in:
parent
fda82f3357
commit
986be8fa1a
@ -358,7 +358,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
|
||||
|
||||
for (panel in panels) {
|
||||
if (click || !panel.mouseClickedChecked(x, y, button)) {
|
||||
focusKilled = panel.killFocusForEverythingExceptInner() || focusKilled
|
||||
focusKilled = panel.killFocus() || focusKilled
|
||||
} else {
|
||||
if (returnSlot != null) {
|
||||
super.mouseClicked(x, y, button)
|
||||
|
@ -560,19 +560,23 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
protected open fun onHovered() {}
|
||||
protected open fun onUnHovered() {}
|
||||
|
||||
var isFocused = false
|
||||
set(value) {
|
||||
var hasFocusedChildren = false
|
||||
private set(value) {
|
||||
if (field != value) {
|
||||
val old = field
|
||||
field = value
|
||||
|
||||
onFocusChanged(value, old)
|
||||
findAbsoluteRoot().updateFocus()
|
||||
onHierarchicalFocusChanged()
|
||||
}
|
||||
}
|
||||
|
||||
var autoKillFocus = true
|
||||
private var focusedAsParent = false
|
||||
var isFocusedThis = false
|
||||
private set(value) {
|
||||
if (field != value) {
|
||||
field = value
|
||||
onFocusChanged()
|
||||
}
|
||||
}
|
||||
|
||||
var autoRequestFocus = true
|
||||
|
||||
val font: Font get() = if (screen is MatteryScreen<*>) screen.font else minecraft.font
|
||||
|
||||
@ -1105,15 +1109,24 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun killFocusInternal(): Boolean {
|
||||
var status = false
|
||||
|
||||
private fun killGrabMouseInput() {
|
||||
for (child in childrenInternal) {
|
||||
status = child.killFocusInternal() || status
|
||||
child.killGrabMouseInput()
|
||||
}
|
||||
|
||||
if (isFocused) {
|
||||
isFocused = false
|
||||
grabMouseInput = false
|
||||
}
|
||||
|
||||
private fun killFocusThis(children: Boolean): Boolean {
|
||||
var status = false
|
||||
|
||||
if (isFocusedThis) {
|
||||
isFocusedThis = false
|
||||
status = true
|
||||
}
|
||||
|
||||
if (children && hasFocusedChildren) {
|
||||
hasFocusedChildren = false
|
||||
status = true
|
||||
}
|
||||
|
||||
@ -1125,29 +1138,19 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
return status
|
||||
}
|
||||
|
||||
private fun killGrabMouseInput() {
|
||||
for (child in childrenInternal) {
|
||||
child.killGrabMouseInput()
|
||||
}
|
||||
|
||||
grabMouseInput = false
|
||||
}
|
||||
|
||||
fun killFocus(): Boolean {
|
||||
if (isEverFocused()) {
|
||||
val status = killFocusInternal()
|
||||
findAbsoluteRoot().updateFocus()
|
||||
return status
|
||||
} else if (isGrabbingMouseInput()) {
|
||||
killGrabMouseInput()
|
||||
return true
|
||||
var status = false
|
||||
status = killFocusThis(true) || status
|
||||
|
||||
for (child in childrenInternal) {
|
||||
status = child.killFocus() || status
|
||||
}
|
||||
|
||||
return false
|
||||
return status
|
||||
}
|
||||
|
||||
fun findHierarchicalFocus(): EditablePanel<*>? {
|
||||
if (isFocused) {
|
||||
if (isFocusedThis) {
|
||||
return this
|
||||
}
|
||||
|
||||
@ -1166,46 +1169,35 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
return findHierarchicalFocus() != null
|
||||
}
|
||||
|
||||
protected open fun onHierarchicalFocusChanged(new: Boolean, old: Boolean) {
|
||||
|
||||
}
|
||||
|
||||
protected open fun onFocusChanged(new: Boolean, old: Boolean) {
|
||||
|
||||
}
|
||||
|
||||
private fun updateFocus() {
|
||||
val old = focusedAsParent
|
||||
focusedAsParent = hasHierarchicalFocus()
|
||||
|
||||
if (focusedAsParent != old) {
|
||||
onHierarchicalFocusChanged(focusedAsParent, old)
|
||||
}
|
||||
|
||||
for (child in childrenInternal) {
|
||||
child.updateFocus()
|
||||
}
|
||||
}
|
||||
protected open fun onHierarchicalFocusChanged() {}
|
||||
protected open fun onFocusChanged() {}
|
||||
|
||||
fun isEverFocused(): Boolean {
|
||||
return isFocused || focusedAsParent
|
||||
return isFocusedThis || hasFocusedChildren
|
||||
}
|
||||
|
||||
fun requestFocus() {
|
||||
if (isFocused) {
|
||||
if (isFocusedThis || !isVisible()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (focusedAsParent) {
|
||||
var child = findHierarchicalFocus()
|
||||
var filter: EditablePanel<*>? = null
|
||||
var parent: EditablePanel<*>? = this
|
||||
|
||||
while (child != null) {
|
||||
child.isFocused = false
|
||||
child = findHierarchicalFocus()
|
||||
while (parent != null) {
|
||||
for (child in parent.childrenInternal) {
|
||||
if (child !== filter) {
|
||||
child.killFocus()
|
||||
}
|
||||
}
|
||||
|
||||
isFocused = true
|
||||
filter = parent
|
||||
parent = parent.parent
|
||||
parent?.killFocusThis(false)
|
||||
parent?.hasFocusedChildren = true
|
||||
}
|
||||
|
||||
isFocusedThis = true
|
||||
}
|
||||
|
||||
protected open fun xPosUpdated(new: Float, old: Float) {}
|
||||
@ -1311,69 +1303,52 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
y in pos.y .. pos2.y
|
||||
}
|
||||
|
||||
fun killFocusForEverythingExcept(except: EditablePanel<*>) {
|
||||
for (child in childrenInternal) {
|
||||
if (child !== except) {
|
||||
child.killFocusForEverythingExceptInner()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun killFocusForEverythingExceptInner(): Boolean {
|
||||
var focusKilled = false
|
||||
|
||||
for (child in childrenInternal) {
|
||||
focusKilled = child.killFocusForEverythingExceptInner() || focusKilled
|
||||
}
|
||||
|
||||
if (autoKillFocus) {
|
||||
focusKilled = killFocus() || focusKilled
|
||||
}
|
||||
|
||||
return focusKilled
|
||||
}
|
||||
|
||||
final override fun mouseClicked(x: Double, y: Double, button: Int): Boolean {
|
||||
if (!isVisible() || !acceptMouseInput) return false
|
||||
if (flashAnyBlocker()) return true
|
||||
if (grabMouseInput) return mouseClickedInner(x, y, button)
|
||||
|
||||
if (grabMouseInput) {
|
||||
if (mouseClickedInner(x, y, button)) {
|
||||
if (autoRequestFocus) requestFocus()
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
for (child in visibleChildrenInternal) {
|
||||
if (child.isGrabbingMouseInput() && child.mouseClickedChecked(x, y, button)) {
|
||||
killFocusForEverythingExcept(child)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
for (child in visibleChildrenInternal) {
|
||||
if (child.mouseClickedChecked(x, y, button)) {
|
||||
killFocusForEverythingExcept(child)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return mouseClickedInner(x, y, button)
|
||||
if (mouseClickedInner(x, y, button)) {
|
||||
if (autoRequestFocus) requestFocus()
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun mouseClickedChecked(x: Double, y: Double, button: Int): Boolean {
|
||||
if (!isVisible() || !acceptMouseInput) return false
|
||||
|
||||
if (isGrabbingMouseInput() || withinBounds(x, y)) {
|
||||
popup()
|
||||
return mouseClicked(x, y, button)
|
||||
} else if (withinExtendedBounds(x, y)) {
|
||||
popup(false)
|
||||
|
||||
for (child in visibleChildrenInternal) {
|
||||
if (child.mouseClickedChecked(x, y, button)) {
|
||||
killFocusForEverythingExcept(child)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if (autoKillFocus) killFocus()
|
||||
} else if (autoKillFocus) {
|
||||
killFocus()
|
||||
}
|
||||
|
||||
return false
|
||||
@ -1509,13 +1484,9 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
|
||||
final override fun keyPressed(key: Int, scancode: Int, mods: Int): Boolean {
|
||||
if (!isVisible() || !acceptKeyboardInput) return false
|
||||
if (!focusedAsParent) return false
|
||||
|
||||
if (flashAnyBlocker(true)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (isFocused) return keyPressedInternal(key, scancode, mods)
|
||||
if (!isEverFocused()) return false
|
||||
if (flashAnyBlocker(true)) return true
|
||||
if (isFocusedThis) return keyPressedInternal(key, scancode, mods)
|
||||
|
||||
for (child in visibleChildrenInternal) {
|
||||
if (child.keyPressed(key, scancode, mods)) {
|
||||
@ -1523,7 +1494,7 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
if (focusedAsParent) return keyPressedInternal(key, scancode, mods)
|
||||
if (hasFocusedChildren) return keyPressedInternal(key, scancode, mods)
|
||||
return false
|
||||
}
|
||||
|
||||
@ -1533,13 +1504,9 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
|
||||
final override fun keyReleased(key: Int, scancode: Int, mods: Int): Boolean {
|
||||
if (!isVisible() || !acceptKeyboardInput) return false
|
||||
if (!focusedAsParent) return false
|
||||
|
||||
if (flashAnyBlocker(false)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (isFocused) return keyReleasedInternal(key, scancode, mods)
|
||||
if (!isEverFocused()) return false
|
||||
if (flashAnyBlocker(false)) return true
|
||||
if (isFocusedThis) return keyReleasedInternal(key, scancode, mods)
|
||||
|
||||
for (child in visibleChildrenInternal) {
|
||||
if (child.keyReleased(key, scancode, mods)) {
|
||||
@ -1547,7 +1514,7 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
if (focusedAsParent) return keyReleasedInternal(key, scancode, mods)
|
||||
if (hasFocusedChildren) return keyReleasedInternal(key, scancode, mods)
|
||||
return false
|
||||
}
|
||||
|
||||
@ -1557,13 +1524,9 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
|
||||
final override fun charTyped(codepoint: Char, mods: Int): Boolean {
|
||||
if (!isVisible() || !acceptKeyboardInput) return false
|
||||
if (!focusedAsParent) return false
|
||||
|
||||
if (flashAnyBlocker()) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (isFocused) return charTypedInternal(codepoint, mods)
|
||||
if (!isEverFocused()) return false
|
||||
if (flashAnyBlocker(false)) return true
|
||||
if (isFocusedThis) return charTypedInternal(codepoint, mods)
|
||||
|
||||
for (child in visibleChildrenInternal) {
|
||||
if (child.charTyped(codepoint, mods)) {
|
||||
@ -1571,6 +1534,7 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
if (hasFocusedChildren) return charTypedInternal(codepoint, mods)
|
||||
return true
|
||||
}
|
||||
|
||||
@ -1638,7 +1602,7 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
screen.popup(this as EditablePanel<MatteryScreen<*>>)
|
||||
}
|
||||
|
||||
if (focus && !isEverFocused()) {
|
||||
if (focus) {
|
||||
requestFocus()
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.client.screen.panels.input
|
||||
|
||||
import com.mojang.blaze3d.platform.InputConstants
|
||||
import net.minecraft.client.gui.components.EditBox
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.network.chat.Component
|
||||
@ -23,15 +24,11 @@ open class EditBoxPanel<out S : Screen>(
|
||||
}
|
||||
|
||||
override fun isFocused(): Boolean {
|
||||
return this@EditBoxPanel.isFocused
|
||||
return this@EditBoxPanel.isFocusedThis
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
autoKillFocus = true
|
||||
}
|
||||
|
||||
override fun copyValues(new_widget: EditBox, old_widget: EditBox) {
|
||||
new_widget.value = old_widget.value
|
||||
}
|
||||
@ -42,11 +39,11 @@ open class EditBoxPanel<out S : Screen>(
|
||||
}
|
||||
|
||||
override fun configureNew(widget: EditBox, recreation: Boolean) {
|
||||
widget.setFocus(isFocused)
|
||||
widget.setFocus(isFocusedThis)
|
||||
}
|
||||
|
||||
override fun onFocusChanged(new: Boolean, old: Boolean) {
|
||||
widget?.setFocus(new)
|
||||
override fun onFocusChanged() {
|
||||
widget?.setFocus(isFocusedThis)
|
||||
}
|
||||
|
||||
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
||||
@ -54,4 +51,13 @@ open class EditBoxPanel<out S : Screen>(
|
||||
requestFocus()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun keyPressedInternal(key: Int, scancode: Int, mods: Int): Boolean {
|
||||
if (key == InputConstants.KEY_ESCAPE && widget?.isActive == true) {
|
||||
widget?.setFocus(false)
|
||||
return true
|
||||
}
|
||||
|
||||
return super.keyPressedInternal(key, scancode, mods)
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ open class NetworkNumberInputPanel<out S : Screen> @JvmOverloads constructor(
|
||||
override fun tickInner() {
|
||||
super.tickInner()
|
||||
|
||||
if (isFocused) {
|
||||
if (isFocusedThis) {
|
||||
if (!isAvailable.asBoolean) {
|
||||
killFocus()
|
||||
return
|
||||
|
@ -19,10 +19,10 @@ open class NetworkedStringInputPanel<out S : Screen>(
|
||||
get() = backend.test(minecraft.player)
|
||||
set(value) {}
|
||||
|
||||
override fun onFocusChanged(new: Boolean, old: Boolean) {
|
||||
super.onFocusChanged(new, old)
|
||||
override fun onFocusChanged() {
|
||||
super.onFocusChanged()
|
||||
|
||||
if (new && !backend.test(minecraft.player)) {
|
||||
if (isFocusedThis && !backend.test(minecraft.player)) {
|
||||
killFocus()
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||
import ru.dbotthepony.mc.otm.core.addAll
|
||||
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.milliTime
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
open class TextInputPanel<out S : Screen>(
|
||||
screen: S,
|
||||
@ -149,7 +148,6 @@ open class TextInputPanel<out S : Screen>(
|
||||
init {
|
||||
scissor = true
|
||||
dockPadding = DockProperty(2f, 2f, 2f, 2f)
|
||||
autoKillFocus = true
|
||||
}
|
||||
|
||||
private var oldText = ArrayList<String>()
|
||||
@ -1138,7 +1136,7 @@ open class TextInputPanel<out S : Screen>(
|
||||
break
|
||||
}
|
||||
|
||||
if (isFocused && milliTime % 1000L > 500L) {
|
||||
if (isFocusedThis && milliTime % 1000L > 500L) {
|
||||
val activeLine = this[cursorLine]
|
||||
|
||||
if (activeLine == null || cursorRow >= activeLine.length) {
|
||||
|
Loading…
Reference in New Issue
Block a user