From 856bf6d6ddf8e979e40d5207ed89a808c8c9a8a7 Mon Sep 17 00:00:00 2001 From: lancer Date: Fri, 12 Sep 2025 11:28:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=89=8B=E5=8A=BF=E6=BB=91=E5=8A=A8=E5=BC=80=E5=A7=8B?= =?UTF-8?q?=E7=BB=93=E6=9D=9F=E5=92=8C=E6=83=AF=E6=80=A7=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E5=BC=80=E5=A7=8B=E7=BB=93=E6=9D=9F=E5=9B=9E=E8=B0=83=20Signed?= =?UTF-8?q?-off-by:=20haoshuo=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ark_component/src/ArkGrid.ts | 20 +++ .../ark_component/src/ArkList.ts | 20 +++ .../ark_component/src/ArkScroll.ts | 20 +++ .../ark_component/src/ArkScrollable.ts | 72 +++++++++ .../ark_component/src/ArkWaterFlow.ts | 20 +++ .../engine/arkComponent.js | 136 ++++++++++++++++ .../arkts_native_api_impl_bridge.cpp | 16 ++ .../arkts_native_scrollable_bridge.cpp | 151 ++++++++++++++++++ .../arkts_native_scrollable_bridge.h | 8 + .../jsview/js_scrollable_base.cpp | 70 ++++++++ .../jsview/js_scrollable_base.h | 4 + .../pattern/scroll/inner/scroll_bar.cpp | 25 +++ .../pattern/scroll/inner/scroll_bar.h | 13 ++ .../pattern/scroll/scroll_pattern.cpp | 12 +- .../pattern/scroll/scroll_pattern.h | 3 +- .../scroll_bar/proxy/scroll_bar_proxy.cpp | 25 +++ .../scroll_bar/proxy/scroll_bar_proxy.h | 10 ++ .../pattern/scroll_bar/scroll_bar_pattern.cpp | 13 ++ .../pattern/scrollable/scrollable.cpp | 105 ++++++++++-- .../pattern/scrollable/scrollable.h | 76 ++++++++- .../pattern/scrollable/scrollable_event_hub.h | 44 +++++ .../scrollable/scrollable_model_ng.cpp | 66 ++++++++ .../pattern/scrollable/scrollable_model_ng.h | 8 + .../pattern/scrollable/scrollable_pattern.cpp | 123 +++++++++++++- .../pattern/scrollable/scrollable_pattern.h | 4 + .../scrollable/scrollable_properties.h | 7 + .../core/interfaces/arkoala/arkoala_api.h | 12 ++ .../core/interfaces/native/node/node_api.cpp | 8 + .../native/node/node_scroll_modifier.cpp | 85 ++++++++++ .../native/node/node_scroll_modifier.h | 8 + .../native/node/scrollable_modifier.cpp | 84 ++++++++++ .../grid/grid_scroller_event_test_ng.cpp | 35 ++++ .../scrollable/scrollable_cover_test_ng.cpp | 6 +- 33 files changed, 1283 insertions(+), 26 deletions(-) diff --git a/frameworks/bridge/declarative_frontend/ark_component/src/ArkGrid.ts b/frameworks/bridge/declarative_frontend/ark_component/src/ArkGrid.ts index f0b64e938bb..5e1caa10131 100644 --- a/frameworks/bridge/declarative_frontend/ark_component/src/ArkGrid.ts +++ b/frameworks/bridge/declarative_frontend/ark_component/src/ArkGrid.ts @@ -784,3 +784,23 @@ globalThis.Grid.onWillStopDragging = function (value: (velocity: number) => void let nodePtr = getUINativeModule().frameNode.getStackTopNode(); getUINativeModule().scrollable.setOnWillStopDragging(nodePtr, value); }; + +globalThis.Grid.onWillStartDragging = function (value: () => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartDragging(nodePtr, value); +}; + +globalThis.Grid.onDidStopDragging = function (value: (isWillFling: boolean) => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopDragging(nodePtr, value); +}; + +globalThis.Grid.onWillStartFling = function (value: () => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartFling(nodePtr, value); +}; + +globalThis.Grid.onDidStopFling = function (value: () => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopFling(nodePtr, value); +}; \ No newline at end of file diff --git a/frameworks/bridge/declarative_frontend/ark_component/src/ArkList.ts b/frameworks/bridge/declarative_frontend/ark_component/src/ArkList.ts index fb30e44b5ea..404620bd1d3 100644 --- a/frameworks/bridge/declarative_frontend/ark_component/src/ArkList.ts +++ b/frameworks/bridge/declarative_frontend/ark_component/src/ArkList.ts @@ -888,3 +888,23 @@ globalThis.List.onWillStopDragging = function (value: (velocity: number) => void let nodePtr = getUINativeModule().frameNode.getStackTopNode(); getUINativeModule().scrollable.setOnWillStopDragging(nodePtr, value); }; + +globalThis.List.onWillStartDragging = function (value: () => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartDragging(nodePtr, value); +}; + +globalThis.List.onDidStopDragging = function (value: (isWillFling: boolean) => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopDragging(nodePtr, value); +}; + +globalThis.List.onWillStartFling = function (value: () => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartFling(nodePtr, value); +}; + +globalThis.List.onDidStopFling = function (value: () => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopFling(nodePtr, value); +}; diff --git a/frameworks/bridge/declarative_frontend/ark_component/src/ArkScroll.ts b/frameworks/bridge/declarative_frontend/ark_component/src/ArkScroll.ts index d495f84f44f..9966a1d0ce9 100644 --- a/frameworks/bridge/declarative_frontend/ark_component/src/ArkScroll.ts +++ b/frameworks/bridge/declarative_frontend/ark_component/src/ArkScroll.ts @@ -631,3 +631,23 @@ globalThis.Scroll.onWillStopDragging = function (value: (velocity: number) => vo let nodePtr = getUINativeModule().frameNode.getStackTopNode(); getUINativeModule().scrollable.setOnWillStopDragging(nodePtr, value); }; + +globalThis.Scroll.onWillStartDragging = function (value: () => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartDragging(nodePtr, value); +}; + +globalThis.Scroll.onDidStopDragging = function (value: (isWillFling: boolean) => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopDragging(nodePtr, value); +}; + +globalThis.Scroll.onWillStartFling = function (value: () => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartFling(nodePtr, value); +}; + +globalThis.Scroll.onDidStopFling = function (value: () => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopFling(nodePtr, value); +}; diff --git a/frameworks/bridge/declarative_frontend/ark_component/src/ArkScrollable.ts b/frameworks/bridge/declarative_frontend/ark_component/src/ArkScrollable.ts index c5e047cf7f2..36ee36904e7 100644 --- a/frameworks/bridge/declarative_frontend/ark_component/src/ArkScrollable.ts +++ b/frameworks/bridge/declarative_frontend/ark_component/src/ArkScrollable.ts @@ -123,6 +123,62 @@ class OnWillStopDraggingModifier extends ModifierWithKey<(velocity: number) => v } } +class OnWillStartDraggingModifier extends ModifierWithKey<() => void> { + constructor(value: () => void) { + super(value); + } + static identity: Symbol = Symbol('onWillStartDragging'); + applyPeer(node: KNode, reset: boolean): void { + if (reset) { + getUINativeModule().scrollable.resetOnWillStartDragging(node); + } else { + getUINativeModule().scrollable.setOnWillStartDragging(node, this.value); + } + } +} + +class OnDidStopDraggingModifier extends ModifierWithKey<(isWillFling: boolean) => void> { + constructor(value: (isWillFling: boolean) => void) { + super(value); + } + static identity: Symbol = Symbol('onDidStopDragging'); + applyPeer(node: KNode, reset: boolean): void { + if (reset) { + getUINativeModule().scrollable.resetOnDidStopDragging(node); + } else { + getUINativeModule().scrollable.setOnDidStopDragging(node, this.value); + } + } +} + +class OnWillStartFlingModifier extends ModifierWithKey<() => void> { + constructor(value: () => void) { + super(value); + } + static identity: Symbol = Symbol('onWillStartFling'); + applyPeer(node: KNode, reset: boolean): void { + if (reset) { + getUINativeModule().scrollable.resetOnWillStartFling(node); + } else { + getUINativeModule().scrollable.setOnWillStartFling(node, this.value); + } + } +} + +class OnDidStopFlingModifier extends ModifierWithKey<() => void> { + constructor(value: () => void) { + super(value); + } + static identity: Symbol = Symbol('onDidStopFling'); + applyPeer(node: KNode, reset: boolean): void { + if (reset) { + getUINativeModule().scrollable.resetOnDidStopFling(node); + } else { + getUINativeModule().scrollable.setOnDidStopFling(node, this.value); + } + } +} + class OnReachEndModifier extends ModifierWithKey<() => void> { constructor(value: () => void) { super(value); @@ -183,4 +239,20 @@ export class ArkScrollable extends ArkComponent implements ScrollableCommonMe modifierWithKey(this._modifiersWithKeys, OnWillStopDraggingModifier.identity, OnWillStopDraggingModifier, callback); return this; } + onWillStartDragging(callback: () => void) : this { + modifierWithKey(this._modifiersWithKeys, OnWillStartDraggingModifier.identity, OnWillStartDraggingModifier, callback); + return this; + } + onDidStopDragging(callback: (isAnimate: boolean) => void) : this { + modifierWithKey(this._modifiersWithKeys, OnDidStopDraggingModifier.identity, OnDidStopDraggingModifier, callback); + return this; + } + onWillStartFling(callback: () => void) : this { + modifierWithKey(this._modifiersWithKeys, OnWillStartFlingModifier.identity, OnWillStartFlingModifier, callback); + return this; + } + onDidStopFling(callback: () => void) : this { + modifierWithKey(this._modifiersWithKeys, OnDidStopFlingModifier.identity, OnDidStopFlingModifier, callback); + return this; + } } \ No newline at end of file diff --git a/frameworks/bridge/declarative_frontend/ark_component/src/ArkWaterFlow.ts b/frameworks/bridge/declarative_frontend/ark_component/src/ArkWaterFlow.ts index bc84baadd8a..98a7417b122 100644 --- a/frameworks/bridge/declarative_frontend/ark_component/src/ArkWaterFlow.ts +++ b/frameworks/bridge/declarative_frontend/ark_component/src/ArkWaterFlow.ts @@ -548,3 +548,23 @@ globalThis.WaterFlow.onWillStopDragging = function (value: (velocity: number) => let nodePtr = getUINativeModule().frameNode.getStackTopNode(); getUINativeModule().scrollable.setOnWillStopDragging(nodePtr, value); }; + +globalThis.WaterFlow.onWillStartDragging = function (value: () => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartDragging(nodePtr, value); +}; + +globalThis.WaterFlow.onDidStopDragging = function (value: (isWillFling: boolean) => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopDragging(nodePtr, value); +}; + +globalThis.WaterFlow.onWillStartFling = function (value: () => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartFling(nodePtr, value); +}; + +globalThis.WaterFlow.onDidStopFling = function (value: () => void): void { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopFling(nodePtr, value); +}; diff --git a/frameworks/bridge/declarative_frontend/engine/arkComponent.js b/frameworks/bridge/declarative_frontend/engine/arkComponent.js index f72154a43a7..086d2e10654 100755 --- a/frameworks/bridge/declarative_frontend/engine/arkComponent.js +++ b/frameworks/bridge/declarative_frontend/engine/arkComponent.js @@ -7068,6 +7068,62 @@ class OnWillStopDraggingModifier extends ModifierWithKey { } OnWillStopDraggingModifier.identity = Symbol('onWillStopDragging'); +class OnWillStartDraggingModifier extends ModifierWithKey { + constructor(value) { + super(value); + } + applyPeer(node, reset) { + if (reset) { + getUINativeModule().scrollable.resetOnWillStartDragging(node); + } else { + getUINativeModule().scrollable.setOnWillStartDragging(node, this.value); + } + } +} +OnWillStartDraggingModifier.identity = Symbol('onWillStartDragging'); + +class OnDidStopDraggingModifier extends ModifierWithKey { + constructor(value) { + super(value); + } + applyPeer(node, reset) { + if (reset) { + getUINativeModule().scrollable.resetOnDidStopDragging(node); + } else { + getUINativeModule().scrollable.setOnDidStopDragging(node, this.value); + } + } +} +OnDidStopDraggingModifier.identity = Symbol('onDidStopDragging'); + +class OnWillStartFlingModifier extends ModifierWithKey { + constructor(value) { + super(value); + } + applyPeer(node, reset) { + if (reset) { + getUINativeModule().scrollable.resetOnWillStartFling(node); + } else { + getUINativeModule().scrollable.setOnWillStartFling(node, this.value); + } + } +} +OnWillStartFlingModifier.identity = Symbol('onWillStartFling'); + +class OnDidStopFlingModifier extends ModifierWithKey { + constructor(value) { + super(value); + } + applyPeer(node, reset) { + if (reset) { + getUINativeModule().scrollable.resetOnDidStopFling(node); + } else { + getUINativeModule().scrollable.setOnDidStopFling(node, this.value); + } + } +} +OnDidStopFlingModifier.identity = Symbol('onDidStopFling'); + class ArkScrollable extends ArkComponent { constructor(nativePtr, classType) { super(nativePtr, classType); @@ -7116,6 +7172,22 @@ class ArkScrollable extends ArkComponent { modifierWithKey(this._modifiersWithKeys, OnWillStopDraggingModifier.identity, OnWillStopDraggingModifier, value); return this; } + onWillStartDragging(value) { + modifierWithKey(this._modifiersWithKeys, OnWillStartDraggingModifier.identity, OnWillStartDraggingModifier, value); + return this; + } + onDidStopDragging(value) { + modifierWithKey(this._modifiersWithKeys, OnDidStopDraggingModifier.identity, OnDidStopDraggingModifier, value); + return this; + } + onWillStartFling(value) { + modifierWithKey(this._modifiersWithKeys, OnWillStartFlingModifier.identity, OnWillStartFlingModifier, value); + return this; + } + onDidStopFling(value) { + modifierWithKey(this._modifiersWithKeys, OnDidStopFlingModifier.identity, OnDidStopFlingModifier, value); + return this; + } } /// @@ -7859,6 +7931,22 @@ if (globalThis.Grid !== undefined) { let nodePtr = getUINativeModule().frameNode.getStackTopNode(); getUINativeModule().scrollable.setOnWillStopDragging(nodePtr, value); }; + globalThis.Grid.onWillStartDragging = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartDragging(nodePtr, value); + }; + globalThis.Grid.onDidStopDragging = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopDragging(nodePtr, value); + }; + globalThis.Grid.onWillStartFling = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartFling(nodePtr, value); + }; + globalThis.Grid.onDidStopFling = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopFling(nodePtr, value); + }; } /// @@ -21707,6 +21795,22 @@ if (globalThis.Scroll !== undefined) { let nodePtr = getUINativeModule().frameNode.getStackTopNode(); getUINativeModule().scrollable.setOnWillStopDragging(nodePtr, value); }; + globalThis.Scroll.onWillStartDragging = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartDragging(nodePtr, value); + }; + globalThis.Scroll.onDidStopDragging = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopDragging(nodePtr, value); + }; + globalThis.Scroll.onWillStartFling = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartFling(nodePtr, value); + }; + globalThis.Scroll.onDidStopFling = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopFling(nodePtr, value); + }; } /// @@ -34911,6 +35015,22 @@ if (globalThis.List !== undefined) { let nodePtr = getUINativeModule().frameNode.getStackTopNode(); getUINativeModule().scrollable.setOnWillStopDragging(nodePtr, value); }; + globalThis.List.onWillStartDragging = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartDragging(nodePtr, value); + }; + globalThis.List.onDidStopDragging = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopDragging(nodePtr, value); + }; + globalThis.List.onWillStartFling = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartFling(nodePtr, value); + }; + globalThis.List.onDidStopFling = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopFling(nodePtr, value); + }; } /// @@ -37850,6 +37970,22 @@ if (globalThis.WaterFlow !== undefined) { let nodePtr = getUINativeModule().frameNode.getStackTopNode(); getUINativeModule().scrollable.setOnWillStopDragging(nodePtr, value); }; + globalThis.WaterFlow.onWillStartDragging = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartDragging(nodePtr, value); + }; + globalThis.WaterFlow.onDidStopDragging = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopDragging(nodePtr, value); + }; + globalThis.WaterFlow.onWillStartFling = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnWillStartFling(nodePtr, value); + }; + globalThis.WaterFlow.onDidStopFling = function (value) { + let nodePtr = getUINativeModule().frameNode.getStackTopNode(); + getUINativeModule().scrollable.setOnDidStopFling(nodePtr, 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 491b3f1269d..212c925452e 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 @@ -5572,6 +5572,22 @@ void ArkUINativeModule::RegisterScrollableAttributes(Local obj panda::FunctionRef::New(const_cast(vm), ScrollableBridge::SetOnWillStopDragging)); scrollable->Set(vm, panda::StringRef::NewFromUtf8(vm, "resetOnWillStopDragging"), panda::FunctionRef::New(const_cast(vm), ScrollableBridge::ResetOnWillStopDragging)); + scrollable->Set(vm, panda::StringRef::NewFromUtf8(vm, "setOnWillStartDragging"), + panda::FunctionRef::New(const_cast(vm), ScrollableBridge::SetOnWillStartDragging)); + scrollable->Set(vm, panda::StringRef::NewFromUtf8(vm, "resetOnWillStartDragging"), + panda::FunctionRef::New(const_cast(vm), ScrollableBridge::ResetOnWillStartDragging)); + scrollable->Set(vm, panda::StringRef::NewFromUtf8(vm, "setOnDidStopDragging"), + panda::FunctionRef::New(const_cast(vm), ScrollableBridge::SetOnDidStopDragging)); + scrollable->Set(vm, panda::StringRef::NewFromUtf8(vm, "resetOnDidStopDragging"), + panda::FunctionRef::New(const_cast(vm), ScrollableBridge::ResetOnDidStopDragging)); + scrollable->Set(vm, panda::StringRef::NewFromUtf8(vm, "setOnWillStartFling"), + panda::FunctionRef::New(const_cast(vm), ScrollableBridge::SetOnWillStartFling)); + scrollable->Set(vm, panda::StringRef::NewFromUtf8(vm, "resetOnWillStartFling"), + panda::FunctionRef::New(const_cast(vm), ScrollableBridge::ResetOnWillStartFling)); + scrollable->Set(vm, panda::StringRef::NewFromUtf8(vm, "setOnDidStopFling"), + panda::FunctionRef::New(const_cast(vm), ScrollableBridge::SetOnDidStopFling)); + scrollable->Set(vm, panda::StringRef::NewFromUtf8(vm, "resetOnDidStopFling"), + panda::FunctionRef::New(const_cast(vm), ScrollableBridge::ResetOnDidStopFling)); object->Set(vm, panda::StringRef::NewFromUtf8(vm, "scrollable"), scrollable); } diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_scrollable_bridge.cpp b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_scrollable_bridge.cpp index 35e6aecbd73..d0f616d1c86 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_scrollable_bridge.cpp +++ b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_scrollable_bridge.cpp @@ -597,4 +597,155 @@ ArkUINativeModuleValue ScrollableBridge::ResetOnWillStopDragging(ArkUIRuntimeCal GetArkUINodeModifiers()->getScrollableModifier()->resetOnWillStopDragging(nativeNode); return panda::JSValueRef::Undefined(vm); } + +ArkUINativeModuleValue ScrollableBridge::SetOnWillStartDragging(ArkUIRuntimeCallInfo* runtimeCallInfo) +{ + EcmaVM* vm = runtimeCallInfo->GetVM(); + CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm)); + Local firstArg = runtimeCallInfo->GetCallArgRef(0); + Local callbackArg = runtimeCallInfo->GetCallArgRef(1); + CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm)); + auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value()); + if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) { + GetArkUINodeModifiers()->getScrollableModifier()->resetOnWillStartDragging(nativeNode); + return panda::JSValueRef::Undefined(vm); + } + auto frameNode = reinterpret_cast(nativeNode); + CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm)); + panda::Local func = callbackArg->ToObject(vm); + std::function callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() { + panda::LocalScope pandaScope(vm); + panda::TryCatch trycatch(vm); + PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode)); + func->Call(vm, func.ToLocal(), nullptr, 0); + }; + GetArkUINodeModifiers()->getScrollableModifier()->setOnWillStartDragging( + nativeNode, reinterpret_cast(&callback)); + return panda::JSValueRef::Undefined(vm); +} + +ArkUINativeModuleValue ScrollableBridge::ResetOnWillStartDragging(ArkUIRuntimeCallInfo* runtimeCallInfo) +{ + EcmaVM* vm = runtimeCallInfo->GetVM(); + CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm)); + Local firstArg = runtimeCallInfo->GetCallArgRef(0); + CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm)); + auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value()); + GetArkUINodeModifiers()->getScrollableModifier()->resetOnWillStartDragging(nativeNode); + return panda::JSValueRef::Undefined(vm); +} + +ArkUINativeModuleValue ScrollableBridge::SetOnDidStopDragging(ArkUIRuntimeCallInfo* runtimeCallInfo) +{ + EcmaVM* vm = runtimeCallInfo->GetVM(); + CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm)); + Local firstArg = runtimeCallInfo->GetCallArgRef(0); + Local callbackArg = runtimeCallInfo->GetCallArgRef(1); + CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm)); + auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value()); + if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) { + GetArkUINodeModifiers()->getScrollableModifier()->resetOnDidStopDragging(nativeNode); + return panda::JSValueRef::Undefined(vm); + } + auto frameNode = reinterpret_cast(nativeNode); + CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm)); + panda::Local func = callbackArg->ToObject(vm); + std::function callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]( + bool isAnimate) { + panda::LocalScope pandaScope(vm); + panda::TryCatch trycatch(vm); + PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode)); + // 1: Array length + panda::Local params[1] = { panda::BooleanRef::New(vm, isAnimate) }; + func->Call(vm, func.ToLocal(), params, 1); // 1: Array length + }; + GetArkUINodeModifiers()->getScrollableModifier()->setOnDidStopDragging( + nativeNode, reinterpret_cast(&callback)); + return panda::JSValueRef::Undefined(vm); +} + +ArkUINativeModuleValue ScrollableBridge::ResetOnDidStopDragging(ArkUIRuntimeCallInfo* runtimeCallInfo) +{ + EcmaVM* vm = runtimeCallInfo->GetVM(); + CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm)); + Local firstArg = runtimeCallInfo->GetCallArgRef(0); + CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm)); + auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value()); + GetArkUINodeModifiers()->getScrollableModifier()->resetOnDidStopDragging(nativeNode); + return panda::JSValueRef::Undefined(vm); +} + +ArkUINativeModuleValue ScrollableBridge::SetOnWillStartFling(ArkUIRuntimeCallInfo* runtimeCallInfo) +{ + EcmaVM* vm = runtimeCallInfo->GetVM(); + CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm)); + Local firstArg = runtimeCallInfo->GetCallArgRef(0); + Local callbackArg = runtimeCallInfo->GetCallArgRef(1); + CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm)); + auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value()); + if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) { + GetArkUINodeModifiers()->getScrollableModifier()->resetOnWillStartFling(nativeNode); + return panda::JSValueRef::Undefined(vm); + } + auto frameNode = reinterpret_cast(nativeNode); + CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm)); + panda::Local func = callbackArg->ToObject(vm); + std::function callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() { + panda::LocalScope pandaScope(vm); + panda::TryCatch trycatch(vm); + PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode)); + func->Call(vm, func.ToLocal(), nullptr, 0); + }; + GetArkUINodeModifiers()->getScrollableModifier()->setOnWillStartFling( + nativeNode, reinterpret_cast(&callback)); + return panda::JSValueRef::Undefined(vm); +} + +ArkUINativeModuleValue ScrollableBridge::ResetOnWillStartFling(ArkUIRuntimeCallInfo* runtimeCallInfo) +{ + EcmaVM* vm = runtimeCallInfo->GetVM(); + CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm)); + Local firstArg = runtimeCallInfo->GetCallArgRef(0); + CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm)); + auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value()); + GetArkUINodeModifiers()->getScrollableModifier()->resetOnWillStartFling(nativeNode); + return panda::JSValueRef::Undefined(vm); +} + +ArkUINativeModuleValue ScrollableBridge::SetOnDidStopFling(ArkUIRuntimeCallInfo* runtimeCallInfo) +{ + EcmaVM* vm = runtimeCallInfo->GetVM(); + CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm)); + Local firstArg = runtimeCallInfo->GetCallArgRef(0); + Local callbackArg = runtimeCallInfo->GetCallArgRef(1); + CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm)); + auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value()); + if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) { + GetArkUINodeModifiers()->getScrollableModifier()->resetOnDidStopFling(nativeNode); + return panda::JSValueRef::Undefined(vm); + } + auto frameNode = reinterpret_cast(nativeNode); + CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm)); + panda::Local func = callbackArg->ToObject(vm); + std::function callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() { + panda::LocalScope pandaScope(vm); + panda::TryCatch trycatch(vm); + PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode)); + func->Call(vm, func.ToLocal(), nullptr, 0); + }; + GetArkUINodeModifiers()->getScrollableModifier()->setOnDidStopFling( + nativeNode, reinterpret_cast(&callback)); + return panda::JSValueRef::Undefined(vm); +} + +ArkUINativeModuleValue ScrollableBridge::ResetOnDidStopFling(ArkUIRuntimeCallInfo* runtimeCallInfo) +{ + EcmaVM* vm = runtimeCallInfo->GetVM(); + CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm)); + Local firstArg = runtimeCallInfo->GetCallArgRef(0); + CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm)); + auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value()); + GetArkUINodeModifiers()->getScrollableModifier()->resetOnDidStopFling(nativeNode); + return panda::JSValueRef::Undefined(vm); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_scrollable_bridge.h b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_scrollable_bridge.h index 9d4951fa236..1a13b85202e 100644 --- a/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_scrollable_bridge.h +++ b/frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_scrollable_bridge.h @@ -52,6 +52,14 @@ public: static ArkUINativeModuleValue ResetOnScrollStop(ArkUIRuntimeCallInfo* runtimeCallInfo); static ArkUINativeModuleValue SetOnWillStopDragging(ArkUIRuntimeCallInfo* runtimeCallInfo); static ArkUINativeModuleValue ResetOnWillStopDragging(ArkUIRuntimeCallInfo* runtimeCallInfo); + static ArkUINativeModuleValue SetOnWillStartDragging(ArkUIRuntimeCallInfo* runtimeCallInfo); + static ArkUINativeModuleValue ResetOnWillStartDragging(ArkUIRuntimeCallInfo* runtimeCallInfo); + static ArkUINativeModuleValue SetOnDidStopDragging(ArkUIRuntimeCallInfo* runtimeCallInfo); + static ArkUINativeModuleValue ResetOnDidStopDragging(ArkUIRuntimeCallInfo* runtimeCallInfo); + static ArkUINativeModuleValue SetOnWillStartFling(ArkUIRuntimeCallInfo* runtimeCallInfo); + static ArkUINativeModuleValue ResetOnWillStartFling(ArkUIRuntimeCallInfo* runtimeCallInfo); + static ArkUINativeModuleValue SetOnDidStopFling(ArkUIRuntimeCallInfo* runtimeCallInfo); + static ArkUINativeModuleValue ResetOnDidStopFling(ArkUIRuntimeCallInfo* runtimeCallInfo); }; } // namespace OHOS::Ace::NG diff --git a/frameworks/bridge/declarative_frontend/jsview/js_scrollable_base.cpp b/frameworks/bridge/declarative_frontend/jsview/js_scrollable_base.cpp index e5f886e62ee..5fd8fb61bc6 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_scrollable_base.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_scrollable_base.cpp @@ -128,6 +128,10 @@ void JSScrollableBase::JSBind(BindingTarget globalObj) JSClass::StaticMethod("digitalCrownSensitivity", &JSScrollableBase::SetDigitalCrownSensitivity); JSClass::StaticMethod("scrollBarMargin", &JSScrollableBase::SetScrollBarMargin); JSClass::StaticMethod("backToTop", &JSScrollableBase::JSBackToTop); + JSClass::StaticMethod("onWillStartDragging", &JSScrollableBase::JSOnWillStartDragging, opt); + JSClass::StaticMethod("onDidStopDragging", &JSScrollableBase::JSOnDidStopDragging, opt); + JSClass::StaticMethod("onWillStartFling", &JSScrollableBase::JSOnWillStartFling, opt); + JSClass::StaticMethod("onDidStopFling", &JSScrollableBase::JSOnDidStopFling, opt); JSClass::InheritAndBind(globalObj); } @@ -198,4 +202,70 @@ void JSScrollableBase::JSBackToTop(const JSCallbackInfo& info) NG::ScrollableModelNG::ResetBackToTop(); } } + +void JSScrollableBase::JSOnWillStartDragging(const JSCallbackInfo& args) +{ + if (args.Length() <= 0) { + return; + } + if (args[0]->IsFunction()) { + auto onWillStartDragging = [execCtx = args.GetExecutionContext(), func = JSRef::Cast(args[0])]() { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + func->Call(JSRef(), 0, nullptr); + }; + NG::ScrollableModelNG::SetOnWillStartDragging(std::move(onWillStartDragging)); + } else { + NG::ScrollableModelNG::SetOnWillStartDragging(nullptr); + } +} + +void JSScrollableBase::JSOnDidStopDragging(const JSCallbackInfo& args) +{ + if (args.Length() <= 0) { + return; + } + if (args[0]->IsFunction()) { + auto onDidStopDragging = [execCtx = args.GetExecutionContext(), func = JSRef::Cast(args[0])]( + bool hasAnimate) { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + auto params = ConvertToJSValues(hasAnimate); + func->Call(JSRef(), params.size(), params.data()); + }; + NG::ScrollableModelNG::SetOnDidStopDragging(std::move(onDidStopDragging)); + } else { + NG::ScrollableModelNG::SetOnDidStopDragging(nullptr); + } +} + +void JSScrollableBase::JSOnWillStartFling(const JSCallbackInfo& args) +{ + if (args.Length() <= 0) { + return; + } + if (args[0]->IsFunction()) { + auto onWillStartFling = [execCtx = args.GetExecutionContext(), func = JSRef::Cast(args[0])]() { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + func->Call(JSRef(), 0, nullptr); + }; + NG::ScrollableModelNG::SetOnWillStartFling(std::move(onWillStartFling)); + } else { + NG::ScrollableModelNG::SetOnWillStartFling(nullptr); + } +} + +void JSScrollableBase::JSOnDidStopFling(const JSCallbackInfo& args) +{ + if (args.Length() <= 0) { + return; + } + if (args[0]->IsFunction()) { + auto onDidStopFling = [execCtx = args.GetExecutionContext(), func = JSRef::Cast(args[0])]() { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + func->Call(JSRef(), 0, nullptr); + }; + NG::ScrollableModelNG::SetOnDidStopFling(std::move(onDidStopFling)); + } else { + NG::ScrollableModelNG::SetOnDidStopFling(nullptr); + } +} } // namespace OHOS::Ace::Framework diff --git a/frameworks/bridge/declarative_frontend/jsview/js_scrollable_base.h b/frameworks/bridge/declarative_frontend/jsview/js_scrollable_base.h index 42d3c326058..30e49017c77 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_scrollable_base.h +++ b/frameworks/bridge/declarative_frontend/jsview/js_scrollable_base.h @@ -31,6 +31,10 @@ public: static void SetScrollBarMargin(const JSCallbackInfo& info); static void JSBackToTop(const JSCallbackInfo& info); static void JSOnWillStopDragging(const JSCallbackInfo& args); + static void JSOnWillStartDragging(const JSCallbackInfo& info); + static void JSOnDidStopDragging(const JSCallbackInfo& info); + static void JSOnWillStartFling(const JSCallbackInfo& info); + static void JSOnDidStopFling(const JSCallbackInfo& info); }; } // namespace OHOS::Ace::Framework #endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_SCROLLABLE_BASE_H diff --git a/frameworks/core/components_ng/pattern/scroll/inner/scroll_bar.cpp b/frameworks/core/components_ng/pattern/scroll/inner/scroll_bar.cpp index 235f77eda66..73e8309267a 100644 --- a/frameworks/core/components_ng/pattern/scroll/inner/scroll_bar.cpp +++ b/frameworks/core/components_ng/pattern/scroll/inner/scroll_bar.cpp @@ -758,6 +758,22 @@ void ScrollBar::HandleDragEnd(const GestureEvent& info) scrollEndCallback_(); } isDriving_ = false; + SnapAnimationOptions snapAnimationOptions = { + .snapDelta = 0, + .animationVelocity = 0, + .dragDistance = CalcPatternOffset(GetDragOffset()), + .snapDirection = SnapDirection::NONE, + .fromScrollBar = true, + .source = SCROLL_FROM_BAR, + }; + bool isWillFling = false; + if (info.GetInputEventType() != InputEventType::AXIS) { + CHECK_NULL_VOID(startSnapAnimationCallback_); + isWillFling = startSnapAnimationCallback_(snapAnimationOptions); + } + if (scrollBarOnDidStopDraggingCallback_) { + scrollBarOnDidStopDraggingCallback_(isWillFling); + } return; } SetDragEndPosition(GetMainOffset(Offset(info.GetGlobalPoint().GetX(), info.GetGlobalPoint().GetY()))); @@ -781,6 +797,9 @@ void ScrollBar::HandleDragEnd(const GestureEvent& info) }; if (startSnapAnimationCallback_ && startSnapAnimationCallback_(snapAnimationOptions)) { isDriving_ = false; + if (scrollBarOnDidStopDraggingCallback_) { + scrollBarOnDidStopDraggingCallback_(true); + } return; } @@ -794,6 +813,9 @@ void ScrollBar::HandleDragEnd(const GestureEvent& info) scrollBar->ProcessFrictionMotionStop(); }); } + if (scrollBarOnDidStopDraggingCallback_) { + scrollBarOnDidStopDraggingCallback_(true); + } frictionController_->PlayMotion(frictionMotion_); } @@ -812,6 +834,9 @@ void ScrollBar::ProcessFrictionMotion(double value) void ScrollBar::ProcessFrictionMotionStop() { + if (scrollBarOnDidStopFlingCallback_) { + scrollBarOnDidStopFlingCallback_(); + } if (scrollEndCallback_) { scrollEndCallback_(); } diff --git a/frameworks/core/components_ng/pattern/scroll/inner/scroll_bar.h b/frameworks/core/components_ng/pattern/scroll/inner/scroll_bar.h index fadf7b05691..4569f583b18 100644 --- a/frameworks/core/components_ng/pattern/scroll/inner/scroll_bar.h +++ b/frameworks/core/components_ng/pattern/scroll/inner/scroll_bar.h @@ -331,6 +331,17 @@ public: { dragFRCSceneCallback_ = std::move(dragFRCSceneCallback); } + + void SetScrollBarOnDidStopDraggingCallback(const OnDidStopDraggingEvent& onDidStopDraggingCallback) + { + scrollBarOnDidStopDraggingCallback_ = onDidStopDraggingCallback; + } + + void SetScrollBarOnDidStopFlingCallback(const OnDidStopFlingEvent& onDidStopFlingCallback) + { + scrollBarOnDidStopFlingCallback_ = onDidStopFlingCallback; + } + void SetDragStartPosition(float position) { dragStartPosition_ = position; @@ -728,6 +739,8 @@ private: Axis axis_ = Axis::VERTICAL; std::optional scrollBarMargin_; DragFRCSceneCallback dragFRCSceneCallback_; + OnDidStopDraggingEvent scrollBarOnDidStopDraggingCallback_; + OnDidStopFlingEvent scrollBarOnDidStopFlingCallback_; // dump info std::list innerScrollBarLayoutInfos_; bool needAddLayoutInfo = false; diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp index 92a6417b124..40b2ed9204f 100644 --- a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp +++ b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp @@ -221,7 +221,9 @@ bool ScrollPattern::SetScrollProperties(const RefPtr& dirty, cons bool ScrollPattern::ScrollSnapTrigger() { if (ScrollableIdle() && !AnimateRunning()) { - SnapAnimationOptions snapAnimationOptions; + SnapAnimationOptions snapAnimationOptions = { + .source = SCROLL_FROM_LAYOUT, + }; if (StartSnapAnimation(snapAnimationOptions)) { if (!IsScrolling()) { FireOnScrollStart(); @@ -1508,13 +1510,15 @@ bool ScrollPattern::StartSnapAnimation(SnapAnimationOptions snapAnimationOptions auto predictSnapOffset = CalcPredictSnapOffset(snapAnimationOptions.snapDelta, snapAnimationOptions.dragDistance, snapAnimationOptions.animationVelocity, snapAnimationOptions.snapDirection); if (predictSnapOffset.has_value() && !NearZero(predictSnapOffset.value(), SPRING_ACCURACY)) { - StartScrollSnapAnimation(predictSnapOffset.value(), snapAnimationOptions.animationVelocity, fromScrollBar); + StartScrollSnapAnimation(predictSnapOffset.value(), snapAnimationOptions.animationVelocity, fromScrollBar, + snapAnimationOptions.source); return true; } return false; } -void ScrollPattern::StartScrollSnapAnimation(float scrollSnapDelta, float scrollSnapVelocity, bool fromScrollBar) +void ScrollPattern::StartScrollSnapAnimation( + float scrollSnapDelta, float scrollSnapVelocity, bool fromScrollBar, int32_t source) { auto scrollableEvent = GetScrollableEvent(); CHECK_NULL_VOID(scrollableEvent); @@ -1524,7 +1528,7 @@ void ScrollPattern::StartScrollSnapAnimation(float scrollSnapDelta, float scroll scrollable->UpdateScrollSnapEndWithOffset( -(scrollSnapDelta + scrollable->GetCurrentPos() - scrollable->GetSnapFinalPosition())); } else { - scrollable->StartScrollSnapAnimation(scrollSnapDelta, scrollSnapVelocity, fromScrollBar); + scrollable->StartScrollSnapAnimation(scrollSnapDelta, scrollSnapVelocity, fromScrollBar, source); if (!IsScrolling()) { FireOnScrollStart(); } diff --git a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.h b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.h index da07c483fc2..195821c3f51 100644 --- a/frameworks/core/components_ng/pattern/scroll/scroll_pattern.h +++ b/frameworks/core/components_ng/pattern/scroll/scroll_pattern.h @@ -388,7 +388,8 @@ public: bool StartSnapAnimation(SnapAnimationOptions snapAnimationOptions) override; - void StartScrollSnapAnimation(float scrollSnapDelta, float scrollSnapVelocity, bool fromScrollBar); + void StartScrollSnapAnimation( + float scrollSnapDelta, float scrollSnapVelocity, bool fromScrollBar, int32_t source = SCROLL_FROM_NONE); SizeF GetChildrenExpandedSize() override; diff --git a/frameworks/core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.cpp b/frameworks/core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.cpp index 47cb9ac3eaf..a282c00b6a5 100644 --- a/frameworks/core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.cpp +++ b/frameworks/core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.cpp @@ -241,6 +241,7 @@ bool ScrollBarProxy::NotifySnapScroll( .dragDistance = CalcPatternOffset(controlDistance, barScrollableDistance, dragDistance), .snapDirection = SnapDirection::NONE, .fromScrollBar = true, + .source = SCROLL_FROM_BAR, }; return scorllableNode_.startSnapAnimationCallback(snapAnimationOptions); } @@ -254,6 +255,30 @@ bool ScrollBarProxy::NotifySnapScrollWithoutChild(SnapAnimationOptions snapAnima return scorllableNode_.startSnapAnimationCallback(snapAnimationOptions); } +void ScrollBarProxy::NotifyScrollBarOnDidStopDragging(bool isWilFling) const +{ + auto node = scorllableNode_; + CHECK_NULL_VOID(node.scrollBarOnDidStopDraggingCallback); + node.scrollBarOnDidStopDraggingCallback(isWilFling); +} + +void ScrollBarProxy::NotifyScrollBarOnDidStopFling() const +{ + auto node = scorllableNode_; + CHECK_NULL_VOID(node.scrollBarOnDidStopFlingCallback); + node.scrollBarOnDidStopFlingCallback(); +} + +void ScrollBarProxy::SetScrollBarOnDidStopDraggingCallback(const OnDidStopDraggingCallback& onDidStopDraggingCallback) +{ + scorllableNode_.scrollBarOnDidStopDraggingCallback = onDidStopDraggingCallback; +} + +void ScrollBarProxy::SetScrollBarOnDidStopFlingCallback(const OnDidStopFlingCallback& onDidStopFlingCallback) +{ + scorllableNode_.scrollBarOnDidStopFlingCallback = onDidStopFlingCallback; +} + float ScrollBarProxy::CalcPatternOffset(float controlDistance, float barScrollableDistance, float delta) const { if (!NearZero(barScrollableDistance)) { diff --git a/frameworks/core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.h b/frameworks/core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.h index 0e34ace9f0d..9a605797da9 100644 --- a/frameworks/core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.h +++ b/frameworks/core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.h @@ -33,6 +33,8 @@ struct ScrollableNodeInfo { StartSnapAnimationCallback startSnapAnimationCallback; ScrollBarFRCallback scrollbarFRcallback; std::function scrollPageCallback; + std::function scrollBarOnDidStopDraggingCallback; + std::function scrollBarOnDidStopFlingCallback; bool operator==(const ScrollableNodeInfo& info) const { @@ -97,6 +99,14 @@ public: void NotifyScrollBarNode(float distance, int32_t source, bool isMouseWheelScroll = false) const; + void NotifyScrollBarOnDidStopDragging(bool isWillFling) const; + + void NotifyScrollBarOnDidStopFling() const; + + void SetScrollBarOnDidStopDraggingCallback(const OnDidStopDraggingEvent& onDidStopDraggingCallback); + + void SetScrollBarOnDidStopFlingCallback(const OnDidStopFlingEvent& onDidStopFlingCallback); + void SetScrollSnapTrigger_(bool scrollSnapTrigger) { scrollSnapTrigger_ = scrollSnapTrigger; diff --git a/frameworks/core/components_ng/pattern/scroll_bar/scroll_bar_pattern.cpp b/frameworks/core/components_ng/pattern/scroll_bar/scroll_bar_pattern.cpp index 6a9e256cb64..6e0161c0f8c 100644 --- a/frameworks/core/components_ng/pattern/scroll_bar/scroll_bar_pattern.cpp +++ b/frameworks/core/components_ng/pattern/scroll_bar/scroll_bar_pattern.cpp @@ -811,6 +811,14 @@ void ScrollBarPattern::HandleDragEnd(const GestureEvent& info) } scrollEndCallback_(); } + + bool isWillFling = false; + CHECK_NULL_VOID(scrollBarProxy_); + if (info.GetInputEventType() != InputEventType::AXIS) { + isWillFling = scrollBarProxy_->NotifySnapScroll( + 0, 0, GetScrollableDistance(), static_cast(GetDragOffset())); + } + scrollBarProxy_->NotifyScrollBarOnDidStopDragging(isWillFling); return; } frictionPosition_ = 0.0; @@ -827,6 +835,7 @@ void ScrollBarPattern::HandleDragEnd(const GestureEvent& info) if (scrollBarProxy_ && scrollBarProxy_->NotifySnapScroll(-(frictionMotion_->GetFinalPosition()), velocity, GetScrollableDistance(), static_cast(GetDragOffset()))) { scrollBarProxy_->SetScrollSnapTrigger_(false); + scrollBarProxy_->NotifyScrollBarOnDidStopDragging(true); return; } if (!frictionController_) { @@ -841,6 +850,9 @@ void ScrollBarPattern::HandleDragEnd(const GestureEvent& info) scrollBar->ProcessFrictionMotionStop(); }); } + if (scrollBarProxy_) { + scrollBarProxy_->NotifyScrollBarOnDidStopDragging(true); + } frictionController_->PlayMotion(frictionMotion_); } @@ -861,6 +873,7 @@ void ScrollBarPattern::ProcessFrictionMotionStop() } CHECK_NULL_VOID(scrollBarProxy_); scrollBarProxy_->SetScrollSnapTrigger_(false); + scrollBarProxy_->NotifyScrollBarOnDidStopFling(); } void ScrollBarPattern::OnCollectTouchTarget(const OffsetF& coordinateOffset, diff --git a/frameworks/core/components_ng/pattern/scrollable/scrollable.cpp b/frameworks/core/components_ng/pattern/scrollable/scrollable.cpp index b5fdc155a8d..3d5436028a7 100644 --- a/frameworks/core/components_ng/pattern/scrollable/scrollable.cpp +++ b/frameworks/core/components_ng/pattern/scrollable/scrollable.cpp @@ -164,7 +164,7 @@ void Scrollable::InitAxisAnimator() auto scrollable = weak.Upgrade(); CHECK_NULL_VOID(scrollable); scrollable->ReportToDragFRCScene(scrollable->currentVelocity_, NG::SceneStatus::END); - scrollable->ProcessScrollMotionStop(); + scrollable->ProcessScrollMotionStop(SCROLL_FROM_AXIS); }; axisAnimator_ = AceType::MakeRefPtr(std::move(axisAnimationCallback), std::move(axisAnimationStartCallback), std::move(axisAnimationFinishCallback)); @@ -492,6 +492,10 @@ void Scrollable::SetAxis(Axis axis) void Scrollable::HandleTouchDown(bool fromcrown) { + isTouchStopAnimation_ = false; + if (state_ != AnimationState::TRANSITION && state_ != AnimationState::IDLE) { + isTouchStopAnimation_ = true; + } if (!fromcrown) { isTouching_ = true; } @@ -510,6 +514,10 @@ void Scrollable::HandleTouchUp() // Two fingers are alternately drag, one finger is released without triggering spring animation. ACE_SCOPED_TRACE("HandleTouchUp, isDragging_:%u, nestedScrolling_:%u id:%d, tag:%s", isDragging_, nestedScrolling_, nodeId_, nodeTag_.c_str()); + if (!isDragging_ && !isScrollBarDragging_ && isTouchStopAnimation_ && onDidStopFlingCallback_) { + isUserFling_ = false; + onDidStopFlingCallback_(); + } if (isDragging_) { return; } @@ -649,6 +657,9 @@ void Scrollable::HandleDragStart(const OHOS::Ace::GestureEvent& info) "IsAxisAnimationRunning:%u, IsSnapAnimationRunning:%u, id:%d, tag:%s", info.GetInputEventType(), info.GetSourceTool(), isAxisEvent, IsAxisAnimationRunning(), IsSnapAnimationRunning(), nodeId_, nodeTag_.c_str()); + if (onWillStartDraggingCallback_) { + onWillStartDraggingCallback_(); + } if (isAxisEvent && !CanStayOverScroll()) { if (!IsAxisAnimationRunning() && !IsSnapAnimationRunning()) { axisSnapDistance_ = currentPos_; @@ -771,7 +782,7 @@ void Scrollable::ProcessAxisUpdateEvent(float mainDelta, bool fromScrollBar) "lastSnapDirection:%d, id:%d, tag:%s", snapDelta, snapDirection, snapDirection_, nodeId_, nodeTag_.c_str()); SnapAnimationOptions snapAnimationOptions = { .snapDelta = snapDelta, .animationVelocity = currentVelocity_, - .snapDirection = snapDirection, .fromScrollBar = fromScrollBar }; + .snapDirection = snapDirection, .fromScrollBar = fromScrollBar, .source = SCROLL_FROM_AXIS }; startSnapAnimationCallback_(snapAnimationOptions); auto isNeedAdjustDirection = (snapType == SnapType::SCROLL_SNAP && snapDirection == SnapDirection::NONE); if (isNeedAdjustDirection) { @@ -847,12 +858,15 @@ void Scrollable::HandleDragEnd(const GestureEvent& info, bool isFromPanEnd) lastPos_ = GetDragOffset(); JankFrameReport::GetInstance().ClearFrameJankFlag(JANK_RUNNING_SCROLL); double mainPosition = Round(GetMainOffset(Offset(info.GetGlobalPoint().GetX(), info.GetGlobalPoint().GetY()))); + bool isWillFling = false; if (!moved_ || isAxisEvent) { LayoutDirectionEst(lastGestureVelocity_, flingVelocityScale_, isScrollFromTouchPad); ResetContinueDragCount(); if (GetSnapType() == SnapType::SCROLL_SNAP) { currentPos_ = mainPosition; - SnapAnimationOptions snapAnimationOptions = { .animationVelocity = currentVelocity_ }; + SnapAnimationOptions snapAnimationOptions = { + .animationVelocity = currentVelocity_, + .source = isAxisEvent ? SCROLL_FROM_AXIS : SCROLL_FROM_NONE }; if (startSnapAnimationCallback_ && startSnapAnimationCallback_(snapAnimationOptions)) { isTouching_ = false; return; @@ -869,11 +883,23 @@ void Scrollable::HandleDragEnd(const GestureEvent& info, bool isFromPanEnd) LayoutDirectionEst(lastGestureVelocity_, springVelocityScale_, isScrollFromTouchPad); CalcOverScrollVelocity(); ResetContinueDragCount(); - HandleOverScroll(currentVelocity_); + isWillFling = HandleOverScroll(currentVelocity_); } else { LayoutDirectionEst(lastGestureVelocity_, flingVelocityScale_, isScrollFromTouchPad); - StartScrollAnimation(mainPosition, currentVelocity_, isScrollFromTouchPad); + isWillFling = StartScrollAnimation(mainPosition, currentVelocity_, isScrollFromTouchPad); } + + if (onDidStopDraggingCallback_) { + onDidStopDraggingCallback_(isWillFling); + } + if (onWillStartFlingCallback_ && isWillFling && !isUserFling_) { + onWillStartFlingCallback_(); + } + if (onDidStopFlingCallback_ && isUserFling_ && !isWillFling) { + onDidStopFlingCallback_(); + } + isUserFling_ = isWillFling; + ACE_SCOPED_TRACE( "HandleDragEnd, mainPosition:%f, getureDelta:%lf, gestureVelocity:%f, currentVelocity:%f, moved_:%u " "canOverScroll_:%u, id:%d, tag:%s", @@ -900,6 +926,9 @@ void Scrollable::ProcessAxisEndEvent() HandleOverScroll(0); SetCanStayOverScroll(false); } + if (onDidStopDraggingCallback_) { + onDidStopDraggingCallback_(false); + } } void Scrollable::ReportToDragFRCScene(double velocity, NG::SceneStatus sceneStatus) @@ -918,7 +947,7 @@ void Scrollable::CalcOverScrollVelocity() currentVelocity_ = currentVelocity_ * exp(-ratio_ * gamma); } -void Scrollable::StartScrollAnimation(float mainPosition, float correctVelocity, bool isScrollFromTouchPad) +bool Scrollable::StartScrollAnimation(float mainPosition, float correctVelocity, bool isScrollFromTouchPad) { if (state_ == AnimationState::SPRING) { StopSpringAnimation(); @@ -956,7 +985,7 @@ void Scrollable::StartScrollAnimation(float mainPosition, float correctVelocity, if (GetSnapType() == SnapType::LIST_SNAP) { currentVelocity_ = 0.0; } - return; + return true; } if (fixScrollParamCallback_) { fixScrollParamCallback_(mainPosition, initVelocity_, finalPosition_); @@ -975,9 +1004,10 @@ void Scrollable::StartScrollAnimation(float mainPosition, float correctVelocity, FrameReport::GetInstance().EndListFling(); } #endif - return; + return false; } TriggerFrictionAnimation(mainPosition, friction, correctVelocity); + return true; } void Scrollable::TriggerFrictionAnimation(float mainPosition, float friction, float correctVelocity) @@ -1006,7 +1036,7 @@ void Scrollable::TriggerFrictionAnimation(float mainPosition, float friction, fl scroll->state_ = AnimationState::IDLE; ACE_SCOPED_TRACE( "Scrollable friction animation finish, id:%d, tag:%s", scroll->nodeId_, scroll->nodeTag_.c_str()); - scroll->ProcessScrollMotionStop(); + scroll->ProcessScrollMotionStop(SCROLL_FROM_ANIMATION); }); state_ = AnimationState::FRICTION; auto context = context_.Upgrade(); @@ -1163,6 +1193,10 @@ void Scrollable::StartListSnapAnimation(float predictSnapOffset, float scrollSna scroll->updateSnapAnimationCount_--; if (scroll->updateSnapAnimationCount_ == 0) { scroll->state_ = AnimationState::IDLE; + if (scroll->onDidStopFlingCallback_ && scroll->isUserFling_) { + scroll->onDidStopFlingCallback_(); + scroll->isUserFling_ = false; + } scroll->axisSnapDistance_ = 0.f; scroll->ProcessScrollSnapStop(); } @@ -1175,7 +1209,8 @@ void Scrollable::StartListSnapAnimation(float predictSnapOffset, float scrollSna MarkNeedFlushAnimationStartTime(); } -void Scrollable::StartScrollSnapAnimation(float scrollSnapDelta, float scrollSnapVelocity, bool fromScrollBar) +void Scrollable::StartScrollSnapAnimation( + float scrollSnapDelta, float scrollSnapVelocity, bool fromScrollBar, int32_t source) { TAG_LOGD(AceLogTag::ACE_SCROLLABLE, "The snap delta of scroll motion is %{public}f, " @@ -1206,7 +1241,7 @@ void Scrollable::StartScrollSnapAnimation(float scrollSnapDelta, float scrollSna snapOffsetProperty_->SetPropertyUnit(PropertyUnit::PIXEL_POSITION); updateSnapAnimationCount_++; snapOffsetProperty_->AnimateWithVelocity( - option, endPos_, scrollSnapVelocity, [weak = AceType::WeakClaim(this), id = Container::CurrentId()]() { + option, endPos_, scrollSnapVelocity, [weak = AceType::WeakClaim(this), id = Container::CurrentId(), source]() { ContainerScope scope(id); auto scroll = weak.Upgrade(); CHECK_NULL_VOID(scroll); @@ -1217,7 +1252,7 @@ void Scrollable::StartScrollSnapAnimation(float scrollSnapDelta, float scrollSna scroll->axisSnapDistance_ = 0.f; scroll->snapDirection_ = SnapDirection::NONE; ACE_SCOPED_TRACE("Scroll snap animation finish, id:%d", scroll->nodeId_); - scroll->ProcessScrollMotionStop(); + scroll->ProcessScrollMotionStop(source); } }); state_ = AnimationState::SNAP; @@ -1346,6 +1381,10 @@ void Scrollable::StartSpringMotion( return; } scroll->state_ = AnimationState::IDLE; + if (scroll->onDidStopFlingCallback_ && scroll->isUserFling_) { + scroll->onDidStopFlingCallback_(); + scroll->isUserFling_ = false; + } scroll->currentVelocity_ = 0.0; scroll->OnAnimateStop(); }); @@ -1407,6 +1446,10 @@ void Scrollable::UpdateSpringMotion(double mainPosition, const ExtentPair& exten ACE_SCOPED_TRACE( "Scrollable updated spring animation finish, id:%d, tag:%s", scroll->nodeId_, scroll->nodeTag_.c_str()); scroll->state_ = AnimationState::IDLE; + if (scroll->onDidStopFlingCallback_ && scroll->isUserFling_) { + scroll->onDidStopFlingCallback_(); + scroll->isUserFling_ = false; + } scroll->currentVelocity_ = 0.0; scroll->OnAnimateStop(); }); @@ -1414,7 +1457,7 @@ void Scrollable::UpdateSpringMotion(double mainPosition, const ExtentPair& exten skipRestartSpring_ = false; } -void Scrollable::ProcessScrollMotionStop() +void Scrollable::ProcessScrollMotionStop(int32_t source) { if (needScrollSnapChange_ && startSnapAnimationCallback_ && frictionOffsetProperty_) { needScrollSnapChange_ = false; @@ -1436,6 +1479,12 @@ void Scrollable::ProcessScrollMotionStop() return; } + if (onDidStopFlingCallback_ && !isTouchStopAnimation_ && source != SCROLL_FROM_AXIS && + source != SCROLL_FROM_LAYOUT) { + onDidStopFlingCallback_(); + isUserFling_ = false; + } + if (isDragUpdateStop_) { return; } @@ -1868,4 +1917,34 @@ void Scrollable::SetMaxFlingVelocity(double max) double density = PipelineBase::GetCurrentDensity(); maxFlingVelocity_ = max * density; } + +void Scrollable::HandleScrollBarOnDidStopDragging(bool isWillFling) +{ + if (onDidStopDraggingCallback_) { + onDidStopDraggingCallback_(isWillFling); + } + if (isTouchStopAnimation_ && !isWillFling) { + isUserFling_ = false; + if (onDidStopFlingCallback_) { + onDidStopFlingCallback_(); + } + } +} + +void Scrollable::HandleScrollBarOnWillStartFling() +{ + if (onWillStartFlingCallback_ && !isUserFling_) { + onWillStartFlingCallback_(); + } + isUserFling_ = true; +} + +void Scrollable::HandleScrollBarOnDidStopFling() +{ + if (onDidStopFlingCallback_ && isUserFling_) { + onDidStopFlingCallback_(); + } + isUserFling_ = false; +} + } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/scrollable/scrollable.h b/frameworks/core/components_ng/pattern/scrollable/scrollable.h index 9a9abc952e3..d3c9975ed6c 100644 --- a/frameworks/core/components_ng/pattern/scrollable/scrollable.h +++ b/frameworks/core/components_ng/pattern/scrollable/scrollable.h @@ -84,6 +84,10 @@ using RemainVelocityCallback = std::function; using GetSnapTypeCallback = std::function; using FixScrollParamCallback = std::function; using OnWillStopDraggingCallback = std::function; +using OnWillStartDraggingCallback = std::function; +using OnDidStopDraggingCallback = std::function; +using OnWillStartFlingCallback = std::function; +using OnDidStopFlingCallback = std::function; class FrameNode; class PipelineContext; @@ -234,7 +238,7 @@ public: return canStayOverScroll_; } - void ProcessScrollMotionStop(); + void ProcessScrollMotionStop(int32_t source); bool DispatchEvent(const TouchEvent& point) override { @@ -307,6 +311,52 @@ public: onWillStopDraggingCallback_ = onWillStopDraggingCallback; } + const OnWillStartDraggingCallback& GetOnWillStartDraggingCallback() const + { + return onWillStartDraggingCallback_; + } + + void SetOnWillStartDraggingCallback(const OnWillStartDraggingCallback& onWillStartDraggingCallback) + { + onWillStartDraggingCallback_ = onWillStartDraggingCallback; + } + + const OnDidStopDraggingCallback& GetOnDidStopDraggingCallback() const + { + return onDidStopDraggingCallback_; + } + + void SetOnDidStopDraggingCallback(const OnDidStopDraggingCallback& onDidStopDraggingCallback) + { + onDidStopDraggingCallback_ = onDidStopDraggingCallback; + } + + const OnWillStartFlingCallback& GetOnWillStartFlingCallback() const + { + return onWillStartFlingCallback_; + } + + void SetOnWillStartFlingCallback(const OnWillStartFlingCallback& onWillStartFlingCallback) + { + onWillStartFlingCallback_ = onWillStartFlingCallback; + } + + const OnDidStopFlingCallback& GetOnDidStopFlingCallback() const + { + return onDidStopFlingCallback_; + } + + void SetOnDidStopFlingCallback(const OnDidStopFlingCallback& onDidStopFlingCallback) + { + onDidStopFlingCallback_ = onDidStopFlingCallback; + } + + void HandleScrollBarOnDidStopDragging(bool isWillFling); + + void HandleScrollBarOnWillStartFling(); + + void HandleScrollBarOnDidStopFling(); + void SetWatchFixCallback(const WatchFixCallback& watchFixCallback) { watchFixCallback_ = watchFixCallback; @@ -417,7 +467,7 @@ public: { handleExtScrollCallback_ = std::move(func); } - void StartScrollAnimation(float mainPosition, float velocity, bool isScrollFromTouchPad = false); + bool StartScrollAnimation(float mainPosition, float velocity, bool isScrollFromTouchPad = false); void SetOnScrollStartRec(std::function&& func) { onScrollStartRec_ = std::move(func); @@ -467,7 +517,8 @@ public: needScrollSnapToSideCallback_ = std::move(needScrollSnapToSideCallback); } - void StartScrollSnapAnimation(float scrollSnapDelta, float scrollSnapVelocity, bool fromScrollBar); + void StartScrollSnapAnimation( + float scrollSnapDelta, float scrollSnapVelocity, bool fromScrollBar, int32_t source = SCROLL_FROM_NONE); void StopSnapController() { @@ -511,6 +562,11 @@ public: return isDragging_; } + void SetIsScrollBarDragging(bool isScrollBarDragging) + { + isScrollBarDragging_ = isScrollBarDragging; + } + void SetDragFRCSceneCallback(DragFRCSceneCallback&& dragFRCSceneCallback) { dragFRCSceneCallback_ = std::move(dragFRCSceneCallback); @@ -597,6 +653,11 @@ public: snapDirection_ = SnapDirection::NONE; } + void SetIsUserFling(bool isUserFling) + { + isUserFling_ = isUserFling; + } + /** * @brief Checks if the scroll event is caused by a mouse wheel. */ @@ -656,6 +717,10 @@ private: ContinuousSlidingCallback continuousSlidingCallback_; GetSnapTypeCallback getSnapTypeCallback_; OnWillStopDraggingCallback onWillStopDraggingCallback_; + OnWillStartDraggingCallback onWillStartDraggingCallback_; + OnDidStopDraggingCallback onDidStopDraggingCallback_; + OnWillStartFlingCallback onWillStartFlingCallback_; + OnDidStopFlingCallback onDidStopFlingCallback_; Axis axis_ = Axis::VERTICAL; // used for ng structure. RefPtr panRecognizerNG_; @@ -669,11 +734,16 @@ private: bool moved_ = false; bool isTouching_ = false; bool isDragging_ = false; + bool isScrollBarDragging_ = false; bool available_ = true; bool needCenterFix_ = false; bool isDragUpdateStop_ = false; bool isFadingAway_ = false; bool isCrownDragging_ = false; + bool isWillFling_ = false; + bool isNeedFireDidStopFling_ = false; + bool isTouchStopAnimation_ = false; + bool isUserFling_ = false; // The accessibilityId of UINode int32_t nodeId_ = 0; // The tag of UINode diff --git a/frameworks/core/components_ng/pattern/scrollable/scrollable_event_hub.h b/frameworks/core/components_ng/pattern/scrollable/scrollable_event_hub.h index 4971e239da0..30595002eaa 100644 --- a/frameworks/core/components_ng/pattern/scrollable/scrollable_event_hub.h +++ b/frameworks/core/components_ng/pattern/scrollable/scrollable_event_hub.h @@ -236,6 +236,45 @@ public: return onJSFrameNodeDidScrollEvent_; } + void SetOnWillStartDragging(OnWillStartDraggingEvent&& event) + { + onWillStartDraggingEvent_ = std::move(event); + } + + const OnWillStartDraggingEvent& GetOnWillStartDragging() const + { + return onWillStartDraggingEvent_; + } + + void SetOnDidStopDragging(OnDidStopDraggingEvent&& event) + { + onDidStopDraggingEvent_ = std::move(event); + } + + const OnDidStopDraggingEvent& GetOnDidStopDragging() const + { + return onDidStopDraggingEvent_; + } + + void SetOnWillStartFling(OnWillStartFlingEvent&& event) + { + onWillStartFlingEvent_ = std::move(event); + } + + const OnWillStartFlingEvent& GetOnWillStartFling() const + { + return onWillStartFlingEvent_; + } + + void SetOnDidStopFling(OnDidStopFlingEvent&& event) + { + onDidStopFlingEvent_ = std::move(event); + } + + const OnDidStopFlingEvent& GetOnDidStopFling() const + { + return onDidStopFlingEvent_; + } private: OnScrollEvent onScrollEvent_; OnWillScrollEvent onWillScrollEvent_; @@ -254,6 +293,11 @@ private: OnScrollFrameBeginEvent onJSFrameNodeScrollFrameBeginEvent_; OnWillScrollEvent onJSFrameNodeWillScrollEvent_; OnScrollEvent onJSFrameNodeDidScrollEvent_; + + OnWillStartDraggingEvent onWillStartDraggingEvent_; + OnDidStopDraggingEvent onDidStopDraggingEvent_; + OnWillStartFlingEvent onWillStartFlingEvent_; + OnDidStopFlingEvent onDidStopFlingEvent_; }; } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SCROLLABLE_SCROLLABLE_EVENT_HUB_H diff --git a/frameworks/core/components_ng/pattern/scrollable/scrollable_model_ng.cpp b/frameworks/core/components_ng/pattern/scrollable/scrollable_model_ng.cpp index bdc442f8336..736c1457f2a 100644 --- a/frameworks/core/components_ng/pattern/scrollable/scrollable_model_ng.cpp +++ b/frameworks/core/components_ng/pattern/scrollable/scrollable_model_ng.cpp @@ -177,6 +177,72 @@ void ScrollableModelNG::SetOnScrollStop(OnScrollStopEvent&& onScrollStop) eventHub->SetOnScrollStop(std::move(onScrollStop)); } +void ScrollableModelNG::SetOnWillStartDragging(OnWillStartDraggingEvent&& event) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnWillStartDragging(std::move(event)); +} + +void ScrollableModelNG::SetOnDidStopDragging(OnDidStopDraggingEvent&& event) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnDidStopDragging(std::move(event)); +} +void ScrollableModelNG::SetOnWillStartFling(OnWillStartFlingEvent&& event) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnWillStartFling(std::move(event)); +} + +void ScrollableModelNG::SetOnDidStopFling(OnDidStopFlingEvent&& event) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnDidStopFling(std::move(event)); +} + +void ScrollableModelNG::SetOnWillStartDragging(FrameNode* frameNode, OnWillStartDraggingEvent&& event) +{ + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnWillStartDragging(std::move(event)); +} + +void ScrollableModelNG::SetOnDidStopDragging(FrameNode* frameNode, OnDidStopDraggingEvent&& event) +{ + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnDidStopDragging(std::move(event)); +} +void ScrollableModelNG::SetOnWillStartFling(FrameNode* frameNode, OnWillStartFlingEvent&& event) +{ + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnWillStartFling(std::move(event)); +} + +void ScrollableModelNG::SetOnDidStopFling(FrameNode* frameNode, OnDidStopFlingEvent&& event) +{ + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnDidStopFling(std::move(event)); +} + void ScrollableModelNG::SetOnScrollStop(FrameNode* frameNode, OnScrollStopEvent&& onScrollStop) { CHECK_NULL_VOID(frameNode); diff --git a/frameworks/core/components_ng/pattern/scrollable/scrollable_model_ng.h b/frameworks/core/components_ng/pattern/scrollable/scrollable_model_ng.h index 5c81e2cd3c1..11896e8f294 100644 --- a/frameworks/core/components_ng/pattern/scrollable/scrollable_model_ng.h +++ b/frameworks/core/components_ng/pattern/scrollable/scrollable_model_ng.h @@ -55,6 +55,10 @@ public: static void SetContentClip(ContentClipMode mode, const RefPtr& rect); static void SetMaxFlingSpeed(double max); static void SetOnWillStopDragging(OnWillStopDraggingEvent&& onWillStopDragging); + static void SetOnWillStartDragging(OnWillStartDraggingEvent&& event) ; + static void SetOnDidStopDragging(OnDidStopDraggingEvent&& event); + static void SetOnWillStartFling(OnWillStartFlingEvent&& event); + static void SetOnDidStopFling(OnDidStopFlingEvent&& event); static void SetEdgeEffect( FrameNode* frameNode, EdgeEffect edgeEffect, bool alwaysEnabled, EffectEdge effectEdge = EffectEdge::ALL); @@ -84,6 +88,10 @@ public: static bool GetFadingEdge(FrameNode* frameNode); static float GetFadingEdgeLength(FrameNode* frameNode); static void SetOnWillStopDragging(FrameNode* frameNode, OnWillStopDraggingEvent&& onWillStopDragging); + static void SetOnWillStartDragging(FrameNode* frameNode, OnWillStartDraggingEvent&& event) ; + static void SetOnDidStopDragging(FrameNode* frameNode, OnDidStopDraggingEvent&& event); + static void SetOnWillStartFling(FrameNode* frameNode, OnWillStartFlingEvent&& event); + static void SetOnDidStopFling(FrameNode* frameNode, OnDidStopFlingEvent&& event); #ifdef SUPPORT_DIGITAL_CROWN static void SetDigitalCrownSensitivity(CrownSensitivity sensitivity); diff --git a/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.cpp b/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.cpp index e1fbdad2f0b..36d1cc1d2c0 100644 --- a/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.cpp +++ b/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.cpp @@ -822,6 +822,61 @@ void ScrollablePattern::SetOnWillStopDraggingCallback(const RefPtr& }); } +void ScrollablePattern::SetOnWillStartDraggingCallback(const RefPtr& scrollable) +{ + CHECK_NULL_VOID(scrollable); + scrollable->SetOnWillStartDraggingCallback([weak = WeakClaim(this)]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + auto eventHub = pattern->GetEventHub(); + CHECK_NULL_VOID(eventHub); + OnWillStartDraggingEvent callback = eventHub->GetOnWillStartDragging(); + CHECK_NULL_VOID(callback); + callback(); + }); +} + +void ScrollablePattern::SetOnDidStopDraggingCallback(const RefPtr& scrollable) +{ + CHECK_NULL_VOID(scrollable); + scrollable->SetOnDidStopDraggingCallback([weak = WeakClaim(this)](bool isAnimate) { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + auto eventHub = pattern->GetEventHub(); + CHECK_NULL_VOID(eventHub); + OnDidStopDraggingEvent callback = eventHub->GetOnDidStopDragging(); + CHECK_NULL_VOID(callback); + callback(isAnimate); + }); +} + +void ScrollablePattern::SetOnWillStartFlingCallback(const RefPtr& scrollable) +{ + CHECK_NULL_VOID(scrollable); + scrollable->SetOnWillStartFlingCallback([weak = WeakClaim(this)]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + auto eventHub = pattern->GetEventHub(); + CHECK_NULL_VOID(eventHub); + OnWillStartFlingEvent callback = eventHub->GetOnWillStartFling(); + CHECK_NULL_VOID(callback); + callback(); + }); +} + +void ScrollablePattern::SetOnDidStopFlingCallback(const RefPtr& scrollable) +{ + CHECK_NULL_VOID(scrollable); + scrollable->SetOnDidStopFlingCallback([weak = WeakClaim(this)]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + auto eventHub = pattern->GetEventHub(); + CHECK_NULL_VOID(eventHub); + OnDidStopFlingEvent callback = eventHub->GetOnDidStopFling(); + CHECK_NULL_VOID(callback); + callback(); + }); +} void ScrollablePattern::SetPanActionEndEvent(const RefPtr& scrollable) { @@ -871,6 +926,10 @@ RefPtr ScrollablePattern::CreateScrollable() SetOnContinuousSliding(scrollable); SetGetSnapTypeCallback(scrollable); SetOnWillStopDraggingCallback(scrollable); + SetOnWillStartDraggingCallback(scrollable); + SetOnDidStopDraggingCallback(scrollable); + SetOnWillStartFlingCallback(scrollable); + SetOnDidStopFlingCallback(scrollable); if (!NearZero(velocityScale_)) { scrollable->SetUnstaticVelocityScale(velocityScale_); } @@ -1091,7 +1150,14 @@ void ScrollablePattern::RegisterScrollBarEventTask() auto pattern = weak.Upgrade(); CHECK_NULL_RETURN(pattern, false); auto scrollable = pattern->GetScrollable(); - if (isMouseWheelScroll && scrollable) { + CHECK_NULL_RETURN(scrollable, pattern->OnScrollCallback(static_cast(offset), source)); + if (source == SCROLL_FROM_START) { + scrollable->SetIsScrollBarDragging(true); + if (scrollable->GetOnWillStartDraggingCallback()) { + scrollable->GetOnWillStartDraggingCallback()(); + } + } + if (isMouseWheelScroll) { scrollable->ProcessAxisUpdateEvent(offset, true); return true; } @@ -1122,6 +1188,31 @@ void ScrollablePattern::RegisterScrollBarEventTask() return pattern->NotifyFRCSceneInfo(SCROLL_BAR_DRAG_SCENE, velocity, sceneStatus); }; scrollBar_->SetDragFRCSceneCallback(std::move(dragFRCSceneCallback)); + + auto scrollBarOnDidStopDraggingCallback = [weak = WeakClaim(this)](bool isWillFling) { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + auto scrollable = pattern->GetScrollable(); + scrollable->SetIsScrollBarDragging(false); + if (scrollable && scrollable->GetOnDidStopDraggingCallback()) { + scrollable->HandleScrollBarOnDidStopDragging(isWillFling); + } + if (isWillFling && scrollable->GetOnWillStartFlingCallback()) { + scrollable->HandleScrollBarOnWillStartFling(); + } + }; + scrollBar_->SetScrollBarOnDidStopDraggingCallback(std::move(scrollBarOnDidStopDraggingCallback)); + + auto scrollBarOnDidStopFlingCallback = [weak = WeakClaim(this)]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + auto scrollable = pattern->GetScrollable(); + if (scrollable && scrollable->GetOnDidStopFlingCallback()) { + scrollable->HandleScrollBarOnDidStopFling(); + } + }; + scrollBar_->SetScrollBarOnDidStopFlingCallback(std::move(scrollBarOnDidStopFlingCallback)); + InitScrollBarGestureEvent(); InitScrollBarMouseEvent(); } @@ -1370,6 +1461,13 @@ void ScrollablePattern::SetScrollBarProxy(const RefPtr& scrollBa } else { pattern->OnScrollStartCallback(); } + auto scrollable = pattern->GetScrollable(); + if (scrollable) { + scrollable->SetIsScrollBarDragging(true); + if (scrollable->GetOnWillStartDraggingCallback()) { + scrollable->GetOnWillStartDraggingCallback()(); + } + } return pattern->OnScrollCallback(static_cast(offset), source); }; auto scrollEndCallback = [weak = WeakClaim(this)](bool nestedScroll) { @@ -1392,9 +1490,30 @@ void ScrollablePattern::SetScrollBarProxy(const RefPtr& scrollBa CHECK_NULL_VOID(pattern); return pattern->ScrollPage(reverse, smooth); }; + auto scrollBarOnDidStopDraggingCallback = [weak = WeakClaim(this)](bool isWillFling) { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + auto scrollable = pattern->GetScrollable(); + scrollable->SetIsScrollBarDragging(false); + if (scrollable && scrollable->GetOnDidStopDraggingCallback()) { + scrollable->HandleScrollBarOnDidStopDragging(isWillFling); + } + if (isWillFling && scrollable->GetOnWillStartFlingCallback()) { + scrollable->HandleScrollBarOnWillStartFling(); + } + }; + auto scrollBarOnDidStopFlingCallback = [weak = WeakClaim(this)]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + auto scrollable = pattern->GetScrollable(); + if (scrollable && scrollable->GetOnDidStopFlingCallback()) { + scrollable->HandleScrollBarOnDidStopFling(); + } + }; ScrollableNodeInfo nodeInfo = { AceType::WeakClaim(this), std::move(scrollFunction), std::move(scrollStartCallback), std::move(scrollEndCallback), std::move(startSnapAnimationCallback), std::move(scrollbarFRcallback), - std::move(scrollPageCallback) }; + std::move(scrollPageCallback), std::move(scrollBarOnDidStopDraggingCallback), + std::move(scrollBarOnDidStopFlingCallback) }; scrollBarProxy->RegisterScrollableNode(nodeInfo); scrollBarProxy_ = scrollBarProxy; } diff --git a/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.h b/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.h index 951c0a27f88..18ec45435cf 100644 --- a/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.h +++ b/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.h @@ -1140,6 +1140,10 @@ private: void SetGetSnapTypeCallback(const RefPtr& scrollable); void SetPanActionEndEvent(const RefPtr& scrollable); void SetOnWillStopDraggingCallback(const RefPtr& scrollable); + void SetOnWillStartDraggingCallback(const RefPtr& scrollable); + void SetOnDidStopDraggingCallback(const RefPtr& scrollable); + void SetOnWillStartFlingCallback(const RefPtr& scrollable); + void SetOnDidStopFlingCallback(const RefPtr& scrollable); RefPtr CreateScrollable(); // Scrollable::UpdateScrollPosition diff --git a/frameworks/core/components_ng/pattern/scrollable/scrollable_properties.h b/frameworks/core/components_ng/pattern/scrollable/scrollable_properties.h index 0ba769aef32..2f6ac4ec404 100644 --- a/frameworks/core/components_ng/pattern/scrollable/scrollable_properties.h +++ b/frameworks/core/components_ng/pattern/scrollable/scrollable_properties.h @@ -216,6 +216,7 @@ constexpr int32_t SCROLL_FROM_ANIMATION_CONTROLLER = 12; constexpr int32_t SCROLL_FROM_BAR_FLING = 13; constexpr int32_t SCROLL_FROM_CROWN = 14; constexpr int32_t SCROLL_FROM_STATUSBAR = 15; +constexpr int32_t SCROLL_FROM_LAYOUT = 16; inline std::string GetSourceStr(int32_t scrollSource) { @@ -459,6 +460,7 @@ struct SnapAnimationOptions { float animationVelocity = 0.f; float dragDistance = 0.f; SnapDirection snapDirection = SnapDirection::NONE; + int32_t source = SCROLL_FROM_NONE; bool fromScrollBar = false; }; @@ -494,6 +496,11 @@ using OnWillScrollEventEx = std::function; +using OnWillStartDraggingEvent = std::function; +using OnDidStopDraggingEvent = std::function; +using OnWillStartFlingEvent = std::function; +using OnDidStopFlingEvent = std::function; + struct ScrollerObserver { RefPtr onTouchEvent; GestureEventFunc onPanActionEndEvent; diff --git a/frameworks/core/interfaces/arkoala/arkoala_api.h b/frameworks/core/interfaces/arkoala/arkoala_api.h index 5bf5726dd7c..69ea5fbaa06 100644 --- a/frameworks/core/interfaces/arkoala/arkoala_api.h +++ b/frameworks/core/interfaces/arkoala/arkoala_api.h @@ -1271,6 +1271,10 @@ enum ArkUIEventSubKind { ON_SCROLL_DID_ZOOM, ON_SCROLL_ZOOM_START, ON_SCROLL_ZOOM_STOP, + ON_SCROLL_WILL_START_DRAGGING, + ON_SCROLL_DID_STOP_DRAGGING, + ON_SCROLL_WILL_START_FLING, + ON_SCROLL_DID_STOP_FLING, ON_TABS_CHANGE = ARKUI_MAX_EVENT_NUM * ARKUI_TABS, ON_NAVIGATOR_CLICK = ARKUI_MAX_EVENT_NUM * ARKUI_NAVIGATOR, @@ -3967,6 +3971,14 @@ struct ArkUIScrollableModifier { void (*getScrollBarMargin)(ArkUINodeHandle node, ArkUIInt32orFloat32 (*values)[2]); void (*setOnWillStopDragging)(ArkUINodeHandle node, void* callback); void (*resetOnWillStopDragging)(ArkUINodeHandle node); + void (*setOnWillStartDragging)(ArkUINodeHandle node, void* callback); + void (*resetOnWillStartDragging)(ArkUINodeHandle node); + void (*setOnDidStopDragging)(ArkUINodeHandle node, void* callback); + void (*resetOnDidStopDragging)(ArkUINodeHandle node); + void (*setOnWillStartFling)(ArkUINodeHandle node, void* callback); + void (*resetOnWillStartFling)(ArkUINodeHandle node); + void (*setOnDidStopFling)(ArkUINodeHandle node, void* callback); + void (*resetOnDidStopFling)(ArkUINodeHandle node); }; struct ArkUIScrollModifier { diff --git a/frameworks/core/interfaces/native/node/node_api.cpp b/frameworks/core/interfaces/native/node/node_api.cpp index 6ffbf15a3cc..04d4df408c7 100644 --- a/frameworks/core/interfaces/native/node/node_api.cpp +++ b/frameworks/core/interfaces/native/node/node_api.cpp @@ -465,6 +465,10 @@ const ComponentAsyncEventHandler scrollNodeAsyncEventHandlers[] = { NodeModifier::SetOnDidZoom, NodeModifier::SetOnZoomStart, NodeModifier::SetOnZoomStop, + NodeModifier::SetOnWillStartDragging, + NodeModifier::SetOnDidStopDragging, + NodeModifier::SetOnWillStartFling, + NodeModifier::SetOnDidStopFling, }; const ComponentAsyncEventHandler TEXT_NODE_ASYNC_EVENT_HANDLERS[] = { @@ -693,6 +697,10 @@ const ResetComponentAsyncEventHandler SCROLL_NODE_RESET_ASYNC_EVENT_HANDLERS[] = NodeModifier::ResetOnDidZoom, NodeModifier::ResetOnZoomStart, NodeModifier::ResetOnZoomStop, + NodeModifier::ResetOnWillStartDragging, + NodeModifier::ResetOnDidStopDragging, + NodeModifier::ResetOnWillStartFling, + NodeModifier::ResetOnDidStopFling, }; const ResetComponentAsyncEventHandler TEXT_NODE_RESET_ASYNC_EVENT_HANDLERS[] = { diff --git a/frameworks/core/interfaces/native/node/node_scroll_modifier.cpp b/frameworks/core/interfaces/native/node/node_scroll_modifier.cpp index 54edd44b78d..3787ebca0d6 100644 --- a/frameworks/core/interfaces/native/node/node_scroll_modifier.cpp +++ b/frameworks/core/interfaces/native/node/node_scroll_modifier.cpp @@ -1378,5 +1378,90 @@ void ResetOnWillStopDragging(ArkUINodeHandle node) CHECK_NULL_VOID(frameNode); ScrollableModelNG::SetOnWillStopDragging(frameNode, nullptr); } + +void SetOnWillStartDragging(ArkUINodeHandle node, void* extraParam) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + auto onWillStartDragging = [extraParam]() -> void { + ArkUINodeEvent event; + event.kind = COMPONENT_ASYNC_EVENT; + event.extraParam = reinterpret_cast(extraParam); + event.componentAsyncEvent.subKind = ON_SCROLL_WILL_START_DRAGGING; + SendArkUISyncEvent(&event); + }; + ScrollableModelNG::SetOnWillStartDragging(frameNode, std::move(onWillStartDragging)); +} + +void ResetOnWillStartDragging(ArkUINodeHandle node) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + ScrollableModelNG::SetOnWillStartDragging(frameNode, nullptr); +} + +void SetOnDidStopDragging(ArkUINodeHandle node, void* extraParam) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + auto onDidStopDragging = [extraParam](bool isWillFling) -> void { + ArkUINodeEvent event; + event.kind = COMPONENT_ASYNC_EVENT; + event.extraParam = reinterpret_cast(extraParam); + event.componentAsyncEvent.subKind = ON_SCROLL_DID_STOP_DRAGGING; + event.componentAsyncEvent.data[0].i32 = isWillFling; + SendArkUISyncEvent(&event); + }; + ScrollableModelNG::SetOnDidStopDragging(frameNode, std::move(onDidStopDragging)); +} + +void ResetOnDidStopDragging(ArkUINodeHandle node) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + ScrollableModelNG::SetOnDidStopDragging(frameNode, nullptr); +} + +void SetOnWillStartFling(ArkUINodeHandle node, void* extraParam) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + auto onWillStartFling = [extraParam]() -> void { + ArkUINodeEvent event; + event.kind = COMPONENT_ASYNC_EVENT; + event.extraParam = reinterpret_cast(extraParam); + event.componentAsyncEvent.subKind = ON_SCROLL_WILL_START_FLING; + SendArkUISyncEvent(&event); + }; + ScrollableModelNG::SetOnWillStartFling(frameNode, std::move(onWillStartFling)); +} + +void ResetOnWillStartFling(ArkUINodeHandle node) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + ScrollableModelNG::SetOnWillStartFling(frameNode, nullptr); +} + +void SetOnDidStopFling(ArkUINodeHandle node, void* extraParam) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + auto onDidStopFling = [extraParam]() -> void { + ArkUINodeEvent event; + event.kind = COMPONENT_ASYNC_EVENT; + event.extraParam = reinterpret_cast(extraParam); + event.componentAsyncEvent.subKind = ON_SCROLL_DID_STOP_FLING; + SendArkUISyncEvent(&event); + }; + ScrollableModelNG::SetOnDidStopFling(frameNode, std::move(onDidStopFling)); +} + +void ResetOnDidStopFling(ArkUINodeHandle node) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + ScrollableModelNG::SetOnDidStopFling(frameNode, nullptr); +} } // namespace NodeModifier } // namespace OHOS::Ace::NG diff --git a/frameworks/core/interfaces/native/node/node_scroll_modifier.h b/frameworks/core/interfaces/native/node/node_scroll_modifier.h index 10039ea42f6..b123d75d1a1 100644 --- a/frameworks/core/interfaces/native/node/node_scroll_modifier.h +++ b/frameworks/core/interfaces/native/node/node_scroll_modifier.h @@ -65,5 +65,13 @@ void SetScrollOnWillScrollCallBack(ArkUINodeHandle node, void* extraParam); void ResetScrollOnWillScrollCallBack(ArkUINodeHandle node); void SetOnWillStopDragging(ArkUINodeHandle node, void* extraParam); void ResetOnWillStopDragging(ArkUINodeHandle node); +void SetOnWillStartDragging(ArkUINodeHandle node, void* extraParam); +void ResetOnWillStartDragging(ArkUINodeHandle node); +void SetOnDidStopDragging(ArkUINodeHandle node, void* extraParam); +void ResetOnDidStopDragging(ArkUINodeHandle node); +void SetOnWillStartFling(ArkUINodeHandle node, void* extraParam); +void ResetOnWillStartFling(ArkUINodeHandle node); +void SetOnDidStopFling(ArkUINodeHandle node, void* extraParam); +void ResetOnDidStopFling(ArkUINodeHandle node); } // namespace OHOS::Ace::NG::NodeModifier #endif // FRAMEWORKS_CORE_INTERFACES_NATIVE_NODE_NODE_SCROLL_MODIFIER_H diff --git a/frameworks/core/interfaces/native/node/scrollable_modifier.cpp b/frameworks/core/interfaces/native/node/scrollable_modifier.cpp index 3bf67883c68..88f657cc0ad 100644 --- a/frameworks/core/interfaces/native/node/scrollable_modifier.cpp +++ b/frameworks/core/interfaces/native/node/scrollable_modifier.cpp @@ -315,6 +315,82 @@ void ResetOnWillStopDragging(ArkUINodeHandle node) CHECK_NULL_VOID(frameNode); ScrollableModelNG::SetOnWillStopDragging(frameNode, nullptr); } + +void SetOnWillStartDragging(ArkUINodeHandle node, void* extraParam) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + if (extraParam) { + auto onWillStartDragging = reinterpret_cast(extraParam); + ScrollableModelNG::SetOnWillStartDragging(frameNode, std::move(*onWillStartDragging)); + } else { + ScrollableModelNG::SetOnWillStartDragging(frameNode, nullptr); + } +} + +void ResetOnWillStartDragging(ArkUINodeHandle node) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + ScrollableModelNG::SetOnWillStartDragging(frameNode, nullptr); +} + +void SetOnDidStopDragging(ArkUINodeHandle node, void* extraParam) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + if (extraParam) { + auto onDidStopDragging = reinterpret_cast(extraParam); + ScrollableModelNG::SetOnDidStopDragging(frameNode, std::move(*onDidStopDragging)); + } else { + ScrollableModelNG::SetOnDidStopDragging(frameNode, nullptr); + } +} + +void ResetOnDidStopDragging(ArkUINodeHandle node) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + ScrollableModelNG::SetOnDidStopDragging(frameNode, nullptr); +} + +void SetOnWillStartFling(ArkUINodeHandle node, void* extraParam) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + if (extraParam) { + auto onWillStartFling = reinterpret_cast(extraParam); + ScrollableModelNG::SetOnWillStartFling(frameNode, std::move(*onWillStartFling)); + } else { + ScrollableModelNG::SetOnWillStartFling(frameNode, nullptr); + } +} + +void ResetOnWillStartFling(ArkUINodeHandle node) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + ScrollableModelNG::SetOnWillStartFling(frameNode, nullptr); +} + +void SetOnDidStopFling(ArkUINodeHandle node, void* extraParam) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + if (extraParam) { + auto onDidStopFling = reinterpret_cast(extraParam); + ScrollableModelNG::SetOnDidStopFling(frameNode, std::move(*onDidStopFling)); + } else { + ScrollableModelNG::SetOnDidStopFling(frameNode, nullptr); + } +} + +void ResetOnDidStopFling(ArkUINodeHandle node) +{ + auto* frameNode = reinterpret_cast(node); + CHECK_NULL_VOID(frameNode); + ScrollableModelNG::SetOnDidStopFling(frameNode, nullptr); +} } // namespace namespace NodeModifier { @@ -356,6 +432,14 @@ const ArkUIScrollableModifier* GetScrollableModifier() .resetOnScrollStopCallBack = ResetOnScrollStopCallBack, .setOnWillStopDragging = SetOnWillStopDragging, .resetOnWillStopDragging = ResetOnWillStopDragging, + .setOnWillStartDragging = SetOnWillStartDragging, + .resetOnWillStartDragging = ResetOnWillStartDragging, + .setOnDidStopDragging = SetOnDidStopDragging, + .resetOnDidStopDragging = ResetOnDidStopDragging, + .setOnWillStartFling = SetOnWillStartFling, + .resetOnWillStartFling = ResetOnWillStartFling, + .setOnDidStopFling = SetOnDidStopFling, + .resetOnDidStopFling = ResetOnDidStopFling, }; CHECK_INITIALIZED_FIELDS_END(modifier, 0, 0, 0); // don't move this line return &modifier; diff --git a/test/unittest/core/pattern/grid/grid_scroller_event_test_ng.cpp b/test/unittest/core/pattern/grid/grid_scroller_event_test_ng.cpp index 24b0433bd88..162aa5ac3cf 100644 --- a/test/unittest/core/pattern/grid/grid_scroller_event_test_ng.cpp +++ b/test/unittest/core/pattern/grid/grid_scroller_event_test_ng.cpp @@ -2055,4 +2055,39 @@ HWTEST_F(GridScrollerEventTestNg, HandleOnWillStopDragging002, TestSize.Level1) EXPECT_TRUE(isOnWillStopDraggingCallBack); EXPECT_FLOAT_EQ(willStopDraggingVelocity.Value(), info.GetMainVelocity()); } + +/** + * @tc.name: HandleOnWillStartDragging001 + * @tc.desc: Test OnWillStartDragging001 + * @tc.type: FUNC + */ +HWTEST_F(GridScrollerEventTestNg, OnWillStartDragging001, TestSize.Level1) +{ + bool isOnWillStartDraggingCallBack = false; + auto onWillStartDragging = [&isOnWillStartDraggingCallBack]() { + isOnWillStartDraggingCallBack = true; + }; + + GridModelNG model = CreateGrid(); + model.SetColumnsTemplate("1fr 1fr"); + model.SetEdgeEffect(EdgeEffect::SPRING, false); + CreateFixedItems(20); + CreateDone(); + eventHub_->SetOnWillStartDragging(onWillStartDragging); + + GestureEvent info; + info.SetMainVelocity(-1200.f); + info.SetMainDelta(-200.f); + auto scrollable = pattern_->GetScrollableEvent()->GetScrollable(); + scrollable->HandleTouchDown(); + scrollable->HandleDragStart(info); + scrollable->HandleDragUpdate(info); + FlushUITasks(); + + scrollable->HandleTouchUp(); + scrollable->HandleDragEnd(info); + FlushUITasks(); + + EXPECT_TRUE(isOnWillStartDraggingCallBack); +} } // namespace OHOS::Ace::NG diff --git a/test/unittest/core/pattern/scrollable/scrollable_cover_test_ng.cpp b/test/unittest/core/pattern/scrollable/scrollable_cover_test_ng.cpp index b1d2c4775a1..cada6ae22e6 100644 --- a/test/unittest/core/pattern/scrollable/scrollable_cover_test_ng.cpp +++ b/test/unittest/core/pattern/scrollable/scrollable_cover_test_ng.cpp @@ -704,7 +704,7 @@ HWTEST_F(ScrollableCoverTestNg, ProcessScrollMotionStopTest001, TestSize.Level1) * @tc.steps: step2. Call ProcessScrollMotionStop * @tc.expected: Verify that the scroll snap change is processed correctly */ - scrollable->ProcessScrollMotionStop(); + scrollable->ProcessScrollMotionStop(0); EXPECT_EQ(scrollable->currentVelocity_, 0.0); EXPECT_FALSE(isOverScrollCallbackCalled); @@ -714,7 +714,7 @@ HWTEST_F(ScrollableCoverTestNg, ProcessScrollMotionStopTest001, TestSize.Level1) */ scrollable->scrollPause_ = true; scrollable->edgeEffect_ = EdgeEffect::SPRING; - scrollable->ProcessScrollMotionStop(); + scrollable->ProcessScrollMotionStop(0); EXPECT_FALSE(scrollable->scrollPause_); /** @@ -728,7 +728,7 @@ HWTEST_F(ScrollableCoverTestNg, ProcessScrollMotionStopTest001, TestSize.Level1) return 0.0f; }; scrollable->scrollPause_ = true; - scrollable->ProcessScrollMotionStop(); + scrollable->ProcessScrollMotionStop(0); EXPECT_TRUE(isOverScrollCallbackCalled); } -- Gitee