From be4b4df4c3965bf891b1ace44c6883f8919c32e5 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Wed, 23 Feb 2022 09:27:32 +0100 Subject: [PATCH] gui: split item element in raw and normal --- .../elements/items/ContainerItemsElement.kt | 16 +-- .../gui/elements/items/ItemElement.kt | 83 ++---------- .../gui/elements/items/RawItemElement.kt | 128 ++++++++++++++++++ .../gui/dragged/elements/item/FloatingItem.kt | 6 +- 4 files changed, 146 insertions(+), 87 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/RawItemElement.kt diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/ContainerItemsElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/ContainerItemsElement.kt index 211af53d1..3a3122911 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/ContainerItemsElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/ContainerItemsElement.kt @@ -81,16 +81,14 @@ class ContainerItemsElement( if (data == null) { item ?: continue - val element = ItemElement( - guiRenderer = guiRenderer, - size = binding.size, - item = item, - slotId = slot, - container = container, - parent = this, - ) itemElements[slot] = ItemElementData( - element = element, + element = ItemElement( + guiRenderer = guiRenderer, + size = binding.size, + item = item, + slotId = slot, + itemsElement = this, + ), offset = binding.start, ) // element.parent = this diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/ItemElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/ItemElement.kt index 4cbb563aa..a94fae85d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/ItemElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/ItemElement.kt @@ -16,44 +16,26 @@ package de.bixilon.minosoft.gui.rendering.gui.elements.items import de.bixilon.minosoft.config.key.KeyCodes import de.bixilon.minosoft.data.inventory.ContainerClickActions import de.bixilon.minosoft.data.inventory.stack.ItemStack -import de.bixilon.minosoft.data.registries.items.block.BlockItem -import de.bixilon.minosoft.data.registries.other.containers.Container -import de.bixilon.minosoft.data.text.ChatColors -import de.bixilon.minosoft.data.text.ChatComponent -import de.bixilon.minosoft.data.text.TextComponent import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer import de.bixilon.minosoft.gui.rendering.gui.elements.Element -import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments -import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments.Companion.getOffset import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable -import de.bixilon.minosoft.gui.rendering.gui.elements.VerticalAlignments -import de.bixilon.minosoft.gui.rendering.gui.elements.VerticalAlignments.Companion.getOffset -import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ColorElement -import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ImageElement -import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement import de.bixilon.minosoft.gui.rendering.gui.gui.popper.item.ItemInfoPopper import de.bixilon.minosoft.gui.rendering.gui.input.ModifierKeys import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions import de.bixilon.minosoft.gui.rendering.system.window.CursorShapes import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes -import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY import de.bixilon.minosoft.protocol.packets.c2s.play.container.ContainerClickC2SP -import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition -import de.bixilon.minosoft.util.KUtil import glm_.vec2.Vec2i -import glm_.vec3.Vec3i class ItemElement( guiRenderer: GUIRenderer, - size: Vec2i, + size: Vec2i = RawItemElement.DEFAULT_SIZE, item: ItemStack?, val slotId: Int = 0, - val container: Container? = null, - parent: Element?, + val itemsElement: ContainerItemsElement, ) : Element(guiRenderer), Pollable { - private var count = -1 - private val countText = TextElement(guiRenderer, "", background = false, noBorder = true) + private val raw = RawItemElement(guiRenderer, size, item, this) private var popper: ItemInfoPopper? = null private var hovered = false @@ -68,7 +50,7 @@ class ItemElement( } init { - this._parent = parent + this._parent = itemsElement _size = size forceApply() } @@ -78,56 +60,15 @@ class ItemElement( if (hovered) { options = (options?.copy(alpha = options.alpha * 0.7f)) ?: GUIVertexOptions(null, 0.7f) } - val stack = stack ?: return - val size = size - val textureSize = size - 1 - - val item = stack.item.item - val model = item.model - if (model == null) { - var element: Element? = null - - var color = ChatColors.WHITE - if (item is BlockItem) { - val defaultState = item.block.defaultState - defaultState.material.color?.let { color = it } - defaultState.blockModel?.getParticleTexture(KUtil.RANDOM, Vec3i.EMPTY)?.let { - element = ImageElement(guiRenderer, it, size = textureSize) - } - } - - (element ?: ColorElement(guiRenderer, textureSize, color)).render(offset, consumer, options) - } else { - model.render2d(offset, consumer, options, textureSize, stack) - } - - val countSize = countText.size - countText.render(offset + Vec2i(HorizontalAlignments.RIGHT.getOffset(size.x, countSize.x), VerticalAlignments.BOTTOM.getOffset(size.y, countSize.y)), consumer, options) + raw.render(offset, consumer, options) } override fun poll(): Boolean { - val stack = stack ?: return false - val count = stack.item.count - if (this.count != count) { - this.count = count - return true - } - - return false + return raw.poll() } override fun forceSilentApply() { - countText.text = when { - count < -99 -> NEGATIVE_INFINITE_TEXT - count < 0 -> TextComponent(count, color = ChatColors.RED) // No clue why I do this... - count == 0 -> ZERO_TEXT - count == 1 -> ChatComponent.EMPTY - count > 99 -> INFINITE_TEXT - count > ProtocolDefinition.ITEM_STACK_MAX_SIZE -> TextComponent(count, color = ChatColors.RED) - else -> TextComponent(count) - } - - cacheUpToDate = false + raw.silentApply() } override fun onMouseEnter(position: Vec2i, absolute: Vec2i): Boolean { @@ -157,7 +98,7 @@ class ItemElement( if (type != KeyChangeTypes.PRESS) { return true } - val container = container ?: return false + val container = itemsElement.container val containerId = renderWindow.connection.player.containers.getKey(container) ?: return false val controlDown = guiRenderer.isKeyDown(ModifierKeys.CONTROL) val shiftDown = guiRenderer.isKeyDown(ModifierKeys.SHIFT) @@ -181,12 +122,4 @@ class ItemElement( override fun toString(): String { return stack.toString() } - - companion object { - private val NEGATIVE_INFINITE_TEXT = TextComponent("-∞").color(ChatColors.RED) - private val INFINITE_TEXT = TextComponent("∞").color(ChatColors.RED) - private val ZERO_TEXT = TextComponent("0").color(ChatColors.YELLOW) - - val DEFAULT_SIZE = Vec2i(17, 17) // 16x16 for the item and 1px for the count offset - } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/RawItemElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/RawItemElement.kt new file mode 100644 index 000000000..0f537f153 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/RawItemElement.kt @@ -0,0 +1,128 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.gui.elements.items + +import de.bixilon.minosoft.data.inventory.stack.ItemStack +import de.bixilon.minosoft.data.registries.items.block.BlockItem +import de.bixilon.minosoft.data.text.ChatColors +import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.data.text.TextComponent +import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer +import de.bixilon.minosoft.gui.rendering.gui.elements.Element +import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments +import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments.Companion.getOffset +import de.bixilon.minosoft.gui.rendering.gui.elements.Pollable +import de.bixilon.minosoft.gui.rendering.gui.elements.VerticalAlignments +import de.bixilon.minosoft.gui.rendering.gui.elements.VerticalAlignments.Companion.getOffset +import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ColorElement +import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ImageElement +import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement +import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer +import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions +import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY +import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition +import de.bixilon.minosoft.util.KUtil +import glm_.vec2.Vec2i +import glm_.vec3.Vec3i + +class RawItemElement( + guiRenderer: GUIRenderer, + size: Vec2i = DEFAULT_SIZE, + item: ItemStack?, + parent: Element?, +) : Element(guiRenderer), Pollable { + private var count = -1 + private val countText = TextElement(guiRenderer, "", background = false, noBorder = true) + + var stack: ItemStack? = item + set(value) { + if (field == value) { + return + } + field = value + apply() + cacheUpToDate = false + } + + init { + this._parent = parent + _size = size + forceApply() + } + + override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) { + val stack = stack ?: return + val size = size + val textureSize = size - 1 + + val item = stack.item.item + val model = item.model + if (model == null) { + var element: Element? = null + + var color = ChatColors.WHITE + if (item is BlockItem) { + val defaultState = item.block.defaultState + defaultState.material.color?.let { color = it } + defaultState.blockModel?.getParticleTexture(KUtil.RANDOM, Vec3i.EMPTY)?.let { + element = ImageElement(guiRenderer, it, size = textureSize) + } + } + + (element ?: ColorElement(guiRenderer, textureSize, color)).render(offset, consumer, options) + } else { + model.render2d(offset, consumer, options, textureSize, stack) + } + + val countSize = countText.size + countText.render(offset + Vec2i(HorizontalAlignments.RIGHT.getOffset(size.x, countSize.x), VerticalAlignments.BOTTOM.getOffset(size.y, countSize.y)), consumer, options) + } + + override fun poll(): Boolean { + val stack = stack ?: return false + val count = stack.item.count + if (this.count != count) { + this.count = count + return true + } + + return false + } + + override fun forceSilentApply() { + countText.text = when { + count < -99 -> NEGATIVE_INFINITE_TEXT + count < 0 -> TextComponent(count, color = ChatColors.RED) // No clue why I do this... + count == 0 -> ZERO_TEXT + count == 1 -> ChatComponent.EMPTY + count > 99 -> INFINITE_TEXT + count > ProtocolDefinition.ITEM_STACK_MAX_SIZE -> TextComponent(count, color = ChatColors.RED) + else -> TextComponent(count) + } + + cacheUpToDate = false + } + + override fun toString(): String { + return stack.toString() + } + + companion object { + private val NEGATIVE_INFINITE_TEXT = TextComponent("-∞").color(ChatColors.RED) + private val INFINITE_TEXT = TextComponent("∞").color(ChatColors.RED) + private val ZERO_TEXT = TextComponent("0").color(ChatColors.YELLOW) + + val DEFAULT_SIZE = Vec2i(17, 17) // 16x16 for the item and 1px for the count offset + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/dragged/elements/item/FloatingItem.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/dragged/elements/item/FloatingItem.kt index 2d28de642..c67995b5d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/dragged/elements/item/FloatingItem.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/dragged/elements/item/FloatingItem.kt @@ -15,7 +15,7 @@ package de.bixilon.minosoft.gui.rendering.gui.gui.dragged.elements.item import de.bixilon.minosoft.data.inventory.stack.ItemStack import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer -import de.bixilon.minosoft.gui.rendering.gui.elements.items.ItemElement +import de.bixilon.minosoft.gui.rendering.gui.elements.items.RawItemElement import de.bixilon.minosoft.gui.rendering.gui.gui.dragged.Dragged import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions @@ -25,9 +25,9 @@ class FloatingItem( guiRenderer: GUIRenderer, val sourceId: Int, val stack: ItemStack, - size: Vec2i = ItemElement.DEFAULT_SIZE, + size: Vec2i = RawItemElement.DEFAULT_SIZE, ) : Dragged(guiRenderer) { - private val itemElement = ItemElement(guiRenderer, size, stack, -1, null, this) + private val itemElement = RawItemElement(guiRenderer, size, stack, this) init { forceSilentApply()