From 4432a3fe40d07b94c3dd5f15059bbd394eae596f Mon Sep 17 00:00:00 2001 From: zenix_zxy Date: Sun, 17 Aug 2025 18:35:29 +0800 Subject: [PATCH] srOverlayCapi Signed-off-by: zenix_zxy Change-Id: I716760e1f101062e4dbbd12ac1e7de60bac3be35 --- .../src/generated/legacy/arkoala_api_legacy.h | 1 + .../arkts_native_common_bridge.cpp | 4 +- .../common/properties/alignment.cpp | 28 +++++ .../components/common/properties/alignment.h | 2 + .../core/components_ng/base/frame_node.cpp | 9 +- .../core/components_ng/base/view_abstract.cpp | 31 ++++- .../core/components_ng/base/view_abstract.h | 3 +- .../components_ng/property/overlay_property.h | 4 +- .../render/adapter/overlay_modifier.h | 17 ++- .../render/adapter/rosen_render_context.cpp | 6 + .../render/adapter/rosen_render_context.h | 2 + .../components_ng/render/render_context.h | 2 + .../core/interfaces/arkoala/arkoala_api.h | 8 +- frameworks/core/interfaces/cjui/cjui_api.h | 7 +- .../native/node/node_common_modifier.cpp | 111 ++++++++++++++---- interfaces/native/node/style_modifier.cpp | 22 +++- ...w_abstract_test_ng_for_property_config.cpp | 41 +++++++ .../layout/layout_property_test_ng_two.cpp | 56 +++++++++ 18 files changed, 315 insertions(+), 39 deletions(-) diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/legacy/arkoala_api_legacy.h b/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/legacy/arkoala_api_legacy.h index e2f790be887..4cf1b0c8134 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/legacy/arkoala_api_legacy.h +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/legacy/arkoala_api_legacy.h @@ -903,6 +903,7 @@ struct ArkUIOverlayOptions { ArkUI_Float32 x; ArkUI_Float32 y; ArkUI_CharPtr content; + ArkUI_Int32 direction; }; union ArkUIInt32orFloat32 { diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.cpp b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.cpp index 9a49b81e5c6..458a59f2db0 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.cpp +++ b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.cpp @@ -3140,8 +3140,10 @@ ArkUINativeModuleValue CommonBridge::SetOverlay(ArkUIRuntimeCallInfo* runtimeCal options.push_back(static_cast(offsetY.value().Unit())); options.push_back(static_cast(hasOptions)); options.push_back(static_cast(hasOffset)); + options.push_back(0); + options.push_back(0); auto textPtr = (text.has_value()) ? text.value().c_str() : nullptr; - GetArkUINodeModifiers()->getCommonModifier()->setOverlay(nativeNode, textPtr, options.data(), options.size()); + GetArkUINodeModifiers()->getCommonModifier()->setOverlay(nativeNode, textPtr, options.data(), options.size(), nullptr); return panda::JSValueRef::Undefined(vm); } diff --git a/frameworks/core/components/common/properties/alignment.cpp b/frameworks/core/components/common/properties/alignment.cpp index 3301c876792..8153267ff61 100644 --- a/frameworks/core/components/common/properties/alignment.cpp +++ b/frameworks/core/components/common/properties/alignment.cpp @@ -73,6 +73,34 @@ NG::OffsetF Alignment::GetAlignPosition( return offset; } +NG::OffsetF Alignment::GetAlignPositionWithDirection(const NG::SizeF& parentSize, const NG::SizeF& childSize, + const Alignment& alignment, TextDirection direction) +{ + Alignment realAlignment = alignment; + if (direction == TextDirection::RTL) { + if (alignment == Alignment::TOP_LEFT) { + realAlignment = Alignment::TOP_RIGHT; + } else if (alignment == Alignment::TOP_CENTER) { + realAlignment = Alignment::TOP_CENTER; + } else if (alignment == Alignment::TOP_RIGHT) { + realAlignment = Alignment::TOP_LEFT; + } else if (alignment == Alignment::CENTER_LEFT) { + realAlignment = Alignment::CENTER_RIGHT; + } else if (alignment == Alignment::CENTER) { + realAlignment = Alignment::CENTER; + } else if (alignment == Alignment::CENTER_RIGHT) { + realAlignment = Alignment::CENTER_LEFT; + } else if (alignment == Alignment::BOTTOM_LEFT) { + realAlignment = Alignment::BOTTOM_RIGHT; + } else if (alignment == Alignment::BOTTOM_CENTER) { + realAlignment = Alignment::BOTTOM_CENTER; + } else if (alignment == Alignment::BOTTOM_RIGHT) { + realAlignment = Alignment::BOTTOM_LEFT; + } + } + return GetAlignPosition(parentSize, childSize, realAlignment); +} + std::string Alignment::GetAlignmentStr(TextDirection direction) const { std::string result; diff --git a/frameworks/core/components/common/properties/alignment.h b/frameworks/core/components/common/properties/alignment.h index 6807e6b85a8..ab4fa3bdf43 100644 --- a/frameworks/core/components/common/properties/alignment.h +++ b/frameworks/core/components/common/properties/alignment.h @@ -55,6 +55,8 @@ public: static Offset GetAlignPosition(const Size& parentSize, const Size& childSize, const Alignment& alignment); static NG::OffsetF GetAlignPosition( const NG::SizeF& parentSize, const NG::SizeF& childSize, const Alignment& alignment); + static NG::OffsetF GetAlignPositionWithDirection(const NG::SizeF& parentSize, const NG::SizeF& childSize, + const Alignment& alignment, TextDirection direction); static const Alignment TOP_LEFT; static const Alignment TOP_CENTER; static const Alignment TOP_RIGHT; diff --git a/frameworks/core/components_ng/base/frame_node.cpp b/frameworks/core/components_ng/base/frame_node.cpp index 431e74eb475..e64a8581b9f 100755 --- a/frameworks/core/components_ng/base/frame_node.cpp +++ b/frameworks/core/components_ng/base/frame_node.cpp @@ -5011,6 +5011,8 @@ void FrameNode::Layout() if (overlayNode_) { LayoutOverlay(); + } else if (renderContext_) { + renderContext_->UpdateOverlayText(); } time = GetSysTimestamp() - time; AddNodeFlexLayouts(); @@ -5573,14 +5575,19 @@ void FrameNode::LayoutOverlay() auto align = Alignment::TOP_LEFT; Dimension offsetX, offsetY; auto childLayoutProperty = overlayNode_->GetLayoutProperty(); + CHECK_NULL_VOID(childLayoutProperty); childLayoutProperty->GetOverlayOffset(offsetX, offsetY); + auto direction = childLayoutProperty->GetNonAutoLayoutDirection(); + if (direction == TextDirection::RTL) { + offsetX = -offsetX; + } auto offset = OffsetF(offsetX.ConvertToPx(), offsetY.ConvertToPx()); if (childLayoutProperty->GetPositionProperty()) { align = childLayoutProperty->GetPositionProperty()->GetAlignment().value_or(align); } auto childSize = overlayNode_->GetGeometryNode()->GetMarginFrameSize(); - auto translate = Alignment::GetAlignPosition(size, childSize, align) + offset; + auto translate = Alignment::GetAlignPositionWithDirection(size, childSize, align, direction) + offset; overlayNode_->GetGeometryNode()->SetMarginFrameOffset(translate); overlayNode_->Layout(); } diff --git a/frameworks/core/components_ng/base/view_abstract.cpp b/frameworks/core/components_ng/base/view_abstract.cpp index c1f19eb5984..a6954c30d40 100644 --- a/frameworks/core/components_ng/base/view_abstract.cpp +++ b/frameworks/core/components_ng/base/view_abstract.cpp @@ -5531,7 +5531,7 @@ void ViewAbstract::SetOverlayComponentContent(const RefPtr& conte void ViewAbstract::AddOverlayToFrameNode(const RefPtr& overlayNode, const std::optional& align, const std::optional& offsetX, - const std::optional& offsetY) + const std::optional& offsetY, TextDirection direction) { auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); CHECK_NULL_VOID(frameNode); @@ -5549,6 +5549,7 @@ void ViewAbstract::AddOverlayToFrameNode(const RefPtr& overlayNod layoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT); layoutProperty->UpdateAlignment(align.value_or(Alignment::TOP_LEFT)); layoutProperty->SetOverlayOffset(offsetX, offsetY); + layoutProperty->UpdateLayoutDirection(direction); auto renderContext = overlayNode->GetRenderContext(); CHECK_NULL_VOID(renderContext); renderContext->UpdateZIndex(INT32_MAX); @@ -6399,6 +6400,34 @@ void ViewAbstract::SetOverlay(FrameNode* frameNode, const NG::OverlayOptions& ov ACE_UPDATE_NODE_RENDER_CONTEXT(OverlayText, overlay, frameNode); } +void ViewAbstract::SetOverlayNode(FrameNode* frameNode, FrameNode* node, const NG::OverlayOptions& overlay) +{ + CHECK_NULL_VOID(frameNode); + SetOverlay(frameNode, overlay); + auto overlayNode = AceType::WeakClaim(node).Upgrade(); + if (overlayNode == nullptr) { + frameNode->SetOverlayNode(nullptr); + return; + } + frameNode->SetOverlayNode(overlayNode); + overlayNode->SetParent(AceType::WeakClaim(frameNode)); + overlayNode->SetActive(true); + overlayNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); + auto layoutProperty = AceType::DynamicCast(overlayNode->GetLayoutProperty()); + CHECK_NULL_VOID(layoutProperty); + layoutProperty->SetIsOverlayNode(true); + layoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT); + layoutProperty->UpdateAlignment(overlay.align); + layoutProperty->SetOverlayOffset(overlay.x, overlay.y); + layoutProperty->UpdateLayoutDirection(overlay.direction); + auto renderContext = overlayNode->GetRenderContext(); + CHECK_NULL_VOID(renderContext); + renderContext->UpdateZIndex(INT32_MAX); + auto focusHub = overlayNode->GetOrCreateFocusHub(); + CHECK_NULL_VOID(focusHub); + focusHub->SetFocusable(false); +} + void ViewAbstract::SetBorderImage(FrameNode* frameNode, const RefPtr& borderImage) { ACE_UPDATE_NODE_RENDER_CONTEXT(BorderImage, borderImage, frameNode); diff --git a/frameworks/core/components_ng/base/view_abstract.h b/frameworks/core/components_ng/base/view_abstract.h index 63b41d72199..19ceafc87a7 100644 --- a/frameworks/core/components_ng/base/view_abstract.h +++ b/frameworks/core/components_ng/base/view_abstract.h @@ -713,6 +713,7 @@ public: static void SetSweepGradient(FrameNode* frameNode, const NG::Gradient& gradient); static void SetRadialGradient(FrameNode* frameNode, const NG::Gradient& gradient); static void SetOverlay(FrameNode* frameNode, const NG::OverlayOptions& overlay); + static void SetOverlayNode(FrameNode* frameNode, FrameNode* overlayNode, const NG::OverlayOptions& overlay); static void SetBorderImage(FrameNode* frameNode, const RefPtr& borderImage); static void SetBorderImageSource(FrameNode* frameNode, const std::string& bdImageSrc); static void SetHasBorderImageSlice(FrameNode* frameNode, bool tag); @@ -1087,7 +1088,7 @@ public: private: static void AddOverlayToFrameNode(const RefPtr& overlayNode, const std::optional& align, const std::optional& offsetX, - const std::optional& offsetY); + const std::optional& offsetY, TextDirection direction = TextDirection::LTR); static void CheckIfParentNeedMarkDirty(FrameNode* frameNode); static OEMVisualEffectFunc oemVisualEffectFunc; diff --git a/frameworks/core/components_ng/property/overlay_property.h b/frameworks/core/components_ng/property/overlay_property.h index 384c15c8647..d3ab8a6ad17 100644 --- a/frameworks/core/components_ng/property/overlay_property.h +++ b/frameworks/core/components_ng/property/overlay_property.h @@ -20,6 +20,7 @@ #include "base/geometry/dimension.h" #include "base/geometry/ng/offset_t.h" +#include "core/components/common/layout/constants.h" #include "core/components/common/properties/alignment.h" #include "core/components_ng/base/inspector_filter.h" #include "core/components_ng/property/property.h" @@ -33,11 +34,12 @@ struct OverlayOptions { Alignment align; Dimension x; Dimension y; + TextDirection direction = TextDirection::LTR; bool operator==(const OverlayOptions& value) const { return (content.compare(value.content) == 0) && (align == value.align) && - (x == value.x) && (y == value.y); + (x == value.x) && (y == value.y) && (direction == value.direction); } void ToJsonValue(std::unique_ptr& json, const InspectorFilter& filter) const diff --git a/frameworks/core/components_ng/render/adapter/overlay_modifier.h b/frameworks/core/components_ng/render/adapter/overlay_modifier.h index b5f3a7a49f4..24decc0de34 100644 --- a/frameworks/core/components_ng/render/adapter/overlay_modifier.h +++ b/frameworks/core/components_ng/render/adapter/overlay_modifier.h @@ -149,13 +149,24 @@ public: return fontManager->IsDefaultFontChanged(); } + void UpdateText() + { + UpdateToRender(); + } + private: static OffsetF GetTextPosition(const SizeF& parentSize, const SizeF& childSize, OverlayOptions& overlay) { - const double dx = overlay.x.ConvertToPx(); - const double dy = overlay.y.ConvertToPx(); + double dx = overlay.x.ConvertToPx(); + double dy = overlay.y.ConvertToPx(); const Alignment align = overlay.align; - OffsetF const offset = Alignment::GetAlignPosition(parentSize, childSize, align); + auto direction = overlay.direction; + direction = direction != TextDirection::AUTO ? direction : (AceApplicationInfo::GetInstance().IsRightToLeft() ? + TextDirection::RTL : TextDirection::LTR); + if (direction == TextDirection::RTL) { + dx = -dx; + } + OffsetF const offset = Alignment::GetAlignPositionWithDirection(parentSize, childSize, align, direction); const float fx = static_cast(dx) + offset.GetX(); const float fy = static_cast(dy) + offset.GetY(); return { fx, fy }; diff --git a/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp b/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp index 106112fe3bd..092ba25e1ab 100755 --- a/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp +++ b/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp @@ -3199,6 +3199,12 @@ void RosenRenderContext::UpdateCustomBackground() RequestNextFrame(); } +void RosenRenderContext::UpdateOverlayText() +{ + CHECK_NULL_VOID(overlayTextModifier_); + overlayTextModifier_->UpdateText(); +} + void RosenRenderContext::OnBackgroundAlignUpdate(const Alignment& align) { CHECK_NULL_VOID(rsNode_); diff --git a/frameworks/core/components_ng/render/adapter/rosen_render_context.h b/frameworks/core/components_ng/render/adapter/rosen_render_context.h index 33e6b422fa9..e88100517dc 100755 --- a/frameworks/core/components_ng/render/adapter/rosen_render_context.h +++ b/frameworks/core/components_ng/render/adapter/rosen_render_context.h @@ -537,6 +537,8 @@ public: void UpdateCustomBackground() override; + void UpdateOverlayText() override; + protected: void OnBackgroundImageUpdate(const ImageSourceInfo& src) override; void OnBackgroundImageRepeatUpdate(const ImageRepeat& imageRepeat) override; diff --git a/frameworks/core/components_ng/render/render_context.h b/frameworks/core/components_ng/render/render_context.h index d3fe4586e63..a3963c9d661 100644 --- a/frameworks/core/components_ng/render/render_context.h +++ b/frameworks/core/components_ng/render/render_context.h @@ -837,6 +837,8 @@ public: virtual void UpdateCustomBackground() {} + virtual void UpdateOverlayText() {} + protected: RenderContext() = default; std::shared_ptr sharedTransitionOption_; diff --git a/frameworks/core/interfaces/arkoala/arkoala_api.h b/frameworks/core/interfaces/arkoala/arkoala_api.h index a81515a77e8..810e7d4728c 100644 --- a/frameworks/core/interfaces/arkoala/arkoala_api.h +++ b/frameworks/core/interfaces/arkoala/arkoala_api.h @@ -1659,6 +1659,7 @@ struct ArkUIOverlayOptions { ArkUI_Float32 x; ArkUI_Float32 y; ArkUI_CharPtr content; + ArkUI_Int32 direction; }; union ArkUIInt32orFloat32 { @@ -2352,8 +2353,8 @@ struct ArkUICommonModifier { void (*setRadialGradient)(ArkUINodeHandle node, const ArkUIInt32orFloat32* values, ArkUI_Int32 valuesLength, const ArkUIInt32orFloat32* colors, ArkUI_Int32 colorsLength, void* resRawPtr); void (*resetRadialGradient)(ArkUINodeHandle node); - void (*setOverlay)( - ArkUINodeHandle node, ArkUI_CharPtr text, const ArkUI_Float32* options, ArkUI_Int32 optionsLength); + void (*setOverlay)(ArkUINodeHandle node, ArkUI_CharPtr text, const ArkUI_Float32* options, + ArkUI_Int32 optionsLength, ArkUINodeHandle overlayNode); void (*resetOverlay)(ArkUINodeHandle node); void (*setBorderImage)( ArkUINodeHandle node, ArkUI_CharPtr src, const ArkUIStringAndFloat* options, ArkUI_Int32 optionsLength); @@ -2624,7 +2625,8 @@ struct ArkUICommonModifier { ArkUI_Bool (*getFocusable)(ArkUINodeHandle node); ArkUI_Bool (*getDefaultFocus)(ArkUINodeHandle node); ArkUI_Int32 (*getResponseRegion)(ArkUINodeHandle node, ArkUI_Float32 (*values)[32]); - ArkUI_CharPtr (*getOverlay)(ArkUINodeHandle node, ArkUIOverlayOptions* options, ArkUI_Int32 unit); + ArkUI_CharPtr (*getOverlay)(ArkUINodeHandle node, ArkUIOverlayOptions* options, ArkUI_Int32 unit, + ArkUINodeHandle& overlayNode); ArkUI_Bool (*getAccessibilityGroup)(ArkUINodeHandle node); ArkUI_CharPtr (*getAccessibilityText)(ArkUINodeHandle node); ArkUI_CharPtr (*getAccessibilityDescription)(ArkUINodeHandle node); diff --git a/frameworks/core/interfaces/cjui/cjui_api.h b/frameworks/core/interfaces/cjui/cjui_api.h index 2aee7bfe0e7..e9851a5948f 100644 --- a/frameworks/core/interfaces/cjui/cjui_api.h +++ b/frameworks/core/interfaces/cjui/cjui_api.h @@ -98,8 +98,8 @@ struct CJUICommonModifier { void (*setRadialGradient)(ArkUINodeHandle node, const ArkUIInt32orFloat32* values, ArkUI_Int32 valuesLength, const ArkUIInt32orFloat32* colors, ArkUI_Int32 colorsLength, void* resRawPtr); void (*resetRadialGradient)(ArkUINodeHandle node); - void (*setOverlay)( - ArkUINodeHandle node, ArkUI_CharPtr text, const ArkUI_Float32* options, ArkUI_Int32 optionsLength); + void (*setOverlay)(ArkUINodeHandle node, ArkUI_CharPtr text, const ArkUI_Float32* options, + ArkUI_Int32 optionsLength, ArkUINodeHandle overlayNode); void (*resetOverlay)(ArkUINodeHandle node); void (*setBorderImage)( ArkUINodeHandle node, ArkUI_CharPtr src, const ArkUIStringAndFloat* options, ArkUI_Int32 optionsLength); @@ -344,7 +344,8 @@ struct CJUICommonModifier { ArkUI_Bool (*getFocusable)(ArkUINodeHandle node); ArkUI_Bool (*getDefaultFocus)(ArkUINodeHandle node); ArkUI_Int32 (*getResponseRegion)(ArkUINodeHandle node, ArkUI_Float32 (*values)[32]); - ArkUI_CharPtr (*getOverlay)(ArkUINodeHandle node, ArkUIOverlayOptions* options, ArkUI_Int32 unit); + ArkUI_CharPtr (*getOverlay)(ArkUINodeHandle node, ArkUIOverlayOptions* options, ArkUI_Int32 unit, + ArkUINodeHandle& overlayNode); ArkUI_Bool (*getAccessibilityGroup)(ArkUINodeHandle node); ArkUI_CharPtr (*getAccessibilityText)(ArkUINodeHandle node); ArkUI_CharPtr (*getAccessibilityDescription)(ArkUINodeHandle node); diff --git a/frameworks/core/interfaces/native/node/node_common_modifier.cpp b/frameworks/core/interfaces/native/node/node_common_modifier.cpp index f0a1549efb8..30151212dc6 100644 --- a/frameworks/core/interfaces/native/node/node_common_modifier.cpp +++ b/frameworks/core/interfaces/native/node/node_common_modifier.cpp @@ -199,6 +199,44 @@ Alignment ParseAlignment(int32_t align) return alignment; } +TextDirection ParseDirection(int32_t dir) +{ + TextDirection direction = TextDirection::LTR; + switch (dir) { + case NUM_0: + direction = TextDirection::LTR; + break; + case NUM_1: + direction = TextDirection::RTL; + break; + case NUM_3: + direction = TextDirection::AUTO; + break; + default: + break; + } + return direction; +} + +int32_t ParseDirectionToIndex(TextDirection dir) +{ + int32_t direction = 0; + switch (dir) { + case TextDirection::LTR: + direction = NUM_0; + break; + case TextDirection::RTL: + direction = NUM_1; + break; + case TextDirection::AUTO: + direction = NUM_3; + break; + default: + break; + } + return direction; +} + int32_t ConvertAlignmentToInt(Alignment alignment) { if (alignment == Alignment::TOP_LEFT) { @@ -2243,22 +2281,10 @@ void ResetRadialGradient(ArkUINodeHandle node) ViewAbstract::SetRadialGradient(frameNode, gradient); } -/** - * @param text text value - * @param options option value - * option[0], option[1]: align(hasValue, value) - * option[2], option[3], option[4]: offsetX(hasValue, value, unit) - * option[5], option[6], option[7]: offsetY(hasValue, value, unit) - * option[8]: hasOptions - * option[9]: hasOffset - * @param optionsLength options length - */ -void SetOverlay(ArkUINodeHandle node, ArkUI_CharPtr text, const ArkUI_Float32* options, ArkUI_Int32 optionsLength) +bool ParseOverlayOptions(const ArkUI_Float32* options, ArkUI_Int32 optionsLength, NG::OverlayOptions& overlay) { - auto* frameNode = reinterpret_cast(node); - CHECK_NULL_VOID(frameNode); - if ((options == nullptr) || (optionsLength != NUM_10)) { - return; + if ((options == nullptr) || (optionsLength != NUM_12)) { + return false; } auto alignHasValue = options[NUM_0]; auto alignValue = options[NUM_1]; @@ -2270,10 +2296,9 @@ void SetOverlay(ArkUINodeHandle node, ArkUI_CharPtr text, const ArkUI_Float32* o auto offsetYUnit = options[NUM_7]; auto hasOptions = options[NUM_8]; auto hasOffset = options[NUM_9]; - NG::OverlayOptions overlay; - if (text != nullptr) { - overlay.content = text; - } + auto hasDirection = options[NUM_10]; + auto direction = options[NUM_11]; + if (static_cast(hasOptions)) { if (static_cast(alignHasValue)) { overlay.align = ParseAlignment(static_cast(alignValue)); @@ -2288,12 +2313,48 @@ void SetOverlay(ArkUINodeHandle node, ArkUI_CharPtr text, const ArkUI_Float32* o overlay.y = CalcDimension(offsetYValue, static_cast(offsetYUnit)); } } + if (static_cast(hasDirection)) { + overlay.direction = ParseDirection(static_cast(direction)); + } else { + overlay.direction = TextDirection::LTR; + } } else { overlay.align = Alignment::TOP_LEFT; overlay.x = CalcDimension(0); overlay.y = CalcDimension(0); } - ViewAbstract::SetOverlay(frameNode, overlay); + return true; +} + +/** + * @param text text value + * @param options option value + * option[0], option[1]: align(hasValue, value) + * option[2], option[3], option[4]: offsetX(hasValue, value, unit) + * option[5], option[6], option[7]: offsetY(hasValue, value, unit) + * option[8]: hasOptions + * option[9]: hasOffset + * option[10], option[11]: direction(hasDirection, direction) + * @param optionsLength options length + */ +void SetOverlay(ArkUINodeHandle node, ArkUI_CharPtr text, const ArkUI_Float32* options, + ArkUI_Int32 optionsLength, ArkUINodeHandle overlayNode) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + NG::OverlayOptions overlay; + if (!ParseOverlayOptions(options, optionsLength, overlay)) { + return; + } + if (text != nullptr) { + overlay.content = text; + } + + if (!overlay.content.empty()) { + ViewAbstract::SetOverlay(frameNode, overlay); + } else { + ViewAbstract::SetOverlayNode(frameNode, reinterpret_cast(overlayNode), overlay); + } } void ResetOverlay(ArkUINodeHandle node) @@ -2304,7 +2365,9 @@ void ResetOverlay(ArkUINodeHandle node) overlay.align = Alignment::TOP_LEFT; overlay.x = CalcDimension(0); overlay.y = CalcDimension(0); + overlay.direction = TextDirection::LTR; ViewAbstract::SetOverlay(frameNode, overlay); + ViewAbstract::SetOverlayNode(frameNode, nullptr, overlay); } /** @@ -6707,7 +6770,8 @@ ArkUI_Int32 GetResponseRegion(ArkUINodeHandle node, ArkUI_Float32 (*values)[32]) return index; } -ArkUI_CharPtr GetOverlay(ArkUINodeHandle node, ArkUIOverlayOptions* options, ArkUI_Int32 unit) +ArkUI_CharPtr GetOverlay(ArkUINodeHandle node, ArkUIOverlayOptions* options, ArkUI_Int32 unit, + ArkUINodeHandle& overlayNode) { auto* frameNode = reinterpret_cast(node); CHECK_NULL_RETURN(frameNode, nullptr); @@ -6716,6 +6780,11 @@ ArkUI_CharPtr GetOverlay(ArkUINodeHandle node, ArkUIOverlayOptions* options, Ark options->x = overlayOptions.x.GetNativeValue(static_cast(unit)); options->y = overlayOptions.y.GetNativeValue(static_cast(unit)); options->content = overlayOptions.content.c_str(); + options->direction = ParseDirectionToIndex(overlayOptions.direction); + auto overlay = frameNode->GetOverlayNode(); + if (overlay) { + overlayNode = reinterpret_cast(AceType::RawPtr(overlay)); + } g_strValue = overlayOptions.content; return g_strValue.c_str(); } diff --git a/interfaces/native/node/style_modifier.cpp b/interfaces/native/node/style_modifier.cpp index c6bf2aecf44..488ba5ef2c0 100644 --- a/interfaces/native/node/style_modifier.cpp +++ b/interfaces/native/node/style_modifier.cpp @@ -73,7 +73,7 @@ const int ALLOW_SIZE_7(7); const int ALLOW_SIZE_8(8); const int ALLOW_SIZE_9(9); const int ALLOW_SIZE_16(16); -const int ALLOW_SIZE_10(10); +const int ALLOW_SIZE_12(12); constexpr int DEFAULT_SIZE_18 = 18; constexpr int DEFAULT_SIZE_24 = 24; @@ -2644,7 +2644,7 @@ int32_t SetOverlay(ArkUI_NodeHandle node, const ArkUI_AttributeItem* item) } auto* fullImpl = GetFullImpl(); - ArkUI_Float32 values[ALLOW_SIZE_10] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + ArkUI_Float32 values[ALLOW_SIZE_12] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; if (item->size > 0) { values[0] = 1; @@ -2667,17 +2667,24 @@ int32_t SetOverlay(ArkUI_NodeHandle node, const ArkUI_AttributeItem* item) } values[8] = item->size > 0 ? 1 : 0; values[9] = item->size > 1 ? 1 : 0; + if (item->size > 3) { + values[NUM_10] = 1; + values[NUM_11] = item->value[3].i32; + } + ArkUI_NodeHandle overlay = reinterpret_cast(item->object); + auto overlayNode = overlay ? overlay->uiNodeHandle : nullptr; fullImpl->getNodeModifiers()->getCommonModifier()->setOverlay( - node->uiNodeHandle, item->string, values, ALLOW_SIZE_10); + node->uiNodeHandle, item->string, values, ALLOW_SIZE_12, overlayNode); return ERROR_CODE_NO_ERROR; } const ArkUI_AttributeItem* GetOverlay(ArkUI_NodeHandle node) { ArkUIOverlayOptions options; + ArkUINodeHandle overlayNode; ArkUI_Int32 unit = GetDefaultUnit(node, UNIT_VP); auto contentStr = GetFullImpl()->getNodeModifiers()->getCommonModifier()->getOverlay( - node->uiNodeHandle, &options, unit); + node->uiNodeHandle, &options, unit, overlayNode); g_attributeItem.string = contentStr; int index = 0; //index 0 : align @@ -2686,7 +2693,14 @@ const ArkUI_AttributeItem* GetOverlay(ArkUI_NodeHandle node) g_numberValues[index++].f32 = options.x; //index 2 : offset y g_numberValues[index++].f32 = options.y; + //index 3 : direction + g_numberValues[index++].i32 = options.direction; g_attributeItem.size = index; + if (overlayNode) { + auto* fullImpl = GetFullImpl(); + void* attachNode = fullImpl->getExtendedAPI()->getAttachNodePtr(overlayNode); + g_attributeItem.object = attachNode; + } return &g_attributeItem; } diff --git a/test/unittest/core/base/view_abstract_test_ng_for_property_config.cpp b/test/unittest/core/base/view_abstract_test_ng_for_property_config.cpp index f1ea51fe15b..2a17e7ae434 100644 --- a/test/unittest/core/base/view_abstract_test_ng_for_property_config.cpp +++ b/test/unittest/core/base/view_abstract_test_ng_for_property_config.cpp @@ -1857,4 +1857,45 @@ HWTEST_F(ViewAbstractTestNg, FocusBoxTest001, TestSize.Level1) ViewAbstract::SetFocusBoxStyleUpdateFunc(style, nullptr, "focusBoxStyleWidth"); EXPECT_TRUE(resMap.find("focusBox") == resMap.end()); } + +/** + * @tc.name: SetOverlayNodeTest001 + * @tc.desc: Test SetOverlayNode + * @tc.type: FUNC + */ +HWTEST_F(ViewAbstractTestNg, SetOverlayNodeTest001, TestSize.Level1) +{ + /** + * @tc.steps: step1.Create frameNode and overlayNode + */ + auto frameNode = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, -1, AceType::MakeRefPtr()); + ASSERT_NE(frameNode, nullptr); + auto overlayNode = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, -1, AceType::MakeRefPtr()); + ASSERT_NE(overlayNode, nullptr); + + /** + * @tc.steps: step2.Create overlayOptions + */ + NG::OverlayOptions options; + const Dimension dimensionValue = Dimension(5); + options.x = dimensionValue; + options.y = dimensionValue; + options.direction = TextDirection::RTL; + + /** + * @tc.steps: step3.Execute SetOverlayNode + */ + ViewAbstract::SetOverlayNode(AceType::RawPtr(frameNode), AceType::RawPtr(overlayNode), options); + auto overlayNodeWithFrameNode = frameNode->GetOverlayNode(); + EXPECT_EQ(overlayNode, overlayNodeWithFrameNode); + auto layoutProperty = AceType::DynamicCast(overlayNodeWithFrameNode->GetLayoutProperty()); + ASSERT_NE(layoutProperty, nullptr); + auto direction = layoutProperty->GetLayoutDirection(); + EXPECT_EQ(direction, TextDirection::RTL); + Dimension x; + Dimension y; + layoutProperty->GetOverlayOffset(x, y); + EXPECT_EQ(x, dimensionValue); + EXPECT_EQ(y, dimensionValue); +} } // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/test/unittest/core/layout/layout_property_test_ng_two.cpp b/test/unittest/core/layout/layout_property_test_ng_two.cpp index 96e8366fc61..d33dcf527cc 100644 --- a/test/unittest/core/layout/layout_property_test_ng_two.cpp +++ b/test/unittest/core/layout/layout_property_test_ng_two.cpp @@ -27,6 +27,7 @@ #include "core/components_ng/layout/layout_property.h" #include "core/components_ng/pattern/custom/custom_measure_layout_node.h" #include "core/components_ng/property/measure_utils.h" +#include "core/components/common/properties/alignment.h" #undef private #undef protected @@ -47,6 +48,41 @@ constexpr Dimension HEIGHT = 2.0_vp; const CalcSize CALC_SIZE = {CalcLength(WIDTH), CalcLength(HEIGHT)}; } // namespace +struct OverlayOptionsTestCase { + Alignment align = Alignment::TOP_LEFT; + TextDirection direction = TextDirection::LTR; + OffsetF expectedResult = OffsetF(); +}; + +const std::vector OVERLAY_OPTIONS_TEST_CASES = { + { Alignment::TOP_LEFT, TextDirection::LTR, OffsetF(0.0f, 0.0f) }, + { Alignment::TOP_LEFT, TextDirection::RTL, OffsetF(50.0f, 0.0f) }, + + { Alignment::TOP_CENTER, TextDirection::LTR, OffsetF(25.0f, 0.0f) }, + { Alignment::TOP_CENTER, TextDirection::RTL, OffsetF(25.0f, 0.0f) }, + + { Alignment::TOP_RIGHT, TextDirection::LTR, OffsetF(50.0f, 0.0f) }, + { Alignment::TOP_RIGHT, TextDirection::RTL, OffsetF(0.0f, 0.0f) }, + + { Alignment::CENTER_LEFT, TextDirection::LTR, OffsetF(0.0f, 25.0f) }, + { Alignment::CENTER_LEFT, TextDirection::RTL, OffsetF(50.0f, 25.0f) }, + + { Alignment::CENTER, TextDirection::LTR, OffsetF(25.0f, 25.0f) }, + { Alignment::CENTER, TextDirection::RTL, OffsetF(25.0f, 25.0f) }, + + { Alignment::CENTER_RIGHT, TextDirection::LTR, OffsetF(50.0f, 25.0f) }, + { Alignment::CENTER_RIGHT, TextDirection::RTL, OffsetF(0.0f, 25.0f) }, + + { Alignment::BOTTOM_LEFT, TextDirection::LTR, OffsetF(0.0f, 50.0f) }, + { Alignment::BOTTOM_LEFT, TextDirection::RTL, OffsetF(50.0f, 50.0f) }, + + { Alignment::BOTTOM_CENTER, TextDirection::LTR, OffsetF(25.0f, 50.0f) }, + { Alignment::BOTTOM_CENTER, TextDirection::RTL, OffsetF(25.0f, 50.0f) }, + + { Alignment::BOTTOM_RIGHT, TextDirection::LTR, OffsetF(50.0f, 50.0f) }, + { Alignment::BOTTOM_RIGHT, TextDirection::RTL, OffsetF(0.0f, 50.0f) }, +}; + class LayoutPropertyTestNgTwo : public testing::Test { public: static void SetUpTestSuite() @@ -1570,4 +1606,24 @@ HWTEST_F(LayoutPropertyTestNgTwo, CheckCalcLayoutConstraintTest02, TestSize.Leve CalcSize(CalcLength("calc(40%)"), CalcLength("calc(40%)"))) << layoutProperty->calcLayoutConstraint_->preSelfIdealSize.value().ToString(); } + +/** + * @tc.name: GetAlignPositionWithDirectionTest001 + * @tc.desc: GetAlignPositionWithDirection + * @tc.type: FUNC + */ +HWTEST_F(LayoutPropertyTestNgTwo, GetAlignPositionWithDirectionTest001, TestSize.Level1) +{ + const SizeF parentSize(100.0f, 100.0f); + const SizeF childSize(50.0f, 50.0f); + for (const auto& testCase : OVERLAY_OPTIONS_TEST_CASES) { + /** + * @tc.steps: step1. call GetAlignPositionWithDirection function. + * @tc.expected: step1. offset equals expectedResult. + */ + auto offset = Alignment::GetAlignPositionWithDirection(parentSize, childSize, + testCase.align, testCase.direction); + EXPECT_EQ(offset, testCase.expectedResult); + } +} } \ No newline at end of file -- Gitee