diff --git a/frameworks/bridge/arkts_frontend/BUILD.gn b/frameworks/bridge/arkts_frontend/BUILD.gn index f94aaff6d740b3a4e42372bdcd0f996cb19feca5..286f17d3966a1f0f74d0afec73ecd6d674dde751 100644 --- a/frameworks/bridge/arkts_frontend/BUILD.gn +++ b/frameworks/bridge/arkts_frontend/BUILD.gn @@ -57,7 +57,6 @@ template("arkts_frontend") { sources = [ "ani_context_module.cpp", "ani_graphics_module.cpp", - "ani_water_flow_module.cpp", "arkts_ani_utils.cpp", "arkts_frontend.cpp", "arkts_plugin_frontend.cpp", diff --git a/frameworks/bridge/arkts_frontend/ani_water_flow_module.cpp b/frameworks/bridge/arkts_frontend/ani_water_flow_module.cpp deleted file mode 100644 index 2727a7ee30ad537a95cdde06eef0f149b5a9fac5..0000000000000000000000000000000000000000 --- a/frameworks/bridge/arkts_frontend/ani_water_flow_module.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "bridge/arkts_frontend/ani_water_flow_module.h" - -#include -#include -#include - -#include "ani_water_flow_module.h" - -#include "base/geometry/calc_dimension.h" -#include "base/utils/string_utils.h" -#include "core/components_ng/base/frame_node.h" -#include "core/components_ng/property/calc_length.h" -#include "core/components_ng/property/measure_property.h" - -namespace { -using namespace OHOS::Ace; - -std::string ANIUtils_ANIStringToStdString(ani_env* env, ani_string ani_str) -{ - ani_size strSize; - env->String_GetUTF8Size(ani_str, &strSize); - - std::vector buffer(strSize + 1); - char* utf8Buffer = buffer.data(); - - ani_size bytesWritten = 0; - env->String_GetUTF8(ani_str, utf8Buffer, strSize + 1, &bytesWritten); - utf8Buffer[bytesWritten] = '\0'; - std::string content = std::string(utf8Buffer); - return content; -} - -std::optional ParseDimension(ani_env* env, ani_ref dimensionRef) -{ - std::optional res; - ani_class doubleClass; - if (env->FindClass("Lstd/core/Double;", &doubleClass) != ANI_OK) { - return res; - } - ani_class stringClass; - if (env->FindClass("Lstd/core/String;", &stringClass) != ANI_OK) { - return res; - } - - ani_boolean isDouble; - env->Object_InstanceOf(static_cast(dimensionRef), doubleClass, &isDouble); - if (isDouble) { - ani_double dimension; - env->Object_CallMethodByName_Double(static_cast(dimensionRef), "unboxed", ":D", &dimension); - if (dimension < 0) { - dimension = 0; - } - res = CalcDimension(dimension, DimensionUnit::VP); - } - - ani_boolean isString; - env->Object_InstanceOf(static_cast(dimensionRef), stringClass, &isString); - if (isString) { - auto stringDimension = ANIUtils_ANIStringToStdString(env, static_cast(dimensionRef)); - res = StringUtils::StringToDimension(stringDimension, true); - if (res->Value() < 0) { - res->SetValue(0.0); - } - } - return res; -} - -NG::MarginProperty ParsePadding(ani_env* env, ani_ref paddingRef) -{ - NG::MarginProperty res; - std::optional left; - std::optional right; - std::optional top; - std::optional bottom; - - ani_ref leftRef; - env->Object_GetPropertyByName_Ref(static_cast(paddingRef), "left", &leftRef); - left = ParseDimension(env, leftRef); - if (left.has_value()) { - if (left.value().Unit() == DimensionUnit::CALC) { - res.left = NG::CalcLength(left.value().CalcValue()); - } else { - res.left = NG::CalcLength(left.value()); - } - } - - ani_ref rightRef; - env->Object_GetPropertyByName_Ref(static_cast(paddingRef), "right", &rightRef); - right = ParseDimension(env, rightRef); - if (right.has_value()) { - if (right.value().Unit() == DimensionUnit::CALC) { - res.right = NG::CalcLength(right.value().CalcValue()); - } else { - res.right = NG::CalcLength(right.value()); - } - } - - ani_ref topRef; - env->Object_GetPropertyByName_Ref(static_cast(paddingRef), "top", &topRef); - top = ParseDimension(env, topRef); - if (top.has_value()) { - if (top.value().Unit() == DimensionUnit::CALC) { - res.top = NG::CalcLength(top.value().CalcValue()); - } else { - res.top = NG::CalcLength(top.value()); - } - } - - ani_ref bottomRef; - env->Object_GetPropertyByName_Ref(static_cast(paddingRef), "bottom", &bottomRef); - bottom = ParseDimension(env, bottomRef); - if (bottom.has_value()) { - if (bottom.value().Unit() == DimensionUnit::CALC) { - res.bottom = NG::CalcLength(bottom.value().CalcValue()); - } else { - res.bottom = NG::CalcLength(bottom.value()); - } - } - return res; -} - -std::optional ParseMargin(ani_env* env, ani_ref marginRef) -{ - NG::MarginProperty res; - ani_class paddingClass; - if (env->FindClass("Larkui/component/units/Padding;", &paddingClass) != ANI_OK) { - return std::make_optional(res); - } - - ani_boolean isPadding; - env->Object_InstanceOf(static_cast(marginRef), paddingClass, &isPadding); - if (isPadding) { - res = ParsePadding(env, marginRef); - } else { - std::optional length = ParseDimension(env, marginRef); - if (length->Unit() == DimensionUnit::CALC) { - res.SetEdges(NG::CalcLength(length->CalcValue())); - } else { - res.SetEdges(NG::CalcLength(length.value())); - } - } - return std::make_optional(res); -} -} // namespace - -namespace OHOS::Ace::Framework { - -NG::WaterFlowSections::Section AniWaterFlowModule::ParseSectionOptions(ani_env* env, ani_ref section) -{ - NG::WaterFlowSections::Section curSection; - ani_double itemsCount; - if (env->Object_GetPropertyByName_Double(static_cast(section), "itemsCount", &itemsCount) != ANI_OK) { - return curSection; - } - curSection.itemsCount = static_cast(itemsCount); - - ani_ref crossCount; - if (env->Object_GetPropertyByName_Ref(static_cast(section), "crossCount", &crossCount) != ANI_OK) { - curSection.crossCount = 1; - } - ani_boolean isUndefined = false; - if (env->Reference_IsUndefined(crossCount, &isUndefined) != ANI_OK) { - curSection.crossCount = 1; - } - if (!isUndefined) { - ani_double crossCnt; - env->Object_CallMethodByName_Double(static_cast(crossCount), "unboxed", ":D", &crossCnt); - if (crossCnt <= 0) { - crossCnt = 1; - } - curSection.crossCount = static_cast(crossCnt); - } - - ani_ref columnsGap; - env->Object_GetPropertyByName_Ref(static_cast(section), "columnsGap", &columnsGap); - isUndefined = false; - env->Reference_IsUndefined(columnsGap, &isUndefined); - if (!isUndefined) { - curSection.columnsGap = ParseDimension(env, columnsGap); - } - - ani_ref rowsGap; - env->Object_GetPropertyByName_Ref(static_cast(section), "rowsGap", &rowsGap); - isUndefined = false; - env->Reference_IsUndefined(rowsGap, &isUndefined); - if (!isUndefined) { - curSection.rowsGap = ParseDimension(env, rowsGap); - } - - ani_ref margin; - env->Object_GetPropertyByName_Ref(static_cast(section), "margin", &margin); - isUndefined = false; - env->Reference_IsUndefined(margin, &isUndefined); - if (!isUndefined) { - curSection.margin = ParseMargin(env, margin); - } - - return curSection; -} - -void AniWaterFlowModule::ParseWaterFlowSections(ani_env* env, ani_ref sections, NG::FrameNode* frameNode) -{ - auto waterFlowSections = NG::WaterFlowModelNG::GetOrCreateWaterFlowSections(frameNode); - CHECK_NULL_VOID(waterFlowSections); - - ani_ref changeArray; - if (env->Object_GetPropertyByName_Ref(static_cast(sections), "changeArray", &changeArray) != ANI_OK) { - return; - } - ani_size changeArrayLength; - if (env->Array_GetLength(static_cast(changeArray), &changeArrayLength) != ANI_OK) { - } - - ani_class sectionChangeInfo; - if (env->FindClass("Larkui/component/waterFlow/SectionChangeInfo;", §ionChangeInfo) != ANI_OK) { - return; - } - - ani_class sectionOptions; - if (env->FindClass("Larkui/component/waterFlow/SectionOptions;", §ionOptions) != ANI_OK) { - return; - } - - for (int32_t i = 0; i < changeArrayLength; i++) { - ani_ref change; - if (env->Array_Get_Ref(static_cast(changeArray), i, &change) != ANI_OK) { - continue; - } - - ani_boolean isSectionChangeInfo; - env->Object_InstanceOf(static_cast(change), sectionChangeInfo, &isSectionChangeInfo); - if (!isSectionChangeInfo) { - continue; - } - - ani_double start = 0.0; - if (env->Object_GetPropertyByName_Double(static_cast(change), "start", &start) != ANI_OK) { - continue; - } - ani_double deleteCount = 0.0; - if (env->Object_GetPropertyByName_Double(static_cast(change), "deleteCount", &deleteCount) != - ANI_OK) { - continue; - } - - ani_ref sectionOptionsArray; - env->Object_GetPropertyByName_Ref(static_cast(change), "sections", §ionOptionsArray); - - ani_size aniLength; - if (env->Array_GetLength(static_cast(sectionOptionsArray), &aniLength) != ANI_OK) { - continue; - } - - int32_t length = static_cast(aniLength); - std::vector newSections; - for (int32_t j = 0; j < length; j++) { - ani_ref section; - if (env->Array_Get_Ref(static_cast(sectionOptionsArray), j, §ion) != ANI_OK) { - continue; - } - ani_boolean isSectionOptions; - env->Object_InstanceOf(static_cast(section), sectionOptions, &isSectionOptions); - if (!isSectionOptions) { - continue; - } - NG::WaterFlowSections::Section curSection = ParseSectionOptions(env, section); - if (curSection.itemsCount < 0) { - continue; - } - newSections.emplace_back(curSection); - } - waterFlowSections->ChangeData(start, deleteCount, newSections); - } -} - -void AniWaterFlowModule::SetWaterFlowSection(ani_env* env, ani_long ptr, ani_object obj) -{ - auto* frameNode = reinterpret_cast(ptr); - CHECK_NULL_VOID(frameNode); - - ani_ref sections; - if (env->Object_GetPropertyByName_Ref(obj, "sections", §ions) != ANI_OK) { - return; - } - - ani_class waterflowSections; - if (env->FindClass("Larkui/component/waterFlow/WaterFlowSections;", &waterflowSections) != ANI_OK) { - return; - } - - ani_boolean isNumber; - env->Object_InstanceOf(static_cast(sections), waterflowSections, &isNumber); - if (isNumber) { - ParseWaterFlowSections(env, sections, frameNode); - } -} -} // namespace OHOS::Ace::Framework diff --git a/frameworks/bridge/arkts_frontend/ani_water_flow_module.h b/frameworks/bridge/arkts_frontend/ani_water_flow_module.h deleted file mode 100644 index 1ea6f1095e025ca742397ca93e4b3b3e284497b9..0000000000000000000000000000000000000000 --- a/frameworks/bridge/arkts_frontend/ani_water_flow_module.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FOUNDATION_ACE_FRAMEWORKS_BRIDGE_ARKTS_FRONTEND_ANI_WATER_FLOW_MODULE_H -#define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_ARKTS_FRONTEND_ANI_WATER_FLOW_MODULE_H - -#include -#include "core/components_ng/pattern/waterflow/water_flow_sections.h" -#include "core/components_ng/pattern/waterflow/water_flow_model_ng.h" - -typedef class __ani_object* ani_object; -typedef struct __ani_env ani_env; -typedef int64_t ani_long; -typedef class __ani_fn_object* ani_fn_object; -typedef class __ani_ref* ani_ref; - -namespace OHOS::Ace::Framework { - -class AniWaterFlowModule { -public: - static void SetWaterFlowSection(ani_env* env, ani_long ptr, ani_object obj); - static void ParseWaterFlowSections(ani_env* env, ani_ref sections, NG::FrameNode* frameNode); - static NG::WaterFlowSections::Section ParseSectionOptions(ani_env* env, ani_ref section); -}; - -} // namespace OHOS::Ace::Framework -#endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_ARKTS_FRONTEND_ANI_WATER_FLOW_MODULE_H 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 e097ea1146cca3eed9c85b3ecf0fde686c53f7a8..490e0d02904a62561972fe5e96fa7649018b1c58 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 @@ -45,7 +45,8 @@ export class ArkUIAniModule { native static _SetDrawCallback(ptr: KPointer, callback: ((context: DrawContext) => void)): void native static _SetDrawModifier(ptr: KPointer, drawModifier: DrawModifier): void native static _Invalidate(ptr: KPointer): void - native static _SetWaterFlowOptions(ptr: KPointer, options: WaterFlowOptions): void + native static _SetWaterFlowSection(ptr: KPointer, sections: WaterFlowSections): void + native static _SetWaterFlowFooterContent(ptr: KPointer, footerContent: KPointer): void // for Drag native static _DragEvent_Set_Data(ptr: KLong, data : unifiedDataChannel.UnifiedData) : void diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/BUILD.gn b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/BUILD.gn index 616dd6463d97384a0eab513fef425a8989b7da63..a3d1ea39ebce93cde219d98e2ab34e94dd176769 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/BUILD.gn +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/BUILD.gn @@ -37,7 +37,7 @@ ohos_shared_library("arkoala_native_ani") { "module.cpp", "utils/ani_utils.cpp", "utils/convert_utils.cpp", - "water_flow/waterFlowSection_module.cpp", + "water_flow/water_flow_module.cpp", "web/web_module_methods.cpp", ] 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 79a55e3475b0b9ee508f82841745d0bdc4cc04d3..2b802591b8534206431d9dbc5690835725cab6ae 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 @@ -27,7 +27,7 @@ #include "load.h" #include "log/log.h" #include "utils/convert_utils.h" -#include "water_flow/waterFlowSection_module.h" +#include "water_flow/water_flow_module.h" #include "web/web_module_methods.h" ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) @@ -115,9 +115,14 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) reinterpret_cast(OHOS::Ace::Ani::Invalidate) }, ani_native_function { - "_SetWaterFlowOptions", - "JLarkui/component/waterFlow/WaterFlowOptions;:V", - reinterpret_cast(OHOS::Ace::Ani::SetWaterFlowOptions) + "_SetWaterFlowSection", + "JLarkui/component/waterFlow/WaterFlowSections;:V", + reinterpret_cast(OHOS::Ace::Ani::SetWaterFlowSection) + }, + ani_native_function { + "_SetWaterFlowFooterContent", + "JJ:V", + reinterpret_cast(OHOS::Ace::Ani::SetWaterFlowFooterContent) }, ani_native_function { "_DragEvent_Set_Data", diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/water_flow/waterFlowSection_module.cpp b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/water_flow/water_flow_module.cpp similarity index 56% rename from frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/water_flow/waterFlowSection_module.cpp rename to frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/water_flow/water_flow_module.cpp index 69b47260ee4479d346999dcda1896ac9db977029..5930ba6376c617b12bc5290858c3b676f13a548d 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/water_flow/waterFlowSection_module.cpp +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/water_flow/water_flow_module.cpp @@ -13,18 +13,25 @@ * limitations under the License. */ -#include "waterFlowSection_module.h" - #include - -#include "common/common_module.h" +#include "water_flow_module.h" +#include "base/utils/utils.h" #include "load.h" +#include "base/log/log.h" + namespace OHOS::Ace::Ani { -void SetWaterFlowOptions(ani_env* env, [[maybe_unused]] ani_object aniClass, ani_long ptr, ani_object waterFlowOptions) +void SetWaterFlowSection(ani_env* env, [[maybe_unused]] ani_object aniClass, ani_long ptr, ani_object waterFlowSection) +{ + const auto* modifier = GetNodeAniModifier(); + CHECK_NULL_VOID(modifier); + modifier->getArkUIAniWaterFlowModifier()->setWaterFlowSection(env, ptr, waterFlowSection); +} + +void SetWaterFlowFooterContent(ani_env* env, [[maybe_unused]] ani_object aniClass, ani_long ptr, ani_long footerContent) { const auto* modifier = GetNodeAniModifier(); CHECK_NULL_VOID(modifier); - modifier->getArkUIAniWaterFlowModifier()->setWaterFlowOptions(env, ptr, waterFlowOptions); + modifier->getArkUIAniWaterFlowModifier()->setWaterFlowFooterContent(env, ptr, footerContent); } } // namespace OHOS::Ace::Ani diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/water_flow/waterFlowSection_module.h b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/water_flow/water_flow_module.h similarity index 79% rename from frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/water_flow/waterFlowSection_module.h rename to frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/water_flow/water_flow_module.h index 5cefd387c9a276026589ae0c1483e0694b709995..3ba2fb5208af6308d0dcb11cdfe2a78dc2350409 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/water_flow/waterFlowSection_module.h +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/ani/native/water_flow/water_flow_module.h @@ -19,7 +19,8 @@ #include "ani.h" namespace OHOS::Ace::Ani { -void SetWaterFlowOptions(ani_env* env, [[maybe_unused]] ani_object aniClass, ani_long ptr, ani_object waterFlowOptions); +void SetWaterFlowSection(ani_env* env, [[maybe_unused]] ani_object aniClass, ani_long ptr, ani_object waterFlowSection); +void SetWaterFlowFooterContent(ani_env* env, [[maybe_unused]] ani_object aniClass, ani_long ptr, ani_long footerContent); } // namespace OHOS::Ace::Ani #endif // KOALA_PROJECTS_ARKOALA_ARKTS_ARKUI_OHOS_ANI_NATIVE_WATER_FLOW_MODULE diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/peers/Deserializer.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/peers/Deserializer.ts index 75f465d3ad40797489c471d996a71f00c083d283..10842c78e28347eac243703996ee99872b297be3 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/peers/Deserializer.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/peers/Deserializer.ts @@ -12549,7 +12549,7 @@ export class Deserializer extends DeserializerBase { let value : Want = ({bundleName: bundleName_result, abilityName: abilityName_result, deviceId: deviceId_result, uri: uri_result, type: type_result, flags: flags_result, action: action_result, parameters: parameters_result, entities: entities_result, moduleName: moduleName_result} as Want) return value } - readWaterFlowOptions(): WaterFlowOptions { + readWaterFlowOptions(): WaterFlowOptions { let valueDeserializer : Deserializer = this const footer_buf_runtimeType = (valueDeserializer.readInt8() as int32) let footer_buf : CustomBuilder | undefined @@ -12562,9 +12562,9 @@ export class Deserializer extends DeserializerBase { let footerContent_buf : ComponentContent | undefined if ((RuntimeType.UNDEFINED) != (footerContent_buf_runtimeType)) { - footerContent_buf = (valueDeserializer.readComponentContent() as ComponentContent) + footerContent_buf = undefined; } - const footerContent_result : ComponentContent | undefined = footerContent_buf + const footerContent_result : ComponentContent | undefined = undefined const scroller_buf_runtimeType = (valueDeserializer.readInt8() as int32) let scroller_buf : Scroller | undefined if ((RuntimeType.UNDEFINED) != (scroller_buf_runtimeType)) @@ -12586,7 +12586,7 @@ export class Deserializer extends DeserializerBase { layoutMode_buf = TypeChecker.WaterFlowLayoutMode_FromNumeric(valueDeserializer.readInt32()) } const layoutMode_result : WaterFlowLayoutMode | undefined = layoutMode_buf - let value : WaterFlowOptions = ({footer: footer_result, footerContent: footerContent_result, scroller: scroller_result, sections: sections_result, layoutMode: layoutMode_result} as WaterFlowOptions) + let value : WaterFlowOptions = ({footer: footer_result, footerContent: footerContent_result, scroller: scroller_result, sections: sections_result, layoutMode: layoutMode_result} as WaterFlowOptions) return value } readWebKeyboardCallbackInfo(): WebKeyboardCallbackInfo { 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 61709a7a5fdb15eb396a703f81a5c20c63a6590d..242c38ac6144a4697da4ff20ab27ccaa8da26bc6 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 @@ -7730,7 +7730,7 @@ export class Serializer extends SerializerBase { valueSerializer.writeString(value_moduleName_value) } } - writeWaterFlowOptions(value: WaterFlowOptions): void { + writeWaterFlowOptions(value: WaterFlowOptions): void { let valueSerializer : Serializer = this const value_footer = value.footer let value_footer_type : int32 = RuntimeType.UNDEFINED diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/waterFlow.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/waterFlow.ts index 0adaeea79ec9fbe2f8edbd9cdbb4f6cf03d4dcf2..259fd4feac9059351bbd0d2124c8fe9e0edc6964 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/waterFlow.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/component/waterFlow.ts @@ -32,7 +32,7 @@ import { Resource } from "global.resource" import { Callback_Number_ScrollState_Literal_Number_offsetRemain, Literal_Number_offsetRemain, Callback_Number_Number_Void } from "./grid" import { ScrollState } from "./list" import { NodeAttach, remember } from "@koalaui/runtime" -import { ComponentContent } from "./arkui-custom" +import { ComponentContent } from "../ComponentContent" import { Scroller, OnScrollFrameBeginCallback } from "./scroll" import { WaterFlowHandWritten } from "../handwritten/WaterFlowImpl" @@ -47,7 +47,7 @@ export class ArkWaterFlowPeer extends ArkScrollableCommonMethodPeer { component?.setPeer(_peer) return _peer } - setWaterFlowOptionsAttribute(options?: WaterFlowOptions): void { + setWaterFlowOptionsAttribute(options?: WaterFlowOptions): void { WaterFlowHandWritten.hookWaterFlowOptionsImpl(this, options); const thisSerializer : Serializer = Serializer.hold() let options_type : int32 = RuntimeType.UNDEFINED @@ -299,14 +299,14 @@ export enum WaterFlowLayoutMode { ALWAYS_TOP_DOWN = 0, SLIDING_WINDOW = 1 } -export interface WaterFlowOptions { +export interface WaterFlowOptions { footer?: CustomBuilder; - footerContent?: ComponentContent; + footerContent?: ComponentContent; scroller?: Scroller; sections?: WaterFlowSections; layoutMode?: WaterFlowLayoutMode; } -export type WaterFlowInterface = (options?: WaterFlowOptions) => WaterFlowAttribute; +export type WaterFlowInterface = (options?: WaterFlowOptions) => WaterFlowAttribute; export interface WaterFlowAttribute extends ScrollableCommonMethod { columnsTemplate(value: string | undefined): this itemConstraintSize(value: ConstraintSizeOptions | undefined): this @@ -318,6 +318,7 @@ export interface WaterFlowAttribute extends ScrollableCommonMethod { enableScrollInteraction(value: boolean | undefined): this friction(value: number | Resource | undefined): this cachedCount(count: number | undefined, show?: boolean): this + cachedCount(value: number | undefined): this onReachStart(value: (() => void) | undefined): this onReachEnd(value: (() => void) | undefined): this onScrollFrameBegin(value: OnScrollFrameBeginCallback | undefined): this @@ -372,6 +373,9 @@ export class ArkWaterFlowStyle extends ArkScrollableCommonMethodStyle implements public cachedCount(count: number | undefined, show?: boolean): this { return this } + public cachedCount(value: number | undefined): this { + return this + } public onReachStart(value: (() => void) | undefined): this { return this } @@ -395,9 +399,9 @@ export class ArkWaterFlowComponent extends ArkScrollableCommonMethodComponent im getPeer(): ArkWaterFlowPeer { return (this.peer as ArkWaterFlowPeer) } - public setWaterFlowOptions(options?: WaterFlowOptions): this { + public setWaterFlowOptions(options?: WaterFlowOptions): this { if (this.checkPriority("setWaterFlowOptions")) { - const options_casted = options as (WaterFlowOptions | undefined) + const options_casted = options as (WaterFlowOptions | undefined) this.getPeer()?.setWaterFlowOptionsAttribute(options_casted) return this } @@ -494,6 +498,18 @@ export class ArkWaterFlowComponent extends ArkScrollableCommonMethodComponent im } return this } + public cachedCount(value: number | undefined): this { + if (this.checkPriority("cachedCount")) { + const count_type = runtimeType(value) + if ((RuntimeType.NUMBER == count_type) || (RuntimeType.UNDEFINED == count_type)) { + const value_casted = value as (number | undefined) + this.getPeer()?.cachedCount0Attribute(value_casted) + return this + } + throw new Error("Can not select appropriate overload") + } + return this + } public onReachStart(value: (() => void) | undefined): this { if (this.checkPriority("onReachStart")) { const value_casted = value as ((() => void) | undefined) @@ -549,10 +565,10 @@ export class ArkWaterFlowComponent extends ArkScrollableCommonMethodComponent im } } /** @memo */ -export function WaterFlow( +export function WaterFlow( /** @memo */ style: ((attributes: WaterFlowAttribute) => void) | undefined, - options?: WaterFlowOptions, + options?: WaterFlowOptions, /** @memo */ content_?: (() => void) | undefined, ): void { diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/WaterFlowImpl.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/WaterFlowImpl.ts index 1af697dbea18459b00eeae1d29fbdfe65bff40e7..3bc5a56abb45ef5b59acf5bb16149314aa0d2d88 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/WaterFlowImpl.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/WaterFlowImpl.ts @@ -13,14 +13,22 @@ * limitations under the License. */ -import { WaterFlowOptions } from "../component/waterFlow" +import { WaterFlowOptions, WaterFlowSections } from "../component/waterFlow" import { PeerNode } from "../PeerNode" import { ArkUIAniModule } from "arkui.ani" +import { KPointer } from "@koalaui/interop" export class WaterFlowHandWritten { - static hookWaterFlowOptionsImpl(peer: PeerNode, options: WaterFlowOptions | undefined): void { + static hookWaterFlowOptionsImpl(peer: PeerNode, options: WaterFlowOptions | undefined): void { if (options !== undefined && options.sections !== undefined) { - ArkUIAniModule._SetWaterFlowOptions(peer.peer.ptr, options) - } + WaterFlowHandWritten.hookWaterFlowSectionImpl(peer, options.sections!); + } else if (options !== undefined && options.footer === undefined && options.footerContent !== undefined && options.footerContent!.getNodePtr() !== undefined) { + // if have section, ignore footer. + ArkUIAniModule._SetWaterFlowFooterContent(peer.peer.ptr, options.footerContent!.getNodePtr()!) + } + } + + static hookWaterFlowSectionImpl(peer: PeerNode, sections: WaterFlowSections): void { + ArkUIAniModule._SetWaterFlowSection(peer.peer.ptr, sections) } } \ No newline at end of file diff --git a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/component/waterFlow.ts b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/component/waterFlow.ts index 060f920341a5042c607c25535eb4a0d8c1944c2b..3c95d557795ea55d764d0b2a1b9cee2ab8564bc7 100644 --- a/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/component/waterFlow.ts +++ b/frameworks/bridge/arkts_frontend/koala_projects/arkoala-arkts/arkui-ohos/src/handwritten/component/waterFlow.ts @@ -99,19 +99,19 @@ export class WaterFlowSections implements MaterializedBase { // 计算实际操作的 start 和 deleteCount const intStart: number = WaterFlowSections.toArrayIndex(start, oldLength); - const bound: number = 0; let intDeleteCount: number = 0; if (deleteCount === undefined && sections === undefined) { intDeleteCount = oldLength - intStart; } - else { + else if(deleteCount !== undefined) { + intDeleteCount = Math.trunc(deleteCount); if (intDeleteCount > oldLength - intStart) { intDeleteCount = oldLength - intStart; } } - intDeleteCount = Math.max(intDeleteCount, bound); + intDeleteCount = intDeleteCount < 0 ? 0 : intDeleteCount; //记录变更 this.changeArray.push({ start: intStart, diff --git a/frameworks/core/interfaces/ani/ani_api.h b/frameworks/core/interfaces/ani/ani_api.h index 9e2269ff83c37491b4f1be7bc7615086408bcb28..0683bc0f26aaf6933e4a61f505bceb7f553e02bf 100644 --- a/frameworks/core/interfaces/ani/ani_api.h +++ b/frameworks/core/interfaces/ani/ani_api.h @@ -96,7 +96,8 @@ struct ArkUIAniContentSlotModifier { void (*setContentSlotOptions)(ArkUIContentSlot node, ArkUINodeContent value); }; struct ArkUIAniWaterFlowModifier { - void (*setWaterFlowOptions)(ani_env* env, ani_long ptr, ani_object fnObj); + void (*setWaterFlowSection)(ani_env* env, ani_long ptr, ani_object obj); + void (*setWaterFlowFooterContent)(ani_env* env, ani_long ptr, ani_long footerPtr); }; struct ArkUIAniComponentSnapshotModifier { int32_t (*getCurrentIdSafely)(); diff --git a/frameworks/core/interfaces/native/ani/waterflow_ani_modifier.cpp b/frameworks/core/interfaces/native/ani/waterflow_ani_modifier.cpp index f2b275e9ceffd04d61654f1cd8ebd18b201de450..c36d8f620a8e3c254feb499c680e2714efed7c4f 100644 --- a/frameworks/core/interfaces/native/ani/waterflow_ani_modifier.cpp +++ b/frameworks/core/interfaces/native/ani/waterflow_ani_modifier.cpp @@ -16,23 +16,325 @@ #include #include - -#include "frameworks/bridge/arkts_frontend/ani_water_flow_module.h" +#include "ani_utils.h" #include "base/log/log.h" #include "core/components_ng/base/frame_node.h" +#include "core/components_ng/pattern/waterflow/water_flow_model_ng.h" +#include "core/interfaces/native/implementation/frame_node_peer_impl.h" + +#include +#include +#include + +#include "base/geometry/calc_dimension.h" +#include "base/utils/string_utils.h" +#include "core/components_ng/base/frame_node.h" +#include "core/components_ng/property/calc_length.h" +#include "core/components_ng/property/measure_property.h" namespace OHOS::Ace::NG { -void SetWaterFlowOptions(ani_env* env, ani_long ptr, ani_object fnObj) + +std::optional ParseDimension(ani_env* env, ani_ref dimensionRef) +{ + std::optional res; + ani_class doubleClass; + if (env->FindClass("Lstd/core/Double;", &doubleClass) != ANI_OK) { + return res; + } + ani_class stringClass; + if (env->FindClass("Lstd/core/String;", &stringClass) != ANI_OK) { + return res; + } + + ani_boolean isDouble; + env->Object_InstanceOf(static_cast(dimensionRef), doubleClass, &isDouble); + if (isDouble) { + ani_double dimension; + env->Object_CallMethodByName_Double(static_cast(dimensionRef), "unboxed", ":D", &dimension); + if (dimension < 0) { + dimension = 0; + } + res = CalcDimension(dimension, DimensionUnit::VP); + } + + ani_boolean isString; + env->Object_InstanceOf(static_cast(dimensionRef), stringClass, &isString); + if (isString) { + auto stringDimension = AniUtils::ANIStringToStdString(env, static_cast(dimensionRef)); + res = StringUtils::StringToDimension(stringDimension, true); + if (res->Value() < 0) { + res->SetValue(0.0); + } + } + return res; +} + +NG::MarginProperty ParsePadding(ani_env* env, ani_ref paddingRef) +{ + NG::MarginProperty res; + std::optional left; + std::optional right; + std::optional top; + std::optional bottom; + + ani_ref leftRef; + env->Object_GetPropertyByName_Ref(static_cast(paddingRef), "left", &leftRef); + left = ParseDimension(env, leftRef); + if (left.has_value()) { + if (left.value().Unit() == DimensionUnit::CALC) { + res.left = NG::CalcLength(left.value().CalcValue()); + } else { + res.left = NG::CalcLength(left.value()); + } + } + + ani_ref rightRef; + env->Object_GetPropertyByName_Ref(static_cast(paddingRef), "right", &rightRef); + right = ParseDimension(env, rightRef); + if (right.has_value()) { + if (right.value().Unit() == DimensionUnit::CALC) { + res.right = NG::CalcLength(right.value().CalcValue()); + } else { + res.right = NG::CalcLength(right.value()); + } + } + + ani_ref topRef; + env->Object_GetPropertyByName_Ref(static_cast(paddingRef), "top", &topRef); + top = ParseDimension(env, topRef); + if (top.has_value()) { + if (top.value().Unit() == DimensionUnit::CALC) { + res.top = NG::CalcLength(top.value().CalcValue()); + } else { + res.top = NG::CalcLength(top.value()); + } + } + + ani_ref bottomRef; + env->Object_GetPropertyByName_Ref(static_cast(paddingRef), "bottom", &bottomRef); + bottom = ParseDimension(env, bottomRef); + if (bottom.has_value()) { + if (bottom.value().Unit() == DimensionUnit::CALC) { + res.bottom = NG::CalcLength(bottom.value().CalcValue()); + } else { + res.bottom = NG::CalcLength(bottom.value()); + } + } + return res; +} + +std::optional ParseMargin(ani_env* env, ani_ref marginRef) +{ + NG::MarginProperty res; + ani_class paddingClass; + if (env->FindClass("Larkui/component/units/Padding;", &paddingClass) != ANI_OK) { + return std::make_optional(res); + } + + ani_boolean isPadding; + env->Object_InstanceOf(static_cast(marginRef), paddingClass, &isPadding); + if (isPadding) { + res = ParsePadding(env, marginRef); + } else { + std::optional length = ParseDimension(env, marginRef); + if (length->Unit() == DimensionUnit::CALC) { + res.SetEdges(NG::CalcLength(length->CalcValue())); + } else { + res.SetEdges(NG::CalcLength(length.value())); + } + } + return std::make_optional(res); +} + +NG::WaterFlowSections::Section ParseSectionOptions(ani_env* env, ani_ref section) +{ + NG::WaterFlowSections::Section curSection; + ani_double itemsCount; + if (env->Object_GetPropertyByName_Double(static_cast(section), "itemsCount", &itemsCount) != ANI_OK) { + return curSection; + } + curSection.itemsCount = static_cast(itemsCount); + + ani_ref crossCount; + if (env->Object_GetPropertyByName_Ref(static_cast(section), "crossCount", &crossCount) != ANI_OK) { + curSection.crossCount = 1; + } + ani_boolean isUndefined = false; + if (env->Reference_IsUndefined(crossCount, &isUndefined) != ANI_OK) { + curSection.crossCount = 1; + } + if (!isUndefined) { + ani_double crossCnt; + env->Object_CallMethodByName_Double(static_cast(crossCount), "unboxed", ":D", &crossCnt); + if (crossCnt <= 0) { + crossCnt = 1; + } + curSection.crossCount = static_cast(crossCnt); + } + + ani_ref columnsGap; + env->Object_GetPropertyByName_Ref(static_cast(section), "columnsGap", &columnsGap); + isUndefined = false; + env->Reference_IsUndefined(columnsGap, &isUndefined); + if (!isUndefined) { + curSection.columnsGap = ParseDimension(env, columnsGap); + } + + ani_ref rowsGap; + env->Object_GetPropertyByName_Ref(static_cast(section), "rowsGap", &rowsGap); + isUndefined = false; + env->Reference_IsUndefined(rowsGap, &isUndefined); + if (!isUndefined) { + curSection.rowsGap = ParseDimension(env, rowsGap); + } + + ani_ref margin; + env->Object_GetPropertyByName_Ref(static_cast(section), "margin", &margin); + isUndefined = false; + env->Reference_IsUndefined(margin, &isUndefined); + if (!isUndefined) { + curSection.margin = ParseMargin(env, margin); + } + + ani_ref func; + env->Object_GetPropertyByName_Ref(static_cast(section), "onGetItemMainSizeByIndex", &func); + + ani_class ClassGetItemMainSizeByIndex; + env->FindClass("Lstd/core/Function1;", &ClassGetItemMainSizeByIndex); + ani_boolean isGetItemMainSizeByIndex; + env->Object_InstanceOf(static_cast(func), ClassGetItemMainSizeByIndex, &isGetItemMainSizeByIndex); + + isUndefined = false; + env->Reference_IsUndefined(func, &isUndefined); + + if (isGetItemMainSizeByIndex && !isUndefined) { + ani_ref fnObjGlobalRef = nullptr; + env->GlobalReference_Create(func, &fnObjGlobalRef); + auto onGetItemMainSizeByIndex = [fnObjGlobalRef, env](int32_t index) { + ani_ref ani_res; + ani_ref ani_index = AniUtils::CreateDouble(env, ani_double(index)); + + env->FunctionalObject_Call(static_cast(fnObjGlobalRef), 1, &ani_index, &ani_res); + ani_double res; + env->Object_CallMethodByName_Double(static_cast(ani_res), "unboxed", ":D", &res); + return static_cast(res); + }; + curSection.onGetItemMainSizeByIndex = std::move(onGetItemMainSizeByIndex); + } + + return curSection; +} + +void ParseWaterFlowSections(ani_env* env, ani_ref sections, NG::FrameNode* frameNode) +{ + auto waterFlowSections = NG::WaterFlowModelNG::GetOrCreateWaterFlowSections(frameNode); + CHECK_NULL_VOID(waterFlowSections); + + ani_ref changeArray; + if (env->Object_GetPropertyByName_Ref(static_cast(sections), "changeArray", &changeArray) != ANI_OK) { + return; + } + ani_size changeArrayLength; + if (env->Array_GetLength(static_cast(changeArray), &changeArrayLength) != ANI_OK) { + } + + ani_class sectionChangeInfo; + if (env->FindClass("Larkui/component/waterFlow/SectionChangeInfo;", §ionChangeInfo) != ANI_OK) { + return; + } + + ani_class sectionOptions; + if (env->FindClass("Larkui/component/waterFlow/SectionOptions;", §ionOptions) != ANI_OK) { + return; + } + + for (int32_t i = 0; i < changeArrayLength; i++) { + ani_ref change; + if (env->Array_Get_Ref(static_cast(changeArray), i, &change) != ANI_OK) { + continue; + } + + ani_boolean isSectionChangeInfo; + env->Object_InstanceOf(static_cast(change), sectionChangeInfo, &isSectionChangeInfo); + if (!isSectionChangeInfo) { + continue; + } + + ani_double start = 0.0; + if (env->Object_GetPropertyByName_Double(static_cast(change), "start", &start) != ANI_OK) { + continue; + } + ani_double deleteCount = 0.0; + if (env->Object_GetPropertyByName_Double(static_cast(change), "deleteCount", &deleteCount) != + ANI_OK) { + continue; + } + + ani_ref sectionOptionsArray; + env->Object_GetPropertyByName_Ref(static_cast(change), "sections", §ionOptionsArray); + + ani_size aniLength; + if (env->Array_GetLength(static_cast(sectionOptionsArray), &aniLength) != ANI_OK) { + continue; + } + + int32_t length = static_cast(aniLength); + std::vector newSections; + for (int32_t j = 0; j < length; j++) { + ani_ref section; + if (env->Array_Get_Ref(static_cast(sectionOptionsArray), j, §ion) != ANI_OK) { + continue; + } + ani_boolean isSectionOptions; + env->Object_InstanceOf(static_cast(section), sectionOptions, &isSectionOptions); + if (!isSectionOptions) { + continue; + } + NG::WaterFlowSections::Section curSection = ParseSectionOptions(env, section); + if (curSection.itemsCount < 0) { + continue; + } + newSections.emplace_back(curSection); + } + waterFlowSections->ChangeData(start, deleteCount, newSections); + } +} + +void SetWaterFlowSection(ani_env* env, ani_long ptr, ani_object obj) { auto* frameNode = reinterpret_cast(ptr); CHECK_NULL_VOID(frameNode); - Framework::AniWaterFlowModule::SetWaterFlowSection(env, ptr, fnObj); + + ani_class waterflowSections; + if (env->FindClass("Larkui/component/waterFlow/WaterFlowSections;", &waterflowSections) != ANI_OK) { + return; + } + + ani_boolean isSection; + + env->Object_InstanceOf(obj, waterflowSections, &isSection); + if (isSection) { + ParseWaterFlowSections(env, obj, frameNode); + } +} + +void SetWaterFlowFooterContent(ani_env* env, ani_long ptr, ani_long footerPtr) +{ + auto* frameNode = reinterpret_cast(ptr); + CHECK_NULL_VOID(frameNode); + auto* footerContentPtr = reinterpret_cast(footerPtr); + CHECK_NULL_VOID(footerContentPtr); + + auto footerContentNodePtr = FrameNodePeer::GetFrameNodeByPeer(footerContentPtr); + CHECK_NULL_VOID(footerContentNodePtr); + WaterFlowModelNG::SetWaterflowFooterWithFrameNode(frameNode, footerContentNodePtr); } const ArkUIAniWaterFlowModifier* GetArkUIAniWaterFlowModifier() { static const ArkUIAniWaterFlowModifier impl = { - .setWaterFlowOptions = OHOS::Ace::NG::SetWaterFlowOptions, + .setWaterFlowSection = OHOS::Ace::NG::SetWaterFlowSection, + .setWaterFlowFooterContent = OHOS::Ace::NG::SetWaterFlowFooterContent, }; return &impl; }