From cd064a1a753654843d3b365923ba2179d9217eef Mon Sep 17 00:00:00 2001 From: Alexey Sivenkov Date: Thu, 26 Sep 2024 17:50:43 +0300 Subject: [PATCH 1/2] Custom Dialog theme adapt --- .../dialog/js_custom_dialog_controller.cpp | 26 ++++++ .../components/dialog/dialog_properties.h | 2 + .../core/components/dialog/dialog_theme.h | 2 +- .../components/theme/theme_manager_impl.cpp | 2 + .../pattern/dialog/dialog_theme_wrapper.h | 71 +++++++++++++++ .../pattern/dialog/dialog_view.cpp | 40 +++++++-- .../pattern/overlay/overlay_manager.cpp | 4 + .../components_ng/token_theme/token_colors.h | 89 ++++++++++++++++++- .../token_theme/token_theme_storage.cpp | 71 ++------------- .../token_theme/token_theme_storage.h | 2 +- 10 files changed, 235 insertions(+), 74 deletions(-) create mode 100644 frameworks/core/components_ng/pattern/dialog/dialog_theme_wrapper.h diff --git a/frameworks/bridge/declarative_frontend/jsview/dialog/js_custom_dialog_controller.cpp b/frameworks/bridge/declarative_frontend/jsview/dialog/js_custom_dialog_controller.cpp index 0dac54db8691..3964fd0e9ccd 100644 --- a/frameworks/bridge/declarative_frontend/jsview/dialog/js_custom_dialog_controller.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/dialog/js_custom_dialog_controller.cpp @@ -233,6 +233,32 @@ void JSCustomDialogController::ConstructorCallback(const JSCallbackInfo& info) JSViewAbstract::SetDialogHoverModeProperties(constructorArg, instance->dialogProperties_); instance->IncRefCount(); info.SetReturnValue(AceType::RawPtr(instance)); + + auto& dialogPropsThemeColors = instance->dialogProperties_.themeColors; + auto themeValue = constructorArg->GetProperty("theme"); + if (themeValue->IsObject()) { + auto themeObj = JSRef::Cast(themeValue); + auto colorsValue = themeObj->GetProperty("colors"); + if (colorsValue->IsObject()) { + auto colorsObj = JSRef::Cast(colorsValue); + auto colorNames = colorsObj->GetPropertyNames(); + for (size_t i = 0; i < colorNames->Length(); ++i) { + auto colorValue = colorNames->GetValueAt(i); + if (!colorValue->IsString()) { + continue; + } + auto colorName = colorValue->ToString(); + auto colorParamValue = colorsObj->GetProperty(colorName.c_str()); + if (Color color; JSViewAbstract::ParseJsColor(colorParamValue, color)) { + dialogPropsThemeColors[colorName] = color.GetValue(); + } + } + auto themeColorModeValue = constructorArg->GetProperty("themeColorMode"); + instance->dialogProperties_.colorMode = themeColorModeValue->IsNumber() + ? themeColorModeValue->ToNumber() + : static_cast(ThemeColorMode::SYSTEM); + } + } } } diff --git a/frameworks/core/components/dialog/dialog_properties.h b/frameworks/core/components/dialog/dialog_properties.h index f031d70ddbfb..d5e32b6bebeb 100644 --- a/frameworks/core/components/dialog/dialog_properties.h +++ b/frameworks/core/components/dialog/dialog_properties.h @@ -247,6 +247,8 @@ struct DialogProperties { std::optional width; std::optional height; std::optional hoverModeArea; + std::unordered_map themeColors; + int32_t colorMode; #ifndef NG_BUILD std::unordered_map callbacks; // diff --git a/frameworks/core/components/dialog/dialog_theme.h b/frameworks/core/components/dialog/dialog_theme.h index ff1c75106299..249e46216ab7 100644 --- a/frameworks/core/components/dialog/dialog_theme.h +++ b/frameworks/core/components/dialog/dialog_theme.h @@ -509,10 +509,10 @@ public: protected: DialogTheme() = default; + Color backgroundColor_; private: Radius radius_; - Color backgroundColor_; TextStyle titleTextStyle_; TextStyle subtitleTextStyle_; TextStyle contentTextStyle_; diff --git a/frameworks/core/components/theme/theme_manager_impl.cpp b/frameworks/core/components/theme/theme_manager_impl.cpp index 392b0fc6bce4..995667ea124a 100644 --- a/frameworks/core/components/theme/theme_manager_impl.cpp +++ b/frameworks/core/components/theme/theme_manager_impl.cpp @@ -87,6 +87,7 @@ #include "core/components_ng/pattern/swiper/swiper_theme_wrapper.h" #include "core/components_ng/pattern/text/text_theme_wrapper.h" #include "core/components_ng/pattern/text_field/text_field_theme_wrapper.h" +#include "core/components_ng/pattern/dialog/dialog_theme_wrapper.h" #include "core/components_ng/token_theme/token_theme_storage.h" namespace OHOS::Ace { @@ -184,6 +185,7 @@ const std::unordered_map(*)(const RefPt { SwiperIndicatorTheme::TypeId(), &ThemeWrapperBuildFunc }, { TextTheme::TypeId(), &ThemeWrapperBuildFunc }, { TextFieldTheme::TypeId(), &ThemeWrapperBuildFunc } + { DialogTheme::TypeId(), &ThemeWrapperBuildFunc } }; } // namespace diff --git a/frameworks/core/components_ng/pattern/dialog/dialog_theme_wrapper.h b/frameworks/core/components_ng/pattern/dialog/dialog_theme_wrapper.h new file mode 100644 index 000000000000..f9c51434401d --- /dev/null +++ b/frameworks/core/components_ng/pattern/dialog/dialog_theme_wrapper.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_DIALOG_DIALOG_THEME_WRAPPER_H +#define FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_DIALOG_DIALOG_THEME_WRAPPER_H + +#include + +#include "base/memory/ace_type.h" +#include "core/components/dialog/dialog_theme.h" +#include "core/components_ng/token_theme/token_theme_wrapper.h" + +namespace OHOS::Ace::NG { + +/** + * DialogThemeWrapper defines colors Dialog component basing on TokenTheme's data. + * DialogThemeWrapper should be built using DialogThemeWrapper::WrapperBuilder. + */ +class DialogThemeWrapper : public DialogTheme, public TokenThemeWrapper +{ + DECLARE_ACE_TYPE(DialogThemeWrapper, DialogTheme); + +public: + class WrapperBuilder : public Builder + { + public: + WrapperBuilder() = default; + ~WrapperBuilder() = default; + + RefPtr BuildWrapper(const RefPtr& themeConstants) const + { + auto wrapper = AceType::Claim(new DialogThemeWrapper()); + if (!themeConstants) { + LOGI("Build DialogThemeWrapper error, themeConstants is null!"); + return wrapper; + } + auto theme = AceType::DynamicCast(wrapper); + ParseNewPattern(themeConstants, theme); + ParsePattern(themeConstants, theme); + return wrapper; + } + }; + + ~DialogThemeWrapper() override = default; + + void ApplyTokenTheme(const TokenTheme& theme) override + { + if (auto colors = theme.Colors(); colors) { + // update only required attributes by TokenTheme tokens + backgroundColor_ = colors->BackgroundPrimary(); + } + } + +protected: + DialogThemeWrapper() = default; +}; + +} // namespace +#endif //FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_DIALOG_DIALOG_THEME_WRAPPER_H diff --git a/frameworks/core/components_ng/pattern/dialog/dialog_view.cpp b/frameworks/core/components_ng/pattern/dialog/dialog_view.cpp index dc51d5f70ace..5b415a61e3a1 100644 --- a/frameworks/core/components_ng/pattern/dialog/dialog_view.cpp +++ b/frameworks/core/components_ng/pattern/dialog/dialog_view.cpp @@ -15,6 +15,8 @@ #include "core/components_ng/pattern/dialog/dialog_view.h" #include "core/components_ng/pattern/dialog/dialog_pattern.h" +#include "core/components_ng/token_theme/token_theme_storage.h" +#include "core/interfaces/native/node/theme_modifier.h" namespace OHOS::Ace::NG { RefPtr DialogView::CreateDialogNode( @@ -22,7 +24,33 @@ RefPtr DialogView::CreateDialogNode( { auto pipeline = PipelineBase::GetCurrentContext(); CHECK_NULL_RETURN(pipeline, nullptr); - auto dialogTheme = pipeline->GetTheme(); + auto dialogNodeId = ElementRegister::GetInstance()->MakeUniqueId(); + auto& themeColors = param.themeColors; + bool changeThemeScope = (themeColors.size() != 0); + if (changeThemeScope) { + auto basisTheme = TokenThemeStorage::GetInstance()->GetDefaultTheme(); + if (!basisTheme) { + basisTheme = TokenThemeStorage::GetInstance()->ObtainSystemTheme(); + } + std::vector colors; + for (size_t i = 0; i < TokenColors::TOTAL_NUMBER; ++i) { + uint32_t color; + auto tokenName = TokenColors::GetColorNameByIndex(i); + if (tokenName != nullptr) { + if (auto search = themeColors.find(tokenName); search != themeColors.end()) { + color = search->second; + } else { + color = basisTheme->Colors()->GetByIndex(i).GetValue(); + } + } + colors.push_back(color); + } + static int32_t dialogThemeId = -2; + auto themeModifier = NodeModifier::GetThemeModifier(); + themeModifier->createTheme(--dialogThemeId, colors.data(), param.colorMode); + TokenThemeStorage::GetInstance()->StoreThemeScope(dialogNodeId, dialogThemeId); + } + auto dialogTheme = pipeline->GetTheme(dialogNodeId); CHECK_NULL_RETURN(dialogTheme, nullptr); std::string tag; @@ -39,11 +67,13 @@ RefPtr DialogView::CreateDialogNode( tag = V2::DIALOG_ETS_TAG; break; } - auto nodeId = ElementRegister::GetInstance()->MakeUniqueId(); - ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", tag.c_str(), nodeId); - RefPtr dialog = FrameNode::CreateFrameNode(tag, nodeId, + ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", tag.c_str(), dialogNodeId); + RefPtr dialog = FrameNode::CreateFrameNode(tag, dialogNodeId, AceType::MakeRefPtr(dialogTheme, customNode)); - + if (changeThemeScope) { + dialog->SetThemeScopeId(dialogNodeId); + dialog->AllowUseParentTheme(false); + } if (customNode) { customNode->Build(nullptr); } diff --git a/frameworks/core/components_ng/pattern/overlay/overlay_manager.cpp b/frameworks/core/components_ng/pattern/overlay/overlay_manager.cpp index a5e7ddc56cbc..26233be06b71 100644 --- a/frameworks/core/components_ng/pattern/overlay/overlay_manager.cpp +++ b/frameworks/core/components_ng/pattern/overlay/overlay_manager.cpp @@ -76,6 +76,7 @@ #include "core/components_ng/pattern/time_picker/timepicker_dialog_view.h" #include "core/components_ng/pattern/toast/toast_pattern.h" #include "core/components_ng/pattern/video/video_full_screen_pattern.h" +#include "core/components_ng/token_theme/token_theme_storage.h" #ifdef WEB_SUPPORTED #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) #include "core/components_ng/pattern/web/web_pattern.h" @@ -798,6 +799,9 @@ void OverlayManager::OnDialogCloseEvent(const RefPtr& node) ContainerScope scope(currentId); auto root = node->GetParent(); + if (auto themeScopeId = node->GetThemeScopeId(); themeScopeId != 0) { + TokenThemeStorage::GetInstance()->RemoveThemeScope(themeScopeId, true); + } CHECK_NULL_VOID(root); node->OnAccessibilityEvent( AccessibilityEventType::PAGE_CLOSE, WindowsContentChangeTypes::CONTENT_CHANGE_TYPE_SUBTREE); diff --git a/frameworks/core/components_ng/token_theme/token_colors.h b/frameworks/core/components_ng/token_theme/token_colors.h index 274f8a89d7e5..5047977866a7 100644 --- a/frameworks/core/components_ng/token_theme/token_colors.h +++ b/frameworks/core/components_ng/token_theme/token_colors.h @@ -23,6 +23,13 @@ namespace OHOS::Ace::NG { class TokenColors : public virtual AceType { DECLARE_ACE_TYPE(TokenColors, AceType); + + struct TokenColorData + { + const char* colorName; + const int32_t systemResourceId; + }; + public: static constexpr int32_t BRAND = 0; static constexpr int32_t WARNING = 1; @@ -303,15 +310,91 @@ public: { return colors_[INTERACTIVE_CLICK]; } + static const char* GetColorNameByIndex(int32_t idx) + { + return GetTokenColorDataByIndex(idx).colorName; + } + + static int32_t GetSystemColorResIdByIndex(int32_t idx) + { + return GetTokenColorDataByIndex(idx).systemResourceId; + } -private: - friend class ThemeBridge; inline Color GetByIndex(int32_t idx) { return colors_[idx]; } + + static const TokenColorData& GetTokenColorDataByIndex(int32_t idx) + { + static const std::vector colorData = { + { /* BRAND = 0 */ "brand", 125830976 }, + { /* WARNING = 1; */ "warning", 125830979 }, + { /* ALERT = 2 */ "alert", 125830980 }, + { /* CONFIRM = 3 */ "confirm", 125830981 }, + + { /* FONT_PRIMARY = 4 */ "fontPrimary", 125830982 }, + { /* FONT_SECONDARY = 5 */ "fontSecondary", 125830983 }, + { /* FONT_TERTIARY = 6 */ "fontTertiary", 125830984 }, + { /* FONT_FOURTH = 7 */ "fontFourth", 125830985 }, + { /* FONT_EMPHASIZE = 8 */ "fontEmphasize", 125830986 }, + + { /* FONT_ON_PRIMARY = 9 */ "fontOnPrimary", 125830987 }, + { /* FONT_ON_SECONDARY = 10 */ "fontOnSecondary", 125830988 }, + { /* FONT_ON_TERTIARY = 11 */ "fontOnTertiary", 125830989 }, + { /* FONT_ON_FOURTH = 12 */ "fontOnFourth", 125830990 }, + + { /* ICON_PRIMARY = 13 */ "iconPrimary", 125830991 }, + { /* ICON_SECONDARY = 14 */ "iconSecondary", 125830992 }, + { /* ICON_TERTIARY = 15 */ "iconTertiary", 125830993 }, + { /* ICON_FOURTH = 16 */ "iconFourth", 125830994 }, + { /* ICON_EMPHASIZE = 17 */ "iconEmphasize", 125830995 }, + { /* ICON_SUB_EMPHASIZE = 18 */ "iconSubEmphasize", 125830996 }, + + { /* ICON_ON_PRIMARY = 19 */ "iconOnPrimary", 125831057 }, + { /* ICON_ON_SECONDARY = 20 */ "iconOnSecondary", 125831058 }, + { /* ICON_ON_TERTIARY = 21 */ "iconOnTertiary", 125831059 }, + { /* ICON_ON_FOURTH = 22 */ "iconOnFourth", 125831060 }, + + { /* BACKGROUND_PRIMARY = 23 */ "backgroundPrimary", 125831061 }, + { /* BACKGROUND_SECONDARY = 24 */ "backgroundSecondary", 125831062 }, + { /* BACKGROUND_TERTIARY = 25 */ "backgroundTertiary", 125831063 }, + { /* BACKGROUND_FOURTH = 26 */ "backgroundFourth", 125831064 }, + { /* BACKGROUND_EMPHASIZE = 27 */ "backgroundEmphasize", 125831065 }, + + { /* COMP_FOREGROUND_PRIMARY = 28 */ "compForegroundPrimary", 125831003 }, + { /* COMP_BACKGROUND_PRIMARY = 29 */ "compBackgroundPrimary", 125831004 }, + { /* COMP_BACKGROUND_PRIMARY_TRAN = 30 */ "compBackgroundPrimaryTran", -1 }, // not defined 'sys.color.comp_background_primary_tran' + { /* COMP_BACKGROUND_PRIMARY_CONTRARY = 31 */ "compBackgroundPrimaryContrary", 125831005 }, + { /* COMP_BACKGROUND_GRAY = 32 */ "compBackgroundGray", 125831006 }, + { /* COMP_BACKGROUND_SECONDARY = 33 */ "compBackgroundSecondary", 125831007 }, + { /* COMP_BACKGROUND_TERTIARY = 34 */ "compBackgroundTertiary", 125831008 }, + { /* COMP_BACKGROUND_EMPHASIZE = 35 */ "compBackgroundEmphasize", 125831009 }, + { /* COMP_BACKGROUND_NEUTRAL = 36 */ "compBackgroundNeutral", 125831066 }, + { /* COMP_EMPHASIZE_SECONDARY = 37 */ "compEmphasizeSecondary", 125831011 }, + { /* COMP_EMPHASIZE_TERTIARY = 38 */ "compEmphasizeTertiary", 125831012 }, + { /* COMP_DIVIDER = 39 */ "compDivider", 125831013 }, + { /* COMP_COMMON_CONTRARY = 40 */ "compCommonContrary", 125831014 }, + { /* COMP_BACKGROUND_FOCUS = 41 */ "compBackgroundFocus", 125831015 }, + { /* COMP_FOCUSED_PRIMARY = 42 */ "compFocusedPrimary", 125831016 }, + { /* COMP_FOCUSED_SECONDARY = 43 */ "compFocusedSecondary", 125831017 }, + { /* COMP_FOCUSED_TERTIARY = 44 */ "compFocusedTertiary", 125831018 }, + + { /* INTERACTIVE_HOVER = 45 */ "interactiveHover", 125831019 }, + { /* INTERACTIVE_PRESSED = 46 */ "interactivePressed", 125831020 }, + { /* INTERACTIVE_FOCUS = 47 */ "interactiveFocus", 125831021 }, + { /* INTERACTIVE_ACTIVE = 48 */ "interactiveActive", 125831022 }, + { /* INTERACTIVE_SELECT = 49 */ "interactiveSelect", 125831023 }, + { /* INTERACTIVE_CLICK = 50 */ "interactiveClick", 125831024 }, + + { /* TOTAL_NUMBER = 51; */ nullptr, -1 } + }; + return (idx >= 0 && idx < TokenColors::TOTAL_NUMBER) ? colorData[idx] : colorData[TokenColors::TOTAL_NUMBER]; + } + +private: std::vector colors_; }; } // namespace OHOS::Ace::NG -#endif // FRAMEWORKS_CORE_COMPONENTS_NG_TOKEN_THEME_TOKEN_COLORS_H \ No newline at end of file +#endif // FRAMEWORKS_CORE_COMPONENTS_NG_TOKEN_THEME_TOKEN_COLORS_H diff --git a/frameworks/core/components_ng/token_theme/token_theme_storage.cpp b/frameworks/core/components_ng/token_theme/token_theme_storage.cpp index 48c11b3a9c71..65c298d468fa 100644 --- a/frameworks/core/components_ng/token_theme/token_theme_storage.cpp +++ b/frameworks/core/components_ng/token_theme/token_theme_storage.cpp @@ -38,8 +38,11 @@ void TokenThemeStorage::StoreThemeScope(TokenThemeScopeId themeScopeId, int32_t themeScopeMap_[themeScopeId] = themeId; } -void TokenThemeStorage::RemoveThemeScope(TokenThemeScopeId themeScopeId) +void TokenThemeStorage::RemoveThemeScope(TokenThemeScopeId themeScopeId, bool removeToken /* = false */) { + if (removeToken) { + CacheRemove(themeScopeMap_[themeScopeId]); + } themeScopeMap_.erase(themeScopeId); } @@ -109,70 +112,10 @@ RefPtr TokenThemeStorage::CreateSystemTokenTheme() auto themeConstants = themeManager->GetThemeConstants(); CHECK_NULL_RETURN(themeConstants, tokenTheme); - static const std::vector resIdSystemColors = { - 125830976 - , 125830979 - , 125830980 - , 125830981 - - , 125830982 - , 125830983 - , 125830984 - , 125830985 - , 125830986 - - , 125830987 - , 125830988 - , 125830989 - , 125830990 - - , 125830991 - , 125830992 - , 125830993 - , 125830994 - , 125830995 - , 125830996 - - , 125831057 - , 125831058 - , 125831059 - , 125831060 - - , 125831061 - , 125831062 - , 125831063 - , 125831064 - , 125831065 - - , 125831003 - , 125831004 - , -1 // not defined for compBackgroundPrimaryTran, 'sys.color.comp_background_primary_tran' - , 125831005 - , 125831006 - , 125831007 - , 125831008 - , 125831009 - , 125831066 - , 125831011 - , 125831012 - , 125831013 - , 125831014 - , 125831015 - , 125831016 - , 125831017 - , 125831018 - - , 125831019 - , 125831020 - , 125831021 - , 125831022 - , 125831023 - , 125831024 - }; std::vector colors; - colors.reserve(resIdSystemColors.size()); - for (auto resId: resIdSystemColors) { - colors.push_back(themeConstants->GetColor(resId)); + colors.reserve(TokenColors::TOTAL_NUMBER); + for (size_t resId = 0; resId < TokenColors::TOTAL_NUMBER; ++resId) { + colors.push_back(themeConstants->GetColor(TokenColors::GetSystemColorResIdByIndex(resId))); } tokenColors->SetColors(std::move(colors)); return tokenTheme; diff --git a/frameworks/core/components_ng/token_theme/token_theme_storage.h b/frameworks/core/components_ng/token_theme/token_theme_storage.h index 0f5543c8efb2..5992ab075a64 100644 --- a/frameworks/core/components_ng/token_theme/token_theme_storage.h +++ b/frameworks/core/components_ng/token_theme/token_theme_storage.h @@ -31,7 +31,7 @@ public: // theme map (key: themeScopeId - value: ark theme instance) void StoreThemeScope(TokenThemeScopeId themeScopeId, int32_t themeId); - void RemoveThemeScope(TokenThemeScopeId themeScopeId); + void RemoveThemeScope(TokenThemeScopeId themeScopeId, bool removeToken = false); const RefPtr& GetTheme(TokenThemeScopeId themeScopeId); // default theme -- Gitee From 0b5a1146eab5b35b09fe1432fe93ec8f36b5e982 Mon Sep 17 00:00:00 2001 From: alexeyermolaev Date: Fri, 27 Sep 2024 11:13:42 +0000 Subject: [PATCH 2/2] update frameworks/core/components/theme/theme_manager_impl.cpp. Signed-off-by: alexeyermolaev --- frameworks/core/components/theme/theme_manager_impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/core/components/theme/theme_manager_impl.cpp b/frameworks/core/components/theme/theme_manager_impl.cpp index 995667ea124a..fd37082614df 100644 --- a/frameworks/core/components/theme/theme_manager_impl.cpp +++ b/frameworks/core/components/theme/theme_manager_impl.cpp @@ -184,7 +184,7 @@ const std::unordered_map(*)(const RefPt { SliderTheme::TypeId(), &ThemeWrapperBuildFunc }, { SwiperIndicatorTheme::TypeId(), &ThemeWrapperBuildFunc }, { TextTheme::TypeId(), &ThemeWrapperBuildFunc }, - { TextFieldTheme::TypeId(), &ThemeWrapperBuildFunc } + { TextFieldTheme::TypeId(), &ThemeWrapperBuildFunc }, { DialogTheme::TypeId(), &ThemeWrapperBuildFunc } }; } // namespace -- Gitee