From d78a1b61146572534ba457584a9308fbf4d355cd Mon Sep 17 00:00:00 2001 From: wangweiyuan Date: Tue, 6 May 2025 11:23:06 +0800 Subject: [PATCH 1/3] stack Signed-off-by: wangweiyuan Change-Id: Ia12df35cab3fd5abd083762ad7f547ab0991a800 --- .../ark_component/src/ArkComponent.ts | 23 +++++++++++ .../engine/arkComponent.js | 22 +++++++++++ .../arkts_native_api_impl_bridge.cpp | 4 ++ .../arkts_native_common_bridge.cpp | 26 +++++++++++++ .../nativeModule/arkts_native_common_bridge.h | 2 + .../jsview/js_view_abstract.cpp | 37 ++++++++++++++++++ .../jsview/js_view_abstract.h | 2 + .../jsview/models/view_abstract_model_impl.h | 1 + .../components/common/properties/alignment.h | 8 ++++ .../core/components_ng/base/view_abstract.cpp | 13 +++++++ .../core/components_ng/base/view_abstract.h | 2 + .../components_ng/base/view_abstract_model.h | 1 + .../base/view_abstract_model_ng.h | 5 +++ .../components_ng/layout/layout_property.cpp | 34 ++++++++++++++++ .../components_ng/layout/layout_property.h | 5 +++ .../core/components_ng/pattern/pattern.h | 1 + .../pattern/stack/stack_layout_algorithm.cpp | 9 ++++- .../property/position_property.h | 3 ++ .../core/interfaces/arkoala/arkoala_api.h | 2 + frameworks/core/interfaces/cjui/cjui_api.h | 2 + .../native/node/node_common_modifier.cpp | 39 +++++++++++++++++++ .../layout/layout_property_test_ng_two.cpp | 18 +++++++++ 22 files changed, 258 insertions(+), 1 deletion(-) diff --git a/frameworks/bridge/declarative_frontend/ark_component/src/ArkComponent.ts b/frameworks/bridge/declarative_frontend/ark_component/src/ArkComponent.ts index 1c85604558d..c4b953e3182 100644 --- a/frameworks/bridge/declarative_frontend/ark_component/src/ArkComponent.ts +++ b/frameworks/bridge/declarative_frontend/ark_component/src/ArkComponent.ts @@ -721,6 +721,20 @@ class AlignModifier extends ModifierWithKey { } } +class LayoutGravityModifier extends ModifierWithKey { + constructor(value: string) { + super(value); + } + static identity: Symbol = Symbol('layoutGravity'); + applyPeer(node: KNode, reset: boolean): void { + if (reset) { + getUINativeModule().common.resetLayoutGravity(node); + } else { + getUINativeModule().common.setLayoutGravity(node, this.value); + } + } + } + class BackdropBlurModifier extends ModifierWithKey { constructor(value: ArkBlurOptions) { super(value); @@ -4628,6 +4642,15 @@ class ArkComponent implements CommonMethod { return this; } + layoutGravity(value:string): this { + if (!isString(value)) { + modifierWithKey(this._modifiersWithKeys, LayoutGravityModifier.identity, LayoutGravityModifier, undefined); + } else { + modifierWithKey(this._modifiersWithKeys, LayoutGravityModifier.identity, LayoutGravityModifier, value); + } + return this; + } + position(value: Position | Edges): this { if (isObject(value)) { modifierWithKey(this._modifiersWithKeys, PositionModifier.identity, PositionModifier, value); diff --git a/frameworks/bridge/declarative_frontend/engine/arkComponent.js b/frameworks/bridge/declarative_frontend/engine/arkComponent.js index fa29ecd53eb..895186e7f1c 100755 --- a/frameworks/bridge/declarative_frontend/engine/arkComponent.js +++ b/frameworks/bridge/declarative_frontend/engine/arkComponent.js @@ -570,6 +570,20 @@ class AlignModifier extends ModifierWithKey { } } AlignModifier.identity = Symbol('align'); +class LayoutGravityModifier extends ModifierWithKey { + constructor(value) { + super(value); + } + applyPeer(node, reset) { + if (reset) { + getUINativeModule().common.resetLayoutGravity(node); + } + else { + getUINativeModule().common.setLayoutGravity(node, this.value); + } + } + } + LayoutGravityModifier.identity = Symbol('layoutGravity'); class BackdropBlurModifier extends ModifierWithKey { constructor(value) { super(value); @@ -4393,6 +4407,14 @@ class ArkComponent { } return this; } + layoutGravity(value) { + if (!isString(value)) { + modifierWithKey(this._modifiersWithKeys, LayoutGravityModifier.identity, LayoutGravityModifier, undefined); + } else { + modifierWithKey(this._modifiersWithKeys, LayoutGravityModifier.identity, LayoutGravityModifier, value); + } + return this; + } position(value) { if (isObject(value)) { modifierWithKey(this._modifiersWithKeys, PositionModifier.identity, PositionModifier, value); diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_impl_bridge.cpp b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_impl_bridge.cpp index 2fb294cd6ef..697540c1d9e 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_impl_bridge.cpp +++ b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_api_impl_bridge.cpp @@ -515,6 +515,10 @@ ArkUINativeModuleValue ArkUINativeModule::GetArkUINativeModule(ArkUIRuntimeCallI panda::FunctionRef::New(const_cast(vm), CommonBridge::SetAlign)); common->Set(vm, panda::StringRef::NewFromUtf8(vm, "resetAlign"), panda::FunctionRef::New(const_cast(vm), CommonBridge::ResetAlign)); + common->Set(vm, panda::StringRef::NewFromUtf8(vm, "setLayoutGravity"), + panda::FunctionRef::New(const_cast(vm), CommonBridge::SetLayoutGravity)); + common->Set(vm, panda::StringRef::NewFromUtf8(vm, "resetLayoutGravity"), + panda::FunctionRef::New(const_cast(vm), CommonBridge::ResetLayoutGravity)); common->Set(vm, panda::StringRef::NewFromUtf8(vm, "setBackdropBlur"), panda::FunctionRef::New(const_cast(vm), CommonBridge::SetBackdropBlur)); common->Set(vm, panda::StringRef::NewFromUtf8(vm, "resetBackdropBlur"), 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 63837d784a3..f5a60448785 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 @@ -2293,6 +2293,32 @@ ArkUINativeModuleValue CommonBridge::ResetAlign(ArkUIRuntimeCallInfo *runtimeCal return panda::JSValueRef::Undefined(vm); } +ArkUINativeModuleValue CommonBridge::SetLayoutGravity(ArkUIRuntimeCallInfo *runtimeCallInfo) +{ + EcmaVM *vm = runtimeCallInfo->GetVM(); + CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr)); + Local firstArg = runtimeCallInfo->GetCallArgRef(NUM_0); + Local secondArg = runtimeCallInfo->GetCallArgRef(NUM_1); + auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value()); + if (secondArg->IsString(vm)) { + GetArkUINodeModifiers()->getCommonModifier()->setLayoutGravity( + nativeNode, secondArg->ToString(vm)->ToString(vm).c_str()); + } else { + GetArkUINodeModifiers()->getCommonModifier()->resetLayoutGravity(nativeNode); + } + return panda::JSValueRef::Undefined(vm); +} + +ArkUINativeModuleValue CommonBridge::ResetLayoutGravity(ArkUIRuntimeCallInfo *runtimeCallInfo) +{ + EcmaVM *vm = runtimeCallInfo->GetVM(); + CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr)); + Local firstArg = runtimeCallInfo->GetCallArgRef(NUM_0); + auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value()); + GetArkUINodeModifiers()->getCommonModifier()->resetLayoutGravity(nativeNode); + return panda::JSValueRef::Undefined(vm); +} + ArkUINativeModuleValue CommonBridge::SetBackdropBlur(ArkUIRuntimeCallInfo *runtimeCallInfo) { EcmaVM *vm = runtimeCallInfo->GetVM(); diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h index 4e3d23df319..6952897ec0f 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h +++ b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h @@ -61,6 +61,8 @@ public: static ArkUINativeModuleValue ResetOpacity(ArkUIRuntimeCallInfo* runtimeCallInfo); static ArkUINativeModuleValue SetAlign(ArkUIRuntimeCallInfo* runtimeCallInfo); static ArkUINativeModuleValue ResetAlign(ArkUIRuntimeCallInfo* runtimeCallInfo); + static ArkUINativeModuleValue SetLayoutGravity(ArkUIRuntimeCallInfo* runtimeCallInfo); + static ArkUINativeModuleValue ResetLayoutGravity(ArkUIRuntimeCallInfo* runtimeCallInfo); static ArkUINativeModuleValue SetBackdropBlur(ArkUIRuntimeCallInfo* runtimeCallInfo); static ArkUINativeModuleValue ResetBackdropBlur(ArkUIRuntimeCallInfo* runtimeCallInfo); static ArkUINativeModuleValue SetHueRotate(ArkUIRuntimeCallInfo* runtimeCallInfo); diff --git a/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp b/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp index 1b47b76af80..29f0b6ae501 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp @@ -1922,6 +1922,22 @@ void JSViewAbstract::JsAlign(const JSCallbackInfo& info) } } +void JSViewAbstract::JsLayoutGravity(const JSCallbackInfo& info) +{ + static std::vector checkList { JSCallbackInfoType::STRING }; + auto jsVal = info[0]; + if (!CheckJSCallbackInfo("JsLayoutGravity", jsVal, checkList)) { + ViewAbstractModel::GetInstance()->SetLayoutGravity(Alignment::CENTER); + return; + } + + if (jsVal->IsString()) { + std::string value = jsVal->ToString(); + Alignment layoutGravityAlignment = ParseLocalizedAlignment(value); + ViewAbstractModel::GetInstance()->SetLayoutGravity(layoutGravityAlignment); + } +} + void JSViewAbstract::JsPosition(const JSCallbackInfo& info) { CalcDimension x; @@ -2167,6 +2183,26 @@ LayoutCalPolicy JSViewAbstract::ParseLayoutPolicy(const std::string& layoutPolic return LayoutCalPolicy::NO_MATCH; } +Alignment JSViewAbstract::ParseLocalizedAlignment(std::string localizedAlignment) +{ + static const std::unordered_map alignmentMap = { + {"top_start", Alignment::TOP_LEFT}, + {"top", Alignment::TOP_CENTER}, + {"top_end", Alignment::TOP_RIGHT}, + {"start", Alignment::CENTER_LEFT}, + {"center", Alignment::CENTER}, + {"end", Alignment::CENTER_RIGHT}, + {"bottom_start", Alignment::BOTTOM_LEFT}, + {"bottom", Alignment::BOTTOM_CENTER}, + {"bottom_end", Alignment::BOTTOM_RIGHT} + }; + auto it = alignmentMap.find(localizedAlignment); + if (it != alignmentMap.end()) { + return it->second; + } + return Alignment::CENTER; +} + void JSViewAbstract::SetVisibility(const JSCallbackInfo& info) { int32_t visible = 0; @@ -7191,6 +7227,7 @@ void JSViewAbstract::JSBind(BindingTarget globalObj) JSClass::StaticMethod("transition", &JSViewAbstract::JsTransition); JSClass::StaticMethod("align", &JSViewAbstract::JsAlign); + JSClass::StaticMethod("layoutGravity", &JSViewAbstract::JsLayoutGravity); JSClass::StaticMethod("position", &JSViewAbstract::JsPosition); JSClass::StaticMethod("markAnchor", &JSViewAbstract::JsMarkAnchor); JSClass::StaticMethod("offset", &JSViewAbstract::JsOffset); diff --git a/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h b/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h index 96049e60618..92c06a4399e 100755 --- a/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h +++ b/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h @@ -424,6 +424,7 @@ public: static void JsLayoutWeight(const JSCallbackInfo& info); static void JsAlign(const JSCallbackInfo& info); + static void JsLayoutGravity(const JSCallbackInfo& info); static void JsPosition(const JSCallbackInfo& info); static void JsMarkAnchor(const JSCallbackInfo& info); static void JsOffset(const JSCallbackInfo& info); @@ -432,6 +433,7 @@ public: static void JsOverlay(const JSCallbackInfo& info); static Alignment ParseAlignment(int32_t align); static LayoutCalPolicy ParseLayoutPolicy(const std::string& layoutPolicy); + static Alignment ParseLocalizedAlignment(std::string localizedAlignment); static void JsAlignRules(const JSCallbackInfo& info); static void JsChainMode(const JSCallbackInfo& info); diff --git a/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h b/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h index e22d791521a..b8a45c70b1c 100755 --- a/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h +++ b/frameworks/bridge/declarative_frontend/jsview/models/view_abstract_model_impl.h @@ -100,6 +100,7 @@ public: void ResetAspectRatio() override {}; void SetAlign(const Alignment& alignment) override; void SetAlign(const std::string& localizedAlignment) override {} + void SetLayoutGravity(const Alignment& alignment) override {} void SetIsMirrorable(const bool& isMirrorable) override {} void SetAlignRules(const std::map& alignRules) override; void SetChainStyle(const ChainInfo& chainInfo) override {} diff --git a/frameworks/core/components/common/properties/alignment.h b/frameworks/core/components/common/properties/alignment.h index 6807e6b85a8..cfdeb4cf393 100644 --- a/frameworks/core/components/common/properties/alignment.h +++ b/frameworks/core/components/common/properties/alignment.h @@ -52,6 +52,14 @@ public: return !operator==(other); } + bool operator<(const Alignment& other) const + { + if (horizontal_ != other.horizontal_) { + return horizontal_ < other.horizontal_; + } + return vertical_ < other.vertical_; + } + 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); diff --git a/frameworks/core/components_ng/base/view_abstract.cpp b/frameworks/core/components_ng/base/view_abstract.cpp index 5aab9e882a0..4337c995bc9 100644 --- a/frameworks/core/components_ng/base/view_abstract.cpp +++ b/frameworks/core/components_ng/base/view_abstract.cpp @@ -1710,6 +1710,14 @@ void ViewAbstract::SetAlign(std::string localizedAlignment) ACE_UPDATE_LAYOUT_PROPERTY(LayoutProperty, LocalizedAlignment, localizedAlignment); } +void ViewAbstract::SetLayoutGravity(Alignment alignment) +{ + if (!ViewStackProcessor::GetInstance()->IsCurrentVisualStateProcess()) { + return; + } + ACE_UPDATE_LAYOUT_PROPERTY(LayoutProperty, LayoutGravity, alignment); +} + void ViewAbstract::SetIsMirrorable(bool isMirrorable) { if (!ViewStackProcessor::GetInstance()->IsCurrentVisualStateProcess()) { @@ -1723,6 +1731,11 @@ void ViewAbstract::SetAlign(FrameNode* frameNode, Alignment alignment) ACE_UPDATE_NODE_LAYOUT_PROPERTY(LayoutProperty, Alignment, alignment, frameNode); } +void ViewAbstract::SetLayoutGravity(FrameNode* frameNode, Alignment alignment) +{ + ACE_UPDATE_NODE_LAYOUT_PROPERTY(LayoutProperty, LayoutGravity, alignment, frameNode); +} + void ViewAbstract::SetVisibility(VisibleType visible) { if (!ViewStackProcessor::GetInstance()->IsCurrentVisualStateProcess()) { diff --git a/frameworks/core/components_ng/base/view_abstract.h b/frameworks/core/components_ng/base/view_abstract.h index 335a4d6f975..9c9b8f3fe99 100644 --- a/frameworks/core/components_ng/base/view_abstract.h +++ b/frameworks/core/components_ng/base/view_abstract.h @@ -273,6 +273,7 @@ public: // layout static void SetAlign(Alignment alignment); static void SetAlign(std::string localizedAlignment); + static void SetLayoutGravity(Alignment alignment); static void SetIsMirrorable(bool isMirrorable); static void SetAlignRules(const std::map &alignRules); static void SetChainStyle(const ChainInfo& chainInfo); @@ -582,6 +583,7 @@ public: static void SetOpacity(FrameNode* frameNode, double opacity); static void SetZIndex(FrameNode* frameNode, int32_t value); static void SetAlign(FrameNode* frameNode, Alignment alignment); + static void SetLayoutGravity(FrameNode* frameNode, Alignment alignment); static void SetBackdropBlur(FrameNode* frameNode, const Dimension& radius, const BlurOption& blurOption, const SysOptions& sysOptions = SysOptions()); static void SetNodeBackdropBlur(FrameNode* frameNode, const Dimension& radius, const BlurOption& blurOption); diff --git a/frameworks/core/components_ng/base/view_abstract_model.h b/frameworks/core/components_ng/base/view_abstract_model.h index 93fec417e13..e87dbf915a6 100755 --- a/frameworks/core/components_ng/base/view_abstract_model.h +++ b/frameworks/core/components_ng/base/view_abstract_model.h @@ -172,6 +172,7 @@ public: virtual void ResetAspectRatio() = 0; virtual void SetAlign(const Alignment& alignment) = 0; virtual void SetAlign(const std::string& localizedAlignment) = 0; + virtual void SetLayoutGravity(const Alignment& alignment) = 0; virtual void SetIsMirrorable(const bool& isMirrorable) = 0; virtual void SetAlignRules(const std::map& alignRules) = 0; virtual void SetChainStyle(const ChainInfo& chainInfo) = 0; diff --git a/frameworks/core/components_ng/base/view_abstract_model_ng.h b/frameworks/core/components_ng/base/view_abstract_model_ng.h index 7447b178dd1..56f8a1db686 100755 --- a/frameworks/core/components_ng/base/view_abstract_model_ng.h +++ b/frameworks/core/components_ng/base/view_abstract_model_ng.h @@ -583,6 +583,11 @@ public: ViewAbstract::SetAlign(localizedAlignment); } + void SetLayoutGravity(const Alignment& alignment) override + { + ViewAbstract::SetLayoutGravity(alignment); + } + void SetIsMirrorable(const bool& isMirrorable) override { ViewAbstract::SetIsMirrorable(isMirrorable); diff --git a/frameworks/core/components_ng/layout/layout_property.cpp b/frameworks/core/components_ng/layout/layout_property.cpp index 21c233c8b08..7762bde7967 100644 --- a/frameworks/core/components_ng/layout/layout_property.cpp +++ b/frameworks/core/components_ng/layout/layout_property.cpp @@ -1124,6 +1124,16 @@ void LayoutProperty::UpdateLocalizedAlignment(std::string value) } } +void LayoutProperty::UpdateLayoutGravity(Alignment value) +{ + if (!positionProperty_) { + positionProperty_ = std::make_unique(); + } + if (positionProperty_->UpdateLayoutGravity(value)) { + propertyChangeFlag_ = propertyChangeFlag_ | PROPERTY_UPDATE_LAYOUT; + } +} + void LayoutProperty::UpdateIsMirrorable(bool value) { if (!positionProperty_) { @@ -2136,6 +2146,16 @@ void LayoutProperty::CheckLocalizedAlignment(const TextDirection& direction) } } +void LayoutProperty::CheckLayoutGravity(const TextDirection& direction) +{ + CHECK_NULL_VOID(GetPositionProperty()); + if (GetPositionProperty()->HasLayoutGravity()) { + auto layoutGravity = GetPositionProperty()->GetLayoutGravity().value_or(Alignment::CENTER); + auto alignment = GetLayoutGravityAlignment(direction, layoutGravity); + GetPositionProperty()->UpdateLayoutGravity(alignment); + } +} + std::string LayoutProperty::LayoutInfoToString() { std::stringstream ss; @@ -2179,4 +2199,18 @@ std::string LayoutProperty::GetAlignmentStringFromLocalized( } return "center"; } + +Alignment LayoutProperty::GetLayoutGravityAlignment(TextDirection layoutDirection, Alignment alignment) +{ + static const std::map alignmentMap = { { Alignment::TOP_LEFT, Alignment::TOP_RIGHT }, + { Alignment::TOP_CENTER, Alignment::TOP_CENTER }, { Alignment::TOP_RIGHT, Alignment::TOP_LEFT }, + { Alignment::CENTER_LEFT, Alignment::CENTER_RIGHT }, { Alignment::CENTER, Alignment::CENTER }, + { Alignment::CENTER_RIGHT, Alignment::CENTER_LEFT }, { Alignment::BOTTOM_LEFT, Alignment::BOTTOM_RIGHT }, + { Alignment::BOTTOM_CENTER, Alignment::BOTTOM_CENTER }, { Alignment::BOTTOM_RIGHT, Alignment::BOTTOM_LEFT } }; + auto it = alignmentMap.find(alignment); + if (it != alignmentMap.end()) { + return layoutDirection == TextDirection::LTR ? it->first : it->second; + } + return Alignment::CENTER; +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/layout/layout_property.h b/frameworks/core/components_ng/layout/layout_property.h index 1b455ddcbce..fb2231d9583 100644 --- a/frameworks/core/components_ng/layout/layout_property.h +++ b/frameworks/core/components_ng/layout/layout_property.h @@ -160,6 +160,8 @@ public: void UpdateLocalizedAlignment(std::string value); + void UpdateLayoutGravity(Alignment value); + void UpdateIsMirrorable(bool value); void UpdateLayoutWeight(float value); @@ -417,6 +419,7 @@ public: void CheckLocalizedBorderImageOutset(const TextDirection& direction); void CheckLocalizedSafeAreaPadding(const TextDirection& direction); void CheckLocalizedAlignment(const TextDirection& direction); + void CheckLayoutGravity(const TextDirection& direction); virtual void OnPropertyChangeMeasure() {} @@ -424,6 +427,8 @@ public: std::string GetAlignmentStringFromLocalized(TextDirection layoutDirection, std::string localizedAlignment); + Alignment GetLayoutGravityAlignment(TextDirection layoutDirection, Alignment alignment); + protected: void UpdateLayoutProperty(const LayoutProperty* layoutProperty); diff --git a/frameworks/core/components_ng/pattern/pattern.h b/frameworks/core/components_ng/pattern/pattern.h index dc2b1a5641d..5463aaa5125 100644 --- a/frameworks/core/components_ng/pattern/pattern.h +++ b/frameworks/core/components_ng/pattern/pattern.h @@ -627,6 +627,7 @@ public: layoutProperty->CheckLocalizedBorderImageWidth(layoutDirection); layoutProperty->CheckLocalizedBorderImageOutset(layoutDirection); layoutProperty->CheckLocalizedAlignment(layoutDirection); + layoutProperty->CheckLayoutGravity(layoutDirection); host->ResetSafeAreaPadding(); layoutProperty->CheckLocalizedSafeAreaPadding(layoutDirection); } diff --git a/frameworks/core/components_ng/pattern/stack/stack_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/stack/stack_layout_algorithm.cpp index 0300f78853f..2f57338e8e4 100644 --- a/frameworks/core/components_ng/pattern/stack/stack_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/stack/stack_layout_algorithm.cpp @@ -55,8 +55,15 @@ void StackLayoutAlgorithm::PerformLayout(LayoutWrapper* layoutWrapper) } // Update child position. for (const auto& child : layoutWrapper->GetAllChildrenWithBuild()) { + auto childAlign = align; + auto childLayoutProperty = child->GetLayoutProperty(); + if (childLayoutProperty && childLayoutProperty->GetPositionProperty() && + childLayoutProperty->GetPositionProperty()->HasLayoutGravity()) { + childAlign = childLayoutProperty->GetPositionProperty()->GetLayoutGravity().value(); + } auto translate = - CalculateStackAlignment(contentSize, child->GetGeometryNode()->GetMarginFrameSize(), align) + paddingOffset; + CalculateStackAlignment(contentSize, child->GetGeometryNode()->GetMarginFrameSize(), childAlign) + + paddingOffset; child->GetGeometryNode()->SetMarginFrameOffset(translate); } // Update content position. diff --git a/frameworks/core/components_ng/property/position_property.h b/frameworks/core/components_ng/property/position_property.h index 579dd8fbf28..7f7ac2986c3 100644 --- a/frameworks/core/components_ng/property/position_property.h +++ b/frameworks/core/components_ng/property/position_property.h @@ -23,6 +23,7 @@ namespace OHOS::Ace::NG { struct PositionProperty { ACE_DEFINE_PROPERTY_GROUP_ITEM(Alignment, Alignment); + ACE_DEFINE_PROPERTY_GROUP_ITEM(LayoutGravity, Alignment); ACE_DEFINE_PROPERTY_GROUP_ITEM(LocalizedAlignment, std::string); ACE_DEFINE_PROPERTY_GROUP_ITEM(IsMirrorable, bool); @@ -34,6 +35,8 @@ struct PositionProperty { } json->PutExtAttr("align", propAlignment.value_or(Alignment::CENTER).GetAlignmentStr(TextDirection::LTR).c_str(), filter); + json->PutExtAttr("layoutGravity", + propLayoutGravity.value_or(Alignment::CENTER).GetAlignmentStr(TextDirection::LTR).c_str(), filter); json->PutExtAttr("localizedAlignment", propLocalizedAlignment.value_or("center").c_str(), filter); } diff --git a/frameworks/core/interfaces/arkoala/arkoala_api.h b/frameworks/core/interfaces/arkoala/arkoala_api.h index 03a516c93f0..377d82ee7aa 100644 --- a/frameworks/core/interfaces/arkoala/arkoala_api.h +++ b/frameworks/core/interfaces/arkoala/arkoala_api.h @@ -1970,6 +1970,8 @@ struct ArkUICommonModifier { void (*setAlign)(ArkUINodeHandle node, ArkUI_Int32 align); void (*setLocalizedAlign)(ArkUINodeHandle node, ArkUI_CharPtr align); void (*resetAlign)(ArkUINodeHandle node); + void (*setLayoutGravity)(ArkUINodeHandle node, ArkUI_CharPtr align); + void (*resetLayoutGravity)(ArkUINodeHandle node); void (*setBackdropBlur)(ArkUINodeHandle node, ArkUI_Float32 value, const ArkUI_Float32* blurValues, ArkUI_Int32 blurValuesSize, ArkUI_Bool disableSystemAdaptation); void (*resetBackdropBlur)(ArkUINodeHandle node); diff --git a/frameworks/core/interfaces/cjui/cjui_api.h b/frameworks/core/interfaces/cjui/cjui_api.h index 56c21cabfd9..4005b19ab2d 100644 --- a/frameworks/core/interfaces/cjui/cjui_api.h +++ b/frameworks/core/interfaces/cjui/cjui_api.h @@ -59,6 +59,8 @@ struct CJUICommonModifier { void (*resetOpacity)(ArkUINodeHandle node); void (*setAlign)(ArkUINodeHandle node, ArkUI_Int32 align); void (*resetAlign)(ArkUINodeHandle node); + void (*setLayoutGravity)(ArkUINodeHandle node, ArkUI_CharPtr align); + void (*resetLayoutGravity)(ArkUINodeHandle node); void (*setBackdropBlur)(ArkUINodeHandle node, ArkUI_Float32 value, const ArkUI_Float32* blurValues, ArkUI_Int32 blurValuesSize, ArkUI_Bool disableSystemAdaptation); void (*resetBackdropBlur)(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 86cd61668ea..cb5cce0b5fb 100644 --- a/frameworks/core/interfaces/native/node/node_common_modifier.cpp +++ b/frameworks/core/interfaces/native/node/node_common_modifier.cpp @@ -189,6 +189,26 @@ Alignment ParseAlignment(int32_t align) return alignment; } +Alignment ParseLocalizedAlignment(std::string localizedAlignment) +{ + static const std::unordered_map alignmentMap = { + {"top_start", Alignment::TOP_LEFT}, + {"top", Alignment::TOP_CENTER}, + {"top_end", Alignment::TOP_RIGHT}, + {"start", Alignment::CENTER_LEFT}, + {"center", Alignment::CENTER}, + {"end", Alignment::CENTER_RIGHT}, + {"bottom_start", Alignment::BOTTOM_LEFT}, + {"bottom", Alignment::BOTTOM_CENTER}, + {"bottom_end", Alignment::BOTTOM_RIGHT} + }; + auto it = alignmentMap.find(localizedAlignment); + if (it != alignmentMap.end()) { + return it->second; + } + return Alignment::CENTER; +} + int32_t ConvertAlignmentToInt(Alignment alignment) { if (alignment == Alignment::TOP_LEFT) { @@ -1137,6 +1157,21 @@ void ResetAlign(ArkUINodeHandle node) ViewAbstract::SetAlign(frameNode, Alignment::CENTER); } +void SetLayoutGravity(ArkUINodeHandle node, ArkUI_CharPtr align) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + Alignment alignment = ParseLocalizedAlignment(align); + ViewAbstract::SetLayoutGravity(frameNode, alignment); +} + +void ResetLayoutGravity(ArkUINodeHandle node) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + ViewAbstract::SetLayoutGravity(frameNode, Alignment::CENTER); +} + void SetBackdropBlur(ArkUINodeHandle node, ArkUI_Float32 value, const ArkUI_Float32* blurValues, ArkUI_Int32 blurValuesSize, ArkUI_Bool disableSystemAdaptation) { @@ -7081,6 +7116,8 @@ const ArkUICommonModifier* GetCommonModifier() .setAlign = SetAlign, .setLocalizedAlign = SetLocalizedAlign, .resetAlign = ResetAlign, + .setLayoutGravity = SetLayoutGravity, + .resetLayoutGravity = ResetLayoutGravity, .setBackdropBlur = SetBackdropBlur, .resetBackdropBlur = ResetBackdropBlur, .setHueRotate = SetHueRotate, @@ -7520,6 +7557,8 @@ const CJUICommonModifier* GetCJUICommonModifier() .resetOpacity = ResetOpacity, .setAlign = SetAlign, .resetAlign = ResetAlign, + .setLayoutGravity = SetLayoutGravity, + .resetLayoutGravity = ResetLayoutGravity, .setBackdropBlur = SetBackdropBlur, .resetBackdropBlur = ResetBackdropBlur, .setHueRotate = SetHueRotate, 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 337cf36e6ce..830314e3394 100644 --- a/test/unittest/core/layout/layout_property_test_ng_two.cpp +++ b/test/unittest/core/layout/layout_property_test_ng_two.cpp @@ -1186,4 +1186,22 @@ HWTEST_F(LayoutPropertyTestNgTwo, UpdateIsMirrorable001, TestSize.Level1) auto isMirrorable1 = layoutProperty->GetPositionProperty()->GetIsMirrorable().value_or(false); EXPECT_EQ(isMirrorable1, false); } + +/** + * @tc.name:CheckLayoutGravity + * @tc.desc: Test cast to CheckLayoutGravity + * @tc.type: FUNC + */ +HWTEST_F(LayoutPropertyTestNgTwo, CheckLayoutGravity, TestSize.Level1) +{ + auto layoutProperty = AceType::MakeRefPtr(); + layoutProperty->UpdateIsMirrorable(true); + layoutProperty->GetPositionProperty()->UpdateLayoutGravity(Alignment::TOP_LEFT); + + layoutProperty->CheckLayoutGravity(TextDirection::LTR); + EXPECT_EQ(layoutProperty->GetPositionProperty()->GetLayoutGravity().value(), Alignment::TOP_LEFT); + + layoutProperty->CheckLayoutGravity(TextDirection::RTL); + EXPECT_EQ(layoutProperty->GetPositionProperty()->GetLayoutGravity().value(), Alignment::TOP_RIGHT); +} } -- Gitee From ca8b591622f305d67b55000272c04d704b77e2bc Mon Sep 17 00:00:00 2001 From: wangweiyuan Date: Thu, 8 May 2025 13:52:47 +0800 Subject: [PATCH 2/3] chang stack direction Signed-off-by: wangweiyuan Change-Id: If22586117a6ede40d42ceb1bd3ae87cf3e9b0eaa --- .../components/common/properties/alignment.h | 8 ------- .../components_ng/layout/layout_property.cpp | 24 ------------------- .../components_ng/layout/layout_property.h | 3 --- .../core/components_ng/pattern/pattern.h | 1 - .../pattern/stack/stack_layout_algorithm.cpp | 3 ++- .../layout/layout_property_test_ng_two.cpp | 18 -------------- 6 files changed, 2 insertions(+), 55 deletions(-) diff --git a/frameworks/core/components/common/properties/alignment.h b/frameworks/core/components/common/properties/alignment.h index cfdeb4cf393..6807e6b85a8 100644 --- a/frameworks/core/components/common/properties/alignment.h +++ b/frameworks/core/components/common/properties/alignment.h @@ -52,14 +52,6 @@ public: return !operator==(other); } - bool operator<(const Alignment& other) const - { - if (horizontal_ != other.horizontal_) { - return horizontal_ < other.horizontal_; - } - return vertical_ < other.vertical_; - } - 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); diff --git a/frameworks/core/components_ng/layout/layout_property.cpp b/frameworks/core/components_ng/layout/layout_property.cpp index 7762bde7967..812c90555d4 100644 --- a/frameworks/core/components_ng/layout/layout_property.cpp +++ b/frameworks/core/components_ng/layout/layout_property.cpp @@ -2146,16 +2146,6 @@ void LayoutProperty::CheckLocalizedAlignment(const TextDirection& direction) } } -void LayoutProperty::CheckLayoutGravity(const TextDirection& direction) -{ - CHECK_NULL_VOID(GetPositionProperty()); - if (GetPositionProperty()->HasLayoutGravity()) { - auto layoutGravity = GetPositionProperty()->GetLayoutGravity().value_or(Alignment::CENTER); - auto alignment = GetLayoutGravityAlignment(direction, layoutGravity); - GetPositionProperty()->UpdateLayoutGravity(alignment); - } -} - std::string LayoutProperty::LayoutInfoToString() { std::stringstream ss; @@ -2199,18 +2189,4 @@ std::string LayoutProperty::GetAlignmentStringFromLocalized( } return "center"; } - -Alignment LayoutProperty::GetLayoutGravityAlignment(TextDirection layoutDirection, Alignment alignment) -{ - static const std::map alignmentMap = { { Alignment::TOP_LEFT, Alignment::TOP_RIGHT }, - { Alignment::TOP_CENTER, Alignment::TOP_CENTER }, { Alignment::TOP_RIGHT, Alignment::TOP_LEFT }, - { Alignment::CENTER_LEFT, Alignment::CENTER_RIGHT }, { Alignment::CENTER, Alignment::CENTER }, - { Alignment::CENTER_RIGHT, Alignment::CENTER_LEFT }, { Alignment::BOTTOM_LEFT, Alignment::BOTTOM_RIGHT }, - { Alignment::BOTTOM_CENTER, Alignment::BOTTOM_CENTER }, { Alignment::BOTTOM_RIGHT, Alignment::BOTTOM_LEFT } }; - auto it = alignmentMap.find(alignment); - if (it != alignmentMap.end()) { - return layoutDirection == TextDirection::LTR ? it->first : it->second; - } - return Alignment::CENTER; -} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/layout/layout_property.h b/frameworks/core/components_ng/layout/layout_property.h index fb2231d9583..7e6daa123d6 100644 --- a/frameworks/core/components_ng/layout/layout_property.h +++ b/frameworks/core/components_ng/layout/layout_property.h @@ -419,7 +419,6 @@ public: void CheckLocalizedBorderImageOutset(const TextDirection& direction); void CheckLocalizedSafeAreaPadding(const TextDirection& direction); void CheckLocalizedAlignment(const TextDirection& direction); - void CheckLayoutGravity(const TextDirection& direction); virtual void OnPropertyChangeMeasure() {} @@ -427,8 +426,6 @@ public: std::string GetAlignmentStringFromLocalized(TextDirection layoutDirection, std::string localizedAlignment); - Alignment GetLayoutGravityAlignment(TextDirection layoutDirection, Alignment alignment); - protected: void UpdateLayoutProperty(const LayoutProperty* layoutProperty); diff --git a/frameworks/core/components_ng/pattern/pattern.h b/frameworks/core/components_ng/pattern/pattern.h index 5463aaa5125..dc2b1a5641d 100644 --- a/frameworks/core/components_ng/pattern/pattern.h +++ b/frameworks/core/components_ng/pattern/pattern.h @@ -627,7 +627,6 @@ public: layoutProperty->CheckLocalizedBorderImageWidth(layoutDirection); layoutProperty->CheckLocalizedBorderImageOutset(layoutDirection); layoutProperty->CheckLocalizedAlignment(layoutDirection); - layoutProperty->CheckLayoutGravity(layoutDirection); host->ResetSafeAreaPadding(); layoutProperty->CheckLocalizedSafeAreaPadding(layoutDirection); } diff --git a/frameworks/core/components_ng/pattern/stack/stack_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/stack/stack_layout_algorithm.cpp index 2f57338e8e4..b2cc9e68f1f 100644 --- a/frameworks/core/components_ng/pattern/stack/stack_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/stack/stack_layout_algorithm.cpp @@ -59,7 +59,8 @@ void StackLayoutAlgorithm::PerformLayout(LayoutWrapper* layoutWrapper) auto childLayoutProperty = child->GetLayoutProperty(); if (childLayoutProperty && childLayoutProperty->GetPositionProperty() && childLayoutProperty->GetPositionProperty()->HasLayoutGravity()) { - childAlign = childLayoutProperty->GetPositionProperty()->GetLayoutGravity().value(); + auto rawChildAlign = childLayoutProperty->GetPositionProperty()->GetLayoutGravity().value_or(Alignment::CENTER); + childAlign = Alignment::GetAlignment(layoutDirection, rawChildAlign.GetAlignmentStr(TextDirection::AUTO)); } auto translate = CalculateStackAlignment(contentSize, child->GetGeometryNode()->GetMarginFrameSize(), childAlign) + 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 830314e3394..337cf36e6ce 100644 --- a/test/unittest/core/layout/layout_property_test_ng_two.cpp +++ b/test/unittest/core/layout/layout_property_test_ng_two.cpp @@ -1186,22 +1186,4 @@ HWTEST_F(LayoutPropertyTestNgTwo, UpdateIsMirrorable001, TestSize.Level1) auto isMirrorable1 = layoutProperty->GetPositionProperty()->GetIsMirrorable().value_or(false); EXPECT_EQ(isMirrorable1, false); } - -/** - * @tc.name:CheckLayoutGravity - * @tc.desc: Test cast to CheckLayoutGravity - * @tc.type: FUNC - */ -HWTEST_F(LayoutPropertyTestNgTwo, CheckLayoutGravity, TestSize.Level1) -{ - auto layoutProperty = AceType::MakeRefPtr(); - layoutProperty->UpdateIsMirrorable(true); - layoutProperty->GetPositionProperty()->UpdateLayoutGravity(Alignment::TOP_LEFT); - - layoutProperty->CheckLayoutGravity(TextDirection::LTR); - EXPECT_EQ(layoutProperty->GetPositionProperty()->GetLayoutGravity().value(), Alignment::TOP_LEFT); - - layoutProperty->CheckLayoutGravity(TextDirection::RTL); - EXPECT_EQ(layoutProperty->GetPositionProperty()->GetLayoutGravity().value(), Alignment::TOP_RIGHT); -} } -- Gitee From ff7368aa343de3c91aa9e4d9871f2aa1681158c2 Mon Sep 17 00:00:00 2001 From: wangweiyuan Date: Thu, 8 May 2025 16:14:23 +0800 Subject: [PATCH 3/3] add tdd Signed-off-by: wangweiyuan Change-Id: I070a542df91d5f77daad85b086dfcd78f094fa1f --- .../core/pattern/stack/stack_new_test_ng.cpp | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/unittest/core/pattern/stack/stack_new_test_ng.cpp b/test/unittest/core/pattern/stack/stack_new_test_ng.cpp index 10c88f844a0..f9ca99a936c 100644 --- a/test/unittest/core/pattern/stack/stack_new_test_ng.cpp +++ b/test/unittest/core/pattern/stack/stack_new_test_ng.cpp @@ -90,4 +90,25 @@ HWTEST_F(StackNewTestNG, Example, TestSize.Level1) EXPECT_EQ(frameNode->GetChildByIndex(SECOND_CHILD)->GetGeometryNode()->GetFrameOffset().GetX(), 45.0f); EXPECT_EQ(frameNode->GetChildByIndex(SECOND_CHILD)->GetGeometryNode()->GetFrameOffset().GetY(), 120.0f); } + +/** + * @tc.name: LayoutGravityTest + * @tc.desc: Test stack Layout with LayoutGravityTest + * @tc.type: FUNC + */ +HWTEST_F(StackNewTestNG, LayoutGravityTest, TestSize.Level1) +{ + auto frameNode = CreateStack([this](StackModelNG model) { + ACE_UPDATE_LAYOUT_PROPERTY(LayoutProperty, Alignment, Alignment::BOTTOM_CENTER); + auto text = CreateText( + u"First child", [this](TextModelNG model) { ViewAbstract::SetLayoutGravity(Alignment::CENTER_RIGHT); }); + }); + CreateLayoutTask(frameNode); + auto textFrameNode = frameNode->GetChildByIndex(FIRST_CHILD); + ASSERT_NE(textFrameNode, nullptr); + auto textLayoutProperty = textFrameNode->GetLayoutProperty(); + ASSERT_NE(textLayoutProperty, nullptr); + ASSERT_NE(textLayoutProperty->GetPositionProperty(), nullptr); + EXPECT_EQ(textLayoutProperty->GetPositionProperty()->GetLayoutGravity().value(), Alignment::CENTER_RIGHT); +} } // namespace OHOS::Ace::NG \ No newline at end of file -- Gitee