1 /*
2  * Copyright (c) 2023-2024 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/nestable_scroll_container.h"
17 
18 #include "core/common/container.h"
19 #include "core/components_ng/pattern/refresh/refresh_pattern.h"
20 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
21 
22 namespace OHOS::Ace::NG {
SearchParent()23 RefPtr<NestableScrollContainer> NestableScrollContainer::SearchParent()
24 {
25     auto host = GetHost();
26     CHECK_NULL_RETURN(host, nullptr);
27     for (auto parent = host->GetParent(); parent != nullptr; parent = parent->GetParent()) {
28         RefPtr<FrameNode> frameNode = AceType::DynamicCast<FrameNode>(parent);
29         if (!frameNode) {
30             continue;
31         }
32         auto pattern = frameNode->GetPattern<NestableScrollContainer>();
33         if (!pattern) {
34             continue;
35         }
36         if ((!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) ||
37                 !isSearchRefresh_) &&
38             InstanceOf<RefreshPattern>(pattern)) {
39             continue;
40         }
41         if (pattern->GetAxis() != GetAxis()) {
42             continue;
43         }
44         return pattern;
45     }
46     return nullptr;
47 }
48 
UpdateNestedModeForChildren(const NestedScrollOptions & childNestedScroll)49 void NestableScrollContainer::UpdateNestedModeForChildren(const NestedScrollOptions& childNestedScroll)
50 {
51     if (!childNestedScroll_) {
52         childNestedScroll_ = std::make_unique<NestedScrollOptions>();
53     }
54     if (*childNestedScroll_ != childNestedScroll) {
55         *childNestedScroll_ = childNestedScroll;
56     }
57 }
58 
SetNestedScroll(const NestedScrollOptions & nestedScroll,bool isFixedNestedScrollMode)59 void NestableScrollContainer::SetNestedScroll(const NestedScrollOptions& nestedScroll, bool isFixedNestedScrollMode)
60 {
61     if (isFixedNestedScrollMode_ && !nestedScroll.NeedParent()) {
62         return;
63     }
64     if (!isFixedNestedScrollMode && AceType::InstanceOf<ScrollablePattern>(this)) {
65         if (nestedScroll.NeedParent()) {
66             isSearchRefresh_ = false;
67         } else {
68             isSearchRefresh_ = true;
69         }
70     }
71     SetIsFixedNestedScrollMode(isFixedNestedScrollMode);
72     auto parent = parent_.Upgrade();
73     if (parent && !nestedScroll.NeedParent() && nestedScroll_.NeedParent()) {
74         isNestedInterrupt_ = true;
75     }
76     nestedScroll_ = nestedScroll;
77 }
78 
SetParentScrollable()79 void NestableScrollContainer::SetParentScrollable()
80 {
81     parent_ = SearchParent();
82     auto parent = parent_.Upgrade();
83     CHECK_NULL_VOID(parent);
84     if (!isFixedNestedScrollMode_) {
85         auto && childNestedMode = parent->GetNestedModeForChildren();
86         auto selfNestedScrollMode = nestedScroll_;
87         if (childNestedMode) {
88             SetNestedScroll(*childNestedMode, true);
89         }
90         if (AceType::InstanceOf<RefreshPattern>(parent)) {
91             parent->SetNestedScroll(selfNestedScrollMode);
92         }
93     }
94 }
95 
OnScrollDragEndRecursive()96 void NestableScrollContainer::OnScrollDragEndRecursive()
97 {
98     auto parent = parent_.Upgrade();
99     if (parent && nestedScroll_.NeedParent()) {
100         parent->OnScrollDragEndRecursive();
101     }
102 }
103 } // namespace OHOS::Ace::NG
104