Compare commits

...

3 Commits

64 changed files with 972 additions and 863 deletions

View File

@ -853,6 +853,7 @@ private fun androidFeatures(provider: MatteryLanguageProvider) {
private fun gui(provider: MatteryLanguageProvider) {
with(provider.english) {
gui("draw_multiblock_guide", "Draw building guide")
gui("ago", "%s ago")
gui("time.short.5s", "5s")

View File

@ -857,6 +857,7 @@ private fun androidFeatures(provider: MatteryLanguageProvider) {
private fun gui(provider: MatteryLanguageProvider) {
with(provider.russian) {
gui("draw_multiblock_guide", "Отображать помощника постройки")
gui("ago", "%s тому назад")
gui("time.short.5s", "5с")

View File

@ -27,8 +27,8 @@ import ru.dbotthepony.mc.otm.client.screen.ExopackInventoryScreen
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.util.DiscreteScrollBarPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.Panel2Widget
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
import ru.dbotthepony.mc.otm.compat.vanilla.InventoryScrollPacket
import ru.dbotthepony.mc.otm.compat.cos.isCosmeticArmorScreen
import ru.dbotthepony.mc.otm.core.TranslatableComponent
@ -89,9 +89,9 @@ private fun inventoryLogic(event: ScreenEvent.Init.Post) {
val eventScreen = event.screen
val screen = if (eventScreen is AbstractContainerScreen<*> && (eventScreen.menu is InventoryMenu || eventScreen.isCosmeticArmorScreen)) eventScreen else return
val widget = Panel2Widget(LargeRectangleButtonPanel(screen, null,
x = screen.guiLeft + screen.xSize - 2f - LargeRectangleButtonPanel.SIZE,
y = screen.guiTop.toFloat() - LargeRectangleButtonPanel.SIZE - 2,
val widget = Panel2Widget(ButtonPanel.square18(screen, null,
x = screen.guiLeft + screen.xSize - 2f - 18f,
y = screen.guiTop.toFloat() - 18f - 2,
icon = Widgets18.RETURN_ARROW_LEFT,
iconWinding = UVWindingOrder.FLOP,
onPress = {
@ -108,8 +108,8 @@ private fun inventoryLogic(event: ScreenEvent.Init.Post) {
event.addListener(widget)
tickWhileClient({ minecraft.screen == screen }) {
widget.panel.x = screen.guiLeft + screen.xSize - 2f - LargeRectangleButtonPanel.SIZE
widget.panel.y = screen.guiTop.toFloat() - LargeRectangleButtonPanel.SIZE - 2f
widget.panel.x = screen.guiLeft + screen.xSize - 2f - 18f
widget.panel.y = screen.guiTop.toFloat() - 18f - 2f
}
}

View File

@ -1,14 +1,14 @@
package ru.dbotthepony.mc.otm.client.render
import net.minecraft.resources.ResourceLocation
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.client.render.sprites.MatteryAtlas
import ru.dbotthepony.mc.otm.core.ResourceLocation
object WidgetLocation {
val LARGE_BUTTON = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/large_button.png"), 72f, 18f)
val STORAGE_CONTROLS = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/storage_controls.png"), 90f, 72f)
val MISC_18 = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/misc18.png"), 72f, 72f)
val WIDGET_18 = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/widget_18.png"), 72f, 72f)
val WIDGET_15 = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/widget_15.png"), 60f, 60f)
val WIDGET_8 = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/widget_8.png"), 64f, 32f)
val SLOT_BACKGROUNDS = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/slot_backgrounds.png"), 72f, 72f)
val MISC = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/misc.png"), 64f, 64f)
@ -16,6 +16,7 @@ object WidgetLocation {
val PATTERN_PANEL_TABS = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/pattern_panel_tabs.png"), 60f, 23f)
val CHECKBOX = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/checkbox.png"), 30f, 60f)
val RADIO = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/radio.png"), 30f, 60f)
val PROGRESS_ARROWS = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/progress_arrows.png"), 22f, 31f)
val HORIZONTAL_GAUGES = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/horizontal_gauges.png"), 96f, 108f)
val VERTICAL_GAUGES = MatteryAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets/vertical_gauges.png"), 90f, 48f)

View File

@ -1,8 +1,6 @@
package ru.dbotthepony.mc.otm.client.render
object Widgets {
val SLOT = WidgetLocation.MISC.sprite(0f, 0f, 18f, 18f)
val ARROW_UP_BUTTON_IDLE = WidgetLocation.MISC.sprite(0f, 18f, 18f, 6f)
val ARROW_UP_BUTTON_HOVERED = WidgetLocation.MISC.sprite(0f, 18f + 6f, 18f, 6f)
val ARROW_UP_BUTTON_PRESSED = WidgetLocation.MISC.sprite(0f, 18f + 6f * 2f, 18f, 6f)

View File

@ -0,0 +1,19 @@
package ru.dbotthepony.mc.otm.client.render
object Widgets15 {
private val misc15 = WidgetLocation.WIDGET_15.grid(rows = 4, columns = 4)
val CHECKED = misc15.next()
val CHECKED_DISABLED = misc15.next()
val UNCHECKED = misc15.next()
val UNCHECKED_DISABLED = misc15.next()
val BUTTON_IDLE_STRETCHABLE = misc15.makeButton(2f)
val BUTTON_IDLE = misc15.next()
val BUTTON_HOVERED_STRETCHABLE = misc15.makeButton(2f)
val BUTTON_HOVERED = misc15.next()
val BUTTON_PRESSED_STRETCHABLE = misc15.makeButton(2f)
val BUTTON_PRESSED = misc15.next()
val BUTTON_DISABLED_STRETCHABLE = misc15.makeButton(2f)
val BUTTON_DISABLED = misc15.next()
}

View File

@ -2,42 +2,12 @@ package ru.dbotthepony.mc.otm.client.render
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
import ru.dbotthepony.mc.otm.capability.FlowDirection
import ru.dbotthepony.mc.otm.client.render.sprites.GridAtlas
import ru.dbotthepony.mc.otm.client.render.sprites.StretchingRectangleElement
import ru.dbotthepony.mc.otm.client.render.sprites.sprite
import ru.dbotthepony.mc.otm.core.immutableMap
import ru.dbotthepony.mc.otm.core.math.RelativeSide
private fun makeButton(grid: GridAtlas): StretchingRectangleElement {
val x = grid.currentX
val y = grid.currentY
return StretchingRectangleElement(
topLeft = grid.texture.sprite(x, y, 2f, 2f, grid.atlasWidth, grid.atlasHeight),
topRight = grid.texture.sprite(x + 16f, y, 2f, 2f, grid.atlasWidth, grid.atlasHeight),
bottomLeft = grid.texture.sprite(x, y + 16f, 2f, 2f, grid.atlasWidth, grid.atlasHeight),
bottomRight = grid.texture.sprite(x + 16f, y + 16f, 2f, 2f, grid.atlasWidth, grid.atlasHeight),
middle = grid.texture.sprite(x + 2f, y + 2f, 14f, 14f, grid.atlasWidth, grid.atlasHeight),
top = grid.texture.sprite(x + 2f, y, 14f, 2f, grid.atlasWidth, grid.atlasHeight),
left = grid.texture.sprite(x, y + 2f, 2f, 14f, grid.atlasWidth, grid.atlasHeight),
right = grid.texture.sprite(x + 16f, y + 2f, 2f, 14f, grid.atlasWidth, grid.atlasHeight),
bottom = grid.texture.sprite(x + 2f, y + 16f, 14f, 2f, grid.atlasWidth, grid.atlasHeight),
)
}
object Widgets18 {
private val buttonGrids = WidgetLocation.LARGE_BUTTON.grid(rows = 1, columns = 4)
val BUTTON_IDLE_STRETCHABLE = makeButton(buttonGrids)
val BUTTON_IDLE = buttonGrids.next()
val BUTTON_HOVERED_STRETCHABLE = makeButton(buttonGrids)
val BUTTON_HOVERED = buttonGrids.next()
val BUTTON_PRESSED_STRETCHABLE = makeButton(buttonGrids)
val BUTTON_PRESSED = buttonGrids.next()
val BUTTON_DISABLED_STRETCHABLE = makeButton(buttonGrids)
val BUTTON_DISABLED = buttonGrids.next()
private val storageGrid = WidgetLocation.STORAGE_CONTROLS.grid(rows = 4, columns = 5)
val SORT_DESCENDING = storageGrid.next()
val SORT_ASCENDING = storageGrid.next()
val SORT_DEFAULT = storageGrid.next()
@ -55,7 +25,16 @@ object Widgets18 {
val STOP = storageGrid.next()
val SORT_NOW = storageGrid.next()
private val miscGrid = WidgetLocation.MISC_18.grid(4, 4)
private val miscGrid = WidgetLocation.WIDGET_18.grid(4, 4)
val BUTTON_IDLE_STRETCHABLE = miscGrid.makeButton(2f)
val BUTTON_IDLE = miscGrid.next()
val BUTTON_HOVERED_STRETCHABLE = miscGrid.makeButton(2f)
val BUTTON_HOVERED = miscGrid.next()
val BUTTON_PRESSED_STRETCHABLE = miscGrid.makeButton(2f)
val BUTTON_PRESSED = miscGrid.next()
val BUTTON_DISABLED_STRETCHABLE = miscGrid.makeButton(2f)
val BUTTON_DISABLED = miscGrid.next()
val COOLDOWN = miscGrid.next()
val CROSS = miscGrid.next()

View File

@ -6,13 +6,18 @@ import ru.dbotthepony.mc.otm.client.render.sprites.GridAtlas
import ru.dbotthepony.mc.otm.core.ResourceLocation
object Widgets8 {
val GRID = GridAtlas(ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets_8.png"), 8f, 8f, columns = 64 / 8, rows = 32 / 8)
private val GRID = WidgetLocation.WIDGET_8.grid(columns = 8, rows = 4)
val BUTTON_IDLE = GRID[0, 0]
val BUTTON_HOVERED = GRID[0, 1]
val BUTTON_PRESSED = GRID[0, 2]
val BUTTON_DISABLED = GRID[0, 3]
val BUTTON_IDLE_STRETCHABLE = GRID.makeButton(2f, 0, 0)
val BUTTON_HOVERED_STRETCHABLE = GRID.makeButton(2f, 0, 1)
val BUTTON_PRESSED_STRETCHABLE = GRID.makeButton(2f, 0, 2)
val BUTTON_DISABLED_STRETCHABLE = GRID.makeButton(2f, 0, 3)
val WHITE_ARROW_DOWN = GRID[1, 0]
val S = GRID[2, 0]
val F = GRID[3, 0]

View File

@ -17,8 +17,8 @@ class BlackHoleGeneratorRenderer(private val context: BlockEntityRendererProvide
packedLight: Int,
packedOverlay: Int
) {
//if (!tile.drawBuildingGuide) return
val multiblock = tile.multiblock ?: return
multiblock.render(poseStack, DynamicBufferSource.WORLD, tile.blockPos)
if (tile.drawBuildingGuide) {
tile.multiblock?.render(poseStack, DynamicBufferSource.WORLD, tile.blockPos)
}
}
}

View File

@ -66,9 +66,10 @@ sealed class AbstractMatterySprite : IGUIRenderable, IUVCoords {
y: Float = 0f,
width: Float = this.width,
height: Float = this.height,
winding: UVWindingOrder = this.winding
winding: UVWindingOrder = this.winding,
color: RGBAColor = RGBAColor.WHITE
) {
renderTexturedRect(stack.last().pose(), x, y, width, height, uvWinding = winding, uv = this, texture = texture)
renderTexturedRect(stack.last().pose(), x, y, width, height, uvWinding = winding, uv = this, texture = texture, color = color)
}
override fun render(

View File

@ -53,6 +53,24 @@ data class GridAtlas(
return this
}
operator fun get(column: Int, row: Int) =
MatterySprite(texture, column * width, row * height, width, height, atlasWidth, atlasHeight)
operator fun get(column: Int, row: Int) = MatterySprite(texture, column * width, row * height, width, height, atlasWidth, atlasHeight)
fun makeButton(padding: Float, column: Int = this.column, row: Int = this.row): StretchingRectangleElement {
val x = column * width
val y = row * height
return StretchingRectangleElement(
topLeft = texture.sprite(x, y, padding, padding, atlasWidth, atlasHeight),
topRight = texture.sprite(x + width - padding, y, padding, padding, atlasWidth, atlasHeight),
bottomLeft = texture.sprite(x, y + height - padding, padding, padding, atlasWidth, atlasHeight),
bottomRight = texture.sprite(x + width - padding, y + height - padding, padding, padding, atlasWidth, atlasHeight),
middle = texture.sprite(x + padding, y + padding, width - padding * 2, height - padding * 2, atlasWidth, atlasHeight),
top = texture.sprite(x + padding, y, width - padding * 2, padding, atlasWidth, atlasHeight),
left = texture.sprite(x, y + padding, padding, height - padding * 2, atlasWidth, atlasHeight),
right = texture.sprite(x + width - padding, y + padding, padding, height - padding * 2, atlasWidth, atlasHeight),
bottom = texture.sprite(x + padding, y + height - padding, width - padding * 2, padding, atlasWidth, atlasHeight),
)
}
}

View File

@ -1,8 +1,10 @@
package ru.dbotthepony.mc.otm.client.render.sprites
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.resources.ResourceLocation
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty
data class StretchingRectangleElement(
@ -16,42 +18,41 @@ data class StretchingRectangleElement(
val bottom: AbstractMatterySprite,
val middle: AbstractMatterySprite,
val padding: DockProperty = DockProperty.EMPTY
) {
fun render(
stack: PoseStack,
x: Float = 0f,
y: Float = 0f,
width: Float,
height: Float,
) : IGUIRenderable {
override fun render(
guiGraphics: MGUIGraphics,
x: Float,
y: Float,
canvasWidth: Float,
canvasHeight: Float,
winding: UVWindingOrder,
color: RGBAColor,
) {
val bgWidth = width - topLeft.width.coerceAtMost(bottomLeft.width) - topRight.width.coerceAtMost(bottomRight.width) - padding.left - padding.right
val bgHeight = height - topLeft.height.coerceAtMost(bottomLeft.height) - topRight.height.coerceAtMost(bottomRight.height) - padding.top - padding.bottom
val bgWidth = canvasWidth - topLeft.width.coerceAtMost(bottomLeft.width) - topRight.width.coerceAtMost(bottomRight.width) - padding.left - padding.right
val bgHeight = canvasHeight - topLeft.height.coerceAtMost(bottomLeft.height) - topRight.height.coerceAtMost(bottomRight.height) - padding.top - padding.bottom
if (bgWidth > 0 && bgHeight > 0) {
middle.render(stack, x + topLeft.width + padding.left, y + topLeft.height + padding.top, bgWidth, bgHeight)
middle.render(guiGraphics, x + topLeft.width + padding.left, y + topLeft.height + padding.top, bgWidth, bgHeight, color = color)
}
top.render(stack, x + topLeft.width, y, width = width - topLeft.width - topRight.width)
bottom.render(stack, x + bottomLeft.width, y + height - bottom.height, width = width - bottomLeft.width - bottomRight.width)
top.render(guiGraphics, x + topLeft.width, y, canvasHeight = top.height, canvasWidth = canvasWidth - topLeft.width - topRight.width, color = color)
bottom.render(guiGraphics, x + bottomLeft.width, y + canvasHeight - bottom.height, canvasWidth = canvasWidth - bottomLeft.width - bottomRight.width, color = color)
left.render(stack, x, y + topLeft.height, height = height - topLeft.height - bottomLeft.height)
right.render(stack, x + width - right.width, y + topRight.height, height = height - topRight.height - bottomRight.height)
left.render(guiGraphics, x, y + topLeft.height, canvasHeight = canvasHeight - topLeft.height - bottomLeft.height, color = color)
right.render(guiGraphics, x + canvasWidth - right.width, y + topRight.height, canvasHeight = canvasHeight - topRight.height - bottomRight.height, color = color)
topLeft.render(stack, x, y)
topRight.render(stack, x + width - topRight.width, y)
topLeft.render(guiGraphics, x, y, color = color)
topRight.render(guiGraphics, x + canvasWidth - topRight.width, y, color = color)
bottomLeft.render(stack, x, y + height - bottomLeft.height)
bottomRight.render(stack, x + width - bottomRight.width, y + height - bottomLeft.height)
bottomLeft.render(guiGraphics, x, y + canvasHeight - bottomLeft.height, color = color)
bottomRight.render(guiGraphics, x + canvasWidth - bottomRight.width, y + canvasHeight - bottomLeft.height, color = color)
}
@JvmOverloads
fun render(
graphics: MGUIGraphics,
x: Float = 0f,
y: Float = 0f,
width: Float,
height: Float,
) = render(graphics.pose, x, y, width, height)
override val width: Float
get() = left.width + middle.width + right.width
override val height: Float
get() = top.height + middle.height + right.height
companion object {
fun square(

View File

@ -13,8 +13,8 @@ import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.client.render.sprites.sprite
import ru.dbotthepony.mc.otm.client.screen.panels.*
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.InventorySlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
@ -247,7 +247,7 @@ class ExopackInventoryScreen(menu: ExopackInventoryMenu) : MatteryScreen<Exopack
scrollPanel.dock = Dock.RIGHT
scrollPanel.setDockMargin(right = 3f)
val closeButtonPanel = LargeRectangleButtonPanel(this, frame, x = frame.width - 2f - LargeRectangleButtonPanel.SIZE, y = -LargeRectangleButtonPanel.SIZE - 2f, icon = Widgets18.RETURN_ARROW_LEFT, onPress = {
val closeButtonPanel = ButtonPanel.square18(this, frame, x = frame.width - 2f - 18f, y = -18f - 2f, icon = Widgets18.RETURN_ARROW_LEFT, onPress = {
shouldOpenVanillaInventory = true
val minecraft = minecraft!!

View File

@ -6,13 +6,13 @@ import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.ColorPickerPanel
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.input.NetworkedStringInputPanel
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeBooleanRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
import ru.dbotthepony.mc.otm.menu.decorative.HoloSignMenu
class HoloSignScreen(menu: HoloSignMenu, inventory: Inventory, title: Component) : MatteryScreen<HoloSignMenu>(menu, title) {
@ -31,26 +31,29 @@ class HoloSignScreen(menu: HoloSignMenu, inventory: Inventory, title: Component)
val controls = makeDeviceControls(this, frame, redstoneConfig = menu.redstone)
controls.addButton(object : LargeRectangleButtonPanel<HoloSignScreen>(this@HoloSignScreen, frame, onPress = {
frame.blockingWindow = ColorPickerPanel.frame(
this@HoloSignScreen,
callback = {
menu.textRed.accept(it.red)
menu.textGreen.accept(it.green)
menu.textBlue.accept(it.blue)
menu.textAlpha.accept(it.alpha)
},
color = RGBAColor(menu.textRed.value, menu.textGreen.value, menu.textBlue.value, menu.textAlpha.value),
isDisabled = { !menu.textRed.and(menu.textGreen).and(menu.textBlue).and(menu.textAlpha).test(minecraft?.player) },
title = TranslatableComponent("otm.gui.change_color"))
}) {
init {
tooltips.add(TranslatableComponent("otm.gui.change_color"))
icon = Widgets18.COLOR_PALETTE
controls.addButton(ButtonPanel.square18(
this@HoloSignScreen,
frame,
icon = Widgets18.COLOR_PALETTE,
onPress = {
frame.blockingWindow = ColorPickerPanel.frame(
this@HoloSignScreen,
callback = {
menu.textRed.accept(it.red)
menu.textGreen.accept(it.green)
menu.textBlue.accept(it.blue)
menu.textAlpha.accept(it.alpha)
},
color = RGBAColor(menu.textRed.value, menu.textGreen.value, menu.textBlue.value, menu.textAlpha.value),
isDisabled = { !menu.textRed.and(menu.textGreen).and(menu.textBlue).and(menu.textAlpha).test(minecraft?.player) },
title = TranslatableComponent("otm.gui.change_color")
)
}
).also {
it.tooltips.add(TranslatableComponent("otm.gui.change_color"))
})
controls.addButton(LargeBooleanRectangleButtonPanel(
controls.addButton(BooleanButtonPanel.square18(
this@HoloSignScreen,
frame,
prop = menu.textAutoScale,
@ -60,7 +63,7 @@ class HoloSignScreen(menu: HoloSignMenu, inventory: Inventory, title: Component)
tooltipInactive = TranslatableComponent("otm.gui.holo_screen.do_not_resize_text"),
))
controls.addButton(LargeBooleanRectangleButtonPanel(
controls.addButton(BooleanButtonPanel.square18(
this@HoloSignScreen,
frame,
prop = menu.locked,

View File

@ -3,32 +3,31 @@ package ru.dbotthepony.mc.otm.client.screen.decorative
import net.minecraft.ChatFormatting
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.network.chat.Component
import net.minecraft.util.RandomSource
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.neoforged.neoforge.common.Tags
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.block.entity.decorative.PainterBlockEntity
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.render.FlatRectangleIcon
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
import ru.dbotthepony.mc.otm.client.render.ItemStackIcon
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
import ru.dbotthepony.mc.otm.client.screen.panels.DockResizeMode
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.RectangleButtonPanel
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.ScrollableCanvasPanel
import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.map
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.core.util.CreativeMenuItemComparator
import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu
@ -114,7 +113,7 @@ class PainterScreen(menu: PainterMenu, inventory: Inventory, title: Component) :
val column = EditablePanel(this, frame)
column.dock = Dock.FILL
val bulk = CheckBoxLabelInputPanel(this, column, menu.isBulk, TranslatableComponent("otm.gui.painter.is_bulk"))
val bulk = BooleanButtonPanel.Checkbox(this, column, menu.isBulk, TranslatableComponent("otm.gui.painter.is_bulk"))
bulk.dock = Dock.BOTTOM
bulk.tooltips.add(TranslatableComponent("otm.gui.painter.is_bulk.desc"))
bulk.tooltips.add(TranslatableComponent("otm.gui.painter.is_bulk.desc2").withStyle(ChatFormatting.GRAY))
@ -124,7 +123,7 @@ class PainterScreen(menu: PainterMenu, inventory: Inventory, title: Component) :
canvas.dock = Dock.FILL
canvas.dockPaddingBottom = 4f
val buttons = ArrayList<RectangleButtonPanel<PainterScreen>>()
val buttons = ArrayList<ButtonPanel<PainterScreen>>()
menu.listeners.addListener(Runnable {
if (frame.isRemoved) return@Runnable
@ -143,13 +142,15 @@ class PainterScreen(menu: PainterMenu, inventory: Inventory, title: Component) :
for (recipe in recipes) {
val recipeOutput = recipe.value.getOutput(menu.inputContainer)
object : LargeRectangleButtonPanel<PainterScreen>(this@PainterScreen, canvas.canvas, icon = ItemStackIcon(recipeOutput, 14f, 14f).fixed()) {
object : ButtonPanel<PainterScreen>(this@PainterScreen, canvas.canvas) {
init {
buttons.add(this)
dockRight = 1f
dockBottom = 1f
}
override val icon: IGUIRenderable = ItemStackIcon(recipeOutput, 14f, 14f).fixed()
override var isDisabled: Boolean
get() = !recipe.value.canCraft(menu.dyeStoredDirect)
set(value) {}

View File

@ -40,7 +40,7 @@ class MatterBottlerScreen(menu: MatterBottlerMenu, inventory: Inventory, title:
progress = ProgressGaugePanel(this, frame, menu.progressWidget, 90f, PROGRESS_ARROW_TOP)
if (minecraft?.player?.isSpectator != true) {
ButtonPanel(this, frame, 46f, 69f, 100f, 20f, TranslatableComponent("otm.matter_bottler.switch_mode"), onPress = menu.workFlow::switchValue)
ButtonPanel.Simple(this, frame, 46f, 69f, 100f, 20f, TranslatableComponent("otm.matter_bottler.switch_mode"), onPress = menu.workFlow::switchValue)
}
makeDeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, upgrades = menu.upgrades)

View File

@ -14,8 +14,6 @@ import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.*
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeBooleanRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.input.TextInputPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.util.DiscreteScrollBarPanel
@ -24,6 +22,7 @@ import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel
import ru.dbotthepony.mc.otm.core.math.integerDivisionDown
import ru.dbotthepony.mc.otm.core.util.ItemSorter
import ru.dbotthepony.mc.otm.core.util.formatMatter
@ -62,10 +61,10 @@ class MatterPanelScreen(
}
controls.addButton(
LargeBooleanRectangleButtonPanel(
BooleanButtonPanel.square18(
this,
frame,
prop = Delegate.Of(menu::isProvidingTasks),
prop = menu.isProvidingTasks,
iconActive = Widgets18.PLAY,
iconInactive = Widgets18.PAUSE,
tooltipActive = TranslatableComponent("otm.gui.matter_panel.is_providing_tasks"),
@ -74,7 +73,7 @@ class MatterPanelScreen(
)
controls.addButton(
LargeRectangleButtonPanel(
ButtonPanel.square18(
this,
frame,
icon = Widgets18.STOP,
@ -284,13 +283,13 @@ class MatterPanelScreen(
}
}
ButtonPanel(this@MatterPanelScreen, frame, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.close"), onPress = frame::remove).also {
ButtonPanel.Simple(this@MatterPanelScreen, frame, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.close"), onPress = frame::remove).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}
if (minecraft?.player?.isSpectator != true) {
ButtonPanel(this@MatterPanelScreen, frame, width = 80f, label = TranslatableComponent("otm.gui.matter_panel.cancel_task"), onPress = Runnable {
ButtonPanel.Simple(this@MatterPanelScreen, frame, width = 80f, label = TranslatableComponent("otm.gui.matter_panel.cancel_task"), onPress = Runnable {
menu.requestTaskCancel(task.id)
frame.remove()
}).also {
@ -399,42 +398,42 @@ class MatterPanelScreen(
}
}
ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.increase_by", 8), onPress = Runnable { input.increase(8) }).also {
ButtonPanel.Simple(this, rowTop, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.increase_by", 8), onPress = Runnable { input.increase(8) }).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}
ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.increase_by", 64), onPress = Runnable { input.increase(64) }).also {
ButtonPanel.Simple(this, rowTop, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.increase_by", 64), onPress = Runnable { input.increase(64) }).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}
ButtonPanel(this, rowTop, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.increase_by", 256), onPress = Runnable { input.increase(256) }).also {
ButtonPanel.Simple(this, rowTop, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.increase_by", 256), onPress = Runnable { input.increase(256) }).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}
ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.decrease_by", 8), onPress = Runnable { input.increase(-8) }).also {
ButtonPanel.Simple(this, rowBottom, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.decrease_by", 8), onPress = Runnable { input.increase(-8) }).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}
ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.decrease_by", 64), onPress = Runnable { input.increase(-64) }).also {
ButtonPanel.Simple(this, rowBottom, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.decrease_by", 64), onPress = Runnable { input.increase(-64) }).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}
ButtonPanel(this, rowBottom, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.decrease_by", 256), onPress = Runnable { input.increase(-256) }).also {
ButtonPanel.Simple(this, rowBottom, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.decrease_by", 256), onPress = Runnable { input.increase(-256) }).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}
ButtonPanel(this, rowControls, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.cancel"), onPress = frame::remove).also {
ButtonPanel.Simple(this, rowControls, width = 40f, label = TranslatableComponent("otm.gui.matter_panel.cancel"), onPress = frame::remove).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}
ButtonPanel(this, rowControls, width = 82f, label = TranslatableComponent("otm.gui.matter_panel.send"), onPress = input::send).also {
ButtonPanel.Simple(this, rowControls, width = 82f, label = TranslatableComponent("otm.gui.matter_panel.send"), onPress = input::send).also {
it.dock = Dock.RIGHT
it.dockLeft = 2f
}

View File

@ -14,14 +14,12 @@ import ru.dbotthepony.mc.otm.client.render.sprites.sprite
import ru.dbotthepony.mc.otm.client.screen.ExopackInventoryScreen
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.SmallBooleanRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.SmallRectangleButtonPanel
import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleRenderButton
import ru.dbotthepony.mc.otm.compat.cos.isCosmeticArmorLoaded
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel
import ru.dbotthepony.mc.otm.network.DisableExopackGlowPacket
import ru.dbotthepony.mc.otm.network.DisplayExopackPacket
import ru.dbotthepony.mc.otm.network.EnableExopackGlowPacket
@ -53,11 +51,11 @@ private fun createExopackAppearanceWindow(screen: MatteryScreen<*>, matteryPlaye
frame.behaveAsWindow()
frame.requestFocus()
CheckBoxLabelPanel(
BooleanButtonPanel.Checkbox(
screen,
frame,
text = TranslatableComponent("otm.gui.exopack.toggle_visibility"),
isChecked = Delegate.Of(
label = TranslatableComponent("otm.gui.exopack.toggle_visibility"),
prop = Delegate.Of(
{
matteryPlayer.isExopackVisible
},
@ -74,11 +72,11 @@ private fun createExopackAppearanceWindow(screen: MatteryScreen<*>, matteryPlaye
it.dockTop = 2f
}
CheckBoxLabelPanel(
BooleanButtonPanel.Checkbox(
screen,
frame,
text = TranslatableComponent("otm.gui.exopack.toggle_glow"),
isChecked = Delegate.Of(
label = TranslatableComponent("otm.gui.exopack.toggle_glow"),
prop = Delegate.Of(
{
matteryPlayer.exopackGlows
},
@ -95,7 +93,7 @@ private fun createExopackAppearanceWindow(screen: MatteryScreen<*>, matteryPlaye
it.dockTop = 2f
}
ButtonPanel(screen, frame, label = TranslatableComponent("otm.gui.exopack.change_color"), onPress = IntConsumer {
ButtonPanel.Simple(screen, frame, label = TranslatableComponent("otm.gui.exopack.change_color"), onPress = IntConsumer {
frame.blockingWindow = ColorPickerPanel.frame(
screen,
callback = { PacketDistributor.sendToServer(SetExopackColorPacket(it)) },
@ -106,7 +104,7 @@ private fun createExopackAppearanceWindow(screen: MatteryScreen<*>, matteryPlaye
it.dockTop = 2f
}
ButtonPanel(screen, frame, label = TranslatableComponent("otm.gui.exopack.change_color2"), onPress = IntConsumer { PacketDistributor.sendToServer(ResetExopackColorPacket) }).also {
ButtonPanel.Simple(screen, frame, label = TranslatableComponent("otm.gui.exopack.change_color2"), onPress = IntConsumer { PacketDistributor.sendToServer(ResetExopackColorPacket) }).also {
it.dock = Dock.TOP
it.dockTop = 2f
}
@ -148,9 +146,9 @@ class EntityRendererPanel<out S : Screen> @JvmOverloads constructor(
if (entity is Player) {
val matteryPlayer = entity.matteryPlayer
if (matteryPlayer != null && matteryPlayer.hasExopack && screen is MatteryScreen<*>) {
exosuitButton = SmallRectangleButtonPanel(screen, this, this.width - 2f - SmallBooleanRectangleButtonPanel.SIZE, 2f,
skinElement = Widgets8.EXOPACK_SHOWN,
if (matteryPlayer.hasExopack && screen is MatteryScreen<*>) {
exosuitButton = ButtonPanel.square8(screen, this, this.width - 2f - 8f, 2f,
icon = Widgets8.EXOPACK_SHOWN,
onPress = {
blockingWindow = createExopackAppearanceWindow(screen, matteryPlayer)
}

View File

@ -395,7 +395,7 @@ open class FramePanel<out S : Screen>(
}
override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
RECTANGLE.render(graphics, width = width, height = height)
RECTANGLE.render(graphics, canvasWidth = width, canvasHeight = height)
// title
val title = title ?: return

View File

@ -8,6 +8,9 @@ import ru.dbotthepony.mc.otm.client.playGuiClickSound
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import java.util.function.IntPredicate
/**
* Barebones "button" base panel, representing anything remotely clickable
*/
abstract class AbstractButtonPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,

View File

@ -1,29 +0,0 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.client.gui.screens.Screen
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.Label
import kotlin.math.roundToInt
abstract class AbstractCheckBoxLabelPanel<out S : Screen> @JvmOverloads constructor(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = CheckBoxPanel.REGULAR_DIMENSIONS + 120f,
height: Float = CheckBoxPanel.REGULAR_DIMENSIONS
) : EditablePanel<S>(screen, parent, x, y, width, height) {
abstract val checkbox: CheckBoxPanel<S>
abstract val label: Label<S>
override fun performLayout() {
super.performLayout()
checkbox.x = dockPadding.left
checkbox.y = dockPadding.top + (height / 2f - checkbox.height / 2f).roundToInt().toFloat()
label.x = checkbox.x + checkbox.width + 4f
label.y = ((height - dockPadding.top - dockPadding.bottom) / 2f - font.lineHeight / 2f).roundToInt().toFloat()
label.width = width - checkbox.width - dockPadding.right
}
}

View File

@ -0,0 +1,288 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.ChatFormatting
import net.minecraft.client.gui.screens.Screen
import net.minecraft.network.chat.Component
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.kommons.util.value
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.render.Widgets15
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback
abstract class BooleanButtonPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float,
height: Float,
) : ButtonPanel<S>(screen, parent, x, y, width, height) {
protected abstract fun onChange(newValue: Boolean)
abstract var isChecked: Boolean
abstract val tooltipActive: Component?
abstract val tooltipInactive: Component?
abstract val iconActive: IGUIRenderable?
abstract val iconInactive: IGUIRenderable?
open val iconDisabledActive: IGUIRenderable?
get() = iconActive
open val iconDisabledInactive: IGUIRenderable?
get() = iconInactive
override val icon: IGUIRenderable?
get() = if (isChecked) {
if (isDisabled) iconDisabledActive else iconActive
} else {
if (isDisabled) iconDisabledInactive else iconInactive
}
override fun onClick(mouseButton: Int) {
val newValue = !isChecked
isChecked = newValue
onChange(newValue)
}
override fun innerRenderTooltips(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
if (isHovered) {
val tooltipActive = tooltipActive
val tooltipInactive = tooltipInactive
if (tooltipActive != null || tooltipInactive != null || tooltips.isNotEmpty()) {
val tooltips = ArrayList<Component>(2 + this.tooltips.size)
if (this.tooltips.isNotEmpty()) {
tooltips.addAll(this.tooltips)
if (tooltipActive != null || tooltipInactive != null)
tooltips.add(SPACE)
}
if (tooltipActive != null) {
if (isChecked)
tooltips.add(TranslatableComponent("otm.gui.tooltip.enum.active", tooltipActive.copy().withStyle(ChatFormatting.WHITE)))
else
tooltips.add(tooltipActive.copy().withStyle(ChatFormatting.GRAY))
}
if (tooltipInactive != null) {
if (isChecked)
tooltips.add(tooltipInactive.copy().withStyle(ChatFormatting.GRAY))
else
tooltips.add(TranslatableComponent("otm.gui.tooltip.enum.active", tooltipInactive.copy().withStyle(ChatFormatting.WHITE)))
}
graphics.renderComponentTooltip(font, tooltips, mouseX.toInt(), mouseY.toInt())
}
}
return super.innerRenderTooltips(graphics, mouseX, mouseY, partialTick)
}
open class Checkbox<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
val prop: Delegate<Boolean>,
) : BooleanButtonPanel<S>(screen, parent, x, y, 15f, 15f) {
constructor(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
prop: Delegate<Boolean>,
label: Component
) : this(screen, parent, x, y, prop) {
width = font.width(label) + 24f
height = 18f
this.label = label
}
constructor(
screen: S,
parent: EditablePanel<*>?,
prop: Delegate<Boolean>,
label: Component
) : this(screen, parent, 0f, 0f, prop, label)
constructor(
screen: S,
parent: EditablePanel<*>?,
prop: Delegate<Boolean>,
) : this(screen, parent, 0f, 0f, prop)
override fun onChange(newValue: Boolean) {
// do nothing
}
var displayUncheckedIcon = true
override var label: Component? = null
override var isChecked: Boolean
get() = prop.get()
set(value) { prop.accept(value) }
override var labelColor: RGBAColor = RGBAColor.WHITE
override val iconWinding: UVWindingOrder
get() = UVWindingOrder.NORMAL
override var iconOnLeft: Boolean = true
override val iconSpaceReservation: SpaceReservation = SpaceReservation.ICON_AND_TEXT
override var isDisabled: Boolean
get() {
if (prop is IPlayerInputWithFeedback<Boolean>) {
return !prop.test(minecraft.player!!)
} else {
return super.isDisabled
}
}
set(value) { super.isDisabled = value }
override var tooltipActive: Component? = null
override val tooltipInactive: Component? = null
override val iconActive: IGUIRenderable
get() = Widgets15.CHECKED
override val iconInactive: IGUIRenderable?
get() = if (displayUncheckedIcon) Widgets15.UNCHECKED else null
override val iconDisabledActive: IGUIRenderable
get() = Widgets15.CHECKED_DISABLED
override val iconDisabledInactive: IGUIRenderable?
get() = if (displayUncheckedIcon) Widgets15.UNCHECKED_DISABLED else null
}
open class Simple<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float,
height: Float,
val prop: Delegate<Boolean>,
override var iconActive: IGUIRenderable? = null,
override var iconInactive: IGUIRenderable? = null,
val onChange: ((newValue: Boolean) -> Unit)? = null,
override var tooltipActive: Component? = null,
override var tooltipInactive: Component? = null,
) : BooleanButtonPanel<S>(screen, parent, x, y, width, height) {
override fun onChange(newValue: Boolean) {
// do nothing
}
override var label: Component? = null
override var isChecked: Boolean
get() = prop.get()
set(value) { prop.accept(value) }
override var labelColor: RGBAColor = RGBAColor.WHITE
override var iconWinding: UVWindingOrder = UVWindingOrder.NORMAL
override var iconOnLeft: Boolean = true
override val iconSpaceReservation: SpaceReservation = SpaceReservation.DEFAULT
override var isDisabled: Boolean
get() {
if (prop is IPlayerInputWithFeedback<Boolean>) {
return !prop.test(minecraft.player!!)
} else {
return super.isDisabled
}
}
set(value) { super.isDisabled = value }
}
companion object {
private val SPACE = TextComponent("")
fun <S : Screen> square18(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
prop: Delegate<Boolean>,
iconActive: IGUIRenderable? = null,
iconInactive: IGUIRenderable? = null,
onChange: ((newValue: Boolean) -> Unit)? = null,
tooltipActive: Component? = null,
tooltipInactive: Component? = null,
): Simple<S> {
return Simple(screen, parent, x, y, 18f, 18f, prop, iconActive, iconInactive, onChange, tooltipActive, tooltipInactive)
}
fun <S : Screen> square15(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
prop: Delegate<Boolean>,
iconActive: IGUIRenderable? = null,
iconInactive: IGUIRenderable? = null,
onChange: ((newValue: Boolean) -> Unit)? = null,
tooltipActive: Component? = null,
tooltipInactive: Component? = null,
): Simple<S> {
return Simple(screen, parent, x, y, 15f, 15f, prop, iconActive, iconInactive, onChange, tooltipActive, tooltipInactive)
}
fun <S : Screen> square8(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
prop: Delegate<Boolean>,
iconActive: IGUIRenderable? = null,
iconInactive: IGUIRenderable? = null,
onChange: ((newValue: Boolean) -> Unit)? = null,
tooltipActive: Component? = null,
tooltipInactive: Component? = null,
): Simple<S> {
return Simple(screen, parent, x, y, 8f, 8f, prop, iconActive, iconInactive, onChange, tooltipActive, tooltipInactive)
}
fun <S : Screen> square18(
screen: S,
parent: EditablePanel<*>?,
prop: Delegate<Boolean>,
iconActive: IGUIRenderable? = null,
iconInactive: IGUIRenderable? = null,
onChange: ((newValue: Boolean) -> Unit)? = null,
tooltipActive: Component? = null,
tooltipInactive: Component? = null,
): Simple<S> {
return Simple(screen, parent, 0f, 0f, 18f, 18f, prop, iconActive, iconInactive, onChange, tooltipActive, tooltipInactive)
}
fun <S : Screen> square15(
screen: S,
parent: EditablePanel<*>?,
prop: Delegate<Boolean>,
iconActive: IGUIRenderable? = null,
iconInactive: IGUIRenderable? = null,
onChange: ((newValue: Boolean) -> Unit)? = null,
tooltipActive: Component? = null,
tooltipInactive: Component? = null,
): Simple<S> {
return Simple(screen, parent, 0f, 0f, 15f, 15f, prop, iconActive, iconInactive, onChange, tooltipActive, tooltipInactive)
}
fun <S : Screen> square8(
screen: S,
parent: EditablePanel<*>?,
prop: Delegate<Boolean>,
iconActive: IGUIRenderable? = null,
iconInactive: IGUIRenderable? = null,
onChange: ((newValue: Boolean) -> Unit)? = null,
tooltipActive: Component? = null,
tooltipInactive: Component? = null,
): Simple<S> {
return Simple(screen, parent, 0f, 0f, 8f, 8f, prop, iconActive, iconInactive, onChange, tooltipActive, tooltipInactive)
}
}
}

View File

@ -1,95 +0,0 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.ChatFormatting
import net.minecraft.client.gui.screens.Screen
import net.minecraft.network.chat.Component
import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.kommons.util.value
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.minecraft
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 ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback
abstract class BooleanRectangleButtonPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float,
height: Float,
val prop: Delegate<Boolean>,
var iconActive: IGUIRenderable? = null,
var iconInactive: IGUIRenderable? = null,
val onChange: ((newValue: Boolean) -> Unit)? = null,
var tooltipActive: Component? = null,
var tooltipInactive: Component? = null,
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height, null) {
override fun onClick(mouseButton: Int) {
val newValue = !prop.value
prop.value = newValue
onChange?.invoke(newValue)
}
override fun innerRenderTooltips(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
if (isHovered) {
val tooltipActive = tooltipActive
val tooltipInactive = tooltipInactive
if (tooltipActive != null || tooltipInactive != null || tooltips.isNotEmpty()) {
val tooltips = ArrayList<Component>(2 + this.tooltips.size)
if (this.tooltips.isNotEmpty()) {
tooltips.addAll(this.tooltips)
if (tooltipActive != null || tooltipInactive != null)
tooltips.add(SPACE)
}
if (tooltipActive != null) {
if (prop.get())
tooltips.add(TranslatableComponent("otm.gui.tooltip.enum.active", tooltipActive.copy().withStyle(ChatFormatting.WHITE)))
else
tooltips.add(tooltipActive.copy().withStyle(ChatFormatting.GRAY))
}
if (tooltipInactive != null) {
if (prop.get())
tooltips.add(tooltipInactive.copy().withStyle(ChatFormatting.GRAY))
else
tooltips.add(TranslatableComponent("otm.gui.tooltip.enum.active", tooltipInactive.copy().withStyle(ChatFormatting.WHITE)))
}
graphics.renderComponentTooltip(font, tooltips, mouseX.toInt(), mouseY.toInt())
}
}
return super.innerRenderTooltips(graphics, mouseX, mouseY, partialTick)
}
override var isDisabled: Boolean
get() {
if (prop is IPlayerInputWithFeedback<Boolean>) {
return !prop.test(minecraft.player!!)
} else {
return super.isDisabled
}
}
set(value) { super.isDisabled = value }
override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
super.innerRender(graphics, mouseX, mouseY, partialTick)
if (prop.value) {
iconActive?.render(graphics, canvasWidth = width, canvasHeight = height)
} else {
iconInactive?.render(graphics, canvasWidth = width, canvasHeight = height)
}
}
companion object {
private val SPACE = TextComponent("")
}
}

View File

@ -7,62 +7,269 @@ import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.render.Widgets15
import ru.dbotthepony.mc.otm.client.render.Widgets8
import java.util.function.IntConsumer
import kotlin.math.min
open class ButtonPanel<out S : Screen>(
/**
* Base button panel, representing traditional buttons, extending [AbstractButtonPanel]
*/
abstract class ButtonPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = 40f,
height: Float = HEIGHT,
var label: Component,
var onPress: IntConsumer? = null
) : AbstractButtonPanel<S>(screen, parent, x, y, width, height) {
constructor(screen: S, parent: EditablePanel<*>?, label: Component, onPress: IntConsumer? = null) : this(screen, parent, x = 0f, label = label, onPress = onPress)
open val labelColor: RGBAColor
get() = RGBAColor.WHITE
open val label: Component?
get() = null
open val icon: IGUIRenderable?
get() = null
open val iconWinding: UVWindingOrder
get() = UVWindingOrder.NORMAL
open val iconOnLeft: Boolean
get() = true
open val iconSpaceReservation: SpaceReservation
get() = SpaceReservation.DEFAULT
constructor(
enum class SpaceReservation {
/**
* Don't reserve space, icon pushes text only when present
*/
DEFAULT,
/**
* Space for icon is always reserved
*/
ICON_AND_TEXT,
/**
* Consider only icon will be present, and align it according to [RenderGravity.CENTER_CENTER].
*
* Having both icon and text will result in undefined behavior
*/
ICON_ONLY;
}
protected open val disabledSprite: IGUIRenderable
get() = if (width >= 18f && height >= 18f)
Widgets18.BUTTON_DISABLED_STRETCHABLE
else if (width >= 15f && height >= 15f)
Widgets15.BUTTON_DISABLED_STRETCHABLE
else
Widgets8.BUTTON_DISABLED_STRETCHABLE
protected open val pressedSprite: IGUIRenderable
get() = if (width >= 18f && height >= 18f)
Widgets18.BUTTON_PRESSED_STRETCHABLE
else if (width >= 15f && height >= 15f)
Widgets15.BUTTON_PRESSED_STRETCHABLE
else
Widgets8.BUTTON_PRESSED_STRETCHABLE
protected open val hoveredSprite: IGUIRenderable
get() = if (width >= 18f && height >= 18f)
Widgets18.BUTTON_HOVERED_STRETCHABLE
else if (width >= 15f && height >= 15f)
Widgets15.BUTTON_HOVERED_STRETCHABLE
else
Widgets8.BUTTON_HOVERED_STRETCHABLE
protected open val idleSprite: IGUIRenderable
get() = if (width >= 18f && height >= 18f)
Widgets18.BUTTON_IDLE_STRETCHABLE
else if (width >= 15f && height >= 15f)
Widgets15.BUTTON_IDLE_STRETCHABLE
else
Widgets8.BUTTON_IDLE_STRETCHABLE
protected open fun renderBackground(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
if (isDisabled) {
disabledSprite.render(graphics, canvasWidth = width, canvasHeight = height)
} else if (isPressed) {
pressedSprite.render(graphics, canvasWidth = width, canvasHeight = height)
} else if (isHovered) {
hoveredSprite.render(graphics, canvasWidth = width, canvasHeight = height)
} else {
idleSprite.render(graphics, canvasWidth = width, canvasHeight = height)
}
}
override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
renderBackground(graphics, mouseX, mouseY, partialTick)
val label = label
val icon = icon
if (label != null) {
if (icon == null && iconSpaceReservation == SpaceReservation.DEFAULT) {
graphics.draw(label, width / 2f, height / 2f, color = labelColor, gravity = RenderGravity.CENTER_CENTER)
} else {
val lWidth = font.width(label).toFloat()
val min = min(width, height)
if (width / 2f - lWidth / 2f >= min + 1f) {
// text to center
graphics.draw(label, width / 2f, height / 2f, color = labelColor, gravity = RenderGravity.CENTER_CENTER)
} else if (iconOnLeft) {
graphics.draw(label, min + 1f, height / 2f, color = labelColor, gravity = RenderGravity.CENTER_LEFT)
} else {
graphics.draw(label, 1f, height / 2f, color = labelColor, gravity = RenderGravity.CENTER_LEFT)
}
}
}
if (icon != null) {
if (iconSpaceReservation != SpaceReservation.ICON_ONLY) {
val size = min(width, height)
if (iconOnLeft) {
icon.render(graphics, 0f, 0f, size, size, winding = iconWinding)
} else {
icon.render(graphics, width - size, 0f, size, size, winding = iconWinding)
}
} else {
icon.render(graphics, 0f, 0f, width, height, winding = iconWinding)
}
}
}
override fun sizeToContents(performLayout: Boolean) {
super.sizeToContents(performLayout)
val label = label
if (label != null) {
height = height.coerceAtLeast(HEIGHT).coerceAtLeast(font.lineHeight.toFloat() + 2f)
width = width.coerceAtLeast(HEIGHT).coerceAtLeast(font.width(label) + 4f)
}
}
open class Simple<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = 40f,
height: Float = HEIGHT,
label: Component,
onPress: Runnable
) : this(screen, parent, x, y, width, height, label, onPress = IntConsumer { onPress.run() })
override var label: Component?,
var onPress: IntConsumer? = null
) : ButtonPanel<S>(screen, parent, x, y, width, height) {
constructor(screen: S, parent: EditablePanel<*>?, label: Component, onPress: IntConsumer? = null) : this(screen, parent, x = 0f, label = label, onPress = onPress)
var textColor = RGBAColor.WHITE
constructor(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = 40f,
height: Float = HEIGHT,
label: Component,
onPress: Runnable
) : this(screen, parent, x, y, width, height, label, onPress = IntConsumer { onPress.run() })
override fun onClick(mouseButton: Int) {
onPress?.accept(mouseButton)
}
protected fun renderStretchableBackground(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
if (isDisabled) {
Widgets18.BUTTON_DISABLED_STRETCHABLE.render(graphics, width = width, height = height)
} else if (isPressed) {
Widgets18.BUTTON_PRESSED_STRETCHABLE.render(graphics, width = width, height = height)
} else if (isHovered) {
Widgets18.BUTTON_HOVERED_STRETCHABLE.render(graphics, width = width, height = height)
} else {
Widgets18.BUTTON_IDLE_STRETCHABLE.render(graphics, width = width, height = height)
override fun onClick(mouseButton: Int) {
onPress?.accept(mouseButton)
}
}
override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
renderStretchableBackground(graphics, mouseX, mouseY, partialTick)
graphics.draw(label, width / 2f, height / 2f, color = textColor, gravity = RenderGravity.CENTER_CENTER)
}
override fun sizeToContents(performLayout: Boolean) {
super.sizeToContents(performLayout)
height = height.coerceAtLeast(HEIGHT).coerceAtLeast(font.lineHeight.toFloat() + 2f)
width = width.coerceAtLeast(HEIGHT).coerceAtLeast(font.width(label) + 4f)
override var labelColor: RGBAColor = RGBAColor.WHITE
override var icon: IGUIRenderable? = null
override var iconOnLeft: Boolean = true
override var iconSpaceReservation = SpaceReservation.DEFAULT
override var iconWinding: UVWindingOrder = UVWindingOrder.NORMAL
}
companion object {
const val HEIGHT = 18f
fun <S : Screen> square18(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
icon: IGUIRenderable? = null,
iconWinding: UVWindingOrder = UVWindingOrder.NORMAL,
onPress: IntConsumer? = null
): Simple<S> {
return Simple(screen, parent, x, y, 18f, 18f, null, onPress).also {
it.icon = icon
it.iconWinding = iconWinding
}
}
fun <S : Screen> square15(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
icon: IGUIRenderable? = null,
iconWinding: UVWindingOrder = UVWindingOrder.NORMAL,
onPress: IntConsumer? = null
): Simple<S> {
return Simple(screen, parent, x, y, 15f, 15f, null, onPress).also {
it.icon = icon
it.iconWinding = iconWinding
}
}
fun <S : Screen> square8(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
icon: IGUIRenderable? = null,
iconWinding: UVWindingOrder = UVWindingOrder.NORMAL,
onPress: IntConsumer? = null
): Simple<S> {
return Simple(screen, parent, x, y, 8f, 8f, null, onPress).also {
it.icon = icon
it.iconWinding = iconWinding
}
}
fun <S : Screen> square18(
screen: S,
parent: EditablePanel<*>?,
icon: IGUIRenderable? = null,
iconWinding: UVWindingOrder = UVWindingOrder.NORMAL,
onPress: IntConsumer? = null
): Simple<S> {
return Simple(screen, parent, 0f, 0f, 18f, 18f, null, onPress).also {
it.icon = icon
it.iconWinding = iconWinding
}
}
fun <S : Screen> square15(
screen: S,
parent: EditablePanel<*>?,
icon: IGUIRenderable? = null,
iconWinding: UVWindingOrder = UVWindingOrder.NORMAL,
onPress: IntConsumer? = null
): Simple<S> {
return Simple(screen, parent, 0f, 0f, 15f, 15f, null, onPress).also {
it.icon = icon
it.iconWinding = iconWinding
}
}
fun <S : Screen> square8(
screen: S,
parent: EditablePanel<*>?,
icon: IGUIRenderable? = null,
iconWinding: UVWindingOrder = UVWindingOrder.NORMAL,
onPress: IntConsumer? = null
): Simple<S> {
return Simple(screen, parent, 0f, 0f, 8f, 8f, null, onPress).also {
it.icon = icon
it.iconWinding = iconWinding
}
}
}
}

View File

@ -5,6 +5,7 @@ import net.minecraft.ChatFormatting
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.kommons.util.value
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
@ -16,8 +17,10 @@ import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
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.IGUIRenderable
import ru.dbotthepony.mc.otm.client.render.sprites.AbstractMatterySprite
import ru.dbotthepony.mc.otm.client.render.ItemStackIcon
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
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
@ -40,6 +43,7 @@ import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput
import ru.dbotthepony.mc.otm.menu.input.FluidConfigPlayerInput
import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
import java.util.function.IntConsumer
import java.util.function.Predicate
import kotlin.math.ceil
import kotlin.math.pow
@ -55,11 +59,11 @@ private fun <S : MatteryScreen<*>> makeRedstoneSettingButton(
x: Float = 0f,
y: Float = 0f,
control: IPlayerInputWithFeedback<RedstoneSetting>
): LargeEnumRectangleButtonPanel<S, RedstoneSetting> {
return object : LargeEnumRectangleButtonPanel<S, RedstoneSetting>(
): EnumButtonPanel<S, RedstoneSetting> {
return object : EnumButtonPanel<S, RedstoneSetting>(
screen, parent, x = x, y = y,
defaultValue = RedstoneSetting.LOW, enum = RedstoneSetting::class.java,
prop = control,
prop = control, height = 18f, width = 18f,
) {
override var isDisabled: Boolean
get() = !control.test(minecraft.player!!)
@ -83,7 +87,7 @@ private class PullPushButton<out S : MatteryScreen<*>, T : Enum<T>>(
defaultValue: T,
val pullProp: BooleanInputWithFeedback,
val pushProp: BooleanInputWithFeedback
) : LargeEnumRectangleButtonPanel<S, T>(screen, parent, x = x, y = y, enum = enum, prop = prop, defaultValue = defaultValue) {
) : EnumButtonPanel<S, T>(screen, parent, x = x, y = y, enum = enum, prop = prop, width = 18f, height = 18f, defaultValue = defaultValue) {
init {
if (pullProp.test(minecraft.player!!)) {
tooltips.add(TranslatableComponent("otm.gui.sides.pull_help").withStyle(ChatFormatting.GRAY))
@ -121,11 +125,11 @@ private class PullPushButton<out S : MatteryScreen<*>, T : Enum<T>>(
}
}
private fun <S : MatteryScreen<*>> makeItemModeButton(screen: S, parent: FramePanel<S>, input: ItemConfigPlayerInput.Piece, side: RelativeSide): LargeEnumRectangleButtonPanel<S, MatteryDeviceBlockEntity.ItemHandlerMode> {
private fun <S : MatteryScreen<*>> makeItemModeButton(screen: S, parent: FramePanel<S>, input: ItemConfigPlayerInput.Piece, side: RelativeSide): EnumButtonPanel<S, MatteryDeviceBlockEntity.ItemHandlerMode> {
val button = PullPushButton(screen, parent, enum = MatteryDeviceBlockEntity.ItemHandlerMode::class.java, prop = input.input, defaultValue = input.default, pullProp = input.pull, pushProp = input.push)
val widgets = Widgets18.CONTROLS[side]!!
for (v in MatteryDeviceBlockEntity.ItemHandlerMode.values()) {
for (v in MatteryDeviceBlockEntity.ItemHandlerMode.entries) {
button.add(v, tooltip = TranslatableComponent(v.translationKey))
button.addSprite(false, false, v, widgets.items[v]!!)
button.addSprite(true, false, v, widgets.itemsPull[v]!!)
@ -139,11 +143,11 @@ private fun <S : MatteryScreen<*>> makeItemModeButton(screen: S, parent: FramePa
return button
}
private fun <S : MatteryScreen<*>> makeEnergyModeButton(screen: S, parent: FramePanel<S>, input: EnergyConfigPlayerInput.Piece, side: RelativeSide): LargeEnumRectangleButtonPanel<S, FlowDirection> {
private fun <S : MatteryScreen<*>> makeEnergyModeButton(screen: S, parent: FramePanel<S>, input: EnergyConfigPlayerInput.Piece, side: RelativeSide): EnumButtonPanel<S, FlowDirection> {
val button = PullPushButton(screen, parent, enum = FlowDirection::class.java, prop = input.input, defaultValue = input.default, pullProp = input.pull, pushProp = input.push)
val widgets = Widgets18.CONTROLS[side]!!
for (v in FlowDirection.values()) {
for (v in FlowDirection.entries) {
button.add(v, tooltip = TranslatableComponent(v.translationKey))
button.addSprite(false, false, v, widgets.flow[v]!!)
button.addSprite(true, false, v, widgets.flowPull[v]!!)
@ -162,11 +166,11 @@ private fun <S : MatteryScreen<*>> makeEnergyModeButton(screen: S, parent: Frame
return button
}
private fun <S : MatteryScreen<*>> makeFluidModeButton(screen: S, parent: FramePanel<S>, input: FluidConfigPlayerInput.Piece, side: RelativeSide): LargeEnumRectangleButtonPanel<S, FlowDirection> {
private fun <S : MatteryScreen<*>> makeFluidModeButton(screen: S, parent: FramePanel<S>, input: FluidConfigPlayerInput.Piece, side: RelativeSide): EnumButtonPanel<S, FlowDirection> {
val button = PullPushButton(screen, parent, enum = FlowDirection::class.java, prop = input.input, defaultValue = input.default, pullProp = input.pull, pushProp = input.push)
val widgets = Widgets18.CONTROLS[side]!!
for (v in FlowDirection.values()) {
for (v in FlowDirection.entries) {
button.add(v, tooltip = TranslatableComponent(v.translationKey))
button.addSprite(false, false, v, widgets.flow[v]!!)
button.addSprite(true, false, v, widgets.flowPull[v]!!)
@ -311,12 +315,12 @@ class DeviceControls<out S : MatteryScreen<*>>(
val balanceInputs: BooleanInputWithFeedback? = null,
val upgrades: UpgradeSlots? = null,
) : EditablePanel<S>(screen, parent, x = parent.width + 3f, height = 0f, width = 0f) {
val itemConfigButton: LargeRectangleButtonPanel<S>?
val energyConfigButton: LargeRectangleButtonPanel<S>?
val fluidConfigButton: LargeRectangleButtonPanel<S>?
val redstoneControlsButton: LargeEnumRectangleButtonPanel<S, RedstoneSetting>?
val balanceInputsButton: LargeBooleanRectangleButtonPanel<S>?
val upgradesButton: LargeRectangleButtonPanel<S>?
val itemConfigButton: ButtonPanel<S>?
val energyConfigButton: ButtonPanel<S>?
val fluidConfigButton: ButtonPanel<S>?
val redstoneControlsButton: EnumButtonPanel<S, RedstoneSetting>?
val balanceInputsButton: BooleanButtonPanel<S>?
val upgradesButton: ButtonPanel<S>?
init {
childrenOrder = -1000
@ -374,7 +378,7 @@ class DeviceControls<out S : MatteryScreen<*>>(
}
fun addStorageMode(prop: Delegate<FlowDirection>) {
val mode = LargeEnumRectangleButtonPanel(screen, this, prop = prop, defaultValue = FlowDirection.BI_DIRECTIONAL, enum = FlowDirection::class.java)
val mode = EnumButtonPanel.square18(screen, this, prop = prop, defaultValue = FlowDirection.BI_DIRECTIONAL, enum = FlowDirection::class.java)
mode.add(FlowDirection.INPUT, Widgets18.ONLY_STORE, FlowDirection.INPUT.title)
mode.add(FlowDirection.OUTPUT, Widgets18.ONLY_EXTRACT, FlowDirection.OUTPUT.title)
@ -384,10 +388,10 @@ class DeviceControls<out S : MatteryScreen<*>>(
addButton(mode)
}
inline fun <reified T : Enum<T>> sortingButtons(ascending: Delegate<Boolean>, sorting: Delegate<T>, default: T, configurator: LargeEnumRectangleButtonPanel<S, T>.() -> Unit): List<EditablePanel<S>> {
inline fun <reified T : Enum<T>> sortingButtons(ascending: Delegate<Boolean>, sorting: Delegate<T>, default: T, configurator: EnumButtonPanel<S, T>.() -> Unit): List<EditablePanel<S>> {
val result = ArrayList<EditablePanel<S>>()
LargeBooleanRectangleButtonPanel(
BooleanButtonPanel.square18(
screen,
this,
prop = ascending,
@ -400,7 +404,7 @@ class DeviceControls<out S : MatteryScreen<*>>(
result.add(it)
}
LargeEnumRectangleButtonPanel(screen, this, enum = T::class.java, prop = sorting, defaultValue = default).also {
EnumButtonPanel.square18(screen, this, enum = T::class.java, prop = sorting, defaultValue = default).also {
prependButton(it)
configurator.invoke(it)
it.finish()
@ -411,7 +415,7 @@ class DeviceControls<out S : MatteryScreen<*>>(
}
fun sortingButtons(input: MatteryMenu.SortInput, unfoldableSettings: Boolean = true) {
object : LargeRectangleButtonPanel<S>(screen, this@DeviceControls) {
object : ButtonPanel<S>(screen, this@DeviceControls, width = 18f, height = 18f) {
var buttons: List<EditablePanel<*>>? = null
init {
@ -421,9 +425,6 @@ class DeviceControls<out S : MatteryScreen<*>>(
tooltips.add(TextComponent(""))
tooltips.add(TranslatableComponent("otm.gui.sorting.sort_settings").withStyle(ChatFormatting.GRAY))
}
icon = Widgets18.SORT_NOW
addButton(this)
if (!unfoldableSettings) {
@ -431,6 +432,9 @@ class DeviceControls<out S : MatteryScreen<*>>(
}
}
override val icon: IGUIRenderable
get() = Widgets18.SORT_NOW
override fun test(value: Int): Boolean {
return value == InputConstants.MOUSE_BUTTON_LEFT || unfoldableSettings && value == InputConstants.MOUSE_BUTTON_RIGHT
}
@ -479,14 +483,16 @@ class DeviceControls<out S : MatteryScreen<*>>(
}
if (upgrades != null) {
upgradesButton = addButton(object : LargeRectangleButtonPanel<S>(
upgradesButton = addButton(object : ButtonPanel<S>(
screen, this@DeviceControls,
icon = Widgets18.UPGRADES
) {
init {
tooltips.add(TranslatableComponent("otm.gui.upgrades"))
}
override val icon: IGUIRenderable
get() = Widgets18.UPGRADES
override fun innerRenderTooltips(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
graphics.renderComponentTooltip(font, ArrayList<Component>().also {
it.add(TranslatableComponent("otm.gui.upgrades"))
@ -559,7 +565,7 @@ class DeviceControls<out S : MatteryScreen<*>>(
}
if (balanceInputs != null) {
balanceInputsButton = addButton(LargeBooleanRectangleButtonPanel(
balanceInputsButton = addButton(BooleanButtonPanel.square18(
screen, this,
prop = balanceInputs,
iconActive = Widgets18.BALANCING_ENABLED,
@ -571,12 +577,11 @@ class DeviceControls<out S : MatteryScreen<*>>(
}
if (itemConfig != null) {
itemConfigButton = addButton(object : LargeRectangleButtonPanel<S>(screen, this@DeviceControls, icon = Widgets18.ITEMS_CONFIGURATION) {
init {
tooltips.add(TranslatableComponent("otm.gui.sides.item_config"))
}
override fun onClick(mouseButton: Int) {
itemConfigButton = addButton(ButtonPanel.square18(
screen,
this@DeviceControls,
icon = Widgets18.ITEMS_CONFIGURATION,
onPress = IntConsumer { mouseButton ->
if (mouseButton == InputConstants.MOUSE_BUTTON_LEFT) {
val frame = makeItemHandlerControlPanel(screen, itemConfig)
@ -584,18 +589,19 @@ class DeviceControls<out S : MatteryScreen<*>>(
frame.y = absoluteY + height + 8f
}
}
).also {
tooltips.add(TranslatableComponent("otm.gui.sides.item_config"))
})
} else {
itemConfigButton = null
}
if (energyConfig != null) {
energyConfigButton = addButton(object : LargeRectangleButtonPanel<S>(screen, this@DeviceControls, icon = Widgets18.ENERGY_CONFIGURATION) {
init {
tooltips.add(TranslatableComponent("otm.gui.sides.energy_config"))
}
override fun onClick(mouseButton: Int) {
energyConfigButton = addButton(ButtonPanel.square18(
screen,
this@DeviceControls,
icon = Widgets18.ENERGY_CONFIGURATION,
onPress = IntConsumer { mouseButton ->
if (mouseButton == InputConstants.MOUSE_BUTTON_LEFT) {
val frame = makeEnergyConfigPanel(screen, energyConfig)
@ -603,18 +609,19 @@ class DeviceControls<out S : MatteryScreen<*>>(
frame.y = absoluteY + height + 8f
}
}
).also {
tooltips.add(TranslatableComponent("otm.gui.sides.energy_config"))
})
} else {
energyConfigButton = null
}
if (fluidConfig != null) {
fluidConfigButton = addButton(object : LargeRectangleButtonPanel<S>(screen, this@DeviceControls, icon = Widgets18.FLUID_CONFIGURATION) {
init {
tooltips.add(TranslatableComponent("otm.gui.sides.fluid_config"))
}
override fun onClick(mouseButton: Int) {
fluidConfigButton = addButton(ButtonPanel.square18(
screen,
this@DeviceControls,
icon = Widgets18.FLUID_CONFIGURATION,
onPress = IntConsumer { mouseButton ->
if (mouseButton == InputConstants.MOUSE_BUTTON_LEFT) {
val frame = makeFluidConfigPanel(screen, fluidConfig)
@ -622,6 +629,8 @@ class DeviceControls<out S : MatteryScreen<*>>(
frame.y = absoluteY + height + 8f
}
}
).also {
tooltips.add(TranslatableComponent("otm.gui.sides.fluid_config"))
})
} else {
fluidConfigButton = null

View File

@ -1,20 +0,0 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.client.gui.screens.Screen
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback
open class CheckBoxInputPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
val widget: IPlayerInputWithFeedback<Boolean>,
x: Float = 0f,
y: Float = 0f,
width: Float = REGULAR_DIMENSIONS + 120f,
height: Float = REGULAR_DIMENSIONS
) : CheckBoxPanel<S>(screen, parent, x, y, width, height, isChecked = widget) {
override var isDisabled: Boolean
get() = !widget.test(minecraft.player!!)
set(value) {}
}

View File

@ -1,24 +0,0 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.client.gui.screens.Screen
import net.minecraft.network.chat.Component
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.Label
import ru.dbotthepony.mc.otm.menu.input.BooleanInputWithFeedback
import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback
import kotlin.math.roundToInt
open class CheckBoxLabelInputPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
val widget: IPlayerInputWithFeedback<Boolean>,
text: Component,
x: Float = 0f,
y: Float = 0f,
width: Float = CheckBoxPanel.REGULAR_DIMENSIONS + 120f,
height: Float = CheckBoxPanel.REGULAR_DIMENSIONS
) : AbstractCheckBoxLabelPanel<S>(screen, parent, x, y, width, height) {
override val checkbox = CheckBoxInputPanel(screen = screen, parent = this, widget = widget, x = 0f, y = 0f, width = CheckBoxPanel.REGULAR_DIMENSIONS, height = CheckBoxPanel.REGULAR_DIMENSIONS)
override val label = Label(screen, this, CheckBoxPanel.REGULAR_DIMENSIONS + 4f, 4f, text = text)
}

View File

@ -1,21 +0,0 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.client.gui.screens.Screen
import net.minecraft.network.chat.Component
import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.Label
open class CheckBoxLabelPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
text: Component,
x: Float = 0f,
y: Float = 0f,
width: Float = CheckBoxPanel.REGULAR_DIMENSIONS + 120f,
height: Float = CheckBoxPanel.REGULAR_DIMENSIONS,
isChecked: Delegate<Boolean> = Delegate.Box(false)
) : AbstractCheckBoxLabelPanel<S>(screen, parent, x, y, width, height) {
override val checkbox = CheckBoxPanel(screen, this, 0f, 0f, isChecked = isChecked)
override val label = Label(screen, this, CheckBoxPanel.REGULAR_DIMENSIONS + 4f, 4f, text = text)
}

View File

@ -1,92 +0,0 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.client.gui.screens.Screen
import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.render.sprites.AbstractMatterySprite
import ru.dbotthepony.mc.otm.client.render.WidgetLocation
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
open class CheckBoxPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = REGULAR_DIMENSIONS,
height: Float = REGULAR_DIMENSIONS,
open val isChecked: Delegate<Boolean> = Delegate.Box(false)
) : AbstractButtonPanel<S>(screen, parent, x, y, width, height) {
open val IDLE_UNCHECKED: AbstractMatterySprite = Companion.IDLE_UNCHECKED
open val IDLE_CHECKED: AbstractMatterySprite = Companion.IDLE_CHECKED
open val HOVERED_UNCHECKED: AbstractMatterySprite = Companion.HOVERED_UNCHECKED
open val HOVERED_CHECKED: AbstractMatterySprite = Companion.HOVERED_CHECKED
open val PRESSED_UNCHECKED: AbstractMatterySprite = Companion.PRESSED_UNCHECKED
open val PRESSED_CHECKED: AbstractMatterySprite = Companion.PRESSED_CHECKED
open val DISABLED_UNCHECKED: AbstractMatterySprite = Companion.DISABLED_UNCHECKED
open val DISABLED_CHECKED: AbstractMatterySprite = Companion.DISABLED_CHECKED
protected fun renderCheckboxBackground(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
if (isDisabled) {
if (isChecked.get()) {
DISABLED_CHECKED.render(graphics, canvasWidth = width, canvasHeight = height)
} else {
DISABLED_UNCHECKED.render(graphics, canvasWidth = width, canvasHeight = height)
}
} else {
if (isPressed) {
if (isChecked.get()) {
PRESSED_CHECKED.render(graphics, canvasWidth = width, canvasHeight = height)
} else {
PRESSED_UNCHECKED.render(graphics, canvasWidth = width, canvasHeight = height)
}
} else if (isHovered) {
if (isChecked.get()) {
HOVERED_CHECKED.render(graphics, canvasWidth = width, canvasHeight = height)
} else {
HOVERED_UNCHECKED.render(graphics, canvasWidth = width, canvasHeight = height)
}
} else {
if (isChecked.get()) {
IDLE_CHECKED.render(graphics, canvasWidth = width, canvasHeight = height)
} else {
IDLE_UNCHECKED.render(graphics, canvasWidth = width, canvasHeight = height)
}
}
}
}
override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
renderCheckboxBackground(graphics, mouseX, mouseY, partialTick)
}
override fun onClick(mouseButton: Int) {
isChecked.accept(!isChecked.get())
}
companion object {
const val REGULAR_DIMENSIONS = 15f
val IDLE_UNCHECKED: AbstractMatterySprite
val IDLE_CHECKED: AbstractMatterySprite
val HOVERED_UNCHECKED: AbstractMatterySprite
val HOVERED_CHECKED: AbstractMatterySprite
val PRESSED_UNCHECKED: AbstractMatterySprite
val PRESSED_CHECKED: AbstractMatterySprite
val DISABLED_UNCHECKED: AbstractMatterySprite
val DISABLED_CHECKED: AbstractMatterySprite
init {
val grid = WidgetLocation.CHECKBOX.grid(columns = 2, rows = 4)
IDLE_CHECKED = grid.next()
IDLE_UNCHECKED = grid.next()
HOVERED_CHECKED = grid.next()
HOVERED_UNCHECKED = grid.next()
PRESSED_CHECKED = grid.next()
PRESSED_UNCHECKED = grid.next()
DISABLED_CHECKED = grid.next()
DISABLED_UNCHECKED = grid.next()
}
}
}

View File

@ -4,10 +4,12 @@ import com.mojang.blaze3d.platform.InputConstants
import net.minecraft.ChatFormatting
import net.minecraft.client.gui.screens.Screen
import net.minecraft.network.chat.Component
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.kommons.util.value
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.playGuiClickSound
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
@ -18,7 +20,7 @@ import java.util.*
import java.util.function.Predicate
import kotlin.collections.ArrayList
abstract class EnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
open class EnumButtonPanel<out S : Screen, T : Enum<T>>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
@ -28,7 +30,7 @@ abstract class EnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
enum: Class<T>,
val prop: Delegate<T>,
val defaultValue: T,
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height, null) {
) : ButtonPanel<S>(screen, parent, x, y, width, height) {
val enum = MatteryStreamCodec.Enum.searchClass(enum)
private val constants: Array<T> = enum.enumConstants
private var isBuilding = true
@ -44,27 +46,48 @@ abstract class EnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
}
set(value) { super.isDisabled = value }
override val labelColor: RGBAColor
get() = RGBAColor.WHITE
override val label: Component?
get() = enumMapping[prop.get()]?.label
override val icon: IGUIRenderable?
get() = if (isDisabled) enumMapping[prop.get()]?.skinElementDisabled else enumMapping[prop.get()]?.skinElement
override var iconOnLeft: Boolean = true
override val iconSpaceReservation: SpaceReservation
get() = if (enumMapping.values.any { it.skinElement != null }) SpaceReservation.ICON_AND_TEXT else SpaceReservation.DEFAULT
override val iconWinding: UVWindingOrder
get() = enumMapping[prop.get()]?.winding ?: UVWindingOrder.NORMAL
data class Entry<T : Enum<T>>(
val key: T,
val skinElement: IGUIRenderable?,
val skinElementDisabled: IGUIRenderable? = skinElement,
val winding: UVWindingOrder = UVWindingOrder.NORMAL,
val tooltip: Component? = null
val tooltip: Component? = null,
val label: Component? = null,
)
protected val enumMapping = EnumMap<T, Entry<T>>(enum)
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))
fun add(
key: T,
skinElement: IGUIRenderable? = null,
tooltip: Component? = null,
label: Component? = null,
skinElementDisabled: IGUIRenderable? = skinElement,
winding: UVWindingOrder = UVWindingOrder.NORMAL
): EnumButtonPanel<S, T> {
return add(Entry(key = key, skinElement = skinElement, winding = winding, tooltip = tooltip, label = label, skinElementDisabled = skinElementDisabled))
}
fun add(entry: Entry<T>): EnumRectangleButtonPanel<S, T> {
fun add(entry: Entry<T>): EnumButtonPanel<S, T> {
check(isBuilding) { "Not building" }
check(enumMapping.put(entry.key, entry) == null) { "Already has mapping for ${entry.key}" }
if (enumMapping.size == enum.enumConstants.size) finish()
return this
}
fun finish(): EnumRectangleButtonPanel<S, T> {
fun finish(): EnumButtonPanel<S, T> {
if (!isBuilding) return this
check(enumMapping.isNotEmpty()) { "No enums were defined, like, at all." }
check(enumMapping.containsKey(defaultValue)) { "Default value $defaultValue is missing from mapping" }
@ -75,8 +98,6 @@ abstract class EnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
check(!isBuilding) { "Still building this button!" }
super.innerRender(graphics, mouseX, mouseY, partialTick)
val entry = enumMapping[prop.get()] ?: return
entry.skinElement?.render(graphics, 0f, 0f, width, height, entry.winding)
}
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
@ -89,6 +110,29 @@ abstract class EnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
return super.mouseReleasedInner(x, y, button)
}
private var lastScroll = System.nanoTime()
var handleScrolling = true
override fun mouseScrolledInner(x: Double, y: Double, scroll: Double): Boolean {
if (!handleScrolling)
return false
if (System.nanoTime() - lastScroll <= 200_000_000L)
return true
lastScroll = System.nanoTime()
if (scroll > 0.0) {
onClick(InputConstants.MOUSE_BUTTON_RIGHT)
playGuiClickSound()
} else if (scroll < 0.0) {
onClick(InputConstants.MOUSE_BUTTON_LEFT)
playGuiClickSound()
}
return true
}
override fun test(value: Int): Boolean {
return value == InputConstants.MOUSE_BUTTON_LEFT ||
value == InputConstants.MOUSE_BUTTON_RIGHT ||
@ -172,5 +216,71 @@ abstract class EnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
companion object {
private val SPACE = TextComponent("")
fun <S : Screen, T : Enum<T>> square18(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
enum: Class<T>,
prop: Delegate<T>,
defaultValue: T,
): EnumButtonPanel<S, T> {
return EnumButtonPanel(screen, parent, x, y, 18f, 18f, enum, prop, defaultValue)
}
fun <S : Screen, T : Enum<T>> square15(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
enum: Class<T>,
prop: Delegate<T>,
defaultValue: T,
): EnumButtonPanel<S, T> {
return EnumButtonPanel(screen, parent, x, y, 15f, 15f, enum, prop, defaultValue)
}
fun <S : Screen, T : Enum<T>> square8(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
enum: Class<T>,
prop: Delegate<T>,
defaultValue: T,
): EnumButtonPanel<S, T> {
return EnumButtonPanel(screen, parent, x, y, 8f, 8f, enum, prop, defaultValue)
}
fun <S : Screen, T : Enum<T>> square18(
screen: S,
parent: EditablePanel<*>?,
enum: Class<T>,
prop: Delegate<T>,
defaultValue: T,
): EnumButtonPanel<S, T> {
return EnumButtonPanel(screen, parent, 0f, 0f, 18f, 18f, enum, prop, defaultValue)
}
fun <S : Screen, T : Enum<T>> square15(
screen: S,
parent: EditablePanel<*>?,
enum: Class<T>,
prop: Delegate<T>,
defaultValue: T,
): EnumButtonPanel<S, T> {
return EnumButtonPanel(screen, parent, 0f, 0f, 15f, 15f, enum, prop, defaultValue)
}
fun <S : Screen, T : Enum<T>> square8(
screen: S,
parent: EditablePanel<*>?,
enum: Class<T>,
prop: Delegate<T>,
defaultValue: T,
): EnumButtonPanel<S, T> {
return EnumButtonPanel(screen, parent, 0f, 0f, 8f, 8f, enum, prop, defaultValue)
}
}
}

View File

@ -1,32 +0,0 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.client.gui.screens.Screen
import net.minecraft.network.chat.Component
import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
open class LargeBooleanRectangleButtonPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = SIZE,
height: Float = SIZE,
prop: Delegate<Boolean>,
iconActive: IGUIRenderable? = null,
iconInactive: IGUIRenderable? = null,
onChange: ((newValue: Boolean) -> Unit)? = null,
tooltipActive: Component? = null,
tooltipInactive: Component? = null,
) : BooleanRectangleButtonPanel<S>(screen, parent, x, y, width, height, prop, iconActive, iconInactive, onChange, tooltipActive, tooltipInactive) {
final override val IDLE = Widgets18.BUTTON_IDLE
final override val HOVERED = Widgets18.BUTTON_HOVERED
final override val PRESSED = Widgets18.BUTTON_PRESSED
final override val DISABLED = Widgets18.BUTTON_DISABLED
companion object {
const val SIZE = 18f
}
}

View File

@ -1,27 +0,0 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.client.gui.screens.Screen
import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
open class LargeEnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = SIZE,
height: Float = SIZE,
enum: Class<T>,
prop: Delegate<T>,
defaultValue: T,
) : EnumRectangleButtonPanel<S, T>(screen, parent, x, y, width, height, enum, prop, defaultValue) {
final override val IDLE = Widgets18.BUTTON_IDLE
final override val HOVERED = Widgets18.BUTTON_HOVERED
final override val PRESSED = Widgets18.BUTTON_PRESSED
final override val DISABLED = Widgets18.BUTTON_DISABLED
companion object {
const val SIZE = 18f
}
}

View File

@ -1,65 +0,0 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.client.gui.screens.Screen
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.minecraft
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
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.menu.MatteryMenu
open class LargeRectangleButtonPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = SIZE,
height: Float = SIZE,
onPress: ((clickButton: Int) -> Unit)? = null,
var icon: IGUIRenderable? = null,
var iconWinding: 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
final override val PRESSED = Widgets18.BUTTON_PRESSED
final override val DISABLED = Widgets18.BUTTON_DISABLED
override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
super.innerRender(graphics, mouseX, mouseY, partialTick)
val color = if (isDisabled || isPressed) RGBAColor.DARK_GRAY else RGBAColor.WHITE
if (iconWinding != null) {
icon?.render(graphics, canvasWidth = width, canvasHeight = height, winding = iconWinding!!, color = color)
} else {
icon?.render(graphics, canvasWidth = width, canvasHeight = height, color = color)
}
}
companion object {
const val SIZE = 18f
fun <S : Screen> input(
screen: S,
parent: EditablePanel<*>?,
input: MatteryMenu.PlayerInput<Nothing?>,
x: Float = 0f,
y: Float = 0f,
width: Float = SIZE,
height: Float = SIZE,
icon: IGUIRenderable? = null,
iconWinding: UVWindingOrder? = null,
): LargeRectangleButtonPanel<S> {
return object : LargeRectangleButtonPanel<S>(screen, parent, x, y, width, height, null, icon, iconWinding) {
override fun onClick(mouseButton: Int) {
input.accept(null)
}
override var isDisabled: Boolean
get() { return !input.test(minecraft.player ?: return false) }
set(value) {}
}
}
}
}

View File

@ -1,43 +0,0 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.client.gui.screens.Screen
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import java.util.function.IntConsumer
@Suppress("PropertyName")
abstract class RectangleButtonPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float,
height: Float,
var onPress: IntConsumer? = null,
) : AbstractButtonPanel<S>(screen, parent, x, y, width, height) {
abstract val PRESSED: IGUIRenderable
abstract val HOVERED: IGUIRenderable
abstract val IDLE: IGUIRenderable
abstract val DISABLED: IGUIRenderable
override fun onClick(mouseButton: Int) {
onPress?.accept(mouseButton)
}
protected fun renderSquareButton(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
if (isDisabled) {
DISABLED.render(graphics, 0f, 0f, width, height)
} else if (isPressed) {
PRESSED.render(graphics, 0f, 0f, width, height)
} else if (isHovered) {
HOVERED.render(graphics, 0f, 0f, width, height)
} else {
IDLE.render(graphics, 0f, 0f, width, height)
}
}
override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
renderSquareButton(graphics, mouseX, mouseY, partialTick)
}
}

View File

@ -1,29 +0,0 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.client.gui.screens.Screen
import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.mc.otm.client.render.*
import ru.dbotthepony.mc.otm.client.render.sprites.AbstractMatterySprite
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
open class SmallBooleanRectangleButtonPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = SIZE,
height: Float = SIZE,
prop: Delegate<Boolean>,
skinElementActive: AbstractMatterySprite? = null,
skinElementInactive: AbstractMatterySprite? = null,
onChange: ((newValue: Boolean) -> Unit)? = null,
) : BooleanRectangleButtonPanel<S>(screen, parent, x, y, width, height, prop, skinElementActive, skinElementInactive, onChange) {
final override val IDLE = Widgets8.BUTTON_IDLE
final override val HOVERED = Widgets8.BUTTON_HOVERED
final override val PRESSED = Widgets8.BUTTON_PRESSED
final override val DISABLED = Widgets8.BUTTON_DISABLED
companion object {
const val SIZE = 8f
}
}

View File

@ -1,27 +0,0 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.client.gui.screens.Screen
import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.mc.otm.client.render.Widgets8
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
open class SmallEnumRectangleButtonPanel<out S : Screen, T : Enum<T>>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = SIZE,
height: Float = SIZE,
enum: Class<T>,
prop: Delegate<T>,
defaultValue: T,
) : EnumRectangleButtonPanel<S, T>(screen, parent, x, y, width, height, enum, prop, defaultValue) {
final override val IDLE = Widgets8.BUTTON_IDLE
final override val HOVERED = Widgets8.BUTTON_HOVERED
final override val PRESSED = Widgets8.BUTTON_PRESSED
final override val DISABLED = Widgets8.BUTTON_DISABLED
companion object {
const val SIZE = 8f
}
}

View File

@ -1,39 +0,0 @@
package ru.dbotthepony.mc.otm.client.screen.panels.button
import net.minecraft.client.gui.screens.Screen
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.render.sprites.MatterySprite
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.render.Widgets8
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
open class SmallRectangleButtonPanel<out S : Screen>(
screen: S,
parent: EditablePanel<*>?,
x: Float = 0f,
y: Float = 0f,
width: Float = SIZE,
height: Float = SIZE,
onPress: ((clickButton: Int) -> Unit)? = null,
val skinElement: MatterySprite? = null,
val skinElementWinding: UVWindingOrder? = null,
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height, onPress) {
final override val IDLE = Widgets8.BUTTON_IDLE
final override val HOVERED = Widgets8.BUTTON_HOVERED
final override val PRESSED = Widgets8.BUTTON_PRESSED
final override val DISABLED = Widgets8.BUTTON_DISABLED
override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
super.innerRender(graphics, mouseX, mouseY, partialTick)
if (skinElementWinding != null) {
skinElement?.render(graphics, canvasWidth = width, canvasHeight = height, winding = skinElementWinding)
} else {
skinElement?.render(graphics, canvasWidth = width, canvasHeight = height)
}
}
companion object {
const val SIZE = 8f
}
}

View File

@ -6,7 +6,7 @@ import ru.dbotthepony.kommons.util.Delegate
import ru.dbotthepony.mc.otm.client.render.Widgets
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.RectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.util.HeightControls
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.math.Decimal
@ -85,11 +85,11 @@ abstract class NumberInputPanel<out S : Screen, N : Number>(
controls.dock = Dock.RIGHT
}
inner class Control(val isIncrease: Boolean) : RectangleButtonPanel<S>(screen, controls, width = HeightControls.BUTTON_WIDTH, height = HeightControls.BUTTON_HEIGHT) {
override val PRESSED = if (!isIncrease) Widgets.ARROW_DOWN_BUTTON_PRESSED else Widgets.ARROW_UP_BUTTON_PRESSED
override val HOVERED = if (!isIncrease) Widgets.ARROW_DOWN_BUTTON_HOVERED else Widgets.ARROW_UP_BUTTON_HOVERED
override val IDLE = if (!isIncrease) Widgets.ARROW_DOWN_BUTTON_IDLE else Widgets.ARROW_UP_BUTTON_IDLE
override val DISABLED = if (!isIncrease) Widgets.ARROW_DOWN_BUTTON_DISABLED else Widgets.ARROW_UP_BUTTON_DISABLED
inner class Control(val isIncrease: Boolean) : ButtonPanel<S>(screen, controls, width = HeightControls.BUTTON_WIDTH, height = HeightControls.BUTTON_HEIGHT) {
override val pressedSprite get() = if (!isIncrease) Widgets.ARROW_DOWN_BUTTON_PRESSED else Widgets.ARROW_UP_BUTTON_PRESSED
override val hoveredSprite get() = if (!isIncrease) Widgets.ARROW_DOWN_BUTTON_HOVERED else Widgets.ARROW_UP_BUTTON_HOVERED
override val idleSprite get() = if (!isIncrease) Widgets.ARROW_DOWN_BUTTON_IDLE else Widgets.ARROW_UP_BUTTON_IDLE
override val disabledSprite get() = if (!isIncrease) Widgets.ARROW_DOWN_BUTTON_DISABLED else Widgets.ARROW_UP_BUTTON_DISABLED
init {
dock = Dock.TOP

View File

@ -45,13 +45,13 @@ open class QueryUserPanel<out S: Screen>(
this.height = height + bottom.height + PADDING + PADDING_TOP + 4f
ButtonPanel(screen, bottom, width = font.width(TranslatableComponent("otm.gui.cancel")) + 12f, label = TranslatableComponent("otm.gui.cancel"), onPress = Runnable {
ButtonPanel.Simple(screen, bottom, width = font.width(TranslatableComponent("otm.gui.cancel")) + 12f, label = TranslatableComponent("otm.gui.cancel"), onPress = Runnable {
onCancel?.run()
this.remove()
}).dock = Dock.RIGHT
if (onConfirm != null) {
ButtonPanel(screen, bottom, width = font.width(TranslatableComponent("otm.gui.confirm")) + 12f, label = TranslatableComponent("otm.gui.confirm"), onPress = Runnable {
ButtonPanel.Simple(screen, bottom, width = font.width(TranslatableComponent("otm.gui.confirm")) + 12f, label = TranslatableComponent("otm.gui.confirm"), onPress = Runnable {
onConfirm.run()
this.remove()
}).also {

View File

@ -23,7 +23,7 @@ open class BackgroundPanel<out S : Screen>(
override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
if (drawBackground) {
RECTANGLE.render(graphics, width = width, height = height)
RECTANGLE.render(graphics, canvasWidth = width, canvasHeight = height)
}
}

View File

@ -6,7 +6,7 @@ import ru.dbotthepony.mc.otm.client.render.sprites.AbstractMatterySprite
import ru.dbotthepony.mc.otm.client.render.Widgets
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.RectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
open class HeightControls<out S : Screen>(
screen: S,
@ -46,11 +46,11 @@ open class HeightControls<out S : Screen>(
decrease.isDisabled = !value.canDecrease
}
inner class Control(val isIncrease: Boolean) : RectangleButtonPanel<S>(screen, this@HeightControls, width = BUTTON_WIDTH, height = BUTTON_HEIGHT) {
override val PRESSED: AbstractMatterySprite = if (isIncrease) Widgets.ARROW_DOWN_BUTTON_PRESSED else Widgets.ARROW_UP_BUTTON_PRESSED
override val HOVERED: AbstractMatterySprite = if (isIncrease) Widgets.ARROW_DOWN_BUTTON_HOVERED else Widgets.ARROW_UP_BUTTON_HOVERED
override val IDLE: AbstractMatterySprite = if (isIncrease) Widgets.ARROW_DOWN_BUTTON_IDLE else Widgets.ARROW_UP_BUTTON_IDLE
override val DISABLED: AbstractMatterySprite = if (isIncrease) Widgets.ARROW_DOWN_BUTTON_DISABLED else Widgets.ARROW_UP_BUTTON_DISABLED
inner class Control(val isIncrease: Boolean) : ButtonPanel<S>(screen, this@HeightControls, width = BUTTON_WIDTH, height = BUTTON_HEIGHT) {
override val pressedSprite get() = if (isIncrease) Widgets.ARROW_DOWN_BUTTON_PRESSED else Widgets.ARROW_UP_BUTTON_PRESSED
override val hoveredSprite get() = if (isIncrease) Widgets.ARROW_DOWN_BUTTON_HOVERED else Widgets.ARROW_UP_BUTTON_HOVERED
override val idleSprite get() = if (isIncrease) Widgets.ARROW_DOWN_BUTTON_IDLE else Widgets.ARROW_UP_BUTTON_IDLE
override val disabledSprite get() = if (isIncrease) Widgets.ARROW_DOWN_BUTTON_DISABLED else Widgets.ARROW_UP_BUTTON_DISABLED
init {
dock = Dock.TOP

View File

@ -11,7 +11,6 @@ import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty
import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeEnumRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.input.IntInputPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel

View File

@ -9,7 +9,7 @@ import ru.dbotthepony.mc.otm.client.render.ItemStackIcon
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.client.screen.panels.*
import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel
@ -71,9 +71,9 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp
settings.add(EditablePanel(this, frame, width = 90f).also {
it.dock = Dock.LEFT
CheckBoxLabelInputPanel(this, it, menu.isWhitelist, TranslatableComponent("otm.gui.filter.is_whitelist")).also { it.dockTop = 20f; it.dock = Dock.TOP }
CheckBoxLabelInputPanel(this, it, menu.matchTag, TranslatableComponent("otm.gui.filter.match_tag")).also { it.dockTop = 4f; it.dock = Dock.TOP }
CheckBoxLabelInputPanel(this, it, menu.matchComponents, TranslatableComponent("otm.gui.filter.match_nbt")).also { it.dockTop = 4f; it.dock = Dock.TOP }
BooleanButtonPanel.Checkbox(this, it, menu.isWhitelist, TranslatableComponent("otm.gui.filter.is_whitelist")).also { it.dockTop = 20f; it.dock = Dock.TOP }
BooleanButtonPanel.Checkbox(this, it, menu.matchTag, TranslatableComponent("otm.gui.filter.match_tag")).also { it.dockTop = 4f; it.dock = Dock.TOP }
BooleanButtonPanel.Checkbox(this, it, menu.matchComponents, TranslatableComponent("otm.gui.filter.match_nbt")).also { it.dockTop = 4f; it.dock = Dock.TOP }
})
frame.CustomTab(view, activeIcon = ItemStackIcon(ItemStack(MItems.PORTABLE_CONDENSATION_DRIVE)))

View File

@ -14,7 +14,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.NetworkedItemGridPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.button.SmallEnumRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.EnumButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
@ -81,7 +81,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
val arrowLine = EditablePanel(this, arrowAndButtons, y = 38f, height = 8f, width = arrowAndButtons.width)
SmallEnumRectangleButtonPanel(this, arrowLine,
EnumButtonPanel.square8(this, arrowLine,
enum = ItemMonitorPlayerSettings.IngredientPriority::class.java,
prop = Delegate.Of(menu.settings::ingredientPriority),
defaultValue = ItemMonitorPlayerSettings.IngredientPriority.SYSTEM)
@ -89,7 +89,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
it.tooltips.add(TranslatableComponent("otm.gui.item_monitor.refill_source.desc"))
for (setting in ItemMonitorPlayerSettings.IngredientPriority.entries) {
it.add(setting, setting.icon, setting.component, setting.winding)
it.add(setting, skinElement = setting.icon, tooltip = setting.component, winding = setting.winding)
}
it.dock = Dock.LEFT
@ -102,7 +102,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
SlotPanel(this, resultAndButtons, menu.craftingResult, y = 18f)
SmallEnumRectangleButtonPanel(this, resultAndButtons, y = 38f,
EnumButtonPanel.square8(this, resultAndButtons, y = 38f,
enum = ItemMonitorPlayerSettings.ResultTarget::class.java,
prop = Delegate.Of(menu.settings::resultTarget),
defaultValue = ItemMonitorPlayerSettings.ResultTarget.MIXED)
@ -110,11 +110,11 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
it.tooltips.add(TranslatableComponent("otm.gui.item_monitor.result_target.desc"))
for (setting in ItemMonitorPlayerSettings.ResultTarget.entries) {
it.add(setting, setting.icon, setting.component, setting.winding)
it.add(setting, skinElement = setting.icon, tooltip = setting.component, winding = setting.winding)
}
}
SmallEnumRectangleButtonPanel(this, resultAndButtons, x = 10f, y = 38f,
EnumButtonPanel.square8(this, resultAndButtons, x = 10f, y = 38f,
enum = ItemMonitorPlayerSettings.Amount::class.java,
prop = Delegate.Of(menu.settings::craftingAmount),
defaultValue = ItemMonitorPlayerSettings.Amount.STACK)
@ -122,7 +122,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
it.tooltips.add(TranslatableComponent("otm.gui.item_monitor.amount.desc"))
for (setting in ItemMonitorPlayerSettings.Amount.entries) {
it.add(setting, setting.icon, setting.component, setting.winding)
it.add(setting, skinElement = setting.icon, tooltip = setting.component, winding = setting.winding)
}
}

View File

@ -5,7 +5,7 @@ import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.client.screen.panels.*
import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.input.IntInputPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
@ -43,7 +43,7 @@ class StorageBusScreen(menu: StorageBusMenu, inventory: Inventory, title: Compon
it.childrenOrder = -2
}
CheckBoxLabelInputPanel(this, right, menu.filter.isWhitelist, TranslatableComponent("otm.gui.filter.is_whitelist")).also {
BooleanButtonPanel.Checkbox(this, right, menu.filter.isWhitelist, TranslatableComponent("otm.gui.filter.is_whitelist")).also {
it.dock = Dock.BOTTOM
it.childrenOrder = -3
}

View File

@ -5,7 +5,7 @@ import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.client.screen.panels.*
import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.FilterSlotPanel
@ -28,19 +28,19 @@ class StorageImporterExporterScreen(menu: StorageImporterExporterMenu, inventory
FilterSlotPanel(this, grid, slot)
}
CheckBoxLabelInputPanel(this, right, menu.filter.isWhitelist, TranslatableComponent("otm.gui.filter.is_whitelist")).also {
BooleanButtonPanel.Checkbox(this, right, menu.filter.isWhitelist, TranslatableComponent("otm.gui.filter.is_whitelist")).also {
it.dock = Dock.BOTTOM
it.dockTop = 2f
it.childrenOrder = -1
}
CheckBoxLabelInputPanel(this, right, menu.filter.matchComponents, TranslatableComponent("otm.gui.filter.match_nbt")).also {
BooleanButtonPanel.Checkbox(this, right, menu.filter.matchComponents, TranslatableComponent("otm.gui.filter.match_nbt")).also {
it.dock = Dock.BOTTOM
it.dockTop = 2f
it.childrenOrder = -2
}
CheckBoxLabelInputPanel(this, right, menu.filter.matchTag, TranslatableComponent("otm.gui.filter.match_tag")).also {
BooleanButtonPanel.Checkbox(this, right, menu.filter.matchTag, TranslatableComponent("otm.gui.filter.match_tag")).also {
it.dock = Dock.BOTTOM
it.dockTop = 2f
it.childrenOrder = -3

View File

@ -614,7 +614,7 @@ class AndroidStationScreen(p_97741_: AndroidStationMenu, p_97742_: Inventory, p_
researchCanvas.parent = research
val bottom = EditablePanel(this, research, 0f, 0f, 0f, 20f)
val close = ButtonPanel(this, bottom, 0f, 0f, 90f, 20f, TranslatableComponent("otm.gui.matter_panel.close"), onPress = Runnable { research!!.remove() })
val close = ButtonPanel.Simple(this, bottom, 0f, 0f, 90f, 20f, TranslatableComponent("otm.gui.matter_panel.close"), onPress = Runnable { research!!.remove() })
bottom.dock = Dock.BOTTOM
close.dock = Dock.RIGHT

View File

@ -2,36 +2,33 @@ package ru.dbotthepony.mc.otm.client.screen.tech
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
import ru.dbotthepony.mc.otm.client.screen.panels.DockResizeMode
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel
import ru.dbotthepony.mc.otm.client.screen.widget.ProfiledMatterGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.ProfiledPowerGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.TallHorizontalProfiledPowerGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.WideProfiledPowerGaugePanel
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.menu.tech.BlackHoleGeneratorMenu
import ru.dbotthepony.mc.otm.menu.tech.CobblerMenu
class BlackHoleGeneratorScreen(menu: BlackHoleGeneratorMenu, inventory: Inventory, title: Component) : MatteryScreen<BlackHoleGeneratorMenu>(menu, inventory, title) {
override fun makeMainFrame(): FramePanel<MatteryScreen<*>> {
val frame = FramePanel.padded(this, 200f, 60f, title)
val left = EditablePanel(this, frame)
val energy = ProfiledPowerGaugePanel(this, frame, menu.energy)
val matter = ProfiledMatterGaugePanel(this, frame, menu.matter)
left.width = energy.width + matter.width + 1f
energy.parent = left
matter.parent = left
matter.dockLeft = 1f
left.dock = Dock.LEFT
energy.dock = Dock.LEFT
matter.dock = Dock.LEFT
matter.dockRight = 4f
val drawGuide = BooleanButtonPanel.Checkbox(this, frame, menu.drawBuildingGuide, TranslatableComponent("otm.gui.draw_multiblock_guide"))
drawGuide.dock = Dock.TOP
drawGuide.dockBottom = 2f
return frame
}
}

View File

@ -9,8 +9,8 @@ import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.client.screen.panels.*
import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.input.TextInputPanel
import ru.dbotthepony.mc.otm.core.math.Decimal
@ -43,9 +43,10 @@ class EnergyCounterScreen(menu: EnergyCounterMenu, inventory: Inventory, title:
panel.dock = Dock.FILL
val current = i++
val button = CheckBoxLabelInputPanel(this, tab.canvas, menu.displayChartOnBlock.map({ it == current }, { current }), TranslatableComponent("block.overdrive_that_matters.energy_counter.display_this"))
val button = BooleanButtonPanel.Checkbox(this, tab.canvas, menu.displayChartOnBlock.map({ it == current }, { current }), TranslatableComponent("block.overdrive_that_matters.energy_counter.display_this"))
button.dock = Dock.BOTTOM
button.dockTop = 2f
button.displayUncheckedIcon = false
}
}
@ -63,7 +64,7 @@ class EnergyCounterScreen(menu: EnergyCounterMenu, inventory: Inventory, title:
labels.add(Label(this, informationTab.canvas, text = TranslatableComponent("otm.gui.power.last_tick")))
labels.add(DynamicLabel(this, informationTab.canvas, textSupplier = { menu.lastTick.formatPower(formatAsReadable = ShiftPressedCond) }))
labels.add(DynamicLabel(this, informationTab.canvas, textSupplier = { TranslatableComponent("block.overdrive_that_matters.energy_counter.facing", menu.inputDirection) }))
labels.add(CheckBoxLabelInputPanel(this, informationTab.canvas, menu.displayChartOnBlock.map({ it == 0 }, { 0 }), TranslatableComponent("block.overdrive_that_matters.energy_counter.display_this")))
labels.add(BooleanButtonPanel.Checkbox(this, informationTab.canvas, menu.displayChartOnBlock.map({ it == 0 }, { 0 }), TranslatableComponent("block.overdrive_that_matters.energy_counter.display_this")).also { it.displayUncheckedIcon = false })
for ((i, label) in labels.withIndex()) {
if (i == 0) {
@ -76,7 +77,7 @@ class EnergyCounterScreen(menu: EnergyCounterMenu, inventory: Inventory, title:
}
if (!menu.player.isSpectator) {
val button = ButtonPanel(this, informationTab.canvas, 0f, 0f, 0f, 20f, TranslatableComponent("block.overdrive_that_matters.energy_counter.switch"), onPress = Runnable { menu.switchDirection.accept(null) })
val button = ButtonPanel.Simple(this, informationTab.canvas, 0f, 0f, 0f, 20f, TranslatableComponent("block.overdrive_that_matters.energy_counter.switch"), onPress = Runnable { menu.switchDirection.accept(null) })
button.dock = Dock.TOP
button.setDockMargin(4f, 5f, 4f, 0f)
}

View File

@ -7,6 +7,7 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.isShiftDown
import ru.dbotthepony.mc.otm.client.playGuiClickSound
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
import ru.dbotthepony.mc.otm.client.render.sprites.MatteryAtlas
import ru.dbotthepony.mc.otm.client.render.RenderGravity
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
@ -16,7 +17,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.DockResizeMode
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.Label
import ru.dbotthepony.mc.otm.client.screen.panels.button.LargeRectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.input.TextInputPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
@ -93,12 +94,15 @@ class EssenceStorageScreen(menu: EssenceStorageMenu, inventory: Inventory, title
outputs.dockResize = DockResizeMode.NONE
outputs.dockMargin = DockProperty(bottom = 3f)
object : LargeRectangleButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, inputs, icon = STORE_1) {
object : ButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, inputs) {
init {
dockRight = 3f
tooltips.add(TranslatableComponent("otm.gui.experience.store", 1))
}
override val icon: IGUIRenderable
get() = STORE_1
override fun onClick(mouseButton: Int) {
menu.storeLevels.accept(1)
}
@ -108,12 +112,15 @@ class EssenceStorageScreen(menu: EssenceStorageMenu, inventory: Inventory, title
set(_) {}
}
object : LargeRectangleButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, inputs, icon = STORE_10) {
object : ButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, inputs) {
init {
dockRight = 3f
tooltips.add(TranslatableComponent("otm.gui.experience.store", 10))
}
override val icon: IGUIRenderable
get() = STORE_10
override fun onClick(mouseButton: Int) {
menu.storeLevels.accept(10)
}
@ -123,12 +130,15 @@ class EssenceStorageScreen(menu: EssenceStorageMenu, inventory: Inventory, title
set(_) {}
}
object : LargeRectangleButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, inputs, icon = STORE_ALL) {
object : ButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, inputs) {
init {
dockRight = 3f
tooltips.add(TranslatableComponent("otm.gui.experience.store_all"))
}
override val icon: IGUIRenderable
get() = STORE_ALL
override fun onClick(mouseButton: Int) {
menu.storeLevels.accept((minecraft!!.player!!.experienceLevel ?: 0) + 1)
}
@ -138,12 +148,15 @@ class EssenceStorageScreen(menu: EssenceStorageMenu, inventory: Inventory, title
set(_) {}
}
object : LargeRectangleButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, outputs, icon = DISPENSE_1) {
object : ButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, outputs) {
init {
dockRight = 3f
tooltips.add(TranslatableComponent("otm.gui.experience.dispense", 1))
}
override val icon: IGUIRenderable
get() = DISPENSE_1
override fun onClick(mouseButton: Int) {
menu.dispenseLevels.accept(1)
}
@ -153,12 +166,15 @@ class EssenceStorageScreen(menu: EssenceStorageMenu, inventory: Inventory, title
set(_) {}
}
object : LargeRectangleButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, outputs, icon = DISPENSE_10) {
object : ButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, outputs) {
init {
dockRight = 3f
tooltips.add(TranslatableComponent("otm.gui.experience.dispense", 10))
}
override val icon: IGUIRenderable
get() = DISPENSE_10
override fun onClick(mouseButton: Int) {
menu.dispenseLevels.accept(10)
}
@ -168,12 +184,15 @@ class EssenceStorageScreen(menu: EssenceStorageMenu, inventory: Inventory, title
set(_) {}
}
object : LargeRectangleButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, outputs, icon = DISPENSE_ALL) {
object : ButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, outputs) {
init {
dockRight = 3f
tooltips.add(TranslatableComponent("otm.gui.experience.dispense_all"))
}
override val icon: IGUIRenderable
get() = DISPENSE_ALL
override fun onClick(mouseButton: Int) {
menu.dispenseLevels.accept(getLevelFromXp(menu.experienceStored) + 1)
}
@ -186,11 +205,14 @@ class EssenceStorageScreen(menu: EssenceStorageMenu, inventory: Inventory, title
val customBar = HorizontalStripPanel(this, frame, height = 18f)
customBar.dock = Dock.TOP
object : LargeRectangleButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, customBar, icon = STORE_CUSTOM) {
object : ButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, customBar) {
init {
tooltips.add(TranslatableComponent("otm.gui.experience.store", customDispense))
}
override val icon: IGUIRenderable
get() = STORE_CUSTOM
override fun onClick(mouseButton: Int) {
menu.storeLevels.accept(customDispense)
}
@ -227,11 +249,14 @@ class EssenceStorageScreen(menu: EssenceStorageMenu, inventory: Inventory, title
}
}
object : LargeRectangleButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, customBar, icon = DISPENSE_CUSTOM) {
object : ButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, customBar) {
init {
tooltips.add(TranslatableComponent("otm.gui.experience.dispense", customDispense))
}
override val icon: IGUIRenderable
get() = DISPENSE_CUSTOM
override fun onClick(mouseButton: Int) {
menu.dispenseLevels.accept(customDispense)
}
@ -241,13 +266,16 @@ class EssenceStorageScreen(menu: EssenceStorageMenu, inventory: Inventory, title
set(_) {}
}
object : LargeRectangleButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, customBar, icon = SET_EXACT) {
object : ButtonPanel<EssenceStorageScreen>(this@EssenceStorageScreen, customBar) {
init {
tooltips.add(TranslatableComponent("otm.gui.experience.set_exact", customDispense))
dock = Dock.RIGHT
dockMargin = DockProperty(right = 4f)
}
override val icon: IGUIRenderable
get() = SET_EXACT
override fun onClick(mouseButton: Int) {
val player = minecraft!!.player!! ?: return

View File

@ -6,6 +6,7 @@ import lain.mods.cos.impl.client.PlayerRenderHandler
import lain.mods.cos.impl.client.gui.GuiCosArmorInventory
import lain.mods.cos.impl.network.payload.PayloadSetSkinArmor
import net.minecraft.client.gui.screens.Screen
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.Container
@ -19,10 +20,12 @@ import net.neoforged.neoforge.network.PacketDistributor
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.render.IGUIRenderable
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.render.sprites.MatterySprite
import ru.dbotthepony.mc.otm.client.render.sprites.sprite
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.RectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleButton.Companion.BUTTON_ACTIVE
import ru.dbotthepony.mc.otm.compat.cos.CosmeticToggleButton.Companion.BUTTON_INACTIVE
import ru.dbotthepony.mc.otm.container.util.awareStream
@ -151,16 +154,7 @@ class CosmeticToggleButton<out S : Screen>(
y: Float = 0f,
width: Float = 5f,
height: Float = 5f
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height) {
override val PRESSED: MatterySprite
get() = BUTTON_ACTIVE
override val HOVERED: MatterySprite
get() = BUTTON_ACTIVE
override val IDLE: MatterySprite
get() = BUTTON_INACTIVE
override val DISABLED: MatterySprite
get() = BUTTON_INACTIVE
) : ButtonPanel<S>(screen, parent, x, y, width, height) {
private val index = when (index) {
EquipmentSlot.FEET -> 0
EquipmentSlot.LEGS -> 1
@ -201,16 +195,7 @@ class CosmeticToggleRenderButton<out S : Screen>(
y: Float = 0f,
width: Float = 5f,
height: Float = 5f
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height) {
override val PRESSED: MatterySprite
get() = BUTTON_ACTIVE
override val HOVERED: MatterySprite
get() = BUTTON_ACTIVE
override val IDLE: MatterySprite
get() = BUTTON_INACTIVE
override val DISABLED: MatterySprite
get() = BUTTON_INACTIVE
) : ButtonPanel<S>(screen, parent, x, y, width, height) {
override fun onClick(mouseButton: Int) {
if (mouseButton == InputConstants.MOUSE_BUTTON_LEFT) {
PlayerRenderHandler.Disabled = !PlayerRenderHandler.Disabled

View File

@ -18,7 +18,7 @@ import ru.dbotthepony.mc.otm.client.render.sprites.MatterySprite
import ru.dbotthepony.mc.otm.client.render.sprites.sprite
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.RectangleButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
import ru.dbotthepony.mc.otm.container.util.awareStream
import ru.dbotthepony.mc.otm.container.util.iterator
@ -193,14 +193,14 @@ class CurioToggleButton<out S : Screen>(
y: Float = 0f,
width: Float = 8f,
height: Float = 8f
) : RectangleButtonPanel<S>(screen, parent, x, y, width, height) {
override val PRESSED: MatterySprite
) : ButtonPanel<S>(screen, parent, x, y, width, height) {
override val pressedSprite: MatterySprite
get() = BUTTON_ACTIVE
override val HOVERED: MatterySprite
override val hoveredSprite: MatterySprite
get() = BUTTON_ACTIVE
override val IDLE: MatterySprite
override val idleSprite: MatterySprite
get() = BUTTON_INACTIVE
override val DISABLED: MatterySprite
override val disabledSprite: MatterySprite
get() = BUTTON_INACTIVE
override fun onClick(mouseButton: Int) {

View File

@ -218,42 +218,42 @@ class ShapedMultiblockBuilder {
}
/**
* Creates new node relative to this node at [diff], which behaves as if being [Or] node
* Creates new node relative to this node at [diff], which behaves by default as [Strategy.OR_EITHER]
*/
fun relative(diff: Vec3i): Node {
return node(pos + diff)
}
/**
* Creates new node relative to this node at [dir] side, which behaves as if being [Or] node
* Creates new node relative to this node at [dir] side, which behaves by default as [Strategy.OR_EITHER]
*/
fun relative(dir: Direction): Node {
return relative(dir.normal)
}
/**
* Creates new node relative to this node at [dir] side, which behaves as if being [Or] node
* Creates new node relative to this node at [dir] side, which behaves by default as [Strategy.OR_EITHER]
*/
fun relative(dir: RelativeSide): Node {
return relative(dir.default)
}
/**
* Creates new node relative to this node at [diff], and configures it in-place using provided [configurator] expression, which behaves as if being [Or] node
* Creates new node relative to this node at [diff], and configures it in-place using provided [configurator] expression, which behaves by default as [Strategy.OR_EITHER]
*/
fun relative(diff: Vec3i, configurator: Node.() -> Unit): Node {
return node(pos + diff).also(configurator)
}
/**
* Creates new node relative to this node at [dir] side, and configures it in-place using provided [configurator] expression, which behaves as if being [Or] node
* Creates new node relative to this node at [dir] side, and configures it in-place using provided [configurator] expression, which behaves by default as [Strategy.OR_EITHER]
*/
fun relative(dir: Direction, configurator: Node.() -> Unit): Node {
return relative(dir.normal).also(configurator)
}
/**
* Creates new node relative to this node at [dir] side, and configures it in-place using provided [configurator] expression, which behaves as if being [Or] node
* Creates new node relative to this node at [dir] side, and configures it in-place using provided [configurator] expression, which behaves by default as [Strategy.OR_EITHER]
*/
fun relative(dir: RelativeSide, configurator: Node.() -> Unit): Node {
return relative(dir.default).also(configurator)

View File

@ -198,7 +198,7 @@ class MatterPanelMenu(
val settings = IItemSortingSettings.inputs(this, tile?.getPlayerSettings(player), ::updateComparators)
var isProvidingTasks by BooleanInputWithFeedback(this, tile?.let { it::isProvidingTasks })
val isProvidingTasks = BooleanInputWithFeedback(this, tile?.let { it::isProvidingTasks })
val cancelAll = PlayerInput(StreamCodecs.NOTHING) { tile?.dropAllTasks() }
val totalMatterStored: Decimal by mSynchronizer.computed(

Binary file not shown.

Before

Width:  |  Height:  |  Size: 817 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 951 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB