Iterate IGUIRenderable, update panels to accept IGUIRenderable where applicable
This commit is contained in:
parent
f9c1258afe
commit
b957378c60
@ -22,13 +22,13 @@ sealed class AbstractMatterySprite : IGUIRenderable {
|
||||
* Expected image width in pixels, used in calculations
|
||||
* and as default width argument in render methods
|
||||
*/
|
||||
abstract val width: Float
|
||||
abstract override val width: Float
|
||||
|
||||
/**
|
||||
* Expected image height in pixels, used in calculations
|
||||
* and as default height argument in render methods
|
||||
*/
|
||||
abstract val height: Float
|
||||
abstract override val height: Float
|
||||
|
||||
abstract val u0: Float
|
||||
abstract val v0: Float
|
||||
@ -45,7 +45,7 @@ sealed class AbstractMatterySprite : IGUIRenderable {
|
||||
|
||||
abstract val type: SpriteType
|
||||
|
||||
open val winding: UVWindingOrder get() = UVWindingOrder.NORMAL
|
||||
override val winding: UVWindingOrder get() = UVWindingOrder.NORMAL
|
||||
|
||||
abstract val texture: ResourceLocation
|
||||
|
||||
@ -76,23 +76,19 @@ sealed class AbstractMatterySprite : IGUIRenderable {
|
||||
renderRaw(stack, x, y, width, height, winding)
|
||||
}
|
||||
|
||||
fun render(
|
||||
graphics: GuiGraphics,
|
||||
x: Float = 0f,
|
||||
y: Float = 0f,
|
||||
width: Float = this.width,
|
||||
height: Float = this.height,
|
||||
winding: UVWindingOrder = this.winding
|
||||
override fun render(
|
||||
guiGraphics: GuiGraphics,
|
||||
x: Float,
|
||||
y: Float,
|
||||
width: Float,
|
||||
height: Float,
|
||||
winding: UVWindingOrder
|
||||
) {
|
||||
render(graphics.pose(), x, y, width, height, winding)
|
||||
render(guiGraphics.pose(), x, y, width, height, winding)
|
||||
}
|
||||
|
||||
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float) {
|
||||
return render(guiGraphics, x, y, width, height, winding)
|
||||
}
|
||||
|
||||
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, gravity: RenderGravity) {
|
||||
return render(guiGraphics, gravity.x(x, width), gravity.y(y, height), width, height, winding)
|
||||
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, gravity: RenderGravity, winding: UVWindingOrder) {
|
||||
render(guiGraphics.pose(), x, y, width, height, winding)
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
|
@ -4,23 +4,40 @@ import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
interface IGUIRenderable {
|
||||
fun render(guiGraphics: GuiGraphics, x: Float, y: Float, gravity: RenderGravity = RenderGravity.TOP_LEFT)
|
||||
/**
|
||||
* Expected width of this gui element, in pixels
|
||||
*/
|
||||
val width: Float
|
||||
|
||||
/**
|
||||
* Render at specified [x], [y] with fixed [width] x [height]
|
||||
* Expected height of this gui element, in pixels
|
||||
*/
|
||||
fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float)
|
||||
val height: Float
|
||||
|
||||
/**
|
||||
* Utilized only for purpose of default argument
|
||||
*/
|
||||
val winding: UVWindingOrder get() = UVWindingOrder.NORMAL
|
||||
|
||||
fun render(guiGraphics: GuiGraphics, x: Float = 0f, y: Float = 0f, gravity: RenderGravity = RenderGravity.TOP_LEFT, winding: UVWindingOrder = this.winding) {
|
||||
render(guiGraphics, gravity.x(x, width), gravity.y(y, height), width, height, winding)
|
||||
}
|
||||
|
||||
/**
|
||||
* Render at specified position [x], [y] with size of [width] x [height], optionally with UV [winding], if we are rendering flat texture/sprite
|
||||
*/
|
||||
fun render(guiGraphics: GuiGraphics, x: Float = 0f, y: Float = 0f, width: Float = this.width, height: Float = this.height, winding: UVWindingOrder = this.winding)
|
||||
|
||||
fun composeBefore(other: IGUIRenderable): IGUIRenderable {
|
||||
return object : IGUIRenderable {
|
||||
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, gravity: RenderGravity) {
|
||||
this@IGUIRenderable.render(guiGraphics, x, y, gravity)
|
||||
other.render(guiGraphics, x, y, gravity)
|
||||
}
|
||||
override val width: Float
|
||||
get() = this@IGUIRenderable.width.coerceAtLeast(other.width)
|
||||
override val height: Float
|
||||
get() = this@IGUIRenderable.height.coerceAtLeast(other.height)
|
||||
|
||||
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float) {
|
||||
this@IGUIRenderable.render(guiGraphics, x, y, width, height)
|
||||
other.render(guiGraphics, x, y, width, height)
|
||||
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, winding: UVWindingOrder) {
|
||||
this@IGUIRenderable.render(guiGraphics, x, y, width, height, winding)
|
||||
other.render(guiGraphics, x, y, width, height, winding)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -29,6 +46,53 @@ interface IGUIRenderable {
|
||||
return other.composeBefore(this)
|
||||
}
|
||||
|
||||
fun padded(left: Float, top: Float, right: Float, bottom: Float): IGUIRenderable {
|
||||
return object : IGUIRenderable {
|
||||
override val width: Float
|
||||
get() = this@IGUIRenderable.width
|
||||
override val height: Float
|
||||
get() = this@IGUIRenderable.height
|
||||
|
||||
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, winding: UVWindingOrder) {
|
||||
this@IGUIRenderable.render(guiGraphics, x + left, y + top, width + right + left, height + bottom + top, winding)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks argument values to default ones and aligns render position to center of render rectangle
|
||||
*
|
||||
* e.g. for example, if we want [ItemStackIcon] to always render as 16x16 pixels icon, even if required render
|
||||
* dimensions are bigger (e.g. 18x18), after calling [fix] on [ItemStackIcon] it will always render as 16x16 icon,
|
||||
* positioned on center of render canvas (e.g. rendering on +0+0 with 18x18 size will put icon at +1+1 and render as 16x16;
|
||||
* rendering on +0+0 with 32x32 canvas will put icon at +8+8 and render as 16x16)
|
||||
*/
|
||||
fun fixed(fixedWidth: Boolean = true, fixedHeight: Boolean = true, fixedWinding: Boolean = true): IGUIRenderable {
|
||||
if (!fixedHeight && !fixedWidth && !fixedWinding) return this
|
||||
|
||||
return object : IGUIRenderable {
|
||||
override val width: Float
|
||||
get() = this@IGUIRenderable.width
|
||||
override val height: Float
|
||||
get() = this@IGUIRenderable.height
|
||||
|
||||
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, winding: UVWindingOrder) {
|
||||
var realX = x
|
||||
var realY = y
|
||||
|
||||
if (fixedWidth && width > this.width) {
|
||||
realX += (width - this.width) / 2f
|
||||
}
|
||||
|
||||
if (fixedHeight && height > this.height) {
|
||||
realY += (height - this.height) / 2f
|
||||
}
|
||||
|
||||
this@IGUIRenderable.render(guiGraphics, realX, realY, if (fixedWidth) this.width else width, if (fixedHeight) this.height else height, if (fixedWinding) this.winding else winding)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun of(value: ItemStack, width: Float = 16f, height: Float = 16f): IGUIRenderable {
|
||||
return ItemStackIcon(value, width, height)
|
||||
@ -40,12 +104,8 @@ interface IGUIRenderable {
|
||||
}
|
||||
}
|
||||
|
||||
data class ItemStackIcon(private val itemStack: ItemStack, val width: Float = 16f, val height: Float = 16f) : IGUIRenderable {
|
||||
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, gravity: RenderGravity) {
|
||||
return render(guiGraphics, gravity.x(x, width), gravity.y(y, height), width, height)
|
||||
}
|
||||
|
||||
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float) {
|
||||
data class ItemStackIcon(private val itemStack: ItemStack, override val width: Float = 16f, override val height: Float = 16f) : IGUIRenderable {
|
||||
override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, winding: UVWindingOrder) {
|
||||
if (x % 1f == 0f && y % 1f == 0f && width == 16f && height == 16f) {
|
||||
guiGraphics.renderFakeItem(itemStack, x.toInt(), y.toInt())
|
||||
clearDepth(guiGraphics.pose(), x, y, width, height)
|
||||
|
@ -1,12 +1,11 @@
|
||||
package ru.dbotthepony.mc.otm.client.screen.panels.button
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.network.chat.Component
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.client.render.AbstractMatterySprite
|
||||
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||
@ -21,8 +20,8 @@ abstract class BooleanRectangleButtonPanel<out S : Screen>(
|
||||
width: Float,
|
||||
height: Float,
|
||||
val prop: GetterSetter<Boolean>,
|
||||
var skinElementActive: AbstractMatterySprite? = null,
|
||||
var skinElementInactive: AbstractMatterySprite? = null,
|
||||
var skinElementActive: IGUIRenderable? = null,
|
||||
var skinElementInactive: IGUIRenderable? = null,
|
||||
val onChange: ((newValue: Boolean) -> Unit)? = null,
|
||||
var tooltipActive: Component? = null,
|
||||
var tooltipInactive: Component? = null,
|
||||
|
@ -4,6 +4,8 @@ import com.mojang.blaze3d.platform.InputConstants
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
@ -12,6 +14,7 @@ import ru.dbotthepony.mc.otm.client.isCtrlDown
|
||||
import ru.dbotthepony.mc.otm.client.isShiftDown
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.client.render.AbstractMatterySprite
|
||||
import ru.dbotthepony.mc.otm.client.render.ItemStackIcon
|
||||
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
|
||||
@ -21,6 +24,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.util.GridPanel
|
||||
import ru.dbotthepony.mc.otm.config.ClientConfig
|
||||
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
@ -36,6 +40,11 @@ import java.util.function.Predicate
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.pow
|
||||
|
||||
private val gunpowder = ItemStackIcon(ItemStack(Items.GUNPOWDER)).fixed()
|
||||
private val barrier = ItemStackIcon(ItemStack(Items.BARRIER)).fixed()
|
||||
private val redstone = ItemStackIcon(ItemStack(Items.REDSTONE)).fixed()
|
||||
private val redstoneUnderBarrier = barrier.composeAfter(redstone).fixed()
|
||||
|
||||
private fun <S : MatteryScreen<*>> makeRedstoneSettingButton(
|
||||
screen: S,
|
||||
parent: EditablePanel<*>?,
|
||||
@ -53,9 +62,9 @@ private fun <S : MatteryScreen<*>> makeRedstoneSettingButton(
|
||||
set(value) {}
|
||||
|
||||
init {
|
||||
add(RedstoneSetting.IGNORED, tooltip = RedstoneSetting.IGNORED.description, skinElement = Widgets18.REDSTONE_IGNORED)
|
||||
add(RedstoneSetting.LOW, tooltip = RedstoneSetting.LOW.description, skinElement = Widgets18.REDSTONE_LOW)
|
||||
add(RedstoneSetting.HIGH, tooltip = RedstoneSetting.HIGH.description, skinElement = Widgets18.REDSTONE_HIGH)
|
||||
add(RedstoneSetting.IGNORED, tooltip = RedstoneSetting.IGNORED.description, skinElement = if (ClientConfig.REDSTONE_CONTROLS_ITEM_ICONS) gunpowder else Widgets18.REDSTONE_IGNORED)
|
||||
add(RedstoneSetting.LOW, tooltip = RedstoneSetting.LOW.description, skinElement = if (ClientConfig.REDSTONE_CONTROLS_ITEM_ICONS) redstoneUnderBarrier else Widgets18.REDSTONE_LOW)
|
||||
add(RedstoneSetting.HIGH, tooltip = RedstoneSetting.HIGH.description, skinElement = if (ClientConfig.REDSTONE_CONTROLS_ITEM_ICONS) redstone else Widgets18.REDSTONE_HIGH)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.network.chat.Component
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.client.render.AbstractMatterySprite
|
||||
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
|
||||
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||
@ -49,14 +50,14 @@ abstract class EnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
|
||||
|
||||
data class Entry<T : Enum<T>>(
|
||||
val key: T,
|
||||
val skinElement: AbstractMatterySprite?,
|
||||
val skinElement: IGUIRenderable?,
|
||||
val winding: UVWindingOrder = UVWindingOrder.NORMAL,
|
||||
val tooltip: Component? = null
|
||||
)
|
||||
|
||||
protected val enumMapping = EnumMap<T, Entry<T>>(enum)
|
||||
|
||||
fun add(key: T, skinElement: AbstractMatterySprite? = null, tooltip: Component? = null, winding: UVWindingOrder = UVWindingOrder.NORMAL): EnumRectangleButtonPanel<S, T> {
|
||||
fun add(key: T, skinElement: IGUIRenderable? = null, tooltip: Component? = null, winding: UVWindingOrder = UVWindingOrder.NORMAL): EnumRectangleButtonPanel<S, T> {
|
||||
return add(Entry(key = key, skinElement = skinElement, winding = winding, tooltip = tooltip))
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import com.mojang.blaze3d.vertex.PoseStack
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import ru.dbotthepony.mc.otm.client.render.AbstractMatterySprite
|
||||
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
|
||||
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
|
||||
import ru.dbotthepony.mc.otm.client.render.Widgets18
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||
@ -16,8 +17,8 @@ open class LargeRectangleButtonPanel<out S : Screen>(
|
||||
width: Float = SIZE,
|
||||
height: Float = SIZE,
|
||||
onPress: ((clickButton: Int) -> Unit)? = null,
|
||||
val skinElement: AbstractMatterySprite? = null,
|
||||
val skinElementWinding: UVWindingOrder? = null,
|
||||
var skinElement: IGUIRenderable? = null,
|
||||
var skinElementWinding: UVWindingOrder? = null,
|
||||
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height, onPress) {
|
||||
final override val IDLE = Widgets18.BUTTON_IDLE
|
||||
final override val HOVERED = Widgets18.BUTTON_HOVERED
|
||||
@ -28,7 +29,7 @@ open class LargeRectangleButtonPanel<out S : Screen>(
|
||||
super.innerRender(graphics, mouseX, mouseY, partialTick)
|
||||
|
||||
if (skinElementWinding != null) {
|
||||
skinElement?.render(graphics, width = width, height = height, winding = skinElementWinding)
|
||||
skinElement?.render(graphics, width = width, height = height, winding = skinElementWinding!!)
|
||||
} else {
|
||||
skinElement?.render(graphics, width = width, height = height)
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import ru.dbotthepony.mc.otm.client.playGuiClickSound
|
||||
import ru.dbotthepony.mc.otm.client.render.AbstractMatterySprite
|
||||
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||
import java.util.function.IntConsumer
|
||||
@ -19,10 +20,10 @@ abstract class RectangleButtonPanel<out S : Screen>(
|
||||
height: Float,
|
||||
var onPress: IntConsumer? = null,
|
||||
) : AbstractButtonPanel<S>(screen, parent, x, y, width, height) {
|
||||
abstract val PRESSED: AbstractMatterySprite
|
||||
abstract val HOVERED: AbstractMatterySprite
|
||||
abstract val IDLE: AbstractMatterySprite
|
||||
abstract val DISABLED: AbstractMatterySprite
|
||||
abstract val PRESSED: IGUIRenderable
|
||||
abstract val HOVERED: IGUIRenderable
|
||||
abstract val IDLE: IGUIRenderable
|
||||
abstract val DISABLED: IGUIRenderable
|
||||
|
||||
override fun onClick(mouseButton: Int) {
|
||||
onPress?.accept(mouseButton)
|
||||
|
@ -4,38 +4,28 @@ import net.minecraftforge.common.ForgeConfigSpec
|
||||
import net.minecraftforge.fml.ModLoadingContext
|
||||
import net.minecraftforge.fml.config.ModConfig
|
||||
|
||||
object ClientConfig {
|
||||
private val specBuilder = ForgeConfigSpec.Builder()
|
||||
@Suppress("JoinDeclarationAndAssignment")
|
||||
private val spec: ForgeConfigSpec
|
||||
private var registered = false
|
||||
|
||||
var ALWAYS_DISPLAY_MATTER_VALUE: Boolean by specBuilder
|
||||
object ClientConfig : AbstractConfig("client", ModConfig.Type.CLIENT) {
|
||||
var ALWAYS_DISPLAY_MATTER_VALUE: Boolean by builder
|
||||
.define("ALWAYS_DISPLAY_MATTER_VALUE", false)
|
||||
|
||||
var EXOPACK_INVENTORY_ROWS: Int by specBuilder
|
||||
var EXOPACK_INVENTORY_ROWS: Int by builder
|
||||
.comment("Amount of inventory rows to show when wearing Exosuit")
|
||||
.defineInRange("EXOPACK_INVENTORY_ROWS", 3, 3, 6)
|
||||
|
||||
var JUMP_BOOST_LOOK_ANGLE: Double by specBuilder
|
||||
var JUMP_BOOST_LOOK_ANGLE: Double by builder
|
||||
.comment("If looking below this angle (actually, looking 'above' as you see in game, but not as you expect it, check with debug screen), Crouch + Jump will trigger jump boost android ability")
|
||||
.defineInRange("JUMP_BOOST_LOOK_ANGLE", 30.0, -180.0, 180.0)
|
||||
|
||||
var EXOPACK_FREE_SCROLL: Boolean by specBuilder
|
||||
var EXOPACK_FREE_SCROLL: Boolean by builder
|
||||
.comment("Allow to scroll Exopack inventory in non OTM inventories when hovering just over inventory slots, not only scrollbar")
|
||||
.define("EXOPACK_FREE_SCROLL", true)
|
||||
|
||||
var ANDROID_HEALTH_HUD: Boolean by specBuilder
|
||||
var ANDROID_HEALTH_HUD: Boolean by builder
|
||||
.comment("Replace hearts with health bar on HUD when you are an android")
|
||||
.define("ANDROID_HEALTH_HUD", true)
|
||||
|
||||
init {
|
||||
spec = specBuilder.build()
|
||||
}
|
||||
|
||||
fun register() {
|
||||
check(!registered) { "Already registered config" }
|
||||
registered = true
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, spec)
|
||||
}
|
||||
var REDSTONE_CONTROLS_ITEM_ICONS: Boolean by builder
|
||||
.comment("Display redstone control button using items instead of custom sprites")
|
||||
.comment("For those who want it.")
|
||||
.define("REDSTONE_CONTROLS_ITEM_ICONS", false)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user