1 /*
2  * Copyright (c) 2021-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_SCROLL_RENDER_MULTI_CHILD_SCROLL_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_RENDER_MULTI_CHILD_SCROLL_H
18 
19 #include "core/common/vibrator/vibrator.h"
20 #include "core/components/common/rotation/rotation_node.h"
21 #include "core/components/list/list_component.h"
22 #include "core/components/list/render_list.h"
23 #include "core/components/scroll/render_scroll.h"
24 
25 namespace OHOS::Ace {
26 
27 class RenderMultiChildScroll : public RenderScroll, public RotationNode {
28     DECLARE_ACE_TYPE(RenderMultiChildScroll, RenderScroll, RotationNode);
29 
30 public:
31     static RefPtr<RenderNode> Create();
32 
33     void AddChild(const RefPtr<RenderList>& child);
34 
35     void JumpToIndex(int32_t index) override;
36 
37     void JumpToPosition(double position, int32_t source = SCROLL_FROM_JUMP) override;
38 
39     // notify start position in global main axis
40     void NotifyDragStart(double startPosition) override;
41 
42     // notify drag offset in global main axis
43     void NotifyDragUpdate(double dragOffset, int32_t source) override;
44 
45     void ProcessScrollOverCallback(double velocity) override;
46 
47     void MoveItemToViewPort(double position, double size, double effectOffset = 0.0);
48 
49     void ScrollToEdge(ScrollEdgeType scrollEdgeType, bool smooth) override;
50 
51     bool ScrollPage(bool reverse, bool smooth, const std::function<void()>& onFinish = nullptr) override;
52 
53     void HandleRotate(double rotateValue, bool isVertical) override;
54 
SetCacheExtent(double cacheExtent)55     void SetCacheExtent(double cacheExtent)
56     {
57         cacheExtent_ = cacheExtent;
58     }
59 
RefreshOffset(double offset)60     void RefreshOffset(double offset)
61     {
62         (axis_ == Axis::HORIZONTAL) ? currentOffset_.SetX(offset) : currentOffset_.SetY(offset);
63     }
64 
65     bool CalculateMainScrollExtent();
66 
67     bool OnRotation(const RotationEvent& event) override;
68 
OnAttachContext()69     void OnAttachContext() override
70     {
71         auto childList = GetChildren();
72         for (const auto& child : childList) {
73             if (child) {
74                 child->Attach(context_);
75             }
76         }
77     }
78 
79     bool IsOutOfBottomBoundary() override;
80 
81     bool IsOutOfTopBoundary() override;
82 
83     double GetMainScrollExtent() const override;
84 
85     double GetFixPositionOnWatch(double final, double current) override;
86 
SetScrollVibrate(bool scrollVibrate)87     void SetScrollVibrate(bool scrollVibrate)
88     {
89         scrollVibrate_ = scrollVibrate;
90     }
91 
GetScrollVibrate()92     bool GetScrollVibrate()
93     {
94         return scrollVibrate_;
95     }
96 
IsUseOnly()97     bool IsUseOnly() override
98     {
99         return true;
100     }
101 
102 protected:
103     void OnPredictLayout(int64_t deadline) override;
104     void PerformLayout() override;
105     void Update(const RefPtr<Component>& component) override;
106     bool ReachMaxCount() const override;
107     bool IsReadyToJump() const;
108 
109     Dimension gradientWidth_;
110     Color backgroundColor_;
111     double offsetBeforeLayout_ = 0.0;
112 
113 private:
114     LayoutParam MakeInnerLayoutParam() const;
115     void UpdateGradient(const RefPtr<ListComponent>& listComponent);
116     void UpdateEdgeEffect(const RefPtr<ListComponent>& listComponent);
117     void ApplyGradientColor();
118     void LayoutChild();
119     void LayoutChild(const RefPtr<RenderNode>& child, const Offset& position, double start, double end);
120     bool LayoutChild(const RefPtr<RenderNode>& curChild, int32_t curIndex, const RefPtr<RenderNode>& lastChild);
121     double CalculateBeginPositionInViewPort(double position, double size, double effectOffset = 0.0);
122     bool ScrollToPosition(double position, int32_t source, bool smooth);
123     void ProcessScrollExtent();
124     void ExtendViewPort();
125     bool HandleCrashTop() override;
126     bool HandleCrashBottom() override;
127 
128     double cacheExtent_ = 300.0;
129     int32_t currentIndex_ = 0;
130     int32_t initialIndex_ = 0;
131     int32_t effectIndex_ = 0;
132     double initialOffset_ = 0.0;
133     double effectOffset_ = 0.0;
134     double accumulatedRotationValue_ = 0.0;
135     bool scrollVibrate_ = true;
136     bool rotationVibrate_ = false;
137 
138     RefPtr<Animator> animateController_;
139     RefPtr<Vibrator> vibrator_;
140 };
141 
142 } // namespace OHOS::Ace
143 
144 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_RENDER_MULTI_CHILD_SCROLL_H
145