• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/scrollable/scrollable_controller.h"
17 
18 #include "base/memory/referenced.h"
19 #include "base/utils/multi_thread.h"
20 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
21 #include "core/components_ng/pattern/waterflow/water_flow_pattern.h"
22 
23 namespace OHOS::Ace::NG {
24 
AnimateToMultiThread(const Dimension & position,float duration,const RefPtr<Curve> & curve,bool smooth,bool canOverScroll)25 bool ScrollableController::AnimateToMultiThread(
26     const Dimension& position, float duration, const RefPtr<Curve>& curve, bool smooth, bool canOverScroll)
27 {
28     auto pattern = scroll_.Upgrade();
29     CHECK_NULL_RETURN(pattern, false);
30     auto host = pattern->GetHost();
31     CHECK_NULL_RETURN(host, false);
32     if (pattern->GetAxis() != Axis::NONE) {
33         if (position.Unit() == DimensionUnit::PERCENT) {
34             return false;
35         }
36         if (Positive(duration) || smooth) {
37             host->PostAfterAttachMainTreeTask([weak = AceType::WeakClaim(AceType::RawPtr(pattern)),
38                                                   weakPtr = AceType::WeakClaim(AceType::RawPtr(host)), position,
39                                                   duration, curve, smooth, canOverScroll]() {
40                 auto host = weakPtr.Upgrade();
41                 CHECK_NULL_VOID(host);
42                 auto pattern = weak.Upgrade();
43                 CHECK_NULL_VOID(pattern);
44                 ACE_SCOPED_TRACE(
45                     "ScrollTo with animation, position:%f, duration:%f, smooth:%u, canOverScroll:%u, id:%d, tag:%s",
46                     position.ConvertToPx(), duration, smooth, canOverScroll,
47                     static_cast<int32_t>(host->GetAccessibilityId()), host->GetTag().c_str());
48                 pattern->AnimateTo(position.ConvertToPx(), duration, curve, smooth, canOverScroll);
49             });
50         } else {
51             host->PostAfterAttachMainTreeTask([weak = AceType::WeakClaim(AceType::RawPtr(pattern)),
52                                                   weakPtr = AceType::WeakClaim(AceType::RawPtr(host)), position]() {
53                 auto host = weakPtr.Upgrade();
54                 CHECK_NULL_VOID(host);
55                 auto pattern = weak.Upgrade();
56                 CHECK_NULL_VOID(pattern);
57                 ACE_SCOPED_TRACE("ScrollTo without animation, position:%f, id:%d, tag:%s", position.ConvertToPx(),
58                     static_cast<int32_t>(host->GetAccessibilityId()), host->GetTag().c_str());
59 
60                 pattern->ScrollTo(position.ConvertToPx());
61             });
62         }
63         return true;
64     }
65     return false;
66 }
67 
ScrollToEdgeMultiThread(ScrollEdgeType scrollEdgeType,bool smooth)68 void ScrollableController::ScrollToEdgeMultiThread(ScrollEdgeType scrollEdgeType, bool smooth)
69 {
70     auto pattern = scroll_.Upgrade();
71     CHECK_NULL_VOID(pattern);
72     if (pattern->GetAxis() == Axis::FREE && pattern->FreeScrollToEdge(scrollEdgeType, smooth, std::nullopt)) {
73         return;
74     }
75     auto host = pattern->GetHost();
76     CHECK_NULL_VOID(host);
77     host->PostAfterAttachMainTreeTask([weak = AceType::WeakClaim(AceType::RawPtr(pattern)), scrollEdgeType, smooth]() {
78         auto pattern = weak.Upgrade();
79         CHECK_NULL_VOID(pattern);
80         if (pattern->GetAxis() != Axis::NONE) {
81             pattern->ScrollToEdge(scrollEdgeType, smooth);
82         }
83     });
84 }
85 
ScrollByMultiThread(double pixelX,double pixelY,bool)86 void ScrollableController::ScrollByMultiThread(double pixelX, double pixelY, bool /* smooth */)
87 {
88     auto pattern = scroll_.Upgrade();
89     CHECK_NULL_VOID(pattern);
90     if (pattern->GetAxis() == Axis::FREE && pattern->FreeScrollBy(OffsetF { -pixelX, -pixelY })) {
91         return;
92     }
93     auto host = pattern->GetHost();
94     CHECK_NULL_VOID(host);
95     host->PostAfterAttachMainTreeTask([weak = AceType::WeakClaim(AceType::RawPtr(pattern)),
96                                           weakNode = AceType::WeakClaim(AceType::RawPtr(host)), pixelX, pixelY]() {
97         auto pattern = weak.Upgrade();
98         CHECK_NULL_VOID(pattern);
99         auto host = weakNode.Upgrade();
100         CHECK_NULL_VOID(host);
101         pattern->StopAnimate();
102         auto offset = pattern->GetAxis() == Axis::VERTICAL ? pixelY : pixelX;
103         ACE_SCOPED_TRACE("ScrollBy, offset:%f, id:%d, tag:%s", static_cast<float>(-offset),
104             static_cast<int32_t>(host->GetAccessibilityId()), host->GetTag().c_str());
105         if (pattern->GetAxis() == Axis::FREE && pattern->FreeScrollBy(OffsetF { -pixelX, -pixelY })) {
106             return;
107         }
108         pattern->SetIsOverScroll(false);
109         pattern->UpdateCurrentOffset(static_cast<float>(-offset), SCROLL_FROM_JUMP);
110     });
111 }
112 
FlingMultiThread(double flingVelocity)113 void ScrollableController::FlingMultiThread(double flingVelocity)
114 {
115     auto pattern = scroll_.Upgrade();
116     CHECK_NULL_VOID(pattern);
117     auto host = pattern->GetHost();
118     CHECK_NULL_VOID(host);
119     host->PostAfterAttachMainTreeTask([weak = AceType::WeakClaim(AceType::RawPtr(pattern)),
120                                           weakNode = AceType::WeakClaim(AceType::RawPtr(host)), flingVelocity]() {
121         auto pattern = weak.Upgrade();
122         CHECK_NULL_VOID(pattern);
123         auto host = weakNode.Upgrade();
124         CHECK_NULL_VOID(host);
125         ACE_SCOPED_TRACE("Fling, flingVelocity:%f, id:%d, tag:%s", static_cast<float>(flingVelocity),
126             static_cast<int32_t>(host->GetAccessibilityId()), host->GetTag().c_str());
127         pattern->Fling(flingVelocity);
128     });
129 }
130 
131 } // namespace OHOS::Ace::NG
132