From 603f46e195823530bafda97f0dda1a332cc39dc8 Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 23 Feb 2022 21:28:53 +0800 Subject: ... --- include/cru/ui/ThemeManager.h | 71 +++++++-------------------- include/cru/ui/ThemeResourceDictionary.h | 84 ++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 53 deletions(-) create mode 100644 include/cru/ui/ThemeResourceDictionary.h (limited to 'include/cru/ui') diff --git a/include/cru/ui/ThemeManager.h b/include/cru/ui/ThemeManager.h index 9176d85e..9917f219 100644 --- a/include/cru/ui/ThemeManager.h +++ b/include/cru/ui/ThemeManager.h @@ -1,28 +1,11 @@ #pragma once #include "Base.h" -#include "cru/common/Base.h" #include "cru/common/Event.h" -#include "cru/common/Exception.h" -#include "cru/platform/graphics/Brush.h" -#include "cru/ui/mapper/MapperRegistry.h" -#include "cru/ui/style/StyleRuleSet.h" -#include "cru/xml/XmlNode.h" +#include "cru/ui/ThemeResourceDictionary.h" -#include -#include -#include -#include +#include namespace cru::ui { -class CRU_UI_API ThemeResourceKeyNotExistException : public Exception { - public: - using Exception::Exception; -}; - -class CRU_UI_API BadThemeResourceException : public Exception { - public: - using Exception::Exception; -}; class CRU_UI_API ThemeManager : public Object { public: @@ -37,33 +20,21 @@ class CRU_UI_API ThemeManager : public Object { ~ThemeManager() override; - IEvent* ThemeResourceChangeEvent() { - return &theme_resource_change_event_; - } - - void ReadResourcesFile(const String& file_path); + std::vector GetThemeResourceDictionaryList() const; - void SetThemeXml(xml::XmlElementNode* root); + void PrependThemeResourceDictionary( + std::unique_ptr theme_resource_dictionary); template T GetResource(const String& key) { - auto find_result = theme_resource_map_.find(key); - if (find_result == theme_resource_map_.cend()) { - throw ThemeResourceKeyNotExistException( - Format(u"Theme resource key \"%s\" not exist.", key)); + for (const auto& resource_dictionary : theme_resource_dictionary_list_) { + try { + return resource_dictionary->GetResource(key); + } catch (ThemeResourceKeyNotExistException&) { + } } - - auto& cache = find_result->second.cache; - auto cache_find_result = cache.find(typeid(T)); - if (cache_find_result != cache.cend()) { - return std::any_cast(cache_find_result->second); - } - - auto mapper_registry = mapper::MapperRegistry::GetInstance(); - auto mapper = mapper_registry->GetMapper(); - auto resource = mapper->MapFromXml(find_result->second.xml_node); - cache[typeid(T)] = resource; - return resource; + throw ThemeResourceKeyNotExistException( + Format(u"Theme resource key {} not exist.", key)); } std::shared_ptr GetResourceBrush( @@ -74,19 +45,13 @@ class CRU_UI_API ThemeManager : public Object { std::shared_ptr GetResourceStyleRuleSet( const String& key); - private: - struct ResourceEntry { - CRU_DEFAULT_CONSTRUCTOR_DESTRUCTOR(ResourceEntry) - CRU_DEFAULT_COPY(ResourceEntry) - CRU_DEFAULT_MOVE(ResourceEntry) - - String name; - xml::XmlElementNode* xml_node; - std::unordered_map cache; - }; + IEvent* ThemeResourceChangeEvent() { + return &theme_resource_change_event_; + } + private: Event theme_resource_change_event_; - std::unique_ptr theme_resource_xml_root_; - std::unordered_map theme_resource_map_; + std::vector> + theme_resource_dictionary_list_; }; } // namespace cru::ui diff --git a/include/cru/ui/ThemeResourceDictionary.h b/include/cru/ui/ThemeResourceDictionary.h new file mode 100644 index 00000000..26f7ec8d --- /dev/null +++ b/include/cru/ui/ThemeResourceDictionary.h @@ -0,0 +1,84 @@ +#pragma once +#include "Base.h" + +#include "cru/common/Base.h" +#include "cru/xml/XmlNode.h" +#include "mapper/MapperRegistry.h" +#include "style/StyleRuleSet.h" + +#include +#include +#include + +namespace cru::ui { +class CRU_UI_API ThemeResourceKeyNotExistException : public Exception { + public: + using Exception::Exception; +}; + +class CRU_UI_API BadThemeResourceException : public Exception { + public: + using Exception::Exception; +}; + +class CRU_UI_API ThemeResourceDictionary : public Object { + CRU_DEFINE_CLASS_LOG_TAG(u"ThemeResources"); + + public: + static std::unique_ptr FromFile(const String& file_path); + + explicit ThemeResourceDictionary(xml::XmlElementNode* xml_root, bool clone = true); + + CRU_DELETE_COPY(ThemeResourceDictionary) + CRU_DELETE_MOVE(ThemeResourceDictionary) + + ~ThemeResourceDictionary() override; + + public: + template + T GetResource(const String& key) { + auto find_result = resource_map_.find(key); + if (find_result == resource_map_.cend()) { + throw ThemeResourceKeyNotExistException( + Format(u"Theme resource key {} not exist.", key)); + } + + auto& cache = find_result->second.cache; + auto cache_find_result = cache.find(typeid(T)); + if (cache_find_result != cache.cend()) { + return std::any_cast(cache_find_result->second); + } + + auto mapper_registry = mapper::MapperRegistry::GetInstance(); + auto mapper = mapper_registry->GetMapper(); + auto resource = mapper->MapFromXml(find_result->second.xml_node); + cache[typeid(T)] = resource; + return resource; + } + + std::shared_ptr GetResourceBrush( + const String& key); + + std::shared_ptr GetResourceFont(const String& key); + + std::shared_ptr GetResourceStyleRuleSet( + const String& key); + + private: + void UpdateResourceMap(xml::XmlElementNode* root_xml); + + private: + struct ResourceEntry { + CRU_DEFAULT_CONSTRUCTOR_DESTRUCTOR(ResourceEntry) + CRU_DEFAULT_COPY(ResourceEntry) + CRU_DEFAULT_MOVE(ResourceEntry) + + String name; + xml::XmlElementNode* xml_node; + std::unordered_map cache; + }; + + std::unique_ptr xml_root_; + std::unordered_map resource_map_; +}; +} // namespace cru::ui -- cgit v1.2.3