aboutsummaryrefslogtreecommitdiff
path: root/src/ui/ThemeResourceDictionary.cpp
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-02-23 21:28:53 +0800
committercrupest <crupest@outlook.com>2022-02-23 21:28:53 +0800
commit603f46e195823530bafda97f0dda1a332cc39dc8 (patch)
tree3378c68e09a4225b172b182a805b0a906233ee83 /src/ui/ThemeResourceDictionary.cpp
parent81b3bfede96dd606597f609985c68994ec0e9ad4 (diff)
downloadcru-603f46e195823530bafda97f0dda1a332cc39dc8.tar.gz
cru-603f46e195823530bafda97f0dda1a332cc39dc8.tar.bz2
cru-603f46e195823530bafda97f0dda1a332cc39dc8.zip
...
Diffstat (limited to 'src/ui/ThemeResourceDictionary.cpp')
-rw-r--r--src/ui/ThemeResourceDictionary.cpp57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/ui/ThemeResourceDictionary.cpp b/src/ui/ThemeResourceDictionary.cpp
new file mode 100644
index 00000000..d9483f6c
--- /dev/null
+++ b/src/ui/ThemeResourceDictionary.cpp
@@ -0,0 +1,57 @@
+#include "cru/ui/ThemeResourceDictionary.h"
+#include "cru/common/io/FileStream.h"
+#include "cru/common/log/Logger.h"
+#include "cru/xml/XmlNode.h"
+#include "cru/xml/XmlParser.h"
+
+namespace cru::ui {
+
+std::unique_ptr<ThemeResourceDictionary> ThemeResourceDictionary::FromFile(
+ const String& file_path) {
+ io::FileStream stream(file_path, io::OpenFileFlags::Read);
+ auto xml_string = stream.ReadAllAsString();
+ auto parser = xml::XmlParser(xml_string);
+ return std::make_unique<ThemeResourceDictionary>(parser.Parse(), false);
+}
+
+ThemeResourceDictionary::ThemeResourceDictionary(xml::XmlElementNode* xml_root,
+ bool clone) {
+ Expects(xml_root);
+ xml_root_.reset(clone ? xml_root->Clone()->AsElement() : xml_root);
+ UpdateResourceMap(xml_root_.get());
+}
+
+ThemeResourceDictionary::~ThemeResourceDictionary() = default;
+
+void ThemeResourceDictionary::UpdateResourceMap(xml::XmlElementNode* xml_root) {
+ if (!xml_root->GetTag().CaseInsensitiveEqual(u"Theme")) {
+ throw Exception(u"Root tag of theme must be 'Theme'.");
+ }
+
+ for (auto child : xml_root->GetChildren()) {
+ if (child->IsElementNode()) {
+ auto c = child->AsElement();
+ if (c->GetTag().CaseInsensitiveEqual(u"Resource")) {
+ auto key_attr = c->GetOptionalAttributeCaseInsensitive(u"key");
+ if (!key_attr) {
+ throw Exception(u"'key' attribute is required for resource.");
+ }
+ if (c->GetChildElementCount() != 1) {
+ throw Exception(u"Resource must have only one child element.");
+ }
+
+ ResourceEntry entry;
+
+ entry.name = *key_attr;
+ entry.xml_node = c->GetFirstChildElement();
+
+ resource_map_[entry.name] = std::move(entry);
+ } else {
+ CRU_LOG_DEBUG(u"Ignore unknown element {} of theme.", c->GetTag());
+ }
+ } else {
+ CRU_LOG_WARN(u"Ignore text node of theme.");
+ }
+ }
+}
+} // namespace cru::ui