From b77029bef9ce3c5a98231854bc140077e9b51895 Mon Sep 17 00:00:00 2001 From: wangxiuxiu96 Date: Wed, 28 May 2025 10:52:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:toast=20&=20dialog=20resource=E6=B7=B1?= =?UTF-8?q?=E6=B5=85=E8=89=B2=E5=88=87=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangxiuxiu96 Change-Id: Ie0236d061907399053a82d03a3ae3e8b244b1fce --- .../frontend_delegate_declarative.cpp | 9 +- .../components/dialog/dialog_properties.h | 33 ++++ .../pattern/dialog/dialog_pattern.cpp | 176 ++++++++++++++++++ .../pattern/dialog/dialog_pattern.h | 12 +- .../pattern/dialog/dialog_view.cpp | 25 +++ .../pattern/dialog/dialog_view.h | 1 + .../pattern/toast/toast_layout_property.h | 4 + .../pattern/toast/toast_pattern.cpp | 8 + .../pattern/toast/toast_pattern.h | 3 + .../pattern/toast/toast_view.cpp | 141 ++++++++++++++ .../components_ng/pattern/toast/toast_view.h | 9 + .../napi/kits/promptaction/prompt_action.cpp | 93 +++++++-- interfaces/napi/kits/utils/napi_utils.cpp | 122 ++++++++++++ interfaces/napi/kits/utils/napi_utils.h | 6 + .../pattern/dialog/dialog_pattern_test_ng.cpp | 35 ++++ 15 files changed, 663 insertions(+), 14 deletions(-) diff --git a/frameworks/bridge/declarative_frontend/frontend_delegate_declarative.cpp b/frameworks/bridge/declarative_frontend/frontend_delegate_declarative.cpp index e09a8598e82..01fd05a1f1e 100644 --- a/frameworks/bridge/declarative_frontend/frontend_delegate_declarative.cpp +++ b/frameworks/bridge/declarative_frontend/frontend_delegate_declarative.cpp @@ -1880,6 +1880,9 @@ void FrontendDelegateDeclarative::ShowDialog(const PromptDialogAttr& dialogAttr, .onStatusChanged = std::move(onStatusChanged), .maskRect = dialogAttr.maskRect, .levelOrder = dialogAttr.levelOrder, + .messageResObj = dialogAttr.messageResObj, + .bgColorResObj = dialogAttr.bgColorResObj, + .titleResObj = dialogAttr.titleResObj, }; #if defined(PREVIEW) if (dialogProperties.isShowInSubWindow) { @@ -1958,7 +1961,10 @@ DialogProperties FrontendDelegateDeclarative::ParsePropertiesFromAttr(const Prom .focusable = dialogAttr.focusable, .dialogLevelMode = dialogAttr.dialogLevelMode, .dialogLevelUniqueId = dialogAttr.dialogLevelUniqueId, - .dialogImmersiveMode = dialogAttr.dialogImmersiveMode + .dialogImmersiveMode = dialogAttr.dialogImmersiveMode, + .bgColorResObj = dialogAttr.bgColorResObj, + .maskColorResObj = dialogAttr.maskColorResObj, + .borderColorResObj = dialogAttr.borderColorResObj }; ParsePartialPropertiesFromAttr(dialogProperties, dialogAttr); return dialogProperties; @@ -2217,6 +2223,7 @@ void FrontendDelegateDeclarative::ShowActionMenu(const PromptDialogAttr& dialogA .dialogLevelMode = dialogAttr.dialogLevelMode, .dialogLevelUniqueId = dialogAttr.dialogLevelUniqueId, .dialogImmersiveMode = dialogAttr.dialogImmersiveMode, + .titleResObj = dialogAttr.titleResObj, }; #if defined(PREVIEW) if (dialogProperties.isShowInSubWindow) { diff --git a/frameworks/core/components/dialog/dialog_properties.h b/frameworks/core/components/dialog/dialog_properties.h index 254f7e80938..81f8633ffb4 100644 --- a/frameworks/core/components/dialog/dialog_properties.h +++ b/frameworks/core/components/dialog/dialog_properties.h @@ -30,6 +30,7 @@ #include "core/event/ace_event_handler.h" #include "core/pipeline/base/component.h" #include "core/components/common/properties/text_style.h" +#include "core/common/resource/resource_object.h" namespace OHOS::Ace { @@ -246,11 +247,31 @@ struct ButtonInfo { RefPtr resourceTextObj; RefPtr resourceFontColorObj; RefPtr resourceBgColorObj; + struct resourceUpdater { + RefPtr resObj; + std::function&, ButtonInfo&)> updateFunc; + }; + std::unordered_map resMap_; // Whether button info is valid, valid if text is not empty. bool IsValid() const { return !text.empty(); } + + void AddResource(const std::string& key, const RefPtr& resObj, + std::function&, ButtonInfo&)>&& updateFunc) + { + if (resObj == nullptr || !updateFunc) { + return; + } + resMap_[key] = { resObj, std::move(updateFunc) }; + } + void ReloadResources() + { + for (const auto& [key, resourceUpdater] : resMap_) { + resourceUpdater.updateFunc(resourceUpdater.resObj, *this); + } + } }; struct DialogProperties { @@ -346,6 +367,12 @@ struct DialogProperties { RefPtr resourceWidthObj; RefPtr resourceHeightObj; RefPtr resourceBdColorObj; + RefPtr maskColorResObj; + RefPtr messageResObj; + RefPtr bgColorResObj; + RefPtr textColorResObj; + RefPtr titleResObj; + RefPtr borderColorResObj; }; struct PromptDialogAttr { @@ -396,6 +423,12 @@ struct PromptDialogAttr { int32_t dialogLevelUniqueId = -1; ImmersiveMode dialogImmersiveMode = ImmersiveMode::DEFAULT; WeakPtr customCNode; + RefPtr maskColorResObj; + RefPtr messageResObj; + RefPtr bgColorResObj; + RefPtr textColorResObj; + RefPtr titleResObj; + RefPtr borderColorResObj; }; enum class PromptActionCommonState { diff --git a/frameworks/core/components_ng/pattern/dialog/dialog_pattern.cpp b/frameworks/core/components_ng/pattern/dialog/dialog_pattern.cpp index b1de699c685..3f049ddc53e 100644 --- a/frameworks/core/components_ng/pattern/dialog/dialog_pattern.cpp +++ b/frameworks/core/components_ng/pattern/dialog/dialog_pattern.cpp @@ -28,6 +28,7 @@ #include "core/common/ace_engine.h" #include "core/common/container.h" #include "core/common/recorder/event_recorder.h" +#include "core/common/resource/resource_parse_utils.h" #include "core/components/button/button_theme.h" #include "core/components/common/properties/alignment.h" #include "core/components/theme/icon_theme.h" @@ -602,6 +603,7 @@ RefPtr DialogPattern::BuildMainTitle(const DialogProperties& dialogPr { auto title = FrameNode::CreateFrameNode( V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr()); + titleNode_ = title; auto titleProp = AceType::DynamicCast(title->GetLayoutProperty()); CHECK_NULL_RETURN(titleProp, nullptr); titleProp->UpdateMaxLines(DIALOG_TITLE_MAXLINES); @@ -735,6 +737,7 @@ RefPtr DialogPattern::BuildContent(const DialogProperties& props) auto contentNode = FrameNode::CreateFrameNode( V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr()); auto contentProp = AceType::DynamicCast(contentNode->GetLayoutProperty()); + messageNode_ = contentNode; CHECK_NULL_RETURN(contentProp, nullptr); // textAlign always align start. When text line count 1 and title doesn't exist, set text center position. contentProp->UpdateTextAlign(TextAlign::START); @@ -863,6 +866,7 @@ RefPtr DialogPattern::CreateButton( // append text inside button auto textNode = CreateButtonText(params.text, textColor); CHECK_NULL_RETURN(textNode, nullptr); + buttonTextNode_ = textNode; textNode->MountToParent(buttonNode); textNode->MarkModifyDone(); SetButtonEnabled(buttonNode, params.enabled); @@ -909,6 +913,178 @@ RefPtr DialogPattern::CreateButton( return buttonNode; } +template +void ParseType(const RefPtr& resObj, T& result) +{ + if constexpr (std::is_same_v) { + ResourceParseUtils::ParseResColor(resObj, result); + } else if constexpr (std::is_same_v) { + ResourceParseUtils::ParseResDimensionNG(resObj, result, DimensionUnit::PX); + } else if constexpr (std::is_same_v) { + ResourceParseUtils::ParseResDimensionFpNG(resObj, result); + } else if constexpr (std::is_same_v>) { + ResourceParseUtils::ParseResFontFamilies(resObj, result); + } +} + +void DialogPattern::RegisterResourceObj(const DialogProperties& param) +{ + if (!SystemProperties::ConfigChangePerform()) { + return; + } + CreateBackgroundColorResourceObj(param); + CreateMessageResourceObj(param); + CreateTitleResourceObj(param); + RegisterBorderColorResourceObj(param); + RegisterBgColorResourceObj(param); + RegisterMaskColorResourceObj(param); +} +void DialogPattern::CreateBackgroundColorResourceObj(const DialogProperties& param) +{ + auto frameNode = GetHost(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + CHECK_NULL_VOID(contentRenderContext_); + + std::string keyColor = "dialog.backgroundColor"; + pattern->RemoveResObj(keyColor); + CHECK_NULL_VOID(param.bgColorResObj); + if (param.bgColorResObj) { + auto&& updateFunc = [weak = AceType::WeakClaim(RawPtr(contentRenderContext_))]( + const RefPtr& resObj) { + auto context = weak.Upgrade(); + CHECK_NULL_VOID(context); + Color result; + ParseType(resObj, result); + context->UpdateBackgroundColor(result); + }; + pattern->AddResObj("dialog.backgroundColor", dialogProperties_.bgColorResObj, std::move(updateFunc)); + } +} + +void DialogPattern::CreateTitleResourceObj(const DialogProperties& param) +{ + auto frameNode = GetHost(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + std::string keyTitle = "dialog.title"; + pattern->RemoveResObj(keyTitle); + CHECK_NULL_VOID(param.titleResObj); + if (param.titleResObj) { + CHECK_NULL_VOID(titleNode_); + auto&& updateFunc = [weak = AceType::WeakClaim(RawPtr(titleNode_))]( + const RefPtr& resObj) { + auto titleNode = weak.Upgrade(); + CHECK_NULL_VOID(titleNode); + auto titleProp = AceType::DynamicCast(titleNode->GetLayoutProperty()); + CHECK_NULL_VOID(titleProp); + std::string result; + ParseType(resObj, result); + titleProp->UpdateContent(result); + }; + pattern->AddResObj("dialog.title", dialogProperties_.titleResObj, std::move(updateFunc)); + } +} + +void DialogPattern::CreateMessageResourceObj(const DialogProperties& param) +{ + auto frameNode = GetHost(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + std::string keyMessage = "dialog.message"; + pattern->RemoveResObj(keyMessage); + CHECK_NULL_VOID(param.messageResObj); + if (param.messageResObj) { + CHECK_NULL_VOID(messageNode_); + auto&& updateFunc = [weak = AceType::WeakClaim(RawPtr(messageNode_))]( + const RefPtr& resObj) { + auto messageNode = weak.Upgrade(); + CHECK_NULL_VOID(messageNode); + auto contentProp = AceType::DynamicCast(messageNode->GetLayoutProperty()); + CHECK_NULL_VOID(contentProp); + std::string result; + ParseType(resObj, result); + contentProp->UpdateContent(result); + }; + pattern->AddResObj("dialog.message", dialogProperties_.messageResObj, std::move(updateFunc)); + } +} + +void DialogPattern::RegisterBorderColorResourceObj(const DialogProperties& param) +{ + auto frameNode = GetHost(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + CHECK_NULL_VOID(contentRenderContext_); + + std::string key = "customdialog.borderColor"; + pattern->RemoveResObj(key); + CHECK_NULL_VOID(param.bgColorResObj); + if (param.bgColorResObj) { + auto&& updateFunc = [weak = AceType::WeakClaim(RawPtr(contentRenderContext_))]( + const RefPtr& resObj) { + auto context = weak.Upgrade(); + CHECK_NULL_VOID(context); + Color result; + ParseType(resObj, result); + context->UpdateBackgroundColor(result); + }; + pattern->AddResObj("customdialog.borderColor", dialogProperties_.borderColorResObj, std::move(updateFunc)); + } +} + +void DialogPattern::RegisterBgColorResourceObj(const DialogProperties& param) +{ + auto frameNode = GetHost(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + CHECK_NULL_VOID(contentRenderContext_); + + std::string key = "customdialog.backgroundColor"; + pattern->RemoveResObj(key); + CHECK_NULL_VOID(param.bgColorResObj); + if (param.bgColorResObj) { + auto&& updateFunc = [weak = AceType::WeakClaim(RawPtr(contentRenderContext_))]( + const RefPtr& resObj) { + auto context = weak.Upgrade(); + CHECK_NULL_VOID(context); + Color result; + ParseType(resObj, result); + context->UpdateBackgroundColor(result); + }; + pattern->AddResObj("customDialog.backgroundColor", dialogProperties_.bgColorResObj, std::move(updateFunc)); + } +} + +void DialogPattern::RegisterMaskColorResourceObj(const DialogProperties& param) +{ + auto frameNode = GetHost(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + CHECK_NULL_VOID(contentRenderContext_); + + std::string key = "customdialog.maskColor"; + pattern->RemoveResObj(key); + CHECK_NULL_VOID(param.bgColorResObj); + if (param.bgColorResObj) { + auto&& updateFunc = [weak = AceType::WeakClaim(RawPtr(contentRenderContext_))]( + const RefPtr& resObj) { + auto context = weak.Upgrade(); + CHECK_NULL_VOID(context); + Color result; + ParseType(resObj, result); + context->UpdateBackgroundColor(result); + }; + pattern->AddResObj("customDialog.maskColor", dialogProperties_.maskColorResObj, std::move(updateFunc)); + } +} + void DialogPattern::UpdateDialogButtonProperty( RefPtr& buttonNode, int32_t index, bool isVertical, int32_t length) { diff --git a/frameworks/core/components_ng/pattern/dialog/dialog_pattern.h b/frameworks/core/components_ng/pattern/dialog/dialog_pattern.h index 0c127c8fce9..57968a70137 100644 --- a/frameworks/core/components_ng/pattern/dialog/dialog_pattern.h +++ b/frameworks/core/components_ng/pattern/dialog/dialog_pattern.h @@ -175,6 +175,7 @@ public: void SetDialogProperties(const DialogProperties& param) { dialogProperties_ = param; + RegisterResourceObj(param); InitHostWindowRect(); } @@ -370,6 +371,13 @@ public: void UpdateButtonFontColor(const std::string colorStr, int32_t buttonIndex); void UpdateButtonText(const std::string text, int32_t buttonIndex); + void RegisterResourceObj(const DialogProperties& param); + void CreateBackgroundColorResourceObj(const DialogProperties& param); + void CreateMessageResourceObj(const DialogProperties& param); + void CreateTitleResourceObj(const DialogProperties& param); + void RegisterBorderColorResourceObj(const DialogProperties& param); + void RegisterBgColorResourceObj(const DialogProperties& param); + void RegisterMaskColorResourceObj(const DialogProperties& param); private: bool AvoidKeyboard() const override { @@ -462,7 +470,8 @@ private: std::optional foldDisplayModeChangedCallbackId_; std::optional hoverModeChangedCallbackId_; bool isFoldStatusChanged_ = false; - + RefPtr titleNode_ = nullptr; + RefPtr messageNode_ = nullptr; // XTS inspector values std::string message_; std::string title_; @@ -497,6 +506,7 @@ private: bool isUIExtensionSubWindow_ = false; bool isDialogDisposed_ = false; RectF hostWindowRect_; + RefPtr buttonTextNode_; }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/dialog/dialog_view.cpp b/frameworks/core/components_ng/pattern/dialog/dialog_view.cpp index fc008f1ca66..c2d78e0205c 100644 --- a/frameworks/core/components_ng/pattern/dialog/dialog_view.cpp +++ b/frameworks/core/components_ng/pattern/dialog/dialog_view.cpp @@ -130,10 +130,35 @@ RefPtr DialogView::CreateDialogNode( SetDialogTransitionEffects(dialog, param, pattern); + AddDialogResource(dialog, param); + dialog->MarkModifyDone(); return dialog; } +void DialogView::AddDialogResource(const RefPtr& dialogNode, const DialogProperties& param) +{ + if (SystemProperties::ConfigChangePerform() && dialogNode) { + auto pattern = dialogNode->GetPattern(); + CHECK_NULL_VOID(pattern); + RefPtr resObj = AceType::MakeRefPtr(); + std::string key = "dialog.buttons"; + pattern->RemoveResObj(key); + CHECK_NULL_VOID(resObj); + auto&& updateFunc = [param, weak = AceType::WeakClaim(AceType::RawPtr(pattern))] + (const RefPtr& resObj) { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + DialogProperties ¶mValue = const_cast(param); + const size_t size = paramValue.buttons.size(); + for (size_t i = 0; i < size; ++i) { + paramValue.buttons[i].ReloadResources(); + } + }; + pattern->AddResObj("dialog.buttons", resObj, std::move(updateFunc)); + } +} + std::string DialogView::GetDialogTag(const DialogProperties& param) { std::string tag; diff --git a/frameworks/core/components_ng/pattern/dialog/dialog_view.h b/frameworks/core/components_ng/pattern/dialog/dialog_view.h index b60dfe63582..7e372cd38d8 100644 --- a/frameworks/core/components_ng/pattern/dialog/dialog_view.h +++ b/frameworks/core/components_ng/pattern/dialog/dialog_view.h @@ -31,6 +31,7 @@ public: static RefPtr CreateDialogNode(const DialogProperties& param, const RefPtr& customNode); static RefPtr CreateDialogNode( const int32_t nodeId, const DialogProperties& param, const RefPtr& customNode); + static void AddDialogResource(const RefPtr& dialogNode, const DialogProperties& param); private: static void SetDialogAccessibilityHoverConsume(const RefPtr& dialog); static std::string GetDialogTag(const DialogProperties& param); diff --git a/frameworks/core/components_ng/pattern/toast/toast_layout_property.h b/frameworks/core/components_ng/pattern/toast/toast_layout_property.h index 190383e9511..13abd07730a 100644 --- a/frameworks/core/components_ng/pattern/toast/toast_layout_property.h +++ b/frameworks/core/components_ng/pattern/toast/toast_layout_property.h @@ -20,6 +20,7 @@ #include "core/components_ng/base/inspector_filter.h" #include "core/components_ng/layout/layout_property.h" #include "core/components_ng/property/property.h" +#include "core/common/resource/resource_object.h" namespace OHOS::Ace::NG { enum class ToastShowMode { @@ -42,6 +43,9 @@ struct ToastInfo { bool enableHoverMode = false; HoverModeAreaType hoverModeArea = HoverModeAreaType::BOTTOM_SCREEN; bool isTypeStyleShadow = true; + RefPtr textColorResObj; + RefPtr messageResObj; + RefPtr bgColorResObj; }; class ACE_EXPORT ToastLayoutProperty : public LayoutProperty { DECLARE_ACE_TYPE(ToastLayoutProperty, LayoutProperty); diff --git a/frameworks/core/components_ng/pattern/toast/toast_pattern.cpp b/frameworks/core/components_ng/pattern/toast/toast_pattern.cpp index 6218743a1dd..e1170765d24 100644 --- a/frameworks/core/components_ng/pattern/toast/toast_pattern.cpp +++ b/frameworks/core/components_ng/pattern/toast/toast_pattern.cpp @@ -694,4 +694,12 @@ RefPtr ToastPattern::GetToastContext() auto context = IsDefaultToast() ? host->GetContextRefPtr() : GetMainPipelineContext(); return context; } + +void ToastPattern::OnColorModeChange(uint32_t colorMode) +{ + Pattern::OnColorModeChange(colorMode); + auto host = GetHost(); + CHECK_NULL_VOID(host); + host->MarkDirtyNode(PROPERTY_UPDATE_NORMAL); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/toast/toast_pattern.h b/frameworks/core/components_ng/pattern/toast/toast_pattern.h index dd68142b8f1..1179c3925ac 100644 --- a/frameworks/core/components_ng/pattern/toast/toast_pattern.h +++ b/frameworks/core/components_ng/pattern/toast/toast_pattern.h @@ -156,6 +156,9 @@ public: return limitPos_; } RefPtr GetToastContext(); + + void OnColorModeChange(uint32_t colorMode) override; + private: void BeforeCreateLayoutWrapper() override; void UpdateToastSize(const RefPtr& toast); diff --git a/frameworks/core/components_ng/pattern/toast/toast_view.cpp b/frameworks/core/components_ng/pattern/toast/toast_view.cpp index c7a772b7be9..95d667ef600 100644 --- a/frameworks/core/components_ng/pattern/toast/toast_view.cpp +++ b/frameworks/core/components_ng/pattern/toast/toast_view.cpp @@ -18,6 +18,7 @@ #include "core/components_ng/pattern/text/text_pattern.h" #include "core/components_ng/pattern/toast/toast_pattern.h" #include "core/components_v2/inspector/inspector_constants.h" +#include "core/common/resource/resource_parse_utils.h" namespace OHOS::Ace::NG { constexpr float MAX_TOAST_SCALE = 2.0f; @@ -72,6 +73,7 @@ RefPtr ToastView::CreateToastNode(const ToastInfo& toastInfo) toastNode->GetOrCreateEventHub()->GetOrCreateGestureEventHub() ->SetHitTestMode(HitTestMode::HTMTRANSPARENT); toastNode->MarkModifyDone(); + CreateWithResourceObj(toastNode, textNode, toastInfo); return toastNode; } @@ -188,4 +190,143 @@ void ToastView::UpdateToastNodeStyle(const RefPtr& toastNode) toastContext->UpdateBackgroundColor(toastBackgroundColor); } } + +void ToastView::CreateWithResourceObj( + const RefPtr& toastNode, const RefPtr& textNode, const ToastInfo& toastInfo) +{ + if (!SystemProperties::ConfigChangePerform()) { + return; + } + CHECK_NULL_VOID(toastNode); + CHECK_NULL_VOID(textNode); + CreateWithResourceObjTextColor(toastNode, textNode, toastInfo.textColorResObj); + CreateWithResourceObjMessage(toastNode, textNode, toastInfo.messageResObj); + CreateWithResourceObjBackgroundColor(toastNode, textNode, toastInfo.bgColorResObj); +} + +void ToastView::CreateWithResourceObjTextColor( + const RefPtr& toastNode, const RefPtr& textNode, const RefPtr& resObj) +{ + if (!SystemProperties::ConfigChangePerform()) { + return; + } + CHECK_NULL_VOID(toastNode); + CHECK_NULL_VOID(textNode); + CHECK_NULL_VOID(resObj); + auto pattern = toastNode->GetPattern(); + CHECK_NULL_VOID(pattern); + std::string key = "Toast.Info.textColor"; + pattern->RemoveResObj(key); + CHECK_NULL_VOID(resObj); + auto&& updateFunc = [weakToastNode = WeakPtr(toastNode), + weakTextNode = WeakPtr(textNode)](const RefPtr& resObj) { + auto toastNode = weakToastNode.Upgrade(); + CHECK_NULL_VOID(toastNode); + auto textNode = weakTextNode.Upgrade(); + CHECK_NULL_VOID(textNode); + + std::optional textColor; + if (resObj != nullptr) { + Color textColorTemp; + if (ResourceParseUtils::ParseResColor(resObj, textColorTemp)) { + textColor = textColorTemp; + } + } + + auto pattern = toastNode->GetPattern(); + CHECK_NULL_VOID(pattern); + auto toastInfo = pattern->GetToastInfo(); + toastInfo.textColor = textColor; + + auto textLayoutProperty = textNode->GetLayoutProperty(); + CHECK_NULL_VOID(textLayoutProperty); + + auto context = PipelineBase::GetCurrentContext(); + CHECK_NULL_VOID(context); + auto toastTheme = context->GetTheme(); + CHECK_NULL_VOID(toastTheme); + auto defaultColor = toastTheme->GetTextStyle().GetTextColor(); + textLayoutProperty->UpdateTextColor(textColor.value_or(defaultColor)); + }; + pattern->AddResObj("Toast.Info.textColor", resObj, std::move(updateFunc)); +} + +void ToastView::CreateWithResourceObjMessage( + const RefPtr& toastNode, const RefPtr& textNode, const RefPtr& resObj) +{ + if (!SystemProperties::ConfigChangePerform()) { + return; + } + CHECK_NULL_VOID(toastNode); + CHECK_NULL_VOID(textNode); + CHECK_NULL_VOID(resObj); + auto pattern = toastNode->GetPattern(); + CHECK_NULL_VOID(pattern); + std::string key = "Toast.Info.message"; + pattern->RemoveResObj(key); + CHECK_NULL_VOID(resObj); + auto&& updateFunc = [weakToastNode = WeakPtr(toastNode), + weakTextNode = WeakPtr(textNode)](const RefPtr& resObj) { + auto toastNode = weakToastNode.Upgrade(); + CHECK_NULL_VOID(toastNode); + auto textNode = weakTextNode.Upgrade(); + CHECK_NULL_VOID(textNode); + + std::string message; + ResourceParseUtils::ParseResString(resObj, message); + + auto pattern = toastNode->GetPattern(); + CHECK_NULL_VOID(pattern); + auto toastInfo = pattern->GetToastInfo(); + toastInfo.message = message; + + auto toastAccessibilityProperty = toastNode->GetAccessibilityProperty(); + CHECK_NULL_VOID(toastAccessibilityProperty); + toastAccessibilityProperty->SetUserTextValue(message); + + auto textLayoutProperty = textNode->GetLayoutProperty(); + CHECK_NULL_VOID(textLayoutProperty); + textLayoutProperty->UpdateContent(message); + }; + pattern->AddResObj("Toast.Info.message", resObj, std::move(updateFunc)); +} + +void ToastView::CreateWithResourceObjBackgroundColor( + const RefPtr& toastNode, const RefPtr& textNode, const RefPtr& resObj) +{ + if (!SystemProperties::ConfigChangePerform()) { + return; + } + CHECK_NULL_VOID(toastNode); + CHECK_NULL_VOID(textNode); + CHECK_NULL_VOID(resObj); + auto pattern = toastNode->GetPattern(); + CHECK_NULL_VOID(pattern); + std::string key = "Toast.Info.backgroundColor"; + pattern->RemoveResObj(key); + CHECK_NULL_VOID(resObj); + auto&& updateFunc = [weakToastNode = WeakPtr(toastNode), + weakTextNode = WeakPtr(textNode)](const RefPtr& resObj) { + auto toastNode = weakToastNode.Upgrade(); + CHECK_NULL_VOID(toastNode); + auto textNode = weakTextNode.Upgrade(); + CHECK_NULL_VOID(textNode); + + std::optional backgroundColor; + if (resObj != nullptr) { + Color backgroundColorTemp; + if (ResourceParseUtils::ParseResColor(resObj, backgroundColorTemp)) { + backgroundColor = backgroundColorTemp; + } + } + + auto pattern = toastNode->GetPattern(); + CHECK_NULL_VOID(pattern); + auto toastInfo = pattern->GetToastInfo(); + toastInfo.backgroundColor = backgroundColor; + + UpdateToastNodeStyle(toastNode); + }; + pattern->AddResObj("Toast.Info.backgroundColor", resObj, std::move(updateFunc)); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/toast/toast_view.h b/frameworks/core/components_ng/pattern/toast/toast_view.h index 1ed592f74bc..19d2b53a3fc 100644 --- a/frameworks/core/components_ng/pattern/toast/toast_view.h +++ b/frameworks/core/components_ng/pattern/toast/toast_view.h @@ -28,12 +28,21 @@ class ACE_EXPORT ToastView { public: static RefPtr CreateToastNode(const ToastInfo& toastInfo); static void UpdateToastNodeStyle(const RefPtr& toastNode); + static void CreateWithResourceObj( + const RefPtr& toastNode, const RefPtr& textNode, const ToastInfo& toastInfo); private: static void UpdateTextLayoutProperty( const RefPtr& textNode, const std::string& message, bool isRightToLeft, const std::optional& textColor); static void UpdateToastContext(const RefPtr& toastContext); + + static void CreateWithResourceObjTextColor(const RefPtr& toastNode, const RefPtr& textNode, + const RefPtr& resObj); + static void CreateWithResourceObjMessage(const RefPtr& toastNode, const RefPtr& textNode, + const RefPtr& resObj); + static void CreateWithResourceObjBackgroundColor(const RefPtr& toastNode, + const RefPtr& textNode, const RefPtr& resObj); }; } // namespace OHOS::Ace::NG diff --git a/interfaces/napi/kits/promptaction/prompt_action.cpp b/interfaces/napi/kits/promptaction/prompt_action.cpp index 94b0ef0727f..52de691c0c8 100644 --- a/interfaces/napi/kits/promptaction/prompt_action.cpp +++ b/interfaces/napi/kits/promptaction/prompt_action.cpp @@ -20,6 +20,7 @@ #include "base/subwindow/subwindow_manager.h" #include "bridge/common/utils/engine_helper.h" #include "core/common/ace_engine.h" +#include "core/common/resource/resource_parse_utils.h" #include "core/components/theme/shadow_theme.h" #include "core/components/toast/toast_theme.h" #include "core/components/button/button_theme.h" @@ -80,7 +81,7 @@ bool ContainerIsSceneBoard() #endif } // namespace -bool GetToastMessage(napi_env env, napi_value messageNApi, std::string& messageString) +bool GetToastMessage(napi_env env, napi_value messageNApi, std::string& messageString, RefPtr& resObj) { size_t ret = 0; ResourceInfo recv; @@ -96,6 +97,7 @@ bool GetToastMessage(napi_env env, napi_value messageNApi, std::string& messageS NapiThrow(env, "Can not parse resource info from input params.", ERROR_CODE_INTERNAL_ERROR); return false; } + resObj = ParseResourceParamToObj(env, messageNApi); if (!ParseString(recv, messageString)) { NapiThrow(env, "Can not get message from resource manager.", ERROR_CODE_INTERNAL_ERROR); return false; @@ -204,7 +206,8 @@ bool GetToastOffset(napi_env env, napi_value offsetApi, std::optional& backgroundColor) +void GetToastBackgroundColor( + napi_env env, napi_value backgroundColorNApi, std::optional& backgroundColor, RefPtr& resObj) { napi_valuetype valueType = napi_undefined; napi_typeof(env, backgroundColorNApi, &valueType); @@ -212,10 +215,12 @@ void GetToastBackgroundColor(napi_env env, napi_value backgroundColorNApi, std:: backgroundColor = std::nullopt; if (ParseNapiColor(env, backgroundColorNApi, color)) { backgroundColor = color; + resObj = ParseResourceParamToObj(env, backgroundColorNApi); } } -void GetToastTextColor(napi_env env, napi_value textColorNApi, std::optional& textColor) +void GetToastTextColor( + napi_env env, napi_value textColorNApi, std::optional& textColor, RefPtr& resObj) { napi_valuetype valueType = napi_undefined; napi_typeof(env, textColorNApi, &valueType); @@ -223,6 +228,7 @@ void GetToastTextColor(napi_env env, napi_value textColorNApi, std::optional textColorResObj; + RefPtr messageResObj; + RefPtr bgColorResObj; + napi_valuetype valueType = napi_undefined; napi_typeof(env, argv, &valueType); if (valueType == napi_object) { @@ -459,7 +469,7 @@ bool GetToastParams(napi_env env, napi_value argv, NG::ToastInfo& toastInfo) NapiThrow(env, "The type of parameters is incorrect.", ERROR_CODE_PARAM_INVALID); return false; } - if (!GetToastMessage(env, messageNApi, toastInfo.message) || + if (!GetToastMessage(env, messageNApi, toastInfo.message, messageResObj) || !GetToastDuration(env, durationNApi, toastInfo.duration) || !GetToastBottom(env, bottomNApi, toastInfo.bottom) || !GetToastShowMode(env, showModeNApi, toastInfo.showMode) || @@ -467,9 +477,12 @@ bool GetToastParams(napi_env env, napi_value argv, NG::ToastInfo& toastInfo) !GetToastOffset(env, offsetApi, toastInfo.offset)) { return false; } + toastInfo.messageResObj = messageResObj; GetToastHoverModeParams(env, argv, toastInfo); - GetToastBackgroundColor(env, backgroundColorNApi, toastInfo.backgroundColor); - GetToastTextColor(env, textColorNApi, toastInfo.textColor); + GetToastBackgroundColor(env, backgroundColorNApi, toastInfo.backgroundColor, bgColorResObj); + GetToastTextColor(env, textColorNApi, toastInfo.textColor, textColorResObj); + toastInfo.bgColorResObj = bgColorResObj; + toastInfo.textColorResObj = textColorResObj; GetToastBackgroundBlurStyle(env, backgroundBlurStyleNApi, toastInfo.backgroundBlurStyle); GetToastShadow(env, shadowNApi, toastInfo.shadow, toastInfo.isTypeStyleShadow); return true; @@ -638,6 +651,10 @@ napi_value JSPromptCloseToast(napi_env env, napi_callback_info info) return nullptr; } +struct ButtonInfoResObj { + RefPtr textResObj; + RefPtr colorResObj; +}; struct PromptAsyncContext { napi_env env = nullptr; napi_value titleNApi = nullptr; @@ -706,6 +723,10 @@ struct PromptAsyncContext { napi_value dialogLevelUniqueId = nullptr; napi_value dialogImmersiveModeApi = nullptr; napi_value focusableApi = nullptr; + RefPtr bgColorResObj; + RefPtr maskColorResObj; + RefPtr borderColorResObj; + std::vector buttonsResObj; }; void DeleteContextAndThrowError( @@ -768,7 +789,8 @@ bool ParseButtons(napi_env env, std::shared_ptr& context, } std::string textString; napi_get_named_property(env, buttonArray, "text", &textNApi); - if (!GetNapiString(env, textNApi, textString, valueType)) { + RefPtr btnTextResObj; + if (!GetNapiString(env, textNApi, textString, valueType, btnTextResObj)) { DeleteContextAndThrowError(env, context, "The type of parameters is incorrect."); return false; } @@ -777,8 +799,9 @@ bool ParseButtons(napi_env env, std::shared_ptr& context, return false; } std::string colorString; + RefPtr btnColorResObj; napi_get_named_property(env, buttonArray, "color", &colorNApi); - if (!GetNapiString(env, colorNApi, colorString, valueType)) { + if (!GetNapiString(env, colorNApi, colorString, valueType, btnColorResObj)) { if (valueType == napi_undefined) { colorString = DEFAULT_FONT_COLOR_STRING_VALUE; } else { @@ -787,6 +810,22 @@ bool ParseButtons(napi_env env, std::shared_ptr& context, } } ButtonInfo buttonInfo = { .text = textString, .textColor = colorString }; + if (btnTextResObj) { + auto updateFunc = [](const RefPtr& btnTextResObjRef, + ButtonInfo& buttonInfo) { + std::string textStr; + buttonInfo.text = textStr; + }; + buttonInfo.AddResource("button.text", btnTextResObj, std::move(updateFunc)); + } + if (btnColorResObj) { + auto updateFunc = [](const RefPtr& btnColorResObjRef, + ButtonInfo& buttonInfo) { + std::string colorStr; + buttonInfo.textColor = colorStr; + }; + buttonInfo.AddResource("button.color", btnColorResObj, std::move(updateFunc)); + } if (primaryButtonNum <= PROMPTACTION_VALID_PRIMARY_BUTTON_NUM) { napi_get_named_property(env, buttonArray, "primary", &primaryButtonNApi); napi_typeof(env, primaryButtonNApi, &valueType); @@ -795,6 +834,10 @@ bool ParseButtons(napi_env env, std::shared_ptr& context, } } context->buttons.emplace_back(buttonInfo); + context->buttonsResObj.emplace_back(ButtonInfoResObj { + .textResObj = ParseResourceParamToObj(env, textNApi), + .colorResObj = ParseResourceParamToObj(env, colorNApi) + }); } return true; } @@ -1117,6 +1160,15 @@ std::optional GetColorProps(napi_env env, napi_value value) return std::nullopt; } +std::optional GetColorProps(napi_env env, napi_value value, RefPtr& resObj) +{ + Color color; + if (ParseNapiColor(env, value, color, resObj)) { + return color; + } + return std::nullopt; +} + std::optional GetBorderStyleProps( napi_env env, const std::shared_ptr& asyncContext) { @@ -1380,6 +1432,7 @@ void GetNapiNamedProperties(napi_env env, napi_value* argv, size_t index, if (index == 0) { napi_get_named_property(env, argv[index], "builder", &asyncContext->builder); napi_get_named_property(env, argv[index], "backgroundColor", &asyncContext->backgroundColorApi); + asyncContext->bgColorResObj = ParseResourceParamToObj(env, asyncContext->backgroundColorApi); napi_get_named_property(env, argv[index], "backgroundBlurStyle", &asyncContext->backgroundBlurStyleApi); napi_get_named_property(env, argv[index], "backgroundBlurStyleOptions", &asyncContext->blurStyleOptionApi); napi_get_named_property(env, argv[index], "backgroundEffect", &asyncContext->effectOptionApi); @@ -1387,6 +1440,7 @@ void GetNapiNamedProperties(napi_env env, napi_value* argv, size_t index, napi_get_named_property(env, argv[index], "cornerRadius", &asyncContext->borderRadiusApi); napi_get_named_property(env, argv[index], "borderWidth", &asyncContext->borderWidthApi); napi_get_named_property(env, argv[index], "borderColor", &asyncContext->borderColorApi); + asyncContext->borderColorResObj = ParseResourceParamToObj(env, asyncContext->borderColorApi); napi_get_named_property(env, argv[index], "borderStyle", &asyncContext->borderStyleApi); napi_get_named_property(env, argv[index], "shadow", &asyncContext->shadowApi); napi_get_named_property(env, argv[index], "width", &asyncContext->widthApi); @@ -1405,6 +1459,7 @@ void GetNapiNamedProperties(napi_env env, napi_value* argv, size_t index, napi_get_named_property(env, argv[index], "maskRect", &asyncContext->maskRectApi); napi_get_named_property(env, argv[index], "autoCancel", &asyncContext->autoCancel); napi_get_named_property(env, argv[index], "maskColor", &asyncContext->maskColorApi); + asyncContext->maskColorResObj = ParseResourceParamToObj(env, asyncContext->maskColorApi); napi_get_named_property(env, argv[index], "transition", &asyncContext->transitionApi); napi_get_named_property(env, argv[index], "dialogTransition", &asyncContext->dialogTransitionApi); napi_get_named_property(env, argv[index], "maskTransition", &asyncContext->maskTransitionApi); @@ -1626,6 +1681,9 @@ napi_value JSPromptShowDialog(napi_env env, napi_callback_info info) int32_t dialogLevelUniqueId = -1; ImmersiveMode dialogImmersiveMode = ImmersiveMode::DEFAULT; PromptDialogAttr lifeCycleAttr = {}; + RefPtr titleResObj; + RefPtr messageResObj; + RefPtr bgColorResObj; for (size_t i = 0; i < argc; i++) { napi_valuetype valueType = napi_undefined; napi_typeof(env, argv[i], &valueType); @@ -1658,10 +1716,13 @@ napi_value JSPromptShowDialog(napi_env env, napi_callback_info info) napi_get_named_property(env, argv[0], "onDidDisappear", &asyncContext->onDidDisappear); napi_get_named_property(env, argv[0], "onWillAppear", &asyncContext->onWillAppear); napi_get_named_property(env, argv[0], "onWillDisappear", &asyncContext->onWillDisappear); - GetNapiString(env, asyncContext->titleNApi, asyncContext->titleString, valueType); - GetNapiString(env, asyncContext->messageNApi, asyncContext->messageString, valueType); + RefPtr titleResObj; + RefPtr messageResObj; + RefPtr bgColorResObj; + GetNapiString(env, asyncContext->titleNApi, asyncContext->titleString, valueType, titleResObj); + GetNapiString(env, asyncContext->messageNApi, asyncContext->messageString, valueType, messageResObj); GetNapiDialogProps(env, asyncContext, alignment, offset, maskRect); - backgroundColor = GetColorProps(env, asyncContext->backgroundColorApi); + backgroundColor = GetColorProps(env, asyncContext->backgroundColorApi, bgColorResObj); shadowProps = GetShadowProps(env, asyncContext); GetNapiBlurStyleAndHoverModeProps(env, asyncContext, backgroundBlurStyle, hoverModeArea, enableHoverMode); GetBackgroundBlurStyleOption(env, asyncContext, blurStyleOption); @@ -1842,6 +1903,9 @@ napi_value JSPromptShowDialog(napi_env env, napi_callback_info info) .onDidDisappear = lifeCycleAttr.onDidDisappear, .onWillAppear = lifeCycleAttr.onWillAppear, .onWillDisappear = lifeCycleAttr.onWillDisappear, + .messageResObj = messageResObj, + .bgColorResObj = bgColorResObj, + .titleResObj = titleResObj, }; #ifdef OHOS_STANDARD_SYSTEM @@ -1933,6 +1997,7 @@ napi_value JSPromptShowActionMenu(napi_env env, napi_callback_info info) LevelMode dialogLevelMode = LevelMode::OVERLAY; int32_t dialogLevelUniqueId = -1; ImmersiveMode dialogImmersiveMode = ImmersiveMode::DEFAULT; + RefPtr titleResObj; for (size_t i = 0; i < argc; i++) { napi_valuetype valueType = napi_undefined; napi_typeof(env, argv[i], &valueType); @@ -1947,7 +2012,7 @@ napi_value JSPromptShowActionMenu(napi_env env, napi_callback_info info) napi_get_named_property(env, argv[0], "levelMode", &asyncContext->dialogLevelModeApi); napi_get_named_property(env, argv[0], "levelUniqueId", &asyncContext->dialogLevelUniqueId); napi_get_named_property(env, argv[0], "immersiveMode", &asyncContext->dialogImmersiveModeApi); - GetNapiString(env, asyncContext->titleNApi, asyncContext->titleString, valueType); + GetNapiString(env, asyncContext->titleNApi, asyncContext->titleString, valueType, titleResObj); if (!HasProperty(env, argv[0], "buttons")) { DeleteContextAndThrowError(env, asyncContext, "Required input parameters are missing."); return nullptr; @@ -2064,6 +2129,7 @@ napi_value JSPromptShowActionMenu(napi_env env, napi_callback_info info) .dialogLevelMode = dialogLevelMode, .dialogLevelUniqueId = dialogLevelUniqueId, .dialogImmersiveMode = dialogImmersiveMode, + .titleResObj = titleResObj, }; #ifdef OHOS_STANDARD_SYSTEM if (SystemProperties::GetExtSurfaceEnabled() || !ContainerIsService()) { @@ -2344,6 +2410,9 @@ PromptDialogAttr GetPromptActionDialog(napi_env env, const std::shared_ptrbgColorResObj, + .maskColorResObj = asyncContext->maskColorResObj, + .borderColorResObj = asyncContext->borderColorResObj, }; return promptDialogAttr; } diff --git a/interfaces/napi/kits/utils/napi_utils.cpp b/interfaces/napi/kits/utils/napi_utils.cpp index 20022d3f0bf..882aae037a3 100644 --- a/interfaces/napi/kits/utils/napi_utils.cpp +++ b/interfaces/napi/kits/utils/napi_utils.cpp @@ -22,6 +22,7 @@ using namespace OHOS::Ace; namespace { const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase); +const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase); constexpr int32_t NAPI_BUF_LENGTH = 256; constexpr int32_t UNKNOWN_RESOURCE_ID = -1; constexpr char BUNDLE_NAME[] = "bundleName"; @@ -152,6 +153,96 @@ bool GetNapiString(napi_env env, napi_value value, std::string& retStr, napi_val return false; } +bool GetNapiString( + napi_env env, napi_value value, std::string& retStr, napi_valuetype& valueType, RefPtr& resObj) +{ + if (NapiStringToString(env, value, retStr)) { + return true; + } + napi_typeof(env, value, &valueType); + if (valueType == napi_object) { + ResourceInfo recv; + if (ParseResourceParam(env, value, recv)) { + ParseString(recv, retStr); + return true; + } + resObj = ParseResourceParamToObj(env, value); + } + return false; +} + +RefPtr ParseResourceParamToObj(napi_env env, napi_value value) +{ + CompleteResourceParam(env, value); + napi_value idNApi = nullptr; + napi_value typeNApi = nullptr; + napi_value paramsNApi = nullptr; + napi_value bundleNameNApi = nullptr; + napi_value moduleNameNApi = nullptr; + napi_valuetype valueType = napi_undefined; + napi_typeof(env, value, &valueType); + if (valueType != napi_object || value == NULL) { + return nullptr; + } + napi_get_named_property(env, value, "id", &idNApi); + napi_get_named_property(env, value, "type", &typeNApi); + napi_get_named_property(env, value, "params", ¶msNApi); + napi_get_named_property(env, value, "bundleName", &bundleNameNApi); + napi_get_named_property(env, value, "moduleName", &moduleNameNApi); + + int32_t id; + int32_t type; + bool isArray = false; + if (napi_is_array(env, paramsNApi, &isArray) != napi_ok || !isArray) { + return nullptr; + } + napi_typeof(env, idNApi, &valueType); + if (valueType == napi_number) { + napi_get_value_int32(env, idNApi, &id); + } + + napi_typeof(env, typeNApi, &valueType); + if (valueType == napi_number) { + napi_get_value_int32(env, typeNApi, &type); + } + + uint32_t arrayLength = 0; + napi_get_array_length(env, paramsNApi, &arrayLength); + std::vector resObjParamsList; + for (uint32_t i = 0; i < arrayLength; i++) { + napi_value indexValue = nullptr; + napi_get_element(env, paramsNApi, i, &indexValue); + napi_typeof(env, indexValue, &valueType); + ResourceObjectParams resObjParams; + if (valueType == napi_string) { + std::string indexStr; + NapiStringToString(env, indexValue, indexStr); + resObjParams.value = indexStr; + resObjParams.type = ResourceObjectParamType::STRING; + } else if (valueType == napi_number) { + int32_t num; + napi_get_value_int32(env, indexValue, &num); + resObjParams.value = std::to_string(num); + resObjParams.type = std::regex_match(std::to_string(num), FLOAT_PATTERN) ? ResourceObjectParamType::FLOAT + : ResourceObjectParamType::INT; + resObjParamsList.push_back(resObjParams); + } + } + std::string bundleName; + std::string moduleName; + napi_typeof(env, bundleNameNApi, &valueType); + if (valueType == napi_string) { + NapiStringToString(env, bundleNameNApi, bundleName); + } + napi_typeof(env, moduleNameNApi, &valueType); + if (valueType == napi_string) { + NapiStringToString(env, moduleNameNApi, moduleName); + } + auto resourceObject = AceType::MakeRefPtr( + id, type, resObjParamsList, bundleName, moduleName, Container::CurrentIdSafely()); + return resourceObject; +} + RefPtr GetThemeConstants(const std::optional& bundleName = std::nullopt, const std::optional& moduleName = std::nullopt) { @@ -958,6 +1049,37 @@ bool ParseNapiColor(napi_env env, napi_value value, Color& result) return ParseColorFromResourceObject(env, value, result); } +bool ParseNapiColor(napi_env env, napi_value value, Color& result, RefPtr& resObj) +{ + napi_valuetype valueType = GetValueType(env, value); + if (valueType != napi_number && valueType != napi_string && valueType != napi_object) { + return false; + } + if (valueType == napi_number) { + int32_t colorId = 0; + napi_get_value_int32(env, value, &colorId); + constexpr uint32_t colorAlphaOffset = 24; + constexpr uint32_t colorAlphaDefaultValue = 0xFF000000; + auto origin = static_cast(colorId); + uint32_t alphaResult = origin; + if ((origin >> colorAlphaOffset) == 0) { + alphaResult = origin | colorAlphaDefaultValue; + } + result = Color(alphaResult); + return true; + } + if (valueType == napi_string) { + std::optional colorString = GetStringFromValueUtf8(env, value); + if (!colorString.has_value()) { + LOGE("Parse color from string failed"); + return false; + } + return Color::ParseColorString(colorString.value(), result); + } + resObj = ParseResourceParamToObj(env, value); + return ParseColorFromResourceObject(env, value, result); +} + bool ParseStyle(napi_env env, napi_value value, std::optional& style) { napi_valuetype valueType = GetValueType(env, value); diff --git a/interfaces/napi/kits/utils/napi_utils.h b/interfaces/napi/kits/utils/napi_utils.h index 43767ead591..e33f33a01f5 100644 --- a/interfaces/napi/kits/utils/napi_utils.h +++ b/interfaces/napi/kits/utils/napi_utils.h @@ -61,6 +61,11 @@ size_t GetParamLen(napi_env env, napi_value param); bool GetNapiString(napi_env env, napi_value value, std::string& retStr, napi_valuetype& valueType); +bool GetNapiString( + napi_env env, napi_value value, std::string& retStr, napi_valuetype& valueType, RefPtr& resObj); + +RefPtr ParseResourceParamToObj(napi_env env, napi_value value); + bool NapiStringToString(napi_env env, napi_value value, std::string& retStr); void NapiThrow(napi_env env, const std::string& message, int32_t errCode); @@ -112,6 +117,7 @@ bool ParseNapiDimension(napi_env env, CalcDimension& result, napi_value napiValu bool ParseNapiDimensionNG( napi_env env, CalcDimension& result, napi_value napiValue, DimensionUnit defaultUnit, bool isSupportPercent); bool ParseNapiColor(napi_env env, napi_value value, Color& result); +bool ParseNapiColor(napi_env env, napi_value value, Color& result, RefPtr& resObj); bool ParseStyle(napi_env env, napi_value value, std::optional& style); bool ParseShadowColorStrategy(napi_env env, napi_value value, ShadowColorStrategy& strategy); } // namespace OHOS::Ace::Napi diff --git a/test/unittest/core/pattern/dialog/dialog_pattern_test_ng.cpp b/test/unittest/core/pattern/dialog/dialog_pattern_test_ng.cpp index f8cf9e6a1a3..4502ae19946 100644 --- a/test/unittest/core/pattern/dialog/dialog_pattern_test_ng.cpp +++ b/test/unittest/core/pattern/dialog/dialog_pattern_test_ng.cpp @@ -1815,4 +1815,39 @@ HWTEST_F(DialogPatternAdditionalTestNg, DialogPatternUpdateBackgroundColorTest00 pattern->UpdateBackGroundColor(colorStr); EXPECT_EQ(dialogContext->GetBackgroundColor().value(), Color::ColorFromString(colorStr)); } + +/** +@tc.name: DialogPatternAdditionalTestNgCreateTitleResourceObj001 +@tc.desc: Test DialogPattern CreateTitleResourceObj +@tc.type: FUNC +*/ +HWTEST_F(DialogPatternAdditionalTestNg, DialogPatternAdditionalTestNgCreateTitleResourceObj001, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create dialogNode and dialogTheme instance. + * @tc.expected: The dialogNode and dialogNode created successfully. + */ + auto dialogTheme = AceType::MakeRefPtr(); + ASSERT_NE(dialogTheme, nullptr); + RefPtr frameNode = FrameNode::CreateFrameNode( + V2::ALERT_DIALOG_ETS_TAG, 1, AceType::MakeRefPtr(dialogTheme, nullptr)); + ASSERT_NE(frameNode, nullptr); + auto pattern = frameNode->GetPattern(); + pattern->titleNode_ = FrameNode::CreateFrameNode("titleNode", 11, AceType::MakeRefPtr()); + pattern->dialogProperties_.titleResObj = AceType::MakeRefPtr(); + ASSERT_NE(pattern, nullptr); + DialogProperties param = {}; + + /** + * @tc.steps: step2. Call CreateTitleResourceObj and check the result. + * @tc.expected: Background color is updated correctly. + */ + param.titleResObj = AceType::MakeRefPtr(); + pattern->CreateTitleResourceObj(param); + auto resMgr = pattern->resourceMgr_; + ASSERT_NE(resMgr, nullptr); + int count = resMgr->resMap_.count("dialog.title"); + EXPECT_NE(count, 0); +} + } // namespace OHOS::Ace::NG -- Gitee