From c767a5711f2dc7537a916e492fbec7d2b0c50294 Mon Sep 17 00:00:00 2001 From: zhenyan121 <3367366583@qq.com> Date: Tue, 21 Jul 2026 16:42:22 +0800 Subject: [PATCH] feat(ui): add ItemSlot widget and refactor hotbar to use it --- include/Cubed/ui/item_slot.hpp | 29 +++++++++++++ include/Cubed/ui/world_ui_manager.hpp | 4 +- src/CMakeLists.txt | 1 + src/ui/item_slot.cpp | 60 +++++++++++++++++++++++++++ src/ui/world_ui_manager.cpp | 15 +++---- 5 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 include/Cubed/ui/item_slot.hpp create mode 100644 src/ui/item_slot.cpp diff --git a/include/Cubed/ui/item_slot.hpp b/include/Cubed/ui/item_slot.hpp new file mode 100644 index 0000000..bb21ed2 --- /dev/null +++ b/include/Cubed/ui/item_slot.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "Cubed/gameplay/block.hpp" +#include "Cubed/ui/image.hpp" +#include "Cubed/ui/widget.hpp" +namespace Cubed { +class TextureManager; +class ItemSlot : public Widget { +public: + static constexpr float DEFAULT_WIDTH = 16.0f; + static constexpr float DEFAULT_HEIGHT = 16.0f; + ItemSlot(Widget* parent); + + ItemSlot& set_default_background(TextureManager& m_texture_manager); + ItemSlot& set_scale(float m_scale); + ItemSlot& set_item(BlockType id, const Texture* texture); + float width() const override; + float height() const override; + +private: + static constexpr const char* DEFAULT_SLOT_PATH = "texture/ui/slot.png"; + void on_render(Renderer& renderer) override; + void on_update(float dt) override; + std::unique_ptr m_background; + std::unique_ptr m_foreground; + BlockType m_block_type; + float m_scale = 1.0f; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/ui/world_ui_manager.hpp b/include/Cubed/ui/world_ui_manager.hpp index f5ba5f9..320fea4 100644 --- a/include/Cubed/ui/world_ui_manager.hpp +++ b/include/Cubed/ui/world_ui_manager.hpp @@ -2,6 +2,7 @@ #include "Cubed/ui/chat_box.hpp" #include "Cubed/ui/image.hpp" +#include "Cubed/ui/item_slot.hpp" #include "Cubed/ui/row_layout.hpp" #include "Cubed/ui/ui_manager.hpp" #include "Cubed/ui/widget.hpp" @@ -35,7 +36,6 @@ private: Label* m_disbable_voice = nullptr; RowLayout* m_hotbar = nullptr; - std::vector m_hotbar_items; - std::vector m_hotbar_slot; + std::vector m_hotbar_slot; }; } // namespace Cubed \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 60e628e..cda79e0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -90,4 +90,5 @@ target_sources(${PROJECT_NAME} audio/audio_stream_source.cpp tools/sensitive_filter.cpp ui/row_layout.cpp + ui/item_slot.cpp ) \ No newline at end of file diff --git a/src/ui/item_slot.cpp b/src/ui/item_slot.cpp new file mode 100644 index 0000000..80f8e7b --- /dev/null +++ b/src/ui/item_slot.cpp @@ -0,0 +1,60 @@ +#include "Cubed/ui/item_slot.hpp" + +namespace Cubed { +ItemSlot::ItemSlot(Widget* parent) : Widget(parent) { + m_background = std::make_unique(this); + m_background->set_fill_parent(true); + m_foreground = std::make_unique(this); + m_foreground->set_texture(nullptr, false).set_fill_parent(true); + Widget::set_width(DEFAULT_WIDTH); + Widget::set_height(DEFAULT_HEIGHT); +} + +ItemSlot& ItemSlot::set_default_background(TextureManager& texture_manager) { + m_background->set_image(DEFAULT_SLOT_PATH, texture_manager, false); + return *this; +} +ItemSlot& ItemSlot::set_scale(float scale) { + m_scale = scale; + update_border(); + return *this; +} +ItemSlot& ItemSlot::set_item(BlockType id, const Texture* texture) { + m_foreground->set_texture(texture, false); + m_block_type = id; + return *this; +} +float ItemSlot::width() const { + if (m_fill_width || m_fill_parent) { + return Widget::width(); + } + return Widget::width() * m_scale; +} +float ItemSlot::height() const { + if (m_fill_width || m_fill_parent) { + return Widget::height(); + } + return Widget::height() * m_scale; +} + +void ItemSlot::on_render(Renderer& renderer) { + Widget::on_render(renderer); + if (m_background) { + m_background->render(renderer); + } + if (m_foreground) { + m_foreground->render(renderer); + } +} +void ItemSlot::on_update(float dt) { + + if (m_background) { + m_background->update(dt); + } + if (m_foreground) { + m_foreground->update(dt); + } + Widget::on_update(dt); +} + +} // namespace Cubed \ No newline at end of file diff --git a/src/ui/world_ui_manager.cpp b/src/ui/world_ui_manager.cpp index ef87644..8ade7cc 100644 --- a/src/ui/world_ui_manager.cpp +++ b/src/ui/world_ui_manager.cpp @@ -34,13 +34,10 @@ void WorldUIManager::init() { hotbar.set_anchor(Anchor::BOTTOM_CENTER); m_hotbar = &hotbar; for (size_t i = 0; i < ClientPlayer::HOTBAR_SUM; ++i) { - auto& bg = hotbar.add_child(); - bg.set_image("texture/ui/slot.png", texture_manager, true); - bg.set_scale(5.0f); - auto& item = bg.add_child(); - item.set_fill_parent(true).set_anchor(Anchor::CENTER); - m_hotbar_items.emplace_back(&item); - m_hotbar_slot.emplace_back(&bg); + auto& slot = hotbar.add_child(); + slot.set_default_background(texture_manager); + slot.set_scale(5.0f); + m_hotbar_slot.emplace_back(&slot); } update_hotbar(); } @@ -144,9 +141,9 @@ void WorldUIManager::update_hotbar() { m_hotbar_slot[i]->set_border_visale(false); } if (type == 0) { - m_hotbar_items[i]->set_texture(nullptr, false); + m_hotbar_slot[i]->set_item(0, nullptr); } else { - m_hotbar_items[i]->set_texture(item_texture[type].get(), false); + m_hotbar_slot[i]->set_item(type, item_texture[type].get()); } } }