Update hover check code to properly determine hover status in case of overlapping panels

This commit is contained in:
DBotThePony 2023-08-20 20:19:54 +07:00
parent b31114ba09
commit 7d05332a90
Signed by: DBot
GPG Key ID: DCC23B5715498507
2 changed files with 61 additions and 34 deletions

View File

@ -104,7 +104,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
RenderSystem.depthFunc(GL11.GL_ALWAYS)
graphics.renderItemDecorations(
font,
super.font,
itemstack,
1,
1,
@ -533,7 +533,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
override fun mouseReleased(p_97812_: Double, p_97813_: Double, p_97814_: Int): Boolean {
if (lastDragSlot != null) {
if (isQuickCrafting) {
if (super.isQuickCrafting) {
returnSlot = lastDragSlot
val ret = super.mouseReleased(p_97812_, p_97813_, p_97814_)
returnSlot = null
@ -644,7 +644,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
// dark background
this.renderBackground(graphics)
hoveredSlot = null
super.hoveredSlot = null
var hovered = false
for (panel in panels) {
@ -692,7 +692,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
val i2 = if (draggingItem.isEmpty) 8 else 16
var overrideCount: String? = null
if (isQuickCrafting && quickCraftSlots.size > 1) {
if (super.isQuickCrafting && super.quickCraftSlots.size > 1) {
itemstack = itemstack.copy()
itemstack.count = quickCraftingRemainder
@ -706,7 +706,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
}
if (menu.carried.isEmpty) {
val hoveredSlot = hoveredSlot
val hoveredSlot = super.hoveredSlot
if (hoveredSlot != null && hoveredSlot.hasItem()) {
this.renderTooltip(graphics, mouseX, mouseY)

View File

@ -25,6 +25,9 @@ import ru.dbotthepony.mc.otm.client.render.popScissorRect
import ru.dbotthepony.mc.otm.client.render.pushScissorRect
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.input.QueryUserPanel
import ru.dbotthepony.mc.otm.core.collect.any
import ru.dbotthepony.mc.otm.core.collect.concatIterators
import ru.dbotthepony.mc.otm.core.collect.flatMap
import java.util.*
import kotlin.collections.ArrayList
import kotlin.math.roundToInt
@ -260,9 +263,18 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
private val childrenInternal = ArrayList<EditablePanel<*>>()
private val visibleChildrenInternal = ArrayList<EditablePanel<*>>()
val children: List<EditablePanel<*>> = Collections.unmodifiableList(childrenInternal)
val visibleChildren: List<EditablePanel<*>> = Collections.unmodifiableList(visibleChildrenInternal)
val allPanels: Iterator<EditablePanel<*>> get() {
return concatIterators(listOf(this).iterator(), childrenInternal.iterator().flatMap { it.allPanels })
}
val allVisiblePanels: Iterator<EditablePanel<*>> get() {
return concatIterators(listOf(this).iterator(), visibleChildrenInternal.iterator().flatMap { it.allVisiblePanels })
}
var layoutInvalidated = true
private set
var boundsInvalidated = true
@ -649,6 +661,9 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
var absoluteY = 0f
private set
/**
* If this exact panel is hovered. Panel is not considered hovered if any of its children are hovered
*/
var isHovered = false
private set(value) {
if (value == field) {
@ -661,6 +676,13 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
onHoverUpdate(old, value)
}
/**
* If this panel or any of its children are hovered
*/
val isEverHovered: Boolean get() {
return isHovered || visibleChildrenInternal.any { it.isEverHovered }
}
fun unsetHovered() {
isHovered = false
@ -772,7 +794,7 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
}
protected open fun shouldRenderTooltips(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
return isHovered || isGrabbingMouseInput()
return isEverHovered || isGrabbingMouseInput()
}
fun isVisible(): Boolean {
@ -835,16 +857,6 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
if (parent == null) {
absoluteX = x
absoluteY = y
} else {
if ((x < 0f || y < 0f || x + width > parent.width || y + height > parent.height) && parent.parent == null) {
// no op - we updated ourselves in tickHover
} else {
isHovered = parent.isHovered &&
mouseX >= absoluteX &&
mouseX < absoluteX + width &&
mouseY >= absoluteY &&
mouseY < absoluteY + height
}
}
}
@ -893,35 +905,50 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
}
}
open fun tickHover(mouseX: Float, mouseY: Float): Boolean {
if (isRemoved) {
return false
fun updateAbsolutePosition() {
val parent = parent
if (parent == null) {
absoluteX = x
absoluteY = y
} else {
absoluteX = parent.absoluteX + x + parent.xOffset
absoluteY = parent.absoluteY + y + parent.yOffset
}
if ((childrenRectHeight > height || childrenRectWidth > width || childrenRectX < 0 || childrenRectY < 0) && parent == null) {
for (child in visibleChildrenInternal) {
child.updateAbsolutePosition()
}
}
fun tickHover(mouseX: Float, mouseY: Float): Boolean {
if (isRemoved)
return false
if (parent == null)
updateAbsolutePosition()
if (mouseX in absoluteX ..< absoluteX + childrenRectWidth.coerceAtLeast(width) && mouseY in absoluteY ..< absoluteY + childrenRectHeight.coerceAtLeast(height)) {
var hit = false
for (child in childrenInternal) {
if (child.tickHover(mouseX, mouseY)) {
for (child in visibleChildrenInternal) {
if (hit) {
child.unsetHovered()
} else if (child.tickHover(mouseX, mouseY)) {
hit = true
}
}
isHovered = mouseX >= absoluteX &&
mouseX <= absoluteX + width &&
mouseY >= absoluteY &&
mouseY <= absoluteY + height
isHovered =
!hit &&
mouseX in absoluteX ..< absoluteX + width &&
mouseY in absoluteY ..< absoluteY + height
return hit || isHovered
} else {
unsetHovered()
return false
}
isHovered =
mouseX >= absoluteX &&
mouseX <= absoluteX + width &&
mouseY >= absoluteY &&
mouseY <= absoluteY + height
return isHovered
}
fun findSlot(mouseX: Float, mouseY: Float): Pair<Boolean, Slot?> {