diff --git a/frameworks/bridge/declarative_frontend/ark_component/src/ArkComponent.ts b/frameworks/bridge/declarative_frontend/ark_component/src/ArkComponent.ts index 1c85604558de4c87496907972e5200b4b83b7a35..c4b953e31827b5b876c6e25bf4a4982711566d70 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 fa29ecd53ebc27e600269ce921c228d555a8795d..895186e7f1ce57de5461d0f4e4c015ab85e03f0f 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 2fb294cd6eff6770a5ae267f66d33687c83a3b5b..697540c1d9ebdc60bb914644a7529464795d37ee 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 63837d784a369655709675b80c46d174f788e343..f5a60448785ff79fe9fc3f1bb9c89f72145b6c39 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 4e3d23df31917f2acfc5939e5af6c9a955b427fa..6952897ec0f9f8e757d1aa85cccecfd056e7fade 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 1b47b76af804397d6bf6ddb972312fdd2d15de92..29f0b6ae5017a81eb17428496e579761c50762f3 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 96049e60618e39daad4f4cad3bf14c3bdb2e4ba4..92c06a4399e63b85439305dfde38eca6fae4b060 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 e22d791521a71613e0db5fa3841ebca748556610..b8a45c70b1c1bbf5e72db2140c24757581fda4b7 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_ng/base/view_abstract.cpp b/frameworks/core/components_ng/base/view_abstract.cpp index 5aab9e882a0e770db848b40529ecf5f93979a77d..4337c995bc9b0c396d3ee4f5b081a7ba50ecab5e 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 335a4d6f97560a9d7811fcd9d9175a6a91a05255..9c9b8f3fe99386a316e09520119a684cd3e01560 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 93fec417e136e6237dedca82b5774ad36e6c7305..e87dbf915a6aa9a0b8d1c023fe578d2831c06b83 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 7447b178dd12db21efb689cb002a9c4537f5542a..56f8a1db686b0f3d69b6d04759f72df28401627e 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 21c233c8b0809ac2bc3d7ade3900cf71ac5f6c33..812c90555d4fd7d3b1e9fb3826cdd96fd599b17f 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_) { diff --git a/frameworks/core/components_ng/layout/layout_property.h b/frameworks/core/components_ng/layout/layout_property.h index 1b455ddcbce896543540a0aa4e13fb6e15d8eb2c..7e6daa123d606538e635e7ba98c6a5fd0bfc4a7d 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); 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 0300f78853f17b46362cca5e2b589742ca15c5de..b2cc9e68f1f50d7ddc1790b1c7e64f1957cea307 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,16 @@ 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()) { + auto rawChildAlign = childLayoutProperty->GetPositionProperty()->GetLayoutGravity().value_or(Alignment::CENTER); + childAlign = Alignment::GetAlignment(layoutDirection, rawChildAlign.GetAlignmentStr(TextDirection::AUTO)); + } 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 579dd8fbf28ba563649f475a1b3a3ee803952226..7f7ac2986c325526174034fea8ba16f7ae249af0 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 03a516c93f07b222b4967cd14e1f0b1f8977852c..377d82ee7aab56ad82320abd0ca8db66c452fb60 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 56c21cabfd91363b48183714674407dc7b79326e..4005b19ab2db8166c9753240a81baee2ca336429 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 86cd61668ea4d6c6f400ca3dd45de33d99cd6cd1..cb5cce0b5fb3670eef00d747ee47e1a708ad7073 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/pattern/stack/stack_new_test_ng.cpp b/test/unittest/core/pattern/stack/stack_new_test_ng.cpp index 10c88f844a04aee6ebe6aa50c7afbb5b594bd91b..f9ca99a936c7e881bbcb110c7e849e0797469236 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