diff --git a/CMakeLists.txt b/CMakeLists.txt index 0dda1fe..5271ad3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,13 +30,16 @@ set(SOURCE_FILES src/input/InputManager.cpp src/scenes/base/SceneManager.cpp src/scenes/gameplay/GameScene.cpp + src/scenes/menu/MainMenuScene.cpp src/graphics/GameRenderer.cpp src/graphics/CoordinateConverter.cpp src/utils/CoordinateTools.cpp src/graphics/font/FontManager.cpp src/graphics/font/TextRenderer.cpp src/ui/components/Button.cpp + src/ui/components/Label.cpp src/ui/managers/GameUIManager.cpp + src/ui/managers/MainMenuUIManager.cpp src/graphics/ui/UIRenderer.cpp ) diff --git a/src/ui/base/UIComponent.h b/src/ui/base/UIComponent.h index 82f96f4..8ceee82 100644 --- a/src/ui/base/UIComponent.h +++ b/src/ui/base/UIComponent.h @@ -1,6 +1,6 @@ #pragma once #include - +#include /** * @brief UI组件抽象基类 * @@ -71,10 +71,26 @@ public: */ bool isEnabled() const { return m_isEnabled; } + /** + * @brief 获取组件名称的哈希值 + * @return 组件名称的哈希值 + */ + size_t getNameHash() const { + return std::hash{}(m_name); + } + + /** + * @brief 设置组件名称 + * @param name 组件名称字符串 + */ + void setName(const std::string& name) { + m_name = name; + } + protected: UIComponent() = default; SDL_FRect m_rect = {0.0f, 0.0f, 0.0f, 0.0f}; ///< 组件位置和尺寸 bool m_isVisible = true; ///< 可见性标志 bool m_isEnabled = true; ///< 启用标志 - + std::string m_name; ///< 组件名称 }; \ No newline at end of file diff --git a/src/ui/base/UIRenderData.h b/src/ui/base/UIRenderData.h index 74ac4b7..c294af2 100644 --- a/src/ui/base/UIRenderData.h +++ b/src/ui/base/UIRenderData.h @@ -13,8 +13,22 @@ struct ButtonData SDL_Color borderColor; }; +struct LabelData +{ + std::string text; + + TextStyle textstytle; + SDL_FRect rect; + SDL_Color backgroundColor; + + int borderThickness; + SDL_Color borderColor; +}; + + // 可以通过索引方式实现,及直接传递Button指针, 在UIRender里面调用getData struct UIRenderData { std::vector buttons; + std::vector labels; }; diff --git a/src/ui/components/Button.cpp b/src/ui/components/Button.cpp index 70d2aa6..9fcefb6 100644 --- a/src/ui/components/Button.cpp +++ b/src/ui/components/Button.cpp @@ -1,15 +1,25 @@ #include "Button.h" +#include "graphics/font/TextRenderer.h" Button::Button() - { } +Button::Button(TextRenderer* textRenderer) : m_textRenderer(textRenderer) { +} void Button::setText(const std::string& text, TextStyle style) { m_buttonData.text = text; m_buttonData.textstytle = style; + + // 如果提供了 TextRenderer,则立即测量文本并更新控件尺寸 + if (m_textRenderer) { + auto [w, h] = m_textRenderer->getTextSize(text, style); + m_rect.w = static_cast(w); + m_rect.h = static_cast(h); + m_buttonData.rect = m_rect; + } } void Button::setBackgroundColor(SDL_Color normal) { @@ -22,9 +32,23 @@ void Button::setBorder(int thickness, SDL_Color color) { } +void Button::setCallback(std::function callback) { + m_callback = callback; +} + void Button::update(float deltaTime) { } +void Button::handleCilck(int x, int y) { + + if (m_callback && m_isEnabled && m_isVisible) { + //SDL_Log("rect x: %f, y: %f, w: %f, h: %f", m_rect.x, m_rect.y, m_rect.w, m_rect.h); + if (x >= m_rect.x && x <= m_rect.x + m_rect.w && + y >= m_rect.y && y <= m_rect.y + m_rect.h) { + m_callback(); + } + } +} diff --git a/src/ui/components/Button.h b/src/ui/components/Button.h index b1cf4f6..fc2ddc6 100644 --- a/src/ui/components/Button.h +++ b/src/ui/components/Button.h @@ -1,9 +1,17 @@ #pragma once #include "ui/base/UIRenderData.h" #include "ui/base/UIComponent.h" +#include + +// 前向声明,避免在头文件包含过多实现细节 +class TextRenderer; +#include class Button : public UIComponent{ public: + // 默认构造(不进行自动测量) Button(); + // 可以传入 TextRenderer 指针以便在 setText 时立即计算文字尺寸并更新 rect + explicit Button(TextRenderer* textRenderer); ~Button() override = default; // 实现UIComponent接口 @@ -31,18 +39,28 @@ public: */ void setBorder(int thickness, SDL_Color color); + void setCallback(std::function callback); ButtonData& getButtonDate() { m_buttonData.rect = m_rect; return m_buttonData; } + /** + * @brief 处理点击事件 + * @param x 点击位置的X坐标 + * @param y 点击位置的Y坐标 + */ + void handleCilck(int x, int y); + private: - + std::function m_callback; ButtonData m_buttonData; + // 用于在 setText 时测量文本尺寸(非拥有) + TextRenderer* m_textRenderer = nullptr; }; diff --git a/src/ui/managers/GameUIManager.cpp b/src/ui/managers/GameUIManager.cpp index 0b4897f..f10afb2 100644 --- a/src/ui/managers/GameUIManager.cpp +++ b/src/ui/managers/GameUIManager.cpp @@ -1,8 +1,9 @@ #include "GameUIManager.h" - -GameUIManager::GameUIManager() +#include "utils/CoordinateTools.h" +GameUIManager::GameUIManager(SDL_Renderer* renderer, TextRenderer* textRenderer) { - + m_renderer = renderer; + m_textRenderer = textRenderer; } GameUIManager::~GameUIManager() { @@ -10,14 +11,20 @@ GameUIManager::~GameUIManager() { } void GameUIManager::init() { - auto button = std::make_unique