diff --git a/frameworks/bridge/arkts_frontend/ani_graphics_module.cpp b/frameworks/bridge/arkts_frontend/ani_graphics_module.cpp index c8ffce6313f0faaa3c19ddf9ad4cf8fe8e2edcaf..1f7b4f4733c3599a76baebab0dd2f66996839a2a 100644 --- a/frameworks/bridge/arkts_frontend/ani_graphics_module.cpp +++ b/frameworks/bridge/arkts_frontend/ani_graphics_module.cpp @@ -21,8 +21,11 @@ #include "canvas_ani/ani_canvas.h" #endif +#include "bridge/arkts_frontend/arkts_ani_utils.h" #include "core/components_ng/pattern/render_node/render_node_pattern.h" +#include "core/interfaces/native/implementation/frame_node_peer_impl.h" #include "core/interfaces/native/implementation/render_node_peer_impl.h" +#include "core/interfaces/native/node/extension_custom_node.h" #include "core/pipeline/pipeline_base.h" namespace OHOS::Ace::Framework { @@ -206,4 +209,56 @@ void AniGraphicsModule::SetDrawModifier(ani_env* env, ani_long ptr, ani_object d } } } + +void AniGraphicsModule::SetCustomCallback( + ani_env* env, ani_long ptr, ani_fn_object fnObjMeasure, ani_fn_object fnObjLayout) +{ + auto customFuncExisted = false; + auto customNode = AceType::MakeRefPtr(); + if (fnObjMeasure != nullptr) { + customFuncExisted = true; + ani_ref fnObjGlobalRef = nullptr; + env->GlobalReference_Create(reinterpret_cast(fnObjMeasure), &fnObjGlobalRef); + auto callbackFunc = [env, fnObjGlobalRef](const NG::LayoutConstraintF& context) -> void { + std::vector params; + auto width1 = ArktsAniUtils::FloatToNumberObject(env, context.maxSize.Width()); + auto height1 = ArktsAniUtils::FloatToNumberObject(env, context.maxSize.Height()); + auto width2 = ArktsAniUtils::FloatToNumberObject(env, context.minSize.Width()); + auto height2 = ArktsAniUtils::FloatToNumberObject(env, context.minSize.Height()); + auto width3 = ArktsAniUtils::FloatToNumberObject(env, context.percentReference.Width()); + auto height3 = ArktsAniUtils::FloatToNumberObject(env, context.percentReference.Height()); + params.emplace_back((ani_ref)width1); + params.emplace_back((ani_ref)height1); + params.emplace_back((ani_ref)width2); + params.emplace_back((ani_ref)height2); + params.emplace_back((ani_ref)width3); + params.emplace_back((ani_ref)height3); + ani_ref fnReturnVal; + env->FunctionalObject_Call( + reinterpret_cast(fnObjGlobalRef), params.size(), params.data(), &fnReturnVal); + }; + customNode->SetMeasureCallback(callbackFunc); + } + if (fnObjLayout != nullptr) { + customFuncExisted = true; + ani_ref fnObjGlobalRef = nullptr; + env->GlobalReference_Create(reinterpret_cast(fnObjLayout), &fnObjGlobalRef); + auto callbackFunc = [env, fnObjGlobalRef](const NG::OffsetF& context) -> void { + std::vector params; + params.emplace_back((ani_ref)ArktsAniUtils::CreateDoubleObject(env, context.GetX())); + params.emplace_back((ani_ref)ArktsAniUtils::CreateDoubleObject(env, context.GetY())); + ani_ref fnReturnVal; + env->FunctionalObject_Call( + reinterpret_cast(fnObjGlobalRef), params.size(), params.data(), &fnReturnVal); + }; + customNode->SetLayoutCallback(callbackFunc); + } + if (!customFuncExisted) { + return; + } + auto* frameNodePeer = reinterpret_cast(ptr); + CHECK_NULL_VOID(frameNodePeer); + auto frameNode = FrameNodePeer::GetFrameNodeByPeer(frameNodePeer); + frameNode->SetExtensionHandler(customNode); +} } // namespace OHOS::Ace::Framework diff --git a/frameworks/bridge/arkts_frontend/ani_graphics_module.h b/frameworks/bridge/arkts_frontend/ani_graphics_module.h index ccdae371c83d484aebbeccfc6e110d6621d89b69..71d50d06f9515beed8065e7c4796e3ec0d563e55 100644 --- a/frameworks/bridge/arkts_frontend/ani_graphics_module.h +++ b/frameworks/bridge/arkts_frontend/ani_graphics_module.h @@ -31,6 +31,7 @@ public: static void SetDrawCallback(ani_env* env, ani_long ptr, ani_fn_object fnObj); static void SetDrawModifier(ani_env* env, ani_long ptr, ani_object fnObj); static void Invalidate(ani_env* env, ani_long ptr); + static void SetCustomCallback(ani_env* env, ani_long ptr, ani_fn_object fnObjMeasure, ani_fn_object fnObjLayout); private: static ani_object CreateDrawingContext(ani_env* env, const NG::DrawingContext& context); diff --git a/frameworks/bridge/arkts_frontend/arkts_ani_utils.cpp b/frameworks/bridge/arkts_frontend/arkts_ani_utils.cpp index 06ac202ba269882b59376e6831d63b9fee20ba18..b3f5c39b44a753efb4765b4b3daf8cc08ddef569 100644 --- a/frameworks/bridge/arkts_frontend/arkts_ani_utils.cpp +++ b/frameworks/bridge/arkts_frontend/arkts_ani_utils.cpp @@ -20,6 +20,7 @@ #include #include "base/log/log.h" +#include "ui/base/utils/utils.h" namespace OHOS::Ace { int32_t ArktsAniUtils::CreateAniBoolean(ani_env* env, bool value, ani_object& result) @@ -99,4 +100,43 @@ ani_env* ArktsAniUtils::GetAniEnv(ani_vm* vm) } return env; } + +ani_object ArktsAniUtils::CreateDoubleObject(ani_env* env, double value) +{ + ani_status state; + static const char* className = "Lstd/core/Double;"; + ani_class persion_cls; + if ((state = env->FindClass(className, &persion_cls)) != ANI_OK) { + LOGE("FindClass std/core/Double failed, %{public}d", state); + return nullptr; + } + ani_method personInfoCtor; + if ((state = env->Class_FindMethod(persion_cls, "", "D:V", &personInfoCtor)) != ANI_OK) { + LOGE("Class_FindMethod Double ctor failed, %{public}d", state); + return nullptr; + } + ani_object personInfoObj; + ani_double aniValue = value; + if ((state = env->Object_New(persion_cls, personInfoCtor, &personInfoObj, aniValue)) != ANI_OK) { + LOGE("New Double object failed, %{public}d", state); + return nullptr; + } + return personInfoObj; +} +double ReplaceInfinity(const float& value) +{ + double res = static_cast(value); + if (GreatOrEqual(res, Infinity())) { + return std::numeric_limits::infinity(); + } + if (LessOrEqual(res, -Infinity())) { + return -std::numeric_limits::infinity(); + } + return res; +} +ani_object ArktsAniUtils::FloatToNumberObject(ani_env* env, const float& value) +{ + auto widthDoouble = ReplaceInfinity(value); + return ArktsAniUtils::CreateDoubleObject(env, widthDoouble); +} } // namespace OHOS::Ace diff --git a/frameworks/bridge/arkts_frontend/arkts_ani_utils.h b/frameworks/bridge/arkts_frontend/arkts_ani_utils.h index 74c0127c20bd908a283ba7e12f3325c252e6239a..1a89131964cff0359c79b9da7d04f57b95d87cad 100644 --- a/frameworks/bridge/arkts_frontend/arkts_ani_utils.h +++ b/frameworks/bridge/arkts_frontend/arkts_ani_utils.h @@ -76,6 +76,14 @@ public: * Get ani env from ani vm. */ static ani_env* GetAniEnv(ani_vm* vm); + /** + * Get std/core/Double. + */ + static ani_object CreateDoubleObject(ani_env* env, double value); + /** + * Get std/core/Double by float. + */ + static ani_object FloatToNumberObject(ani_env* env, const float& value); }; } // namespace OHOS::Ace diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/FrameNode.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/FrameNode.ts index 3cd99ccd66a1859c1a9c4d337b2d1832ef46940f..c2b177cdf47e1cf21b936d5059a8f09af950b4fd 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/FrameNode.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/FrameNode.ts @@ -45,6 +45,11 @@ import { Resource } from 'global.resource'; export interface CrossLanguageOptions { attributeSetting?: boolean; } +export interface LayoutConstraint { + maxSize: Size; + minSize: Size; + percentReference: Size; +} export class ArkFrameNodePeer extends ArkCommonMethodPeer { constructor(peerPtr: KPointer, id: int32, name: string = "", flags: int32 = 0) { @@ -153,6 +158,7 @@ export class FrameNode implements MaterializedBase { ArkUIAniModule._Common_Restore_InstanceId(); FrameNodeFinalizationRegisterProxy.ElementIdToOwningFrameNode_.set(this._nodeId, this); this.onDraw_serialize(this.onDraw); + ArkUIAniModule._SetCustomCallback(this!.peer!.ptr, this.onMeasureInner, this.onLayoutInner); } } static getFinalizer(): KPointer { @@ -393,6 +399,79 @@ export class FrameNode implements MaterializedBase { } public onDraw(context: DrawContext): void { } + public onMeasureInner(width1: number, height1: number, width2: number, height2: number, + width3: number, height3: number): void { + const maxSize: Size = { width: width1, height: height1 }; + const minSize: Size = { width: width2, height: height2 }; + const percentReference: Size = { width: width3, height: height3 }; + const constraint: LayoutConstraint = { maxSize: maxSize, minSize: minSize, percentReference: percentReference }; + this.onMeasure(constraint); + } + public onMeasure(constraint: LayoutConstraint): void { + } + public onLayoutInner(x: number, y: number): void { + const position: Position = { x: x, y: y }; + this.onLayout(position); + } + public onLayout(position: Position): void { + } + public setMeasuredSize(size: Size): void { + const size_casted = size as (Size); + this.setMeasuredSize_serialize(size_casted); + return; + } + public setLayoutPosition(position: Position): void { + const position_casted = position as (Position); + this.setLayoutPosition_serialize(position_casted); + return; + } + public measure(constraint: LayoutConstraint): void { + const constraint_casted = constraint as (LayoutConstraint); + const instanceId = this.instanceId_!.toInt(); + ArkUIAniModule._Common_Sync_InstanceId(instanceId); + this.measure_serialize(constraint_casted); + ArkUIAniModule._Common_Restore_InstanceId(); + return; + } + public layout(position: Position): void { + const position_casted = position as (Position); + const instanceId = this.instanceId_!.toInt(); + ArkUIAniModule._Common_Sync_InstanceId(instanceId); + this.layout_serialize(position_casted); + ArkUIAniModule._Common_Restore_InstanceId(); + return; + } + private setMeasuredSize_serialize(size: Size): void { + const thisSerializer : Serializer = Serializer.hold(); + thisSerializer.writeSize(size); + ArkUIGeneratedNativeModule._FrameNode_setMeasuredSize(this.peer!.ptr, thisSerializer.asBuffer(), thisSerializer.length()); + thisSerializer.release(); + } + private setLayoutPosition_serialize(position: Position): void { + const thisSerializer : Serializer = Serializer.hold(); + thisSerializer.writeGraphicsPosition(position); + ArkUIGeneratedNativeModule._FrameNode_setLayoutPosition(this.peer!.ptr, thisSerializer.asBuffer(), thisSerializer.length()); + thisSerializer.release(); + } + private measure_serialize(constraint: LayoutConstraint): void { + const thisSerializer : Serializer = Serializer.hold(); + thisSerializer.writeLayoutConstraint(constraint); + ArkUIGeneratedNativeModule._FrameNode_measure(this.peer!.ptr, thisSerializer.asBuffer(), thisSerializer.length()); + thisSerializer.release(); + } + private layout_serialize(position: Position): void { + const thisSerializer : Serializer = Serializer.hold(); + thisSerializer.writeGraphicsPosition(position); + ArkUIGeneratedNativeModule._FrameNode_layout(this.peer!.ptr, thisSerializer.asBuffer(), thisSerializer.length()); + thisSerializer.release(); + } + public setNeedsLayout(): void { + this.setNeedsLayout_serialize(); + return; + } + private setNeedsLayout_serialize(): void { + ArkUIGeneratedNativeModule._FrameNode_setNeedsLayout(this.peer!.ptr); + } public invalidate(): void { ArkUIGeneratedNativeModule._FrameNode_invalidate(this.peer!.ptr); }; diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/arkts/ArkUIAniModule.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/arkts/ArkUIAniModule.ts index c05333a97bcca9aaa29b3cfb40fc2a544fba63de..3ce8d83df8e976b76426d1037c2a07c6b05c75f6 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/arkts/ArkUIAniModule.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/arkts/ArkUIAniModule.ts @@ -107,4 +107,7 @@ export class ArkUIAniModule { // for ImageSpan native static _ImageSpan_Set_PixelMap(ptr: KPointer, pixelmap: image.PixelMap): void native static _ImageSpan_SetAlt_PixelMap(ptr: KPointer, pixelmap: image.PixelMap): void + native static _SetCustomCallback(ptr: KPointer, + measureCallback: ((width1: number, height1: number, width2: number, height2: number, width3: number, + height3: number) => void), layoutCallback: ((x: number, y: number) => void)): void } diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/common/common_module.cpp b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/common/common_module.cpp index a2387b8b18faac7297def6fb7ab4ed114ad23aa6..03aa44404828db157c43d4a1d415e891c44771b8 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/common/common_module.cpp +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/common/common_module.cpp @@ -100,4 +100,13 @@ ani_long BuilderProxyNodeConstruct(ani_env* env, [[maybe_unused]] ani_object ani CHECK_NULL_RETURN(builderProxyNode, nativeObj); return reinterpret_cast(builderProxyNode); } +void SetCustomCallback(ani_env* env, ani_object obj, ani_long ptr, + ani_fn_object fnObjMeasure, ani_fn_object fnObjLayout) +{ + const auto* modifier = GetNodeAniModifier(); + if (!modifier || !modifier->getCommonAniModifier() || !env) { + return; + } + modifier->getCommonAniModifier()->setCustomCallback(env, ptr, fnObjMeasure, fnObjLayout); +} } // namespace OHOS::Ace::Ani diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/common/common_module.h b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/common/common_module.h index 6467e295cc7bb28ee4a47be329fe7d320bb8a64d..a9a5c90399cd2f90fd7ab07dd553c034ef0e9740 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/common/common_module.h +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/common/common_module.h @@ -27,6 +27,8 @@ void SetDrawCallback(ani_env* env, ani_object obj, ani_long ptr, ani_fn_object f void SetDrawModifier(ani_env* env, [[maybe_unused]] ani_object aniClass, ani_long ptr, ani_object drawModifier); void Invalidate(ani_env* env, [[maybe_unused]] ani_object aniClass, ani_long ptr); ani_long BuilderProxyNodeConstruct(ani_env* env, [[maybe_unused]] ani_object aniClass, ani_int id); +void SetCustomCallback(ani_env* env, ani_object obj, ani_long ptr, + ani_fn_object fnObjMeasure, ani_fn_object fnObjLayout); } // namespace OHOS::Ace::Ani #endif // KOALA_PROJECTS_ARKOALA_ARKTS_ARKUI_OHOS_ANI_NATIVE_COMMON_MODULE diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/module.cpp b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/module.cpp index 4027f26b53064d077adb8dd16a7fb7e06a7319b0..2f2ea87ef64067b28821b5c2b8da6cf53d06219f 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/module.cpp +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/module.cpp @@ -244,6 +244,11 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) "JL@ohos/multimedia/image/image/PixelMap;:V", reinterpret_cast(OHOS::Ace::Ani::SetImageSpanAltPixelMap) }, + ani_native_function { + "_SetCustomCallback", + nullptr, + reinterpret_cast(OHOS::Ace::Ani::SetCustomCallback) + }, }; auto bindRst = env->Class_BindNativeMethods(cls, methods.data(), methods.size()); diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/arkts/ArkUIGeneratedNativeModule.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/arkts/ArkUIGeneratedNativeModule.ts index 4bde52cc2d6e2fa6327a30bb7fcc8fb2f84e641f..7cc6a6dc6b8c4b737647a3de52163475e5f5a975 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/arkts/ArkUIGeneratedNativeModule.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/arkts/ArkUIGeneratedNativeModule.ts @@ -4243,6 +4243,16 @@ export class ArkUIGeneratedNativeModule { native static _FrameNode_dispose(ptr: KPointer): void @ani.unsafe.Direct native static _FrameNode_getOpacity(ptr: KPointer): number + @ani.unsafe.Direct + native static _FrameNode_setMeasuredSize(ptr: KPointer, thisArray: KSerializerBuffer, thisLength: int32): void + @ani.unsafe.Direct + native static _FrameNode_setLayoutPosition(ptr: KPointer, thisArray: KSerializerBuffer, thisLength: int32): void + @ani.unsafe.Direct + native static _FrameNode_measure(ptr: KPointer, thisArray: KSerializerBuffer, thisLength: int32): void + @ani.unsafe.Direct + native static _FrameNode_layout(ptr: KPointer, thisArray: KSerializerBuffer, thisLength: int32): void + @ani.unsafe.Direct + native static _FrameNode_setNeedsLayout(ptr: KPointer): void @ani.unsafe.Quick native static _FrameNode_getPositionToWindowWithTransform(ptr: KPointer): KInteropReturnBuffer @ani.unsafe.Quick diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/peers/Serializer.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/peers/Serializer.ts index 9e63052d4475656ac99f87a14fc33db73d02f608..6de9a820e9204b4c76592ebcb3600e816316d238 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/peers/Serializer.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/peers/Serializer.ts @@ -101,7 +101,7 @@ import { EventTargetInfo, EventTargetInfoInternal, GestureControl, GestureGroupI import { Filter, FilterInternal, TileMode, WaterRippleMode, FlyMode, VisualEffect, VisualEffectInternal, BrightnessBlender } from "./../arkui-uieffect" import { FocusPriority, KeyProcessingMode, FocusBoxStyle } from "./../focus" import { FormDimension, FormRenderingMode, FormShape, Callback_Any_Void, Callback_FormCallbackInfo_Void, FormCallbackInfo, Callback_Literal_Number_errcode_String_msg_Void, Literal_Number_errcode_String_msg, FormInfo } from "./../formComponent" -import { FrameNode, FrameNodeInternal } from "../../FrameNode" +import { FrameNode, FrameNodeInternal, LayoutConstraint } from "../../FrameNode" import { FrictionMotion, FrictionMotionInternal, ScrollMotion, ScrollMotionInternal, SpringProp, SpringPropInternal, SpringMotion, SpringMotionInternal } from "./../animator" import { FullscreenInfo, PlaybackInfo, PlaybackSpeed, PreparedInfo, SeekMode, VideoController, VideoControllerInternal, Callback_FullscreenInfo_Void, Callback_PlaybackInfo_Void, Callback_PreparedInfo_Void, PosterOptions, VideoOptions } from "./../video" import { GridAttribute, Callback_Number_Number_ComputedBarAttribute, ComputedBarAttribute, Callback_Number_Number_Void, GridDirection, Callback_ItemDragInfo_Void, Callback_ItemDragInfo_Number_Number_Void, Callback_ItemDragInfo_Number_Void, Callback_ItemDragInfo_Number_Number_Boolean_Void, GridItemAlignment, Callback_Number_ScrollState_Literal_Number_offsetRemain, Literal_Number_offsetRemain, Callback_Number_Tuple_Number_Number, Callback_Number_Tuple_Number_Number_Number_Number, Tuple_Number_Number_Number_Number, GridLayoutOptions } from "./../grid" @@ -3629,6 +3629,15 @@ export class Serializer extends SerializerBase { valueSerializer.writeNumber(value_largestImageLoadEndTime_value) } } + writeLayoutConstraint(value: LayoutConstraint): void { + let valueSerializer : Serializer = this; + const value_maxSize = value.maxSize; + valueSerializer.writeSize(value_maxSize); + const value_minSize = value.minSize; + valueSerializer.writeSize(value_minSize); + const value_percentReference = value.percentReference; + valueSerializer.writeSize(value_percentReference); + } writeLeadingMarginPlaceholder(value: LeadingMarginPlaceholder): void { let valueSerializer : Serializer = this const value_pixelMap = value.pixelMap diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/Serializers.h b/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/Serializers.h index 4801d49e76bb69dbdda5bf74726e24fe835c5c11..8a84e81c7fa5ef57da219ae8e30226f9e3c3fff0 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/Serializers.h +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/Serializers.h @@ -93742,6 +93742,15 @@ class Deserializer : public DeserializerBase { value.largestImageLoadEndTime = largestImageLoadEndTime_buf; return value; } + Ark_LayoutConstraint readLayoutConstraint() + { + Ark_LayoutConstraint value = {}; + Deserializer& valueDeserializer = *this; + value.maxSize = valueDeserializer.readSize(); + value.minSize = valueDeserializer.readSize(); + value.percentReference = valueDeserializer.readSize(); + return value; + } Ark_LeadingMarginPlaceholder readLeadingMarginPlaceholder() { Ark_LeadingMarginPlaceholder value = {}; diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/arkoala_api_generated.h b/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/arkoala_api_generated.h index a3e26800c7d7c004e1944e9d103caa01337516c8..7e69b28ac4c79ccbb9a35bd85cd2f48e4e2d5257 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/arkoala_api_generated.h +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/arkoala_api_generated.h @@ -1975,6 +1975,8 @@ typedef struct KeyEventPeer* Ark_KeyEvent; typedef struct Opt_KeyEvent Opt_KeyEvent; typedef struct Ark_LargestContentfulPaint Ark_LargestContentfulPaint; typedef struct Opt_LargestContentfulPaint Opt_LargestContentfulPaint; +typedef struct Ark_LayoutConstraint Ark_LayoutConstraint; +typedef struct Opt_LayoutConstraint Opt_LayoutConstraint; typedef struct Ark_LeadingMarginPlaceholder Ark_LeadingMarginPlaceholder; typedef struct Opt_LeadingMarginPlaceholder Opt_LeadingMarginPlaceholder; typedef struct LengthMetricsPeer LengthMetricsPeer; @@ -13112,6 +13114,15 @@ typedef struct Opt_LargestContentfulPaint { Ark_Tag tag; Ark_LargestContentfulPaint value; } Opt_LargestContentfulPaint; +typedef struct Ark_LayoutConstraint { + Ark_Size maxSize; + Ark_Size minSize; + Ark_Size percentReference; +} Ark_LayoutConstraint; +typedef struct Opt_LayoutConstraint { + Ark_Tag tag; + Ark_LayoutConstraint value; +} Opt_LayoutConstraint; typedef struct Ark_LeadingMarginPlaceholder { Ark_PixelMap pixelMap; Ark_Tuple_Dimension_Dimension size; @@ -24278,6 +24289,15 @@ typedef struct GENERATED_ArkUIFrameNodeAccessor { Ark_Int32 (*getChildrenCount)(Ark_FrameNode peer); void (*dispose)(Ark_FrameNode peer); Ark_Number (*getOpacity)(Ark_FrameNode peer); + void (*setMeasuredSize)(Ark_FrameNode peer, + const Ark_Size* size); + void (*setLayoutPosition)(Ark_FrameNode peer, + const Ark_Position* position); + void (*measure)(Ark_FrameNode peer, + const Ark_LayoutConstraint* constraint); + void (*layout)(Ark_FrameNode peer, + const Ark_Position* position); + void (*setNeedsLayout)(Ark_FrameNode peer); Ark_Position (*getPositionToWindowWithTransform)(Ark_FrameNode peer); Ark_FrameNode (*getFrameNodeByKey)(const Ark_String* name); Ark_Number (*getIdByFrameNode)(Ark_FrameNode peer, diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/bridge_generated.cc b/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/bridge_generated.cc index 2edfa8022fcebbad96b94d0ded9882d0f07b74be..5954018983ee0f8bd0190e761332a316941b48ce 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/bridge_generated.cc +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala/framework/native/src/generated/bridge_generated.cc @@ -33943,6 +33943,39 @@ Ark_Number impl_FrameNode_getOpacity(Ark_NativePointer thisPtr) { return GetAccessors()->getFrameNodeAccessor()->getOpacity(self); } KOALA_INTEROP_DIRECT_1(FrameNode_getOpacity, KInteropNumber, Ark_NativePointer) +void impl_FrameNode_setMeasuredSize(Ark_NativePointer thisPtr, KSerializerBuffer thisArray, int32_t thisLength) { + Ark_FrameNode self = reinterpret_cast(thisPtr); + Deserializer thisDeserializer(thisArray, thisLength); + Ark_Size size_value = thisDeserializer.readSize();; + GetAccessors()->getFrameNodeAccessor()->setMeasuredSize(self, (const Ark_Size*)&size_value); +} +KOALA_INTEROP_DIRECT_V3(FrameNode_setMeasuredSize, Ark_NativePointer, KSerializerBuffer, int32_t) +void impl_FrameNode_setLayoutPosition(Ark_NativePointer thisPtr, KSerializerBuffer thisArray, int32_t thisLength) { + Ark_FrameNode self = reinterpret_cast(thisPtr); + Deserializer thisDeserializer(thisArray, thisLength); + Ark_Position position_value = thisDeserializer.readPosition();; + GetAccessors()->getFrameNodeAccessor()->setLayoutPosition(self, (const Ark_Position*)&position_value); +} +KOALA_INTEROP_DIRECT_V3(FrameNode_setLayoutPosition, Ark_NativePointer, KSerializerBuffer, int32_t) +void impl_FrameNode_measure(Ark_NativePointer thisPtr, KSerializerBuffer thisArray, int32_t thisLength) { + Ark_FrameNode self = reinterpret_cast(thisPtr); + Deserializer thisDeserializer(thisArray, thisLength); + Ark_LayoutConstraint constraint_value = thisDeserializer.readLayoutConstraint();; + GetAccessors()->getFrameNodeAccessor()->measure(self, (const Ark_LayoutConstraint*)&constraint_value); +} +KOALA_INTEROP_DIRECT_V3(FrameNode_measure, Ark_NativePointer, KSerializerBuffer, int32_t) +void impl_FrameNode_layout(Ark_NativePointer thisPtr, KSerializerBuffer thisArray, int32_t thisLength) { + Ark_FrameNode self = reinterpret_cast(thisPtr); + Deserializer thisDeserializer(thisArray, thisLength); + Ark_Position position_value = thisDeserializer.readPosition();; + GetAccessors()->getFrameNodeAccessor()->layout(self, (const Ark_Position*)&position_value); +} +KOALA_INTEROP_DIRECT_V3(FrameNode_layout, Ark_NativePointer, KSerializerBuffer, int32_t) +void impl_FrameNode_setNeedsLayout(Ark_NativePointer thisPtr) { + Ark_FrameNode self = reinterpret_cast(thisPtr); + GetAccessors()->getFrameNodeAccessor()->setNeedsLayout(self); +} +KOALA_INTEROP_DIRECT_V1(FrameNode_setNeedsLayout, Ark_NativePointer) KInteropReturnBuffer impl_FrameNode_getPositionToWindowWithTransform(Ark_NativePointer thisPtr) { Ark_FrameNode self = reinterpret_cast(thisPtr); const auto &retValue = GetAccessors()->getFrameNodeAccessor()->getPositionToWindowWithTransform(self); diff --git a/frameworks/core/interfaces/ani/ani_api.h b/frameworks/core/interfaces/ani/ani_api.h index a8e17ddfb6324d201ccb2052e1f3be966d783003..a32e8ff59211f4b732ec4cc9b634ea6fdd9d9b70 100644 --- a/frameworks/core/interfaces/ani/ani_api.h +++ b/frameworks/core/interfaces/ani/ani_api.h @@ -81,6 +81,7 @@ struct ArkUIAniCommonModifier { void (*setDrawCallback)(ani_env* env, ani_long ptr, ani_fn_object fnObj); ArkUI_Int32 (*getCurrentInstanceId)(); ani_long (*builderProxyNodeConstruct)(ArkUI_Int32 id); + void (*setCustomCallback)(ani_env* env, ani_long ptr, ani_fn_object fnObjMeasure, ani_fn_object fnObjLayout); }; struct ArkUIAniCustomNodeModifier { ani_long (*constructCustomNode)(ani_int); diff --git a/frameworks/core/interfaces/native/ani/common_ani_modifier.cpp b/frameworks/core/interfaces/native/ani/common_ani_modifier.cpp index c011dc050957b66720d9bc6454e4545fbda238ee..27485415fca2c60b651aee3b4cc22ad0577592b0 100644 --- a/frameworks/core/interfaces/native/ani/common_ani_modifier.cpp +++ b/frameworks/core/interfaces/native/ani/common_ani_modifier.cpp @@ -74,6 +74,11 @@ ani_long BuilderProxyNodeConstruct(ArkUI_Int32 id) return reinterpret_cast(AceType::RawPtr(proxyNode)); } +void SetCustomCallback(ani_env* env, ani_long ptr, ani_fn_object fnObjMeasure, ani_fn_object fnObjLayout) +{ + Framework::AniGraphicsModule::SetCustomCallback(env, ptr, fnObjMeasure, fnObjLayout); +} + const ArkUIAniCommonModifier* GetCommonAniModifier() { static const ArkUIAniCommonModifier impl = { @@ -82,7 +87,8 @@ const ArkUIAniCommonModifier* GetCommonAniModifier() .restoreInstanceId = OHOS::Ace::NG::RestoreInstanceId, .setDrawCallback = OHOS::Ace::NG::SetDrawCallback, .getCurrentInstanceId = OHOS::Ace::NG::GetCurrentInstanceId, - .builderProxyNodeConstruct = OHOS::Ace::NG::BuilderProxyNodeConstruct }; + .builderProxyNodeConstruct = OHOS::Ace::NG::BuilderProxyNodeConstruct, + .setCustomCallback = OHOS::Ace::NG::SetCustomCallback }; return &impl; } diff --git a/frameworks/core/interfaces/native/generated/interface/arkoala_api_generated.h b/frameworks/core/interfaces/native/generated/interface/arkoala_api_generated.h index cd83f18501aab01aa73c30975c771e51283a42d8..4a7676e73d67362f60d1c36882174c310c3fff0f 100644 --- a/frameworks/core/interfaces/native/generated/interface/arkoala_api_generated.h +++ b/frameworks/core/interfaces/native/generated/interface/arkoala_api_generated.h @@ -1975,6 +1975,8 @@ typedef struct KeyEventPeer* Ark_KeyEvent; typedef struct Opt_KeyEvent Opt_KeyEvent; typedef struct Ark_LargestContentfulPaint Ark_LargestContentfulPaint; typedef struct Opt_LargestContentfulPaint Opt_LargestContentfulPaint; +typedef struct Ark_LayoutConstraint Ark_LayoutConstraint; +typedef struct Opt_LayoutConstraint Opt_LayoutConstraint; typedef struct Ark_LeadingMarginPlaceholder Ark_LeadingMarginPlaceholder; typedef struct Opt_LeadingMarginPlaceholder Opt_LeadingMarginPlaceholder; typedef struct LengthMetricsPeer LengthMetricsPeer; @@ -13112,6 +13114,15 @@ typedef struct Opt_LargestContentfulPaint { Ark_Tag tag; Ark_LargestContentfulPaint value; } Opt_LargestContentfulPaint; +typedef struct Ark_LayoutConstraint { + Ark_Size maxSize; + Ark_Size minSize; + Ark_Size percentReference; +} Ark_LayoutConstraint; +typedef struct Opt_LayoutConstraint { + Ark_Tag tag; + Ark_LayoutConstraint value; +} Opt_LayoutConstraint; typedef struct Ark_LeadingMarginPlaceholder { Ark_PixelMap pixelMap; Ark_Tuple_Dimension_Dimension size; @@ -24266,6 +24277,15 @@ typedef struct GENERATED_ArkUIFrameNodeAccessor { Ark_Int32 (*getChildrenCount)(Ark_FrameNode peer); void (*dispose)(Ark_FrameNode peer); Ark_Number (*getOpacity)(Ark_FrameNode peer); + void (*setMeasuredSize)(Ark_FrameNode peer, + const Ark_Size* size); + void (*setLayoutPosition)(Ark_FrameNode peer, + const Ark_Position* position); + void (*measure)(Ark_FrameNode peer, + const Ark_LayoutConstraint* constraint); + void (*layout)(Ark_FrameNode peer, + const Ark_Position* position); + void (*setNeedsLayout)(Ark_FrameNode peer); Ark_Position (*getPositionToWindowWithTransform)(Ark_FrameNode peer); Ark_FrameNode (*getFrameNodeByKey)(const Ark_String* name); Ark_Number (*getIdByFrameNode)(Ark_FrameNode peer, diff --git a/frameworks/core/interfaces/native/implementation/frame_node_accessor.cpp b/frameworks/core/interfaces/native/implementation/frame_node_accessor.cpp index 7c361a1dcf79279d0d181a2380c9c02418a285cf..c1f44fb948c990fa57b493ed1d1087a0069aee60 100644 --- a/frameworks/core/interfaces/native/implementation/frame_node_accessor.cpp +++ b/frameworks/core/interfaces/native/implementation/frame_node_accessor.cpp @@ -39,6 +39,18 @@ enum class ExpandMode : uint32_t { EXPAND, LAZY_EXPAND, }; +// same as inner defines in property.h +typedef enum { + ARKUI_DIRTY_FLAG_MEASURE = 0b1, + ARKUI_DIRTY_FLAG_LAYOUT = 0b10, + /** mark the node need to do attribute diff to drive update. */ + ARKUI_DIRTY_FLAG_ATTRIBUTE_DIFF = 0b100, + ARKUI_DIRTY_FLAG_MEASURE_SELF = 0b1000, + ARKUI_DIRTY_FLAG_MEASURE_SELF_AND_PARENT = 0b10000, + ARKUI_DIRTY_FLAG_MEASURE_BY_CHILD_REQUEST = 0b100000, + ARKUI_DIRTY_FLAG_RENDER = 0b1000000, + ARKUI_DIRTY_FLAG_MEASURE_SELF_AND_CHILD = 0b1000000000, +} ArkUIDirtyFlag; } std::map FrameNodePeer::peerMap_; namespace OHOS::Ace::NG::GeneratedModifier { @@ -569,7 +581,7 @@ Ark_Boolean GetCrossLanguageOptionsImpl(Ark_FrameNode peer) Ark_Number GetIdByFrameNodeImpl(Ark_FrameNode peer, Ark_FrameNode node) { const auto errValue = Converter::ArkValue(-1); - auto currentNode = FrameNodePeer::GetFrameNodeByPeer(peer); + auto currentNode = FrameNodePeer::GetFrameNodeByPeer(node); CHECK_NULL_RETURN(currentNode, errValue); auto nodeId = currentNode->GetId(); return Converter::ArkValue(nodeId); @@ -812,6 +824,82 @@ Ark_SizeLengthMetrics GetUserConfigSizeImpl(Ark_FrameNode peer) }; return retValue; } +void SetMeasuredSizeImpl(Ark_FrameNode peer, const Ark_Size* size) +{ + CHECK_NULL_VOID(size); + auto peerNode = FrameNodePeer::GetFrameNodeByPeer(peer); + CHECK_NULL_VOID(peerNode); + auto widthValue = Converter::Convert(size->width); + auto heightValue = Converter::Convert(size->height); + peerNode->GetGeometryNode()->SetFrameWidth(widthValue); + peerNode->GetGeometryNode()->SetFrameHeight(heightValue); +} +void SetLayoutPositionImpl(Ark_FrameNode peer, const Ark_Position* position) +{ + CHECK_NULL_VOID(position); + auto peerNode = FrameNodePeer::GetFrameNodeByPeer(peer); + CHECK_NULL_VOID(peerNode); + auto xValue = Converter::Convert(position->x.value); + auto yValue = Converter::Convert(position->y.value); + peerNode->GetGeometryNode()->SetMarginFrameOffsetX(xValue.Value()); + peerNode->GetGeometryNode()->SetMarginFrameOffsetY(yValue.Value()); +} +void MeasureImpl(Ark_FrameNode peer, const Ark_LayoutConstraint* constraint) +{ + auto peerNode = FrameNodePeer::GetFrameNodeByPeer(peer); + CHECK_NULL_VOID(peerNode); + CHECK_NULL_VOID(constraint); + Ark_Size maxSize = constraint->maxSize; + Ark_Size minSize = constraint->minSize; + Ark_Size percentReference = constraint->percentReference; + auto minWidth = Converter::Convert(constraint->minSize.width); + auto minHeight = Converter::Convert(constraint->minSize.height); + auto maxWidth = Converter::Convert(constraint->maxSize.width); + auto maxHeight = Converter::Convert(constraint->maxSize.height); + auto percentReferenceWidth = Converter::Convert(constraint->percentReference.width); + auto percentReferenceHeight = Converter::Convert(constraint->percentReference.height); + std::optional constraintF = std::make_optional(); + // minWidth + constraintF->minSize.SetWidth(minWidth); + // minHeight + constraintF->minSize.SetHeight(minHeight); + // maxWidth + constraintF->maxSize.SetWidth(maxWidth); + // maxHeight + constraintF->maxSize.SetHeight(maxHeight); + // minWidth == maxWidth + if (minWidth == maxWidth) { + constraintF->selfIdealSize.SetWidth(minWidth); + } + // minHeight == maxHeight + if (minHeight == maxHeight) { + constraintF->selfIdealSize.SetHeight(minHeight); + } + // percentReferenceWidth + constraintF->percentReference.SetWidth(percentReferenceWidth); + // percentReferenceHeight + constraintF->percentReference.SetHeight(percentReferenceHeight); + peerNode->SetActive(true); + peerNode->Measure(constraintF); +} +void LayoutImpl(Ark_FrameNode peer, const Ark_Position* position) +{ + CHECK_NULL_VOID(position); + auto peerNode = FrameNodePeer::GetFrameNodeByPeer(peer); + CHECK_NULL_VOID(peerNode); + auto xValue = Converter::Convert(position->x.value); + auto yValue = Converter::Convert(position->y.value); + peerNode->SetActive(true); + peerNode->GetGeometryNode()->SetMarginFrameOffsetX(xValue.Value()); + peerNode->GetGeometryNode()->SetMarginFrameOffsetY(yValue.Value()); + peerNode->Layout(); +} +void SetNeedsLayoutImpl(Ark_FrameNode peer) +{ + auto peerNode = FrameNodePeer::GetFrameNodeByPeer(peer); + CHECK_NULL_VOID(peerNode); + peerNode->MarkDirtyNode(ARKUI_DIRTY_FLAG_MEASURE_SELF_AND_PARENT); +} } // FrameNodeAccessor const GENERATED_ArkUIFrameNodeAccessor* GetFrameNodeAccessor() { @@ -824,6 +912,11 @@ const GENERATED_ArkUIFrameNodeAccessor* GetFrameNodeAccessor() FrameNodeAccessor::GetNextSiblingImpl, FrameNodeAccessor::GetPreviousSiblingImpl, FrameNodeAccessor::GetParentImpl, FrameNodeAccessor::GetChildrenCountImpl, FrameNodeAccessor::DisposeImpl, FrameNodeAccessor::GetOpacityImpl, + FrameNodeAccessor::SetMeasuredSizeImpl, + FrameNodeAccessor::SetLayoutPositionImpl, + FrameNodeAccessor::MeasureImpl, + FrameNodeAccessor::LayoutImpl, + FrameNodeAccessor::SetNeedsLayoutImpl, FrameNodeAccessor::GetPositionToWindowWithTransformImpl, FrameNodeAccessor::GetFrameNodeByKeyImpl, FrameNodeAccessor::GetIdByFrameNodeImpl, FrameNodeAccessor::MoveToImpl, FrameNodeAccessor::GetFirstChildIndexWithoutExpandImpl, FrameNodeAccessor::GetLastChildIndexWithoutExpandImpl,