1 /*
2  * Copyright (c) 2022 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_V2_LIST_RENDER_LIST_ITEM_GROUP_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_LIST_RENDER_LIST_ITEM_GROUP_H
18 
19 #include <stdint.h>
20 #include "core/components_v2/list/list_item_group_component.h"
21 #include "base/geometry/dimension.h"
22 #include "core/components_v2/list/list_component.h"
23 #include "core/components_v2/list/list_item_component.h"
24 #include "core/components_v2/list/list_item_generator.h"
25 #include "core/components_v2/list/render_list_item.h"
26 #include "core/gestures/long_press_recognizer.h"
27 
28 namespace OHOS::Ace::V2 {
29 
30 struct ListItemLayoutParam {
31     size_t startCacheCount;
32     size_t endCacheCount;
33     double startMainPos;
34     double endMainPos;
35     double listMainSize;
36     double referencePos;
37     double maxLaneLength;
38     bool forwardLayout;
39     bool isVertical;
40     StickyStyle sticky;
41     int32_t lanes;
42     ListItemAlign align;
43 };
44 
45 class RenderListItemGroup : public RenderListItem {
46     DECLARE_ACE_TYPE(V2::RenderListItemGroup, V2::RenderListItem);
47 
48 public:
49     static RefPtr<RenderNode> Create();
50 
51     RenderListItemGroup() = default;
52     ~RenderListItemGroup() override = default;
53 
54     void Update(const RefPtr<Component>& component) override;
55     void Paint(RenderContext& context, const Offset& offset) override;
56     void PerformLayout() override;
IsForwardLayout()57     bool IsForwardLayout() const override
58     {
59         return forwardLayout_;
60     }
RegisterItemGenerator(WeakPtr<ListItemGenerator> && listItemGenerator)61     void RegisterItemGenerator(WeakPtr<ListItemGenerator>&& listItemGenerator)
62     {
63         itemGenerator_ = std::move(listItemGenerator);
64     }
65 
GetMainSize(const Size & size)66     double GetMainSize(const Size& size) const
67     {
68         return vertical_ ? size.Height() : size.Width();
69     }
70 
GetMainAxis(const Offset & size)71     double GetMainAxis(const Offset& size) const
72     {
73         return vertical_ ? size.GetY() : size.GetX();
74     }
75 
GetCrossSize(const Size & size)76     double GetCrossSize(const Size& size) const
77     {
78         return vertical_ ? size.Width() : size.Height();
79     }
80 
GetSpace()81     double GetSpace() const
82     {
83         return spaceWidth_;
84     }
85 
GetListSpace()86     Dimension GetListSpace() const
87     {
88         return listSpace_;
89     }
90 
GetCurrStartCacheCount()91     size_t GetCurrStartCacheCount() const
92     {
93         return currStartCacheCount_;
94     }
95 
GetCurrEndCacheCount()96     size_t GetCurrEndCacheCount() const
97     {
98         return currEndCacheCount_;
99     }
100 
IsVertical()101     bool IsVertical() const
102     {
103         return vertical_;
104     }
105 
GetStartIndex()106     size_t GetStartIndex() const
107     {
108         return startIndex_;
109     }
110 
GetStartIndexOffset()111     double GetStartIndexOffset() const
112     {
113         return startIndexOffset_;
114     }
115 
GetReferencePos()116     double GetReferencePos() const
117     {
118         return forwardLayout_ ? forwardReferencePos_ : backwardReferencePos_;
119     }
120 
GetLanes()121     size_t GetLanes() const
122     {
123         return lanes_;
124     }
125 
126     template<class T>
MakeValue(double mainValue,double crossValue)127     T MakeValue(double mainValue, double crossValue) const
128     {
129         return vertical_ ? T(crossValue, mainValue) : T(mainValue, crossValue);
130     }
131 
132     void RemoveAllItems();
133     RefPtr<RenderListItem> RequestListItem(size_t index, bool atStart);
134     RefPtr<RenderNode> RequestListItemHeader();
135     RefPtr<RenderNode> RequestListItemFooter();
136     void RecycleListItem(size_t index);
137     size_t TotalCount();
138     RefPtr<RenderNode> GetRenderNode();
139     void SetItemGroupLayoutParam(const ListItemLayoutParam &param);
140     void SetChainOffset(double offset);
SetRenderNode(const WeakPtr<RenderNode> & renderNode)141     void SetRenderNode(const WeakPtr<RenderNode>& renderNode)
142     {
143         renderNode_ = renderNode;
144     }
145     void SetNeedLayoutDeep();
146 
147 protected:
PaintDivider(RenderContext & context)148     virtual void PaintDivider(RenderContext& context) {}
149 
GetItemDivider()150     const std::unique_ptr<ItemDivider>& GetItemDivider() const
151     {
152         return component_->GetItemDivider();
153     }
154 
GetItems()155     const std::list<RefPtr<RenderListItem>>& GetItems() const
156     {
157         return items_;
158     }
159 
160 private:
161     LayoutParam MakeInnerLayout();
162     double LayoutOrRecycleCurrentItems();
163     void RecycleStartCacheItems();
164     double LayoutALine(std::list<RefPtr<RenderListItem>>::iterator& it);
165     void RequestNewItemsAtEnd(double& curMainPos);
166     void RequestNewItemsAtStart();
167     void LayoutHeaderFooter(bool reachEnd);
168     void SetItemsPostion();
169     double CalculateCrossOffset(double crossSize, double childCrossSize);
170 
171     WeakPtr<ListItemGenerator> itemGenerator_;
172     RefPtr<ListItemGroupComponent> component_;
173     std::list<RefPtr<RenderListItem>> items_;
174     RefPtr<RenderNode> header_;
175     RefPtr<RenderNode> footer_;
176     double spaceWidth_ = 0.0;
177 
178     // param for frontend
179     Dimension listSpace_;
180     bool stickyHeader_ = false;
181     bool stickyFooter_ = false;
182     WeakPtr<RenderNode> renderNode_;
183 
184     // layout param
185     bool forwardLayout_ = true;
186     double forwardReferencePos_ = 0.0;
187     double backwardReferencePos_ = 0.0;
188     double startMainPos_ = 0.0;
189     double endMainPos_ = 0.0;
190     double listMainSize_ = 0.0;
191     double maxLaneLength_ = 0.0;
192     size_t startCacheCount_ = 0;
193     size_t endCacheCount_ = 0;
194     size_t lanes_ = 1;
195     bool vertical_ = true;
196     ListItemAlign align_ = V2::ListItemAlign::START;
197 
198     // layout status
199     bool isInitialized_ = false;
200     size_t startIndex_ = 0;
201     double startIndexOffset_ = 0.0;
202     double endIndexOffset_ = 0.0;
203     size_t currStartCacheCount_ = 0;
204     size_t currEndCacheCount_ = 0;
205 
206     ACE_DISALLOW_COPY_AND_MOVE(RenderListItemGroup);
207 };
208 
209 } // namespace OHOS::Ace::V2
210 
211 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_LIST_RENDER_LIST_ITEM_GROUP_H
212