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
+7 -2
View File
@@ -196,8 +196,13 @@ xmlelement Parser::parseOpenTag() {
if (peek() == '=') { if (peek() == '=') {
nextChar(); nextChar();
skipWhitespace(); skipWhitespace();
expect('"');
attrtext = parseString('"'); char quote = peek();
if (quote != '\'' && quote != '"') {
throw error("string literal expected");
}
skip(1);
attrtext = parseString(quote);
} }
node->set(attrname, attrtext); node->set(attrname, attrtext);
} }
+1 -3
View File
@@ -284,9 +284,7 @@ void create_404_page(Engine* engine) {
auto menu = engine->getGUI()->getMenu(); auto menu = engine->getGUI()->getMenu();
auto panel = menus::create_page(engine, "404", 400, 0.0f, 8); auto panel = menus::create_page(engine, "404", 400, 0.0f, 8);
panel->add(std::make_shared<Label>( panel->add(guiutil::create("<label context='menu'>@Page does not exists</label>"));
langs::get(L"Page does not exists", L"menu"))
);
panel->add(guiutil::backButton(menu)); panel->add(guiutil::backButton(menu));
} }
+8
View File
@@ -1,9 +1,11 @@
#include "gui_util.h" #include "gui_util.h"
#include "elements/controls.h" #include "elements/controls.h"
#include "elements/containers.h" #include "elements/containers.h"
#include "gui_xml.h"
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "../../logic/scripting/scripting.h"
#include "../../frontend/locale/langs.h" #include "../../frontend/locale/langs.h"
#include "../../delegates.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) { void guiutil::alert(GUI* gui, const std::wstring& text, runnable on_hidden) {
auto menu = gui->getMenu(); auto menu = gui->getMenu();
auto panel = std::make_shared<Panel>(glm::vec2(500, 200), glm::vec4(8.0f), 8.0f); auto panel = std::make_shared<Panel>(glm::vec2(500, 200), glm::vec4(8.0f), 8.0f);
+4
View File
@@ -21,6 +21,10 @@ namespace guiutil {
std::shared_ptr<gui::PagesControl> menu 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( void alert(
gui::GUI* gui, gui::GUI* gui,
const std::wstring& text, const std::wstring& text,
+25 -9
View File
@@ -146,22 +146,25 @@ static void _readPanel(UiXmlReader& reader, xml::xmlelement element, Panel& pane
} }
} }
static std::wstring readAndProcessInnerText(xml::xmlelement element, const std::string& context) {
static std::wstring readAndProcessInnerText(xml::xmlelement element) {
std::wstring text = L""; std::wstring text = L"";
if (element->size() == 1) { if (element->size() == 1) {
std::string source = element->sub(0)->attr("#").getText(); std::string source = element->sub(0)->attr("#").getText();
util::trim(source); util::trim(source);
text = util::str2wstr_utf8(source); text = util::str2wstr_utf8(source);
if (text[0] == '@') { 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; return text;
} }
static std::shared_ptr<UINode> readLabel(UiXmlReader& reader, xml::xmlelement element) { 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); auto label = std::make_shared<Label>(text);
_readUINode(reader, element, *label); _readUINode(reader, element, *label);
if (element->has("valign")) { 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) { 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); auto button = std::make_shared<Button>(text, glm::vec4(0.0f), nullptr);
_readPanel(reader, element, *button); _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) { 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(); bool checked = element->attr("checked", "false").asBool();
auto checkbox = std::make_shared<FullCheckBox>(text, glm::vec2(), checked); auto checkbox = std::make_shared<FullCheckBox>(text, glm::vec2(), checked);
_readPanel(reader, element, *checkbox); _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) { static std::shared_ptr<UINode> readTextBox(UiXmlReader& reader, xml::xmlelement element) {
auto placeholder = util::str2wstr_utf8(element->attr("placeholder", "").getText()); 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)); auto textbox = std::make_shared<TextBox>(placeholder, glm::vec4(0.0f));
_readPanel(reader, element, *textbox); _readPanel(reader, element, *textbox);
textbox->setText(text); 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) { UiXmlReader::UiXmlReader(const scripting::Environment& env) : env(env) {
contextStack.push("");
add("image", readImage); add("image", readImage);
add("label", readLabel); add("label", readLabel);
add("panel", readPanel); add("panel", readPanel);
@@ -354,7 +358,6 @@ void UiXmlReader::addIgnore(const std::string& tag) {
std::shared_ptr<UINode> UiXmlReader::readUINode(xml::xmlelement element) { std::shared_ptr<UINode> UiXmlReader::readUINode(xml::xmlelement element) {
const std::string& tag = element->getTag(); const std::string& tag = element->getTag();
auto found = readers.find(tag); auto found = readers.find(tag);
if (found == readers.end()) { if (found == readers.end()) {
if (ignored.find(tag) != ignored.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+"'"); 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( std::shared_ptr<UINode> UiXmlReader::readXML(
@@ -383,6 +395,10 @@ std::shared_ptr<UINode> UiXmlReader::readXML(
return readUINode(root); return readUINode(root);
} }
const std::string& UiXmlReader::getContext() const {
return contextStack.top();
}
const std::string& UiXmlReader::getFilename() const { const std::string& UiXmlReader::getFilename() const {
return filename; return filename;
} }
+3
View File
@@ -2,6 +2,7 @@
#define FRONTEND_GUI_GUI_XML_H_ #define FRONTEND_GUI_GUI_XML_H_
#include <memory> #include <memory>
#include <stack>
#include <unordered_set> #include <unordered_set>
#include <unordered_map> #include <unordered_map>
@@ -20,6 +21,7 @@ namespace gui {
class UiXmlReader { class UiXmlReader {
std::unordered_map<std::string, uinode_reader> readers; std::unordered_map<std::string, uinode_reader> readers;
std::unordered_set<std::string> ignored; std::unordered_set<std::string> ignored;
std::stack<std::string> contextStack;
std::string filename; std::string filename;
const scripting::Environment& env; const scripting::Environment& env;
public: public:
@@ -53,6 +55,7 @@ namespace gui {
xml::xmlelement root xml::xmlelement root
); );
const std::string& getContext() const;
const scripting::Environment& getEnvironment() const; const scripting::Environment& getEnvironment() const;
const std::string& getFilename() const; const std::string& getFilename() const;
}; };