Merge branch 'spark'
This commit is contained in:
commit
46d7a2a25d
105
resources/config/multiplayer_menu.json
Normal file
105
resources/config/multiplayer_menu.json
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"type": "LinearLayout",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": 1920,
|
||||||
|
"height": 1080,
|
||||||
|
"orientation": "vertical",
|
||||||
|
"spacing": 20,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "TextView",
|
||||||
|
"name": "titleText",
|
||||||
|
"x": 300,
|
||||||
|
"y": 100,
|
||||||
|
"width": 1320,
|
||||||
|
"height": 100,
|
||||||
|
"text": "Multiplayer",
|
||||||
|
"fontPath": "resources/fonts/DroidSans.ttf",
|
||||||
|
"fontSize": 72,
|
||||||
|
"color": [1, 1, 1, 1],
|
||||||
|
"centered": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextView",
|
||||||
|
"name": "serverLabel",
|
||||||
|
"x": 400,
|
||||||
|
"y": 250,
|
||||||
|
"width": 1120,
|
||||||
|
"height": 50,
|
||||||
|
"text": "Enter server name or IP:",
|
||||||
|
"fontPath": "resources/fonts/DroidSans.ttf",
|
||||||
|
"fontSize": 32,
|
||||||
|
"color": [1, 1, 1, 1],
|
||||||
|
"centered": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextField",
|
||||||
|
"name": "serverInputField",
|
||||||
|
"x": 400,
|
||||||
|
"y": 320,
|
||||||
|
"width": 1120,
|
||||||
|
"height": 60,
|
||||||
|
"placeholder": "Enter server name or IP",
|
||||||
|
"fontPath": "resources/fonts/DroidSans.ttf",
|
||||||
|
"fontSize": 28,
|
||||||
|
"maxLength": 256,
|
||||||
|
"color": [1, 1, 1, 1],
|
||||||
|
"placeholderColor": [0.6, 0.6, 0.6, 1],
|
||||||
|
"backgroundColor": [0.15, 0.15, 0.15, 1],
|
||||||
|
"borderColor": [0.7, 0.7, 0.7, 1]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "LinearLayout",
|
||||||
|
"x": 400,
|
||||||
|
"y": 450,
|
||||||
|
"width": 1120,
|
||||||
|
"height": 80,
|
||||||
|
"orientation": "horizontal",
|
||||||
|
"spacing": 30,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"type": "Button",
|
||||||
|
"name": "connectButton",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": 530,
|
||||||
|
"height": 80,
|
||||||
|
"textures": {
|
||||||
|
"normal": "resources/main_menu/single.png",
|
||||||
|
"hover": "resources/main_menu/single.png",
|
||||||
|
"pressed": "resources/main_menu/single.png"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Button",
|
||||||
|
"name": "backButton",
|
||||||
|
"x": 590,
|
||||||
|
"y": 0,
|
||||||
|
"width": 530,
|
||||||
|
"height": 80,
|
||||||
|
"textures": {
|
||||||
|
"normal": "resources/main_menu/exit.png",
|
||||||
|
"hover": "resources/main_menu/exit.png",
|
||||||
|
"pressed": "resources/main_menu/exit.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "TextView",
|
||||||
|
"name": "statusText",
|
||||||
|
"x": 400,
|
||||||
|
"y": 580,
|
||||||
|
"width": 1120,
|
||||||
|
"height": 50,
|
||||||
|
"text": "Ready to connect",
|
||||||
|
"fontPath": "resources/fonts/DroidSans.ttf",
|
||||||
|
"fontSize": 24,
|
||||||
|
"color": [0.8, 0.8, 0.8, 1],
|
||||||
|
"centered": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
79
src/Game.cpp
79
src/Game.cpp
@ -405,9 +405,53 @@ namespace ZL
|
|||||||
std::cerr << "Single button pressed: " << name << " -> load gameplay UI\n";
|
std::cerr << "Single button pressed: " << name << " -> load gameplay UI\n";
|
||||||
loadGameplayUI();
|
loadGameplayUI();
|
||||||
});
|
});
|
||||||
uiManager.setButtonCallback("multiplayerButton", [loadGameplayUI](const std::string& name) {
|
/*uiManager.setButtonCallback("multiplayerButton", [loadGameplayUI](const std::string& name) {
|
||||||
std::cerr << "Multiplayer button pressed: " << name << " -> load gameplay UI\n";
|
std::cerr << "Multiplayer button pressed: " << name << " -> load gameplay UI\n";
|
||||||
loadGameplayUI();
|
loadGameplayUI();
|
||||||
|
});*/
|
||||||
|
|
||||||
|
uiManager.setButtonCallback("multiplayerButton", [this](const std::string& name) {
|
||||||
|
std::cerr << "Multiplayer button pressed → opening multiplayer menu\n";
|
||||||
|
|
||||||
|
uiManager.startAnimationOnNode("playButton", "buttonsExit");
|
||||||
|
uiManager.startAnimationOnNode("settingsButton", "buttonsExit");
|
||||||
|
uiManager.startAnimationOnNode("multiplayerButton", "buttonsExit");
|
||||||
|
uiManager.startAnimationOnNode("exitButton", "buttonsExit");
|
||||||
|
|
||||||
|
if (uiManager.pushMenuFromFile("resources/config/multiplayer_menu.json", this->renderer, CONST_ZIP_FILE)) {
|
||||||
|
|
||||||
|
// Callback для кнопки подключения
|
||||||
|
uiManager.setButtonCallback("connectButton", [this](const std::string& buttonName) {
|
||||||
|
std::string serverAddress = uiManager.getTextFieldValue("serverInputField");
|
||||||
|
|
||||||
|
if (serverAddress.empty()) {
|
||||||
|
uiManager.setText("statusText", "Please enter server address");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uiManager.setText("statusText", "Connecting to " + serverAddress + "...");
|
||||||
|
std::cerr << "Connecting to server: " << serverAddress << std::endl;
|
||||||
|
|
||||||
|
// Здесь добавить вашу логику подключения к серверу
|
||||||
|
// connectToServer(serverAddress);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Callback для кнопки назад
|
||||||
|
uiManager.setButtonCallback("backButton", [this](const std::string& buttonName) {
|
||||||
|
uiManager.popMenu();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Callback для отслеживания ввода текста
|
||||||
|
uiManager.setTextFieldCallback("serverInputField",
|
||||||
|
[this](const std::string& fieldName, const std::string& newText) {
|
||||||
|
std::cout << "Server input field changed to: " << newText << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
std::cerr << "Multiplayer menu loaded successfully\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "Failed to load multiplayer menu\n";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
uiManager.setButtonCallback("exitButton", [](const std::string& name) {
|
uiManager.setButtonCallback("exitButton", [](const std::string& name) {
|
||||||
std::cerr << "Exit from main menu pressed: " << name << " -> exiting\n";
|
std::cerr << "Exit from main menu pressed: " << name << " -> exiting\n";
|
||||||
@ -1670,10 +1714,8 @@ namespace ZL
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
if (event.type == SDL_FINGERDOWN) {
|
if (event.type == SDL_FINGERDOWN) {
|
||||||
// Координаты Finger в SDL нормализованы от 0.0 до 1.0
|
|
||||||
int mx = static_cast<int>(event.tfinger.x * Environment::width);
|
int mx = static_cast<int>(event.tfinger.x * Environment::width);
|
||||||
int my = static_cast<int>(event.tfinger.y * Environment::height);
|
int my = static_cast<int>(event.tfinger.y * Environment::height);
|
||||||
handleDown(mx, my);
|
handleDown(mx, my);
|
||||||
@ -1689,24 +1731,20 @@ namespace ZL
|
|||||||
handleMotion(mx, my);
|
handleMotion(mx, my);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (event.type == SDL_MOUSEBUTTONDOWN) {
|
if (event.type == SDL_MOUSEBUTTONDOWN) {
|
||||||
int mx = event.button.x;
|
int mx = event.button.x;
|
||||||
int my = event.button.y;
|
int my = event.button.y;
|
||||||
handleDown(mx, my);
|
handleDown(mx, my);
|
||||||
}
|
}
|
||||||
if (event.type == SDL_MOUSEBUTTONUP) {
|
if (event.type == SDL_MOUSEBUTTONUP) {
|
||||||
|
|
||||||
int mx = event.button.x;
|
int mx = event.button.x;
|
||||||
int my = event.button.y;
|
int my = event.button.y;
|
||||||
handleUp(mx, my);
|
handleUp(mx, my);
|
||||||
}
|
}
|
||||||
if (event.type == SDL_MOUSEMOTION) {
|
if (event.type == SDL_MOUSEMOTION) {
|
||||||
|
|
||||||
int mx = event.motion.x;
|
int mx = event.motion.x;
|
||||||
int my = event.motion.y;
|
int my = event.motion.y;
|
||||||
handleMotion(mx, my);
|
handleMotion(mx, my);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.type == SDL_MOUSEWHEEL) {
|
if (event.type == SDL_MOUSEWHEEL) {
|
||||||
@ -1721,18 +1759,29 @@ namespace ZL
|
|||||||
Environment::zoom = zoomstep;
|
Environment::zoom = zoomstep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (event.type == SDL_KEYUP)
|
|
||||||
{
|
// Обработка ввода текста
|
||||||
if (event.key.keysym.sym == SDLK_i)
|
if (event.type == SDL_KEYDOWN) {
|
||||||
{
|
if (event.key.keysym.sym == SDLK_BACKSPACE) {
|
||||||
|
uiManager.onKeyBackspace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.type == SDL_TEXTINPUT) {
|
||||||
|
// Пропускаем ctrl+c и другие команды
|
||||||
|
if ((event.text.text[0] & 0x80) == 0) { // ASCII символы
|
||||||
|
uiManager.onKeyPress((unsigned char)event.text.text[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.type == SDL_KEYUP) {
|
||||||
|
if (event.key.keysym.sym == SDLK_i) {
|
||||||
x = x + 1;
|
x = x + 1;
|
||||||
}
|
}
|
||||||
if (event.key.keysym.sym == SDLK_k)
|
if (event.key.keysym.sym == SDLK_k) {
|
||||||
{
|
|
||||||
x = x - 1;
|
x = x - 1;
|
||||||
}
|
}
|
||||||
if (event.key.keysym.sym == SDLK_a)
|
if (event.key.keysym.sym == SDLK_a) {
|
||||||
{
|
|
||||||
Environment::shipState.position = { 9466.15820, 1046.00159, 18531.2090 };
|
Environment::shipState.position = { 9466.15820, 1046.00159, 18531.2090 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -168,6 +168,20 @@ namespace ZL {
|
|||||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
renderer.DisableVertexAttribArray(vTexCoordName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UiTextField::draw(Renderer& renderer) const {
|
||||||
|
if (textRenderer) {
|
||||||
|
float textX = rect.x + 10.0f;
|
||||||
|
float textY = rect.y + rect.h / 2.0f;
|
||||||
|
|
||||||
|
if (text.empty()) {
|
||||||
|
textRenderer->drawText(placeholder, textX, textY, 1.0f, false, placeholderColor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
textRenderer->drawText(text, textX, textY, 1.0f, false, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UiManager::loadFromFile(const std::string& path, Renderer& renderer, const std::string& zipFile) {
|
void UiManager::loadFromFile(const std::string& path, Renderer& renderer, const std::string& zipFile) {
|
||||||
std::string content;
|
std::string content;
|
||||||
try {
|
try {
|
||||||
@ -207,6 +221,7 @@ namespace ZL {
|
|||||||
buttons.clear();
|
buttons.clear();
|
||||||
sliders.clear();
|
sliders.clear();
|
||||||
textViews.clear();
|
textViews.clear();
|
||||||
|
textFields.clear();
|
||||||
collectButtonsAndSliders(root);
|
collectButtonsAndSliders(root);
|
||||||
|
|
||||||
nodeActiveAnims.clear();
|
nodeActiveAnims.clear();
|
||||||
@ -277,7 +292,7 @@ namespace ZL {
|
|||||||
if (!t.contains(key) || !t[key].is_string()) return nullptr;
|
if (!t.contains(key) || !t[key].is_string()) return nullptr;
|
||||||
std::string path = t[key].get<std::string>();
|
std::string path = t[key].get<std::string>();
|
||||||
try {
|
try {
|
||||||
std::cout << "UiManager: --loading texture for button '" << "' : " << path << " Zip file: " << zipFile << std::endl;
|
std::cout << "UiManager: --loading texture for slider '" << s->name << "' : " << path << " Zip file: " << zipFile << std::endl;
|
||||||
auto data = CreateTextureDataFromPng(path.c_str(), zipFile.c_str());
|
auto data = CreateTextureDataFromPng(path.c_str(), zipFile.c_str());
|
||||||
return std::make_shared<Texture>(data);
|
return std::make_shared<Texture>(data);
|
||||||
}
|
}
|
||||||
@ -299,6 +314,44 @@ namespace ZL {
|
|||||||
|
|
||||||
node->slider = s;
|
node->slider = s;
|
||||||
}
|
}
|
||||||
|
else if (node->type == "TextField") {
|
||||||
|
auto tf = std::make_shared<UiTextField>();
|
||||||
|
tf->name = node->name;
|
||||||
|
tf->rect = node->rect;
|
||||||
|
|
||||||
|
if (j.contains("placeholder")) tf->placeholder = j["placeholder"].get<std::string>();
|
||||||
|
if (j.contains("fontPath")) tf->fontPath = j["fontPath"].get<std::string>();
|
||||||
|
if (j.contains("fontSize")) tf->fontSize = j["fontSize"].get<int>();
|
||||||
|
if (j.contains("maxLength")) tf->maxLength = j["maxLength"].get<int>();
|
||||||
|
|
||||||
|
if (j.contains("color") && j["color"].is_array() && j["color"].size() == 4) {
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
tf->color[i] = j["color"][i].get<float>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j.contains("placeholderColor") && j["placeholderColor"].is_array() && j["placeholderColor"].size() == 4) {
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
tf->placeholderColor[i] = j["placeholderColor"][i].get<float>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j.contains("backgroundColor") && j["backgroundColor"].is_array() && j["backgroundColor"].size() == 4) {
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
tf->backgroundColor[i] = j["backgroundColor"][i].get<float>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j.contains("borderColor") && j["borderColor"].is_array() && j["borderColor"].size() == 4) {
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
tf->borderColor[i] = j["borderColor"][i].get<float>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tf->textRenderer = std::make_unique<TextRenderer>();
|
||||||
|
if (!tf->textRenderer->init(renderer, tf->fontPath, tf->fontSize, zipFile)) {
|
||||||
|
std::cerr << "Failed to init TextRenderer for TextField: " << tf->name << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->textField = tf;
|
||||||
|
}
|
||||||
|
|
||||||
if (j.contains("animations") && j["animations"].is_object()) {
|
if (j.contains("animations") && j["animations"].is_object()) {
|
||||||
for (auto it = j["animations"].begin(); it != j["animations"].end(); ++it) {
|
for (auto it = j["animations"].begin(); it != j["animations"].end(); ++it) {
|
||||||
@ -406,7 +459,10 @@ namespace ZL {
|
|||||||
if (node->textView) {
|
if (node->textView) {
|
||||||
textViews.push_back(node->textView);
|
textViews.push_back(node->textView);
|
||||||
}
|
}
|
||||||
for (auto& c : node->children) collectButtonsAndSliders(c); // ìîæíî ïåðåèìåíîâàòü â collectControls
|
if (node->textField) {
|
||||||
|
textFields.push_back(node->textField);
|
||||||
|
}
|
||||||
|
for (auto& c : node->children) collectButtonsAndSliders(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UiManager::setButtonCallback(const std::string& name, std::function<void(const std::string&)> cb) {
|
bool UiManager::setButtonCallback(const std::string& name, std::function<void(const std::string&)> cb) {
|
||||||
@ -476,13 +532,36 @@ namespace ZL {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<UiTextField> UiManager::findTextField(const std::string& name) {
|
||||||
|
for (auto& tf : textFields) if (tf->name == name) return tf;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UiManager::setTextFieldCallback(const std::string& name, std::function<void(const std::string&, const std::string&)> cb) {
|
||||||
|
auto tf = findTextField(name);
|
||||||
|
if (!tf) {
|
||||||
|
std::cerr << "UiManager: setTextFieldCallback failed, textfield not found: " << name << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tf->onTextChanged = std::move(cb);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UiManager::getTextFieldValue(const std::string& name) {
|
||||||
|
auto tf = findTextField(name);
|
||||||
|
if (!tf) return "";
|
||||||
|
return tf->text;
|
||||||
|
}
|
||||||
|
|
||||||
bool UiManager::pushMenuFromFile(const std::string& path, Renderer& renderer, const std::string& zipFile) {
|
bool UiManager::pushMenuFromFile(const std::string& path, Renderer& renderer, const std::string& zipFile) {
|
||||||
MenuState prev;
|
MenuState prev;
|
||||||
prev.root = root;
|
prev.root = root;
|
||||||
prev.buttons = buttons;
|
prev.buttons = buttons;
|
||||||
prev.sliders = sliders;
|
prev.sliders = sliders;
|
||||||
|
prev.textFields = textFields;
|
||||||
prev.pressedButton = pressedButton;
|
prev.pressedButton = pressedButton;
|
||||||
prev.pressedSlider = pressedSlider;
|
prev.pressedSlider = pressedSlider;
|
||||||
|
prev.focusedTextField = focusedTextField;
|
||||||
prev.path = "";
|
prev.path = "";
|
||||||
|
|
||||||
prev.animCallbacks = animCallbacks;
|
prev.animCallbacks = animCallbacks;
|
||||||
@ -490,6 +569,7 @@ namespace ZL {
|
|||||||
try {
|
try {
|
||||||
nodeActiveAnims.clear();
|
nodeActiveAnims.clear();
|
||||||
animCallbacks.clear();
|
animCallbacks.clear();
|
||||||
|
focusedTextField = nullptr;
|
||||||
for (auto& b : buttons) {
|
for (auto& b : buttons) {
|
||||||
if (b) {
|
if (b) {
|
||||||
b->animOffsetX = 0.0f;
|
b->animOffsetX = 0.0f;
|
||||||
@ -523,8 +603,10 @@ namespace ZL {
|
|||||||
root = s.root;
|
root = s.root;
|
||||||
buttons = s.buttons;
|
buttons = s.buttons;
|
||||||
sliders = s.sliders;
|
sliders = s.sliders;
|
||||||
|
textFields = s.textFields;
|
||||||
pressedButton = s.pressedButton;
|
pressedButton = s.pressedButton;
|
||||||
pressedSlider = s.pressedSlider;
|
pressedSlider = s.pressedSlider;
|
||||||
|
focusedTextField = s.focusedTextField;
|
||||||
|
|
||||||
animCallbacks = s.animCallbacks;
|
animCallbacks = s.animCallbacks;
|
||||||
|
|
||||||
@ -565,6 +647,9 @@ namespace ZL {
|
|||||||
for (const auto& tv : textViews) {
|
for (const auto& tv : textViews) {
|
||||||
tv->draw(renderer);
|
tv->draw(renderer);
|
||||||
}
|
}
|
||||||
|
for (const auto& tf : textFields) {
|
||||||
|
tf->draw(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
renderer.PopMatrix();
|
renderer.PopMatrix();
|
||||||
renderer.PopProjectionMatrix();
|
renderer.PopProjectionMatrix();
|
||||||
@ -785,6 +870,16 @@ namespace ZL {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& tf : textFields) {
|
||||||
|
if (tf->rect.contains((float)x, (float)y)) {
|
||||||
|
focusedTextField = tf;
|
||||||
|
tf->focused = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tf->focused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UiManager::onMouseUp(int x, int y) {
|
void UiManager::onMouseUp(int x, int y) {
|
||||||
@ -806,6 +901,30 @@ namespace ZL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UiManager::onKeyPress(unsigned char key) {
|
||||||
|
if (!focusedTextField) return;
|
||||||
|
|
||||||
|
if (key >= 32 && key <= 126) {
|
||||||
|
if (focusedTextField->text.length() < (size_t)focusedTextField->maxLength) {
|
||||||
|
focusedTextField->text += key;
|
||||||
|
if (focusedTextField->onTextChanged) {
|
||||||
|
focusedTextField->onTextChanged(focusedTextField->name, focusedTextField->text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UiManager::onKeyBackspace() {
|
||||||
|
if (!focusedTextField) return;
|
||||||
|
|
||||||
|
if (!focusedTextField->text.empty()) {
|
||||||
|
focusedTextField->text.pop_back();
|
||||||
|
if (focusedTextField->onTextChanged) {
|
||||||
|
focusedTextField->onTextChanged(focusedTextField->name, focusedTextField->text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<UiButton> UiManager::findButton(const std::string& name) {
|
std::shared_ptr<UiButton> UiManager::findButton(const std::string& name) {
|
||||||
for (auto& b : buttons) if (b->name == name) return b;
|
for (auto& b : buttons) if (b->name == name) return b;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@ -90,6 +90,26 @@ namespace ZL {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UiTextField {
|
||||||
|
std::string name;
|
||||||
|
UiRect rect;
|
||||||
|
std::string text = "";
|
||||||
|
std::string placeholder = "";
|
||||||
|
std::string fontPath = "resources/fonts/DroidSans.ttf";
|
||||||
|
int fontSize = 32;
|
||||||
|
std::array<float, 4> color = { 1.f, 1.f, 1.f, 1.f };
|
||||||
|
std::array<float, 4> placeholderColor = { 0.5f, 0.5f, 0.5f, 1.f };
|
||||||
|
std::array<float, 4> backgroundColor = { 0.2f, 0.2f, 0.2f, 1.f };
|
||||||
|
std::array<float, 4> borderColor = { 0.5f, 0.5f, 0.5f, 1.f };
|
||||||
|
int maxLength = 256;
|
||||||
|
bool focused = false;
|
||||||
|
|
||||||
|
std::unique_ptr<TextRenderer> textRenderer;
|
||||||
|
std::function<void(const std::string&, const std::string&)> onTextChanged;
|
||||||
|
|
||||||
|
void draw(Renderer& renderer) const;
|
||||||
|
};
|
||||||
|
|
||||||
struct UiNode {
|
struct UiNode {
|
||||||
std::string type;
|
std::string type;
|
||||||
UiRect rect;
|
UiRect rect;
|
||||||
@ -98,6 +118,7 @@ namespace ZL {
|
|||||||
std::shared_ptr<UiButton> button;
|
std::shared_ptr<UiButton> button;
|
||||||
std::shared_ptr<UiSlider> slider;
|
std::shared_ptr<UiSlider> slider;
|
||||||
std::shared_ptr<UiTextView> textView;
|
std::shared_ptr<UiTextView> textView;
|
||||||
|
std::shared_ptr<UiTextField> textField;
|
||||||
std::string orientation = "vertical";
|
std::string orientation = "vertical";
|
||||||
float spacing = 0.0f;
|
float spacing = 0.0f;
|
||||||
|
|
||||||
@ -126,9 +147,11 @@ namespace ZL {
|
|||||||
void onMouseMove(int x, int y);
|
void onMouseMove(int x, int y);
|
||||||
void onMouseDown(int x, int y);
|
void onMouseDown(int x, int y);
|
||||||
void onMouseUp(int x, int y);
|
void onMouseUp(int x, int y);
|
||||||
|
void onKeyPress(unsigned char key);
|
||||||
|
void onKeyBackspace();
|
||||||
|
|
||||||
bool isUiInteraction() const {
|
bool isUiInteraction() const {
|
||||||
return pressedButton != nullptr || pressedSlider != nullptr;
|
return pressedButton != nullptr || pressedSlider != nullptr || focusedTextField != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopAllAnimations() {
|
void stopAllAnimations() {
|
||||||
@ -158,6 +181,10 @@ namespace ZL {
|
|||||||
std::shared_ptr<UiTextView> findTextView(const std::string& name);
|
std::shared_ptr<UiTextView> findTextView(const std::string& name);
|
||||||
bool setText(const std::string& name, const std::string& newText);
|
bool setText(const std::string& name, const std::string& newText);
|
||||||
|
|
||||||
|
std::shared_ptr<UiTextField> findTextField(const std::string& name);
|
||||||
|
bool setTextFieldCallback(const std::string& name, std::function<void(const std::string&, const std::string&)> cb);
|
||||||
|
std::string getTextFieldValue(const std::string& name);
|
||||||
|
|
||||||
bool pushMenuFromFile(const std::string& path, Renderer& renderer, const std::string& zipFile = "");
|
bool pushMenuFromFile(const std::string& path, Renderer& renderer, const std::string& zipFile = "");
|
||||||
bool popMenu();
|
bool popMenu();
|
||||||
void clearMenuStack();
|
void clearMenuStack();
|
||||||
@ -200,19 +227,23 @@ namespace ZL {
|
|||||||
std::vector<std::shared_ptr<UiButton>> buttons;
|
std::vector<std::shared_ptr<UiButton>> buttons;
|
||||||
std::vector<std::shared_ptr<UiSlider>> sliders;
|
std::vector<std::shared_ptr<UiSlider>> sliders;
|
||||||
std::vector<std::shared_ptr<UiTextView>> textViews;
|
std::vector<std::shared_ptr<UiTextView>> textViews;
|
||||||
|
std::vector<std::shared_ptr<UiTextField>> textFields;
|
||||||
|
|
||||||
std::map<std::shared_ptr<UiNode>, std::vector<ActiveAnim>> nodeActiveAnims;
|
std::map<std::shared_ptr<UiNode>, std::vector<ActiveAnim>> nodeActiveAnims;
|
||||||
std::map<std::pair<std::string, std::string>, std::function<void()>> animCallbacks; // key: (nodeName, animName)
|
std::map<std::pair<std::string, std::string>, std::function<void()>> animCallbacks; // key: (nodeName, animName)
|
||||||
|
|
||||||
std::shared_ptr<UiButton> pressedButton;
|
std::shared_ptr<UiButton> pressedButton;
|
||||||
std::shared_ptr<UiSlider> pressedSlider;
|
std::shared_ptr<UiSlider> pressedSlider;
|
||||||
|
std::shared_ptr<UiTextField> focusedTextField;
|
||||||
|
|
||||||
struct MenuState {
|
struct MenuState {
|
||||||
std::shared_ptr<UiNode> root;
|
std::shared_ptr<UiNode> root;
|
||||||
std::vector<std::shared_ptr<UiButton>> buttons;
|
std::vector<std::shared_ptr<UiButton>> buttons;
|
||||||
std::vector<std::shared_ptr<UiSlider>> sliders;
|
std::vector<std::shared_ptr<UiSlider>> sliders;
|
||||||
|
std::vector<std::shared_ptr<UiTextField>> textFields;
|
||||||
std::shared_ptr<UiButton> pressedButton;
|
std::shared_ptr<UiButton> pressedButton;
|
||||||
std::shared_ptr<UiSlider> pressedSlider;
|
std::shared_ptr<UiSlider> pressedSlider;
|
||||||
|
std::shared_ptr<UiTextField> focusedTextField;
|
||||||
std::string path;
|
std::string path;
|
||||||
std::map<std::pair<std::string, std::string>, std::function<void()>> animCallbacks;
|
std::map<std::pair<std::string, std::string>, std::function<void()>> animCallbacks;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user