mirror of
https://github.com/zhenyan121/SporeBG-Conid.git
synced 2026-04-10 06:14:08 +08:00
Added button handle event
This commit is contained in:
@@ -30,13 +30,16 @@ set(SOURCE_FILES
|
|||||||
src/input/InputManager.cpp
|
src/input/InputManager.cpp
|
||||||
src/scenes/base/SceneManager.cpp
|
src/scenes/base/SceneManager.cpp
|
||||||
src/scenes/gameplay/GameScene.cpp
|
src/scenes/gameplay/GameScene.cpp
|
||||||
|
src/scenes/menu/MainMenuScene.cpp
|
||||||
src/graphics/GameRenderer.cpp
|
src/graphics/GameRenderer.cpp
|
||||||
src/graphics/CoordinateConverter.cpp
|
src/graphics/CoordinateConverter.cpp
|
||||||
src/utils/CoordinateTools.cpp
|
src/utils/CoordinateTools.cpp
|
||||||
src/graphics/font/FontManager.cpp
|
src/graphics/font/FontManager.cpp
|
||||||
src/graphics/font/TextRenderer.cpp
|
src/graphics/font/TextRenderer.cpp
|
||||||
src/ui/components/Button.cpp
|
src/ui/components/Button.cpp
|
||||||
|
src/ui/components/Label.cpp
|
||||||
src/ui/managers/GameUIManager.cpp
|
src/ui/managers/GameUIManager.cpp
|
||||||
|
src/ui/managers/MainMenuUIManager.cpp
|
||||||
src/graphics/ui/UIRenderer.cpp
|
src/graphics/ui/UIRenderer.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
#include <string>
|
||||||
/**
|
/**
|
||||||
* @brief UI组件抽象基类
|
* @brief UI组件抽象基类
|
||||||
*
|
*
|
||||||
@@ -71,10 +71,26 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isEnabled() const { return m_isEnabled; }
|
bool isEnabled() const { return m_isEnabled; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取组件名称的哈希值
|
||||||
|
* @return 组件名称的哈希值
|
||||||
|
*/
|
||||||
|
size_t getNameHash() const {
|
||||||
|
return std::hash<std::string>{}(m_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 设置组件名称
|
||||||
|
* @param name 组件名称字符串
|
||||||
|
*/
|
||||||
|
void setName(const std::string& name) {
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UIComponent() = default;
|
UIComponent() = default;
|
||||||
SDL_FRect m_rect = {0.0f, 0.0f, 0.0f, 0.0f}; ///< 组件位置和尺寸
|
SDL_FRect m_rect = {0.0f, 0.0f, 0.0f, 0.0f}; ///< 组件位置和尺寸
|
||||||
bool m_isVisible = true; ///< 可见性标志
|
bool m_isVisible = true; ///< 可见性标志
|
||||||
bool m_isEnabled = true; ///< 启用标志
|
bool m_isEnabled = true; ///< 启用标志
|
||||||
|
std::string m_name; ///< 组件名称
|
||||||
};
|
};
|
||||||
@@ -13,8 +13,22 @@ struct ButtonData
|
|||||||
SDL_Color borderColor;
|
SDL_Color borderColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LabelData
|
||||||
|
{
|
||||||
|
std::string text;
|
||||||
|
|
||||||
|
TextStyle textstytle;
|
||||||
|
SDL_FRect rect;
|
||||||
|
SDL_Color backgroundColor;
|
||||||
|
|
||||||
|
int borderThickness;
|
||||||
|
SDL_Color borderColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// 可以通过索引方式实现,及直接传递Button指针, 在UIRender里面调用getData
|
// 可以通过索引方式实现,及直接传递Button指针, 在UIRender里面调用getData
|
||||||
struct UIRenderData
|
struct UIRenderData
|
||||||
{
|
{
|
||||||
std::vector<ButtonData> buttons;
|
std::vector<ButtonData> buttons;
|
||||||
|
std::vector<LabelData> labels;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,15 +1,25 @@
|
|||||||
#include "Button.h"
|
#include "Button.h"
|
||||||
|
#include "graphics/font/TextRenderer.h"
|
||||||
|
|
||||||
Button::Button()
|
Button::Button()
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Button::Button(TextRenderer* textRenderer) : m_textRenderer(textRenderer) {
|
||||||
|
}
|
||||||
|
|
||||||
void Button::setText(const std::string& text, TextStyle style) {
|
void Button::setText(const std::string& text, TextStyle style) {
|
||||||
m_buttonData.text = text;
|
m_buttonData.text = text;
|
||||||
m_buttonData.textstytle = style;
|
m_buttonData.textstytle = style;
|
||||||
|
|
||||||
|
// 如果提供了 TextRenderer,则立即测量文本并更新控件尺寸
|
||||||
|
if (m_textRenderer) {
|
||||||
|
auto [w, h] = m_textRenderer->getTextSize(text, style);
|
||||||
|
m_rect.w = static_cast<float>(w);
|
||||||
|
m_rect.h = static_cast<float>(h);
|
||||||
|
m_buttonData.rect = m_rect;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::setBackgroundColor(SDL_Color normal) {
|
void Button::setBackgroundColor(SDL_Color normal) {
|
||||||
@@ -22,9 +32,23 @@ void Button::setBorder(int thickness, SDL_Color color) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Button::setCallback(std::function<void()> callback) {
|
||||||
|
m_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
void Button::update(float deltaTime) {
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "ui/base/UIRenderData.h"
|
#include "ui/base/UIRenderData.h"
|
||||||
#include "ui/base/UIComponent.h"
|
#include "ui/base/UIComponent.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
// 前向声明,避免在头文件包含过多实现细节
|
||||||
|
class TextRenderer;
|
||||||
|
#include <functional>
|
||||||
class Button : public UIComponent{
|
class Button : public UIComponent{
|
||||||
public:
|
public:
|
||||||
|
// 默认构造(不进行自动测量)
|
||||||
Button();
|
Button();
|
||||||
|
// 可以传入 TextRenderer 指针以便在 setText 时立即计算文字尺寸并更新 rect
|
||||||
|
explicit Button(TextRenderer* textRenderer);
|
||||||
~Button() override = default;
|
~Button() override = default;
|
||||||
|
|
||||||
// 实现UIComponent接口
|
// 实现UIComponent接口
|
||||||
@@ -31,18 +39,28 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setBorder(int thickness, SDL_Color color);
|
void setBorder(int thickness, SDL_Color color);
|
||||||
|
|
||||||
|
void setCallback(std::function<void()> callback);
|
||||||
|
|
||||||
ButtonData& getButtonDate() {
|
ButtonData& getButtonDate() {
|
||||||
m_buttonData.rect = m_rect;
|
m_buttonData.rect = m_rect;
|
||||||
return m_buttonData;
|
return m_buttonData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 处理点击事件
|
||||||
|
* @param x 点击位置的X坐标
|
||||||
|
* @param y 点击位置的Y坐标
|
||||||
|
*/
|
||||||
|
void handleCilck(int x, int y);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::function<void()> m_callback;
|
||||||
ButtonData m_buttonData;
|
ButtonData m_buttonData;
|
||||||
|
// 用于在 setText 时测量文本尺寸(非拥有)
|
||||||
|
TextRenderer* m_textRenderer = nullptr;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#include "GameUIManager.h"
|
#include "GameUIManager.h"
|
||||||
|
#include "utils/CoordinateTools.h"
|
||||||
GameUIManager::GameUIManager()
|
GameUIManager::GameUIManager(SDL_Renderer* renderer, TextRenderer* textRenderer)
|
||||||
{
|
{
|
||||||
|
m_renderer = renderer;
|
||||||
|
m_textRenderer = textRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameUIManager::~GameUIManager() {
|
GameUIManager::~GameUIManager() {
|
||||||
@@ -10,14 +11,20 @@ GameUIManager::~GameUIManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GameUIManager::init() {
|
void GameUIManager::init() {
|
||||||
auto button = std::make_unique<Button>();
|
auto button = std::make_unique<Button>(m_textRenderer);
|
||||||
button->setBackgroundColor({255, 100, 0, 255});
|
button->setBackgroundColor({255, 100, 0, 255});
|
||||||
button->setBorder(2, {0, 0, 0, 255});
|
button->setBorder(2, {0, 0, 0, 255});
|
||||||
button->setPosition(20, 20);
|
button->setPosition(20, 20);
|
||||||
button->setEnabled(true);
|
button->setEnabled(true);
|
||||||
button->setVisible(true);
|
button->setVisible(true);
|
||||||
button->setText("hello,world!!", {"SourceHanSansSC-Regular.otf", 48, {0, 0, 0, 255}});
|
button->setText("hello,world!!", {"SourceHanSansSC-Regular.otf", 48, {0, 0, 0, 255}});
|
||||||
m_buttons.push_back(std::move(button));
|
button->setName("TestButton");
|
||||||
|
m_buttons.emplace(button->getNameHash(), std::move(button));
|
||||||
|
auto label = std::make_unique<Label>();
|
||||||
|
label->setPosition(1200, 20);
|
||||||
|
label->setText("0 0", {"SourceHanSansSC-Regular.otf", 48, {0, 0, 0, 255}});
|
||||||
|
label->setName("MousePositionLabel");
|
||||||
|
m_labels.emplace(label->getNameHash(), std::move(label));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -32,12 +39,31 @@ void GameUIManager::CollectRenderData() {
|
|||||||
//SDL_Log("CollectRenderData called. buttons count = %zu", m_buttons.size());
|
//SDL_Log("CollectRenderData called. buttons count = %zu", m_buttons.size());
|
||||||
// 清理上一帧的数据
|
// 清理上一帧的数据
|
||||||
m_uiRenderData.buttons.clear();
|
m_uiRenderData.buttons.clear();
|
||||||
|
m_uiRenderData.labels.clear();
|
||||||
//SDL_Log("collect data\n");
|
//SDL_Log("collect data\n");
|
||||||
for (auto& button : m_buttons) {
|
for (auto& button : m_buttons) {
|
||||||
if(!button->isVisible()) {
|
if(!button.second->isVisible()) {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
m_uiRenderData.buttons.push_back(button->getButtonDate());
|
m_uiRenderData.buttons.push_back(button.second->getButtonDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& label : m_labels) {
|
||||||
|
if(!label.second->isVisible()) {
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
m_uiRenderData.labels.push_back(label.second->getLabelDate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameUIManager::UpdateMousePositon(float x, float y) {
|
||||||
|
|
||||||
|
auto logicalPos = physicalToLogical(static_cast<float>(x), static_cast<float>(y), m_renderer);
|
||||||
|
int lx = logicalPos.first;
|
||||||
|
int ly = logicalPos.second;
|
||||||
|
std::string pos = std::to_string(lx) + " " + std::to_string(ly);
|
||||||
|
|
||||||
|
m_labels[makeHash("MousePositionLabel")]->setText(pos);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <SDL3/SDL.h>
|
#include "ui/base/IUIManager.h"
|
||||||
#include <SDL3_ttf/SDL_ttf.h>
|
|
||||||
#include "ui/components/Button.h"
|
|
||||||
#include "ui/base/UIRenderData.h"
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
class GameUIManager {
|
|
||||||
private:
|
|
||||||
std::vector<std::unique_ptr<Button>> m_buttons;
|
|
||||||
UIRenderData m_uiRenderData;
|
|
||||||
|
|
||||||
|
class GameUIManager : public IUIManager {
|
||||||
|
private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameUIManager();
|
GameUIManager(SDL_Renderer* renderer, TextRenderer* textRenderer);
|
||||||
|
|
||||||
~GameUIManager();
|
~GameUIManager();
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
@@ -19,4 +14,6 @@ public:
|
|||||||
const UIRenderData& getUIRenderData();
|
const UIRenderData& getUIRenderData();
|
||||||
// 收集渲染数据
|
// 收集渲染数据
|
||||||
void CollectRenderData();
|
void CollectRenderData();
|
||||||
|
|
||||||
|
void UpdateMousePositon(float x, float y);
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user