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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLLABLE_NESTABLE_SCROLL_CONTAINER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLLABLE_NESTABLE_SCROLL_CONTAINER_H
18 
19 #include "base/memory/ace_type.h"
20 #include "base/utils/noncopyable.h"
21 #include "core/components_ng/pattern/pattern.h"
22 #include "core/components_ng/pattern/scrollable/scrollable.h"
23 
24 namespace OHOS::Ace::NG {
25 class NestableScrollContainer : public virtual Pattern {
26     DECLARE_ACE_TYPE(NestableScrollContainer, Pattern)
27 public:
28     NestableScrollContainer() = default;
29     ~NestableScrollContainer() override = default;
30 
31     virtual Axis GetAxis() const = 0;
32 
33     /**
34      * @brief Handle regular scroll motion.
35      *
36      * @param offset delta on the main axis.
37      * @param source scroll source type defined in scrollable_properties.h.
38      * @param state current nested state. Defines how this function is triggered.
39      * @param velocity current velocity on the main axis.
40      * @return remaining offset and whether the edge is reached
41      */
42     virtual ScrollResult HandleScroll(
43         float offset, int32_t source, NestedState state = NestedState::GESTURE, float velocity = 0.f) = 0;
44 
45     /**
46      * @brief Handle drag end velocity, triggering a scroll animation or a bounce animation on overScroll.
47      *
48      * @param velocity drag end velocity.
49      * @param child components that call HandleScrollVelocity.
50      * @return true if velocity is consumed
51      */
52     virtual bool HandleScrollVelocity(float velocity, const RefPtr<NestableScrollContainer>& child = nullptr) = 0;
53 
54     /**
55      * @brief Called when the scroll starts, recursively pass upwards.
56      *
57      * @param child components that call OnScrollStartRecursive.
58      * @param position The global position of the first touch point.
59      * @param velocity current velocity on the main axis.
60      */
61     virtual void OnScrollStartRecursive(
62         WeakPtr<NestableScrollContainer> child, float position, float velocity = 0.f) = 0;
63 
64     /**
65      * @brief This function is called when the scrolling ends, recursively pass upwards.
66      *
67      * @param velocity The velocity of the DragEnd event. Optionally passed to parent when the child won't call
68      * HandleScrollVelocity.
69      */
70     virtual void OnScrollEndRecursive(const std::optional<float>& velocity) = 0;
71 
72     /**
73      * @brief Determine if a component is in an out-of-bounds state.
74      */
NestedScrollOutOfBoundary()75     virtual bool NestedScrollOutOfBoundary()
76     {
77         return false;
78     }
79 
80     void UpdateNestedModeForChildren(const NestedScrollOptions& childNestedScroll);
81 
82     void SetNestedScroll(const NestedScrollOptions& nestedScroll, bool isFixedNestedScrollMode = false);
83 
GetNestedScroll()84     const NestedScrollOptions GetNestedScroll() const
85     {
86         return nestedScroll_;
87     }
88 
89     void SetParentScrollable();
90 
GetNestedScrollParent()91     RefPtr<NestableScrollContainer> GetNestedScrollParent()
92     {
93         return parent_.Upgrade();
94     }
95 
96     /**
97      * @brief Passes the velocity of the current component to the child component for processing.
98      *
99      * @param remainVelocity the velocity of the current component.
100      */
RemainVelocityToChild(float remainVelocity)101     virtual void RemainVelocityToChild(float remainVelocity) {}
102 
103     virtual void OnScrollDragEndRecursive();
104 
StopScrollAnimation()105     virtual void StopScrollAnimation() {};
106 
107 protected:
108     /**
109      * @brief Helper function. Searches for the parent NestableScrollContainer of the current instance.
110      *
111      * @return RefPtr<NestableScrollContainer> A reference to the parent NestableScrollContainer.
112      */
113     virtual RefPtr<NestableScrollContainer> SearchParent();
114 
GetNestedModeForChildren()115     const std::unique_ptr<NestedScrollOptions>& GetNestedModeForChildren() const
116     {
117         return childNestedScroll_;
118     }
119 
SetIsFixedNestedScrollMode(bool isFixedNestedScrollMode)120     void SetIsFixedNestedScrollMode(bool isFixedNestedScrollMode)
121     {
122         isFixedNestedScrollMode_ = isFixedNestedScrollMode;
123     }
124 
GetIsFixedNestedScrollMode()125     bool GetIsFixedNestedScrollMode() const
126     {
127         return isFixedNestedScrollMode_;
128     }
129 
SetNestedScrollParent(RefPtr<NestableScrollContainer> parent)130     void SetNestedScrollParent(RefPtr<NestableScrollContainer> parent)
131     {
132         parent_ = parent;
133     }
134 
SetIsSearchRefresh(bool isSearchRefresh)135     void SetIsSearchRefresh(bool isSearchRefresh)
136     {
137         isSearchRefresh_ = isSearchRefresh;
138     }
139 
GetIsSearchRefresh()140     bool GetIsSearchRefresh() const
141     {
142         return isSearchRefresh_;
143     }
144 
SetIsNestedInterrupt(bool isNestedInterrupt)145     void SetIsNestedInterrupt(bool isNestedInterrupt)
146     {
147         isNestedInterrupt_ = isNestedInterrupt;
148     }
149 
GetIsNestedInterrupt()150     bool GetIsNestedInterrupt() const
151     {
152         return isNestedInterrupt_;
153     }
154 
155 private:
156     std::unique_ptr<NestedScrollOptions> childNestedScroll_;
157     WeakPtr<NestableScrollContainer> parent_;
158 
159     NestedScrollOptions nestedScroll_ = {
160         .forward = NestedScrollMode::SELF_ONLY,
161         .backward = NestedScrollMode::SELF_ONLY,
162     };
163 
164     bool isFixedNestedScrollMode_ = false;
165     bool isSearchRefresh_ = true;
166     bool isNestedInterrupt_ = false; // nested scroll interrupted by change of nested mode
167     ACE_DISALLOW_COPY_AND_MOVE(NestableScrollContainer);
168 };
169 } // namespace OHOS::Ace::NG
170 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLLABLE_NESTABLE_SCROLL_CONTAINER_H
171