diff options
author | crupest <crupest@outlook.com> | 2022-02-23 21:28:53 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-02-23 21:28:53 +0800 |
commit | 603f46e195823530bafda97f0dda1a332cc39dc8 (patch) | |
tree | 3378c68e09a4225b172b182a805b0a906233ee83 /src/ui/ThemeResourceDictionary.cpp | |
parent | 81b3bfede96dd606597f609985c68994ec0e9ad4 (diff) | |
download | cru-603f46e195823530bafda97f0dda1a332cc39dc8.tar.gz cru-603f46e195823530bafda97f0dda1a332cc39dc8.tar.bz2 cru-603f46e195823530bafda97f0dda1a332cc39dc8.zip |
...
Diffstat (limited to 'src/ui/ThemeResourceDictionary.cpp')
-rw-r--r-- | src/ui/ThemeResourceDictionary.cpp | 57 |
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 |