Add UI layout XML automation
This commit is contained in:
71
src/ui_core/layout_xml.cpp
Normal file
71
src/ui_core/layout_xml.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "ui_core/layout_xml.h"
|
||||
|
||||
#include "ui_core/layout_value.h"
|
||||
|
||||
#include <tinyxml2.h>
|
||||
|
||||
namespace pp::ui {
|
||||
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] pp::foundation::Status visit_element(const tinyxml2::XMLElement& element, LayoutParseSummary& summary)
|
||||
{
|
||||
++summary.node_count;
|
||||
|
||||
for (const char* name : { "width", "height" }) {
|
||||
const char* value = element.Attribute(name);
|
||||
if (value == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto length = parse_layout_length(value);
|
||||
if (!length) {
|
||||
return length.status();
|
||||
}
|
||||
++summary.length_attribute_count;
|
||||
}
|
||||
|
||||
for (const tinyxml2::XMLElement* child = element.FirstChildElement();
|
||||
child != nullptr;
|
||||
child = child->NextSiblingElement()) {
|
||||
const auto status = visit_element(*child, summary);
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pp::foundation::Result<LayoutParseSummary> parse_layout_xml(std::string_view xml)
|
||||
{
|
||||
if (xml.empty()) {
|
||||
return pp::foundation::Result<LayoutParseSummary>::failure(
|
||||
pp::foundation::Status::invalid_argument("layout XML must not be empty"));
|
||||
}
|
||||
|
||||
tinyxml2::XMLDocument document;
|
||||
const auto error = document.Parse(xml.data(), xml.size());
|
||||
if (error != tinyxml2::XML_SUCCESS) {
|
||||
return pp::foundation::Result<LayoutParseSummary>::failure(
|
||||
pp::foundation::Status::invalid_argument("layout XML could not be parsed"));
|
||||
}
|
||||
|
||||
const tinyxml2::XMLElement* root = document.RootElement();
|
||||
if (root == nullptr) {
|
||||
return pp::foundation::Result<LayoutParseSummary>::failure(
|
||||
pp::foundation::Status::invalid_argument("layout XML has no root element"));
|
||||
}
|
||||
|
||||
LayoutParseSummary summary;
|
||||
const auto status = visit_element(*root, summary);
|
||||
if (!status.ok()) {
|
||||
return pp::foundation::Result<LayoutParseSummary>::failure(status);
|
||||
}
|
||||
|
||||
return pp::foundation::Result<LayoutParseSummary>::success(summary);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user