HTTPS
https://git.nageyqma.icu/nageyqma/odin_next.git
SSH
git@git.nageyqma.icu:nageyqma/odin_next.git
HTTPS 链接可直接 git clone;推送代码请使用 SSH。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
package com.odtheking.odin.clickgui.widget
import com.odtheking.odin.clickgui.ClickGUI
import com.odtheking.odin.utils.ui.animations.Fade
import net.minecraft.client.gui.ComponentPath
import net.minecraft.client.gui.GuiGraphicsExtractor
import net.minecraft.client.gui.components.AbstractWidget
import net.minecraft.client.gui.components.events.ContainerEventHandler
import net.minecraft.client.gui.components.events.GuiEventListener
import net.minecraft.client.gui.narration.NarrationElementOutput
import net.minecraft.client.gui.navigation.FocusNavigationEvent
import net.minecraft.client.input.MouseButtonEvent
import net.minecraft.client.input.MouseButtonInfo
import net.minecraft.client.sounds.SoundManager
import net.minecraft.network.chat.Component
abstract class OdinWidget(x: Int, y: Int, width: Int, height: Int, message: Component) : AbstractWidget(x, y, width, height, message) {
private val hoverFade = Fade(HOVER_DURATION)
private val descriptionDelay = Fade(DESCRIPTION_DELAY, settles = false)
private var boundsHovered = false
protected open val clickButtons = LEFT_ONLY
protected open val description get() = ""
protected val hover get() = hoverFade.progress(boundsHovered)
final override fun isValidClickButton(buttonInfo: MouseButtonInfo): Boolean = buttonInfo.button() in clickButtons
final override fun extractWidgetRenderState(graphics: GuiGraphicsExtractor, mouseX: Int, mouseY: Int, partialTick: Float) {
boundsHovered = visible && isOver(mouseX, mouseY, x, y, width, height)
render(graphics, mouseX, mouseY)
val resting = wantsDescription(mouseX, mouseY)
if (description.isNotEmpty() && resting && descriptionDelay.progress(true) >= 1f)
ClickGUI.setDescription(description, right + DESCRIPTION_GAP, y)
else if (!resting) descriptionDelay.progress(false)
}
protected open fun wantsDescription(mouseX: Int, mouseY: Int): Boolean = boundsHovered
protected abstract fun render(graphics: GuiGraphicsExtractor, mouseX: Int, mouseY: Int)
override fun playDownSound(soundManager: SoundManager) = Unit
override fun updateWidgetNarration(output: NarrationElementOutput) = defaultButtonNarrationText(output)
companion object {
const val LEFT = 0
const val RIGHT = 1
val LEFT_ONLY = intArrayOf(LEFT)
val BOTH_BUTTONS = intArrayOf(LEFT, RIGHT)
private const val HOVER_DURATION = 150L
private const val DESCRIPTION_DELAY = 600L
private const val DESCRIPTION_GAP = 10
}
}
abstract class OdinContainerWidget(x: Int, y: Int, width: Int, height: Int, message: Component) : OdinWidget(x, y, width, height, message), ContainerEventHandler {
private var focusedChild: GuiEventListener? = null
private var draggingChild = false
private var selfFocused = false
override val clickButtons: IntArray = BOTH_BUTTONS
abstract override fun children(): List<GuiEventListener>
override fun getFocused(): GuiEventListener? = focusedChild
override fun setFocused(listener: GuiEventListener?) {
if (focusedChild === listener) return
focusedChild?.isFocused = false
listener?.isFocused = true
focusedChild = listener
}
override fun isDragging(): Boolean = draggingChild
override fun setDragging(dragging: Boolean) {
draggingChild = dragging
}
override fun isFocused(): Boolean = selfFocused || focusedChild != null
override fun setFocused(focused: Boolean) {
selfFocused = focused
if (!focused) setFocused(null)
}
override fun nextFocusPath(event: FocusNavigationEvent): ComponentPath? =
super<ContainerEventHandler>.nextFocusPath(event)
override fun mouseClicked(event: MouseButtonEvent, doubleClick: Boolean): Boolean =
super<ContainerEventHandler>.mouseClicked(event, doubleClick) ||
super<OdinWidget>.mouseClicked(event, doubleClick)
override fun mouseReleased(event: MouseButtonEvent): Boolean =
super<ContainerEventHandler>.mouseReleased(event) || super<OdinWidget>.mouseReleased(event)
override fun mouseDragged(event: MouseButtonEvent, dragX: Double, dragY: Double): Boolean =
super<ContainerEventHandler>.mouseDragged(event, dragX, dragY) ||
super<OdinWidget>.mouseDragged(event, dragX, dragY)
override fun render(graphics: GuiGraphicsExtractor, mouseX: Int, mouseY: Int) {
renderChildren(graphics, mouseX, mouseY)
}
protected fun renderChildren(graphics: GuiGraphicsExtractor, mouseX: Int, mouseY: Int) {
for (child in children()) {
if (child is AbstractWidget) child.extractRenderState(graphics, mouseX, mouseY, 0f)
}
}
}
internal fun isOver(mouseX: Int, mouseY: Int, x: Int, y: Int, width: Int, height: Int): Boolean =
mouseX >= x && mouseX < x + width && mouseY >= y && mouseY < y + height