diff --git a/frameworks/core/components/theme/theme_manager_impl.cpp b/frameworks/core/components/theme/theme_manager_impl.cpp index f4abb31e88ca57cc51c2a114308a3b2c24e47162..b590e78fd8b59a3e6772d93be9bc7c507a5c45c8 100644 --- a/frameworks/core/components/theme/theme_manager_impl.cpp +++ b/frameworks/core/components/theme/theme_manager_impl.cpp @@ -16,6 +16,7 @@ #include "core/components/theme/theme_manager_impl.h" #include "core/common/agingadapation/aging_adapation_dialog_theme.h" +#include "core/common/resource/resource_manager.h" #include "core/components/badge/badge_theme.h" #include "core/components/button/button_theme.h" #include "core/components/calendar/calendar_theme.h" @@ -73,6 +74,7 @@ #include "core/components_ng/pattern/rich_editor/rich_editor_theme.h" #include "core/components_ng/pattern/scrollable/scrollable_theme.h" #include "core/components_ng/pattern/swiper/swiper_theme.h" +#include "core/components_ng/token_theme/token_theme_storage.h" namespace OHOS::Ace { namespace { @@ -148,6 +150,16 @@ const std::unordered_map(*)(const RefPtr }, { NG::SwiperTheme::TypeId(), &ThemeBuildFunc }, }; + +template +RefPtr ThemeWrapperBuildFunc(const RefPtr& themeConstants) +{ + return T().BuildWrapper(themeConstants); +} + +const std::unordered_map(*)(const RefPtr&)> + TOKEN_THEME_WRAPPER_BUILDERS = { + }; } // namespace ThemeManagerImpl::ThemeManagerImpl() @@ -171,11 +183,69 @@ RefPtr ThemeManagerImpl::GetTheme(ThemeType type) if (builderIter == THEME_BUILDERS.end()) { return nullptr; } + auto pipelineContext = NG::PipelineContext::GetCurrentContext(); + CHECK_NULL_RETURN(pipelineContext, nullptr); + ColorMode localMode = pipelineContext->GetLocalColorMode(); + ColorMode systemMode = SystemProperties::GetColorMode(); + bool needRestore = false; + if (localMode != ColorMode::COLOR_MODE_UNDEFINED && localMode != systemMode) { + // Ordinary themes should work in system color mode. Only theme wrappers support local color mode. + ResourceManager::GetInstance().UpdateColorMode(systemMode); + pipelineContext->SetLocalColorMode(ColorMode::COLOR_MODE_UNDEFINED); + needRestore = true; + } auto theme = builderIter->second(themeConstants_); + if (needRestore) { + pipelineContext->SetLocalColorMode(localMode); + ResourceManager::GetInstance().UpdateColorMode(localMode); + } themes_.emplace(type, theme); return theme; } +RefPtr ThemeManagerImpl::GetTheme(ThemeType type, NG::TokenThemeScopeId themeScopeId) +{ + auto tokenTheme = NG::TokenThemeStorage::GetInstance()->GetTheme(themeScopeId); + if (!tokenTheme) { + return GetTheme(type); + } + + ColorMode currentMode = GetCurrentColorMode(); + ColorMode themeMode = tokenTheme->GetColorMode(); + auto& themeWrappers = GetThemeWrappers(themeMode == ColorMode::COLOR_MODE_UNDEFINED ? currentMode : themeMode); + auto findIter = themeWrappers.find(type); + if (findIter != themeWrappers.end()) { + auto wrapper = findIter->second; + wrapper->ApplyTokenTheme(*tokenTheme); + return AceType::DynamicCast(wrapper); + } + + auto builderIter = TOKEN_THEME_WRAPPER_BUILDERS.find(type); + if (builderIter == TOKEN_THEME_WRAPPER_BUILDERS.end()) { + return GetTheme(type); + } + + auto pipelineContext = NG::PipelineContext::GetCurrentContext(); + CHECK_NULL_RETURN(pipelineContext, GetTheme(type)); + bool needRestore = false; + if (themeMode != ColorMode::COLOR_MODE_UNDEFINED && themeMode != currentMode) { + // Local color mode of the current theme does not match actual color scheme. + // Current color mode is system. Need to switch to local color mode temporarily. + ResourceManager::GetInstance().UpdateColorMode(themeMode); + pipelineContext->SetLocalColorMode(themeMode); + needRestore = true; + } + auto wrapper = builderIter->second(themeConstants_); + if (needRestore) { + // Switching resource manager back into system color mode + pipelineContext->SetLocalColorMode(ColorMode::COLOR_MODE_UNDEFINED); + ResourceManager::GetInstance().UpdateColorMode(currentMode); + } + wrapper->ApplyTokenTheme(*tokenTheme); + themeWrappers.emplace(type, wrapper); + return AceType::DynamicCast(wrapper); +} + Color ThemeManagerImpl::GetBackgroundColor() const { auto findIter = themes_.find(AppTheme::TypeId()); @@ -203,6 +273,22 @@ Color ThemeManagerImpl::GetBackgroundColor() const void ThemeManagerImpl::LoadResourceThemes() { themes_.clear(); + themeWrappersLight_.clear(); + themeWrappersDark_.clear(); themeConstants_->LoadTheme(currentThemeId_); } + +ColorMode ThemeManagerImpl::GetCurrentColorMode() const +{ + auto pipelineContext = NG::PipelineContext::GetCurrentContext(); + ColorMode systemMode = SystemProperties::GetColorMode(); + CHECK_NULL_RETURN(pipelineContext, systemMode); + ColorMode localMode = pipelineContext->GetLocalColorMode(); + return localMode == ColorMode::COLOR_MODE_UNDEFINED ? systemMode : localMode; +} + +ThemeManagerImpl::ThemeWrappers& ThemeManagerImpl::GetThemeWrappers(ColorMode mode) +{ + return mode == ColorMode::DARK ? themeWrappersDark_ : themeWrappersLight_; +} } // namespace OHOS::Ace diff --git a/frameworks/core/components/theme/theme_manager_impl.h b/frameworks/core/components/theme/theme_manager_impl.h index a53f8cd14f53a536084fe4f1eea48e177ce40ef7..37009c1291048cf1a95fd49c9b43d8751de51f60 100644 --- a/frameworks/core/components/theme/theme_manager_impl.h +++ b/frameworks/core/components/theme/theme_manager_impl.h @@ -18,6 +18,7 @@ #include "core/components/theme/resource_adapter.h" #include "core/components/theme/theme_manager.h" +#include "core/components_ng/token_theme/token_theme_wrapper.h" namespace OHOS::Ace { class ACE_EXPORT ThemeManagerImpl : public ThemeManager { @@ -93,6 +94,18 @@ public: return AceType::DynamicCast(GetTheme(T::TypeId())); } + /* + * Get the theme and update it according to the TokenTheme, that given in param. + * @return Target component theme. + */ + RefPtr GetTheme(ThemeType type, int32_t themeScopeId) override; + + template + RefPtr GetTheme(int32_t themeScopeId) + { + return AceType::DynamicCast(GetTheme(T::TypeId()), themeScopeId); + } + void LoadResourceThemes() override; uint32_t GetResourceLimitKeys() const override @@ -101,11 +114,16 @@ public: } private: + using ThemeWrappers = std::unordered_map>; std::unordered_map> themes_; + ThemeWrappers themeWrappersLight_; + ThemeWrappers themeWrappersDark_; RefPtr themeConstants_; int32_t currentThemeId_ = -1; ACE_DISALLOW_COPY_AND_MOVE(ThemeManagerImpl); + ThemeWrappers& GetThemeWrappers(ColorMode mode); + ColorMode GetCurrentColorMode() const; }; } // namespace OHOS::Ace #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_THEME_THEME_MANAGER_H