parent
9cf7a4cdd9
commit
f8e38949b5
@ -423,19 +423,19 @@ private enum class PreviewScrollers(
|
||||
LEFT_TO_RIGHT(
|
||||
init = { it, random ->
|
||||
it.xOffset = it.width
|
||||
it.yOffset = random.nextFloat(-it.boundingHeight + 18f, 0f)
|
||||
it.yOffset = random.nextFloat(-it.childrenRectHeight + 18f, 0f)
|
||||
},
|
||||
|
||||
scroll = { it, _ ->
|
||||
it.xOffset -= 1f
|
||||
it.xOffset >= -it.boundingWidth
|
||||
it.xOffset >= -it.childrenRectWidth
|
||||
}
|
||||
),
|
||||
|
||||
RIGHT_TO_LEFT(
|
||||
init = { it, random ->
|
||||
it.xOffset = -it.boundingWidth
|
||||
it.yOffset = random.nextFloat(-it.boundingHeight + 18f, 0f)
|
||||
it.xOffset = -it.childrenRectWidth
|
||||
it.yOffset = random.nextFloat(-it.childrenRectHeight + 18f, 0f)
|
||||
},
|
||||
|
||||
scroll = { it, _ ->
|
||||
@ -446,8 +446,8 @@ private enum class PreviewScrollers(
|
||||
|
||||
BOTTOM_TO_TOP(
|
||||
init = { it, random ->
|
||||
it.yOffset = -it.boundingHeight
|
||||
it.xOffset = random.nextFloat(-it.boundingWidth + 18f, 0f)
|
||||
it.yOffset = -it.childrenRectHeight
|
||||
it.xOffset = random.nextFloat(-it.childrenRectWidth + 18f, 0f)
|
||||
},
|
||||
|
||||
scroll = { it, _ ->
|
||||
@ -459,12 +459,12 @@ private enum class PreviewScrollers(
|
||||
TOP_TO_BOTTOM(
|
||||
init = { it, random ->
|
||||
it.yOffset = it.height
|
||||
it.xOffset = random.nextFloat(-it.boundingWidth + 18f, 0f)
|
||||
it.xOffset = random.nextFloat(-it.childrenRectWidth + 18f, 0f)
|
||||
},
|
||||
|
||||
scroll = { it, _ ->
|
||||
it.yOffset -= 1f
|
||||
it.yOffset >= it.boundingHeight
|
||||
it.yOffset >= it.childrenRectHeight
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp
|
||||
|
||||
for (i in 0 until GRID_WIDTH * GRID_HEIGHT) {
|
||||
object : AbstractSlotPanel<DriveViewerScreen>(this@DriveViewerScreen, grid, 0f, 0f) {
|
||||
override fun getItemStack(): ItemStack {
|
||||
override val itemStack: ItemStack get() {
|
||||
val index = i + scrollBar.scroll * GRID_WIDTH
|
||||
return menu.networkedItemView.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY
|
||||
}
|
||||
@ -72,7 +72,7 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp
|
||||
|
||||
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||
renderSlotBackground(stack, mouseX, mouseY, partialTick)
|
||||
renderRegular(stack, getItemStack(), "")
|
||||
renderRegular(stack, itemStack, "")
|
||||
}
|
||||
|
||||
override fun getItemStackTooltip(stack: ItemStack): List<Component> {
|
||||
|
@ -56,7 +56,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
||||
object : AbstractSlotPanel<ItemMonitorScreen>(this@ItemMonitorScreen, gridPanel) {
|
||||
private val index get() = i + viewScrollBar.scroll * ITEM_GRID_WIDTH
|
||||
|
||||
override fun getItemStack(): ItemStack {
|
||||
override val itemStack: ItemStack get() {
|
||||
return menu.networkedItemView.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
|
||||
|
||||
for (i in 0 until 9) {
|
||||
object : AbstractSlotPanel<ItemMonitorScreen>(this@ItemMonitorScreen, craftingHistory) {
|
||||
override fun getItemStack(): ItemStack {
|
||||
override val itemStack: ItemStack get() {
|
||||
return ItemStack(Items.ARROW, 42)
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ class MatterPanelScreen(
|
||||
|
||||
private val index: Int get() = (scrollBar.scroll + row) * GRID_WIDTH + i
|
||||
|
||||
override fun getItemStack(): ItemStack {
|
||||
override val itemStack: ItemStack get() {
|
||||
if (isPatternView) {
|
||||
return menu.patterns.getOrNull(index)?.stack() ?: ItemStack.EMPTY
|
||||
} else {
|
||||
@ -132,7 +132,7 @@ class MatterPanelScreen(
|
||||
dock = Dock.LEFT
|
||||
}
|
||||
|
||||
override fun getItemStack(): ItemStack {
|
||||
override val itemStack: ItemStack get() {
|
||||
return menu.tasks.firstOrNull { it.id == task.id }?.let { it.stack((it.required + it.inProgress).coerceAtLeast(1)) } ?: task.stack((task.required + task.inProgress).coerceAtLeast(1))
|
||||
}
|
||||
|
||||
@ -187,7 +187,7 @@ class MatterPanelScreen(
|
||||
dockRight = 2f
|
||||
}
|
||||
|
||||
override fun getItemStack(): ItemStack {
|
||||
override val itemStack: ItemStack get() {
|
||||
return pattern.stack()
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ import ru.dbotthepony.mc.otm.client.moveMousePosScaled
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.*
|
||||
import ru.dbotthepony.mc.otm.core.maxScrollDivision
|
||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||
import java.util.Collections
|
||||
|
||||
/**
|
||||
* This class encapsulate most of logic for handling EditablePanel and it's children.
|
||||
@ -34,6 +35,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
|
||||
constructor(menu: T, title: Component) : this(menu, menu.inventory, title)
|
||||
|
||||
protected val panels = ArrayDeque<EditablePanel<*>>()
|
||||
val panelsView: List<EditablePanel<*>> = Collections.unmodifiableList(panels)
|
||||
|
||||
var inventoryFrame: FramePanel<MatteryScreen<*>>? = null
|
||||
var mainFrame: FramePanel<MatteryScreen<*>>? = null
|
||||
|
@ -20,7 +20,7 @@ abstract class AbstractSlotPanel<out S : MatteryScreen<*>> @JvmOverloads constru
|
||||
width: Float = SIZE,
|
||||
height: Float = SIZE,
|
||||
open val noItemIcon: SkinElement? = null
|
||||
) : EditablePanel<S>(screen, parent, x, y, width, height) {
|
||||
) : EditablePanel<S>(screen, parent, x, y, width, height), IItemStackPanel {
|
||||
protected open fun renderSlotBackground(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||
SLOT_BACKGROUND.render(stack, width = width, height = height)
|
||||
}
|
||||
@ -68,15 +68,13 @@ abstract class AbstractSlotPanel<out S : MatteryScreen<*>> @JvmOverloads constru
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun getItemStack(): ItemStack
|
||||
|
||||
protected open fun getItemStackTooltip(stack: ItemStack): List<Component> {
|
||||
return screen.getTooltipFromItem(stack)
|
||||
}
|
||||
|
||||
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||
renderSlotBackground(stack, mouseX, mouseY, partialTick)
|
||||
val itemStack = getItemStack()
|
||||
val itemStack = itemStack
|
||||
renderRegular(stack, itemStack)
|
||||
|
||||
if (itemStack.isEmpty) {
|
||||
@ -86,7 +84,7 @@ abstract class AbstractSlotPanel<out S : MatteryScreen<*>> @JvmOverloads constru
|
||||
|
||||
override fun innerRenderTooltips(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
|
||||
if (isHovered) {
|
||||
val itemstack = getItemStack()
|
||||
val itemstack = itemStack
|
||||
|
||||
if (!itemstack.isEmpty) {
|
||||
// val font = RenderProperties.get(itemstack).getFont(itemstack)
|
||||
|
@ -6,19 +6,20 @@ import com.mojang.blaze3d.vertex.PoseStack
|
||||
import net.minecraft.client.gui.Font
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.client.renderer.Rect2i
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.inventory.Slot
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.client.moveMousePosScaled
|
||||
import ru.dbotthepony.mc.otm.client.render.ScissorRect
|
||||
import ru.dbotthepony.mc.otm.client.render.currentScissorRect
|
||||
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 java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@JvmRecord
|
||||
data class ScreenPos(val x: Float, val y: Float)
|
||||
@ -44,6 +45,16 @@ interface ISlotPanel<S : Slot> {
|
||||
val slot: S
|
||||
}
|
||||
|
||||
interface IItemStackPanel {
|
||||
val itemStack: ItemStack
|
||||
}
|
||||
|
||||
data class Rect2f(val x: Float, val y: Float, val width: Float, val height: Float) {
|
||||
fun toIntRect(): Rect2i {
|
||||
return Rect2i(x.roundToInt(), y.roundToInt(), width.roundToInt(), height.roundToInt())
|
||||
}
|
||||
}
|
||||
|
||||
open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
val screen: S,
|
||||
parent: EditablePanel<*>?,
|
||||
@ -262,17 +273,61 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
dockPadding = DockProperty(left, top, right, bottom)
|
||||
}
|
||||
|
||||
// абсолютное начало координат этой панели и потомков
|
||||
// негативно если потомок выходит за границы
|
||||
var boundingX = 0f
|
||||
/**
|
||||
* Rectangle which hold all children in panel-local (to this panel) coordinates
|
||||
*/
|
||||
var childrenRectX = 0f
|
||||
private set
|
||||
var boundingY = 0f
|
||||
|
||||
/**
|
||||
* Rectangle which hold all children in panel-local (to this panel) coordinates
|
||||
*/
|
||||
var childrenRectY = 0f
|
||||
private set
|
||||
var boundingWidth = 0f
|
||||
|
||||
/**
|
||||
* Rectangle which hold all children in panel-local (to this panel) coordinates
|
||||
*/
|
||||
var childrenRectWidth = 0f
|
||||
private set
|
||||
var boundingHeight = 0f
|
||||
|
||||
/**
|
||||
* Rectangle which hold all children in panel-local (to this panel) coordinates
|
||||
*/
|
||||
var childrenRectHeight = 0f
|
||||
private set
|
||||
|
||||
val isOutsideOfParent: Boolean get() {
|
||||
val parent = parent ?: return false
|
||||
return x < 0 || y < 0 || x + width > parent.width || y + height > parent.height
|
||||
}
|
||||
|
||||
fun calculateAbsoluteRectangle(): Rect2f {
|
||||
val x = if (childrenRectX < 0) childrenRectX + absoluteX else absoluteX
|
||||
val y = if (childrenRectY < 0) childrenRectY + absoluteY else absoluteY
|
||||
val width = if (childrenRectWidth > width) childrenRectWidth else width
|
||||
val height = if (childrenRectHeight > height) childrenRectHeight else height
|
||||
|
||||
return Rect2f(x, y, width, height)
|
||||
}
|
||||
|
||||
fun calculateAbsoluteRectangles(): List<Rect2f> {
|
||||
if (childrenRectX >= 0 && childrenRectY >= 0 && childrenRectWidth <= width && childrenRectHeight <= height) {
|
||||
return listOf(Rect2f(absoluteX, absoluteY, width, height))
|
||||
}
|
||||
|
||||
val result = ArrayList<Rect2f>()
|
||||
result.add(Rect2f(absoluteX, absoluteY, width, height))
|
||||
|
||||
for (children in children) {
|
||||
if (children.isOutsideOfParent) {
|
||||
result.addAll(children.calculateAbsoluteRectangles())
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Абсолютная координата, обновляется на отрисовке
|
||||
var absoluteX = 0f
|
||||
private set
|
||||
@ -445,7 +500,7 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
return false
|
||||
}
|
||||
|
||||
if ((boundingHeight > height || boundingWidth > width || boundingX < 0 || boundingY < 0) && parent == null) {
|
||||
if ((childrenRectHeight > height || childrenRectWidth > width || childrenRectX < 0 || childrenRectY < 0) && parent == null) {
|
||||
var hit = false
|
||||
|
||||
for (child in children) {
|
||||
@ -511,6 +566,46 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
return false to null
|
||||
}
|
||||
|
||||
fun findItemStack(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean = false): Pair<Boolean, ItemStack> {
|
||||
if (!isVisible()) {
|
||||
return false to ItemStack.EMPTY
|
||||
}
|
||||
|
||||
if (!acceptMouseInput && !ignoreMouseInputLock) {
|
||||
return (mouseX >= absoluteX &&
|
||||
mouseX <= absoluteX + width &&
|
||||
mouseY >= absoluteY &&
|
||||
mouseY <= absoluteY + height) to ItemStack.EMPTY
|
||||
}
|
||||
|
||||
if (trapMouseInput && this is IItemStackPanel) {
|
||||
return true to this.itemStack
|
||||
}
|
||||
|
||||
for (child in children) {
|
||||
val (status, itemStack) = child.findItemStack(mouseX, mouseY, ignoreMouseInputLock)
|
||||
|
||||
if (status) {
|
||||
return true to itemStack
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
mouseX >= absoluteX &&
|
||||
mouseX <= absoluteX + width &&
|
||||
mouseY >= absoluteY &&
|
||||
mouseY <= absoluteY + height
|
||||
) {
|
||||
if (this is IItemStackPanel) {
|
||||
return true to this.itemStack
|
||||
}
|
||||
|
||||
return true to ItemStack.EMPTY
|
||||
}
|
||||
|
||||
return false to ItemStack.EMPTY
|
||||
}
|
||||
|
||||
fun renderTooltips(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
|
||||
if (!isVisible()) {
|
||||
return false
|
||||
@ -717,19 +812,22 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
fun updateBounds() {
|
||||
boundsInvalidated = false
|
||||
|
||||
boundingX = 0f
|
||||
boundingY = 0f
|
||||
boundingWidth = 0f
|
||||
boundingHeight = 0f
|
||||
childrenRectX = width
|
||||
childrenRectY = height
|
||||
childrenRectWidth = 0f
|
||||
childrenRectHeight = 0f
|
||||
|
||||
for (child in children) {
|
||||
if (child.isVisible()) {
|
||||
boundingX = boundingX.coerceAtMost(child.x)
|
||||
boundingY = boundingY.coerceAtMost(child.y)
|
||||
boundingWidth = boundingWidth.coerceAtLeast(child.x + child.width)
|
||||
boundingHeight = boundingHeight.coerceAtLeast(child.y + child.height)
|
||||
childrenRectX = childrenRectX.coerceAtMost(child.x)
|
||||
childrenRectY = childrenRectY.coerceAtMost(child.y)
|
||||
childrenRectWidth = childrenRectWidth.coerceAtLeast(child.x + child.width)
|
||||
childrenRectHeight = childrenRectHeight.coerceAtLeast(child.y + child.height)
|
||||
}
|
||||
}
|
||||
|
||||
childrenRectX = childrenRectX.coerceAtMost(childrenRectWidth)
|
||||
childrenRectY = childrenRectY.coerceAtMost(childrenRectHeight)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -941,8 +1039,8 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
fun withinExtendedBounds(x: Double, y: Double): Boolean {
|
||||
val pos: ScreenPos = localToScreen(boundingX, boundingY)
|
||||
return pos.x <= x && pos.x + boundingWidth > x && pos.y <= y && pos.y + boundingHeight > y
|
||||
val pos: ScreenPos = localToScreen(childrenRectX, childrenRectY)
|
||||
return pos.x <= x && pos.x + childrenRectWidth > x && pos.y <= y && pos.y + childrenRectHeight > y
|
||||
}
|
||||
|
||||
fun killFocusForEverythingExcept(except: EditablePanel<*>) {
|
||||
|
@ -16,7 +16,7 @@ open class FilterSlotPanel<out S : MatteryScreen<*>> @JvmOverloads constructor(
|
||||
width: Float = SIZE,
|
||||
height: Float = SIZE
|
||||
) : AbstractSlotPanel<S>(screen, parent, x, y, width, height) {
|
||||
override fun getItemStack(): ItemStack {
|
||||
override val itemStack: ItemStack get() {
|
||||
return slot.get()
|
||||
}
|
||||
|
||||
|
@ -44,9 +44,8 @@ open class SlotPanel<out S : MatteryScreen<*>, T : Slot> @JvmOverloads construct
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getItemStack(): ItemStack {
|
||||
return slot.item
|
||||
}
|
||||
override val itemStack: ItemStack
|
||||
get() = slot.item
|
||||
|
||||
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||
renderSlotBackground(stack, mouseX, mouseY, partialTick)
|
||||
|
@ -3,20 +3,25 @@ package ru.dbotthepony.mc.otm.compat.jei
|
||||
import mezz.jei.api.IModPlugin
|
||||
import mezz.jei.api.JeiPlugin
|
||||
import mezz.jei.api.constants.RecipeTypes
|
||||
import mezz.jei.api.gui.handlers.IGuiContainerHandler
|
||||
import mezz.jei.api.helpers.IJeiHelpers
|
||||
import mezz.jei.api.registration.IGuiHandlerRegistration
|
||||
import mezz.jei.api.registration.IRecipeCatalystRegistration
|
||||
import mezz.jei.api.registration.IRecipeCategoryRegistration
|
||||
import mezz.jei.api.registration.IRecipeRegistration
|
||||
import net.minecraft.client.renderer.Rect2i
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.registry.MBlocks
|
||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||
import ru.dbotthepony.mc.otm.registry.MItems
|
||||
import ru.dbotthepony.mc.otm.registry.MRecipes
|
||||
import ru.dbotthepony.mc.otm.registry.WriteOnce
|
||||
import java.util.stream.Collectors
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
var helpers: IJeiHelpers by WriteOnce()
|
||||
var isJeiLoaded = false
|
||||
private set
|
||||
|
||||
@JeiPlugin
|
||||
@ -24,6 +29,13 @@ var helpers: IJeiHelpers by WriteOnce()
|
||||
class JEIPlugin : IModPlugin {
|
||||
companion object {
|
||||
private val LOCATION = ResourceLocation(OverdriveThatMatters.MOD_ID, "jei_plugin")
|
||||
|
||||
var helpers: IJeiHelpers by WriteOnce()
|
||||
private set
|
||||
}
|
||||
|
||||
init {
|
||||
isJeiLoaded = true
|
||||
}
|
||||
|
||||
override fun getPluginUid(): ResourceLocation {
|
||||
@ -45,4 +57,20 @@ class JEIPlugin : IModPlugin {
|
||||
|
||||
registration.addRecipes(PlatePressRecipeCategory.recipeType, level.recipeManager.getAllRecipesFor(MRecipes.PLATE_PRESS).filter { !it.isIncomplete })
|
||||
}
|
||||
|
||||
override fun registerGuiHandlers(registration: IGuiHandlerRegistration) {
|
||||
registration.addGenericGuiContainerHandler(MatteryScreen::class.java, object : IGuiContainerHandler<MatteryScreen<*>> {
|
||||
override fun getGuiExtraAreas(containerScreen: MatteryScreen<*>): MutableList<Rect2i> {
|
||||
return containerScreen.panelsView.stream().map { it.calculateAbsoluteRectangles() }.flatMap { it.stream() }.map { it.toIntRect() }.collect(Collectors.toList())
|
||||
}
|
||||
|
||||
override fun getIngredientUnderMouse(
|
||||
containerScreen: MatteryScreen<*>,
|
||||
mouseX: Double,
|
||||
mouseY: Double
|
||||
): Any? {
|
||||
return containerScreen.panelsView.stream().map { it.findItemStack(mouseX.toFloat(), mouseY.toFloat(), ignoreMouseInputLock = true) }.filter { it.first }.findAny().orElse(null)?.second
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ object PlatePressRecipeCategory : IRecipeCategory<PlatePressRecipe>, IDrawable {
|
||||
}
|
||||
|
||||
private val iconField by lazy {
|
||||
helpers.guiHelper.createDrawableItemStack(ItemStack(MItems.PLATE_PRESS))
|
||||
JEIPlugin.helpers.guiHelper.createDrawableItemStack(ItemStack(MItems.PLATE_PRESS))
|
||||
}
|
||||
|
||||
override fun getIcon(): IDrawable {
|
||||
|
Loading…
Reference in New Issue
Block a user