xml elements context

This commit is contained in:
MihailRis 2024-03-19 14:54:50 +03:00
parent 4b6c61ad89
commit 8b8bc55ff7
6 changed files with 48 additions and 14 deletions

View File

@ -196,8 +196,13 @@ xmlelement Parser::parseOpenTag() {
if (peek() == '=') {
nextChar();
skipWhitespace();
expect('"');
attrtext = parseString('"');
char quote = peek();
if (quote != '\'' && quote != '"') {
throw error("string literal expected");
}
skip(1);
attrtext = parseString(quote);
}
node->set(attrname, attrtext);
}

View File

@ -284,9 +284,7 @@ void create_404_page(Engine* engine) {
auto menu = engine->getGUI()->getMenu();
auto panel = menus::create_page(engine, "404", 400, 0.0f, 8);
panel->add(std::make_shared<Label>(
langs::get(L"Page does not exists", L"menu"))
);
panel->add(guiutil::create("<label context='menu'>@Page does not exists</label>"));
panel->add(guiutil::backButton(menu));
}

View File

@ -1,9 +1,11 @@
#include "gui_util.h"
#include "elements/controls.h"
#include "elements/containers.h"
#include "gui_xml.h"
#include <glm/glm.hpp>
#include "../../logic/scripting/scripting.h"
#include "../../frontend/locale/langs.h"
#include "../../delegates.h"
@ -32,6 +34,12 @@ std::shared_ptr<Button> guiutil::gotoButton(
});
}
std::shared_ptr<gui::UINode> guiutil::create(const std::string& source) {
scripting::Environment env(0);
UiXmlReader reader(env);
return reader.readXML("<string>", source);
}
void guiutil::alert(GUI* gui, const std::wstring& text, runnable on_hidden) {
auto menu = gui->getMenu();
auto panel = std::make_shared<Panel>(glm::vec2(500, 200), glm::vec4(8.0f), 8.0f);

View File

@ -21,6 +21,10 @@ namespace guiutil {
std::shared_ptr<gui::PagesControl> menu
);
/// @brief Create element from XML
/// @param source XML
std::shared_ptr<gui::UINode> create(const std::string& source);
void alert(
gui::GUI* gui,
const std::wstring& text,

View File

@ -146,22 +146,25 @@ static void _readPanel(UiXmlReader& reader, xml::xmlelement element, Panel& pane
}
}
static std::wstring readAndProcessInnerText(xml::xmlelement element) {
static std::wstring readAndProcessInnerText(xml::xmlelement element, const std::string& context) {
std::wstring text = L"";
if (element->size() == 1) {
std::string source = element->sub(0)->attr("#").getText();
util::trim(source);
text = util::str2wstr_utf8(source);
if (text[0] == '@') {
text = langs::get(text.substr(1));
if (context.empty()) {
text = langs::get(text.substr(1));
} else {
text = langs::get(text.substr(1), util::str2wstr_utf8(context));
}
}
}
return text;
}
static std::shared_ptr<UINode> readLabel(UiXmlReader& reader, xml::xmlelement element) {
std::wstring text = readAndProcessInnerText(element);
std::wstring text = readAndProcessInnerText(element, reader.getContext());
auto label = std::make_shared<Label>(text);
_readUINode(reader, element, *label);
if (element->has("valign")) {
@ -194,7 +197,7 @@ static std::shared_ptr<UINode> readPanel(UiXmlReader& reader, xml::xmlelement el
}
static std::shared_ptr<UINode> readButton(UiXmlReader& reader, xml::xmlelement element) {
std::wstring text = readAndProcessInnerText(element);
std::wstring text = readAndProcessInnerText(element, reader.getContext());
auto button = std::make_shared<Button>(text, glm::vec4(0.0f), nullptr);
_readPanel(reader, element, *button);
@ -218,7 +221,7 @@ static std::shared_ptr<UINode> readButton(UiXmlReader& reader, xml::xmlelement e
}
static std::shared_ptr<UINode> readCheckBox(UiXmlReader& reader, xml::xmlelement element) {
auto text = readAndProcessInnerText(element);
auto text = readAndProcessInnerText(element, reader.getContext());
bool checked = element->attr("checked", "false").asBool();
auto checkbox = std::make_shared<FullCheckBox>(text, glm::vec2(), checked);
_readPanel(reader, element, *checkbox);
@ -245,7 +248,7 @@ static std::shared_ptr<UINode> readCheckBox(UiXmlReader& reader, xml::xmlelement
static std::shared_ptr<UINode> readTextBox(UiXmlReader& reader, xml::xmlelement element) {
auto placeholder = util::str2wstr_utf8(element->attr("placeholder", "").getText());
auto text = readAndProcessInnerText(element);
auto text = readAndProcessInnerText(element, reader.getContext());
auto textbox = std::make_shared<TextBox>(placeholder, glm::vec4(0.0f));
_readPanel(reader, element, *textbox);
textbox->setText(text);
@ -330,6 +333,7 @@ static std::shared_ptr<UINode> readTrackBar(UiXmlReader& reader, xml::xmlelement
}
UiXmlReader::UiXmlReader(const scripting::Environment& env) : env(env) {
contextStack.push("");
add("image", readImage);
add("label", readLabel);
add("panel", readPanel);
@ -354,7 +358,6 @@ void UiXmlReader::addIgnore(const std::string& tag) {
std::shared_ptr<UINode> UiXmlReader::readUINode(xml::xmlelement element) {
const std::string& tag = element->getTag();
auto found = readers.find(tag);
if (found == readers.end()) {
if (ignored.find(tag) != ignored.end()) {
@ -362,7 +365,16 @@ std::shared_ptr<UINode> UiXmlReader::readUINode(xml::xmlelement element) {
}
throw std::runtime_error("unsupported element '"+tag+"'");
}
return found->second(*this, element);
bool hascontext = element->has("context");
if (hascontext) {
contextStack.push(element->attr("context").getText());
}
auto node = found->second(*this, element);
if (hascontext) {
contextStack.pop();
}
return node;
}
std::shared_ptr<UINode> UiXmlReader::readXML(
@ -383,6 +395,10 @@ std::shared_ptr<UINode> UiXmlReader::readXML(
return readUINode(root);
}
const std::string& UiXmlReader::getContext() const {
return contextStack.top();
}
const std::string& UiXmlReader::getFilename() const {
return filename;
}

View File

@ -2,6 +2,7 @@
#define FRONTEND_GUI_GUI_XML_H_
#include <memory>
#include <stack>
#include <unordered_set>
#include <unordered_map>
@ -20,6 +21,7 @@ namespace gui {
class UiXmlReader {
std::unordered_map<std::string, uinode_reader> readers;
std::unordered_set<std::string> ignored;
std::stack<std::string> contextStack;
std::string filename;
const scripting::Environment& env;
public:
@ -53,6 +55,7 @@ namespace gui {
xml::xmlelement root
);
const std::string& getContext() const;
const scripting::Environment& getEnvironment() const;
const std::string& getFilename() const;
};