• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_LIST_LIST_ITEM_GROUP_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_LIST_LIST_ITEM_GROUP_PATTERN_H
18 
19 #include "base/memory/referenced.h"
20 #include "base/utils/noncopyable.h"
21 #include "base/utils/utils.h"
22 #include "core/components_ng/pattern/list/list_item_group_accessibility_property.h"
23 #include "core/components_ng/pattern/list/list_children_main_size.h"
24 #include "core/components_ng/pattern/list/list_item_group_layout_algorithm.h"
25 #include "core/components_ng/pattern/list/list_item_group_layout_property.h"
26 #include "core/components_ng/pattern/list/list_layout_property.h"
27 #include "core/components_ng/pattern/list/list_position_map.h"
28 #include "core/components_ng/pattern/pattern.h"
29 #include "core/components_ng/syntax/shallow_builder.h"
30 
31 namespace OHOS::Ace::NG {
32 
33 struct ListItemGroupPaintInfo {
34     TextDirection layoutDirection = TextDirection::LTR;
35     float mainSize = 0.0f;
36     bool vertical = false;
37     int32_t lanes = 1;
38     float spaceWidth = 0.0f;
39     float laneGutter = 0.0f;
40     int32_t totalItemCount = 0;
41 };
42 
43 enum ListItemGroupArea {
44     NONE_AREA,
45     IN_LIST_ITEM_AREA,
46     IN_HEADER_AREA,
47     IN_FOOTER_AREA
48 };
49 
50 struct VisibleContentInfo {
51     int32_t area = -1;
52     int32_t indexInGroup = -1;
53 };
54 
55 struct ListMainSizeValues {
56     float startPos = 0.0f;
57     float endPos = 0.0f;
58     std::optional<int32_t> jumpIndexInGroup;
59     float prevContentMainSize = 0.0f;
60     ScrollAlign scrollAlign = ScrollAlign::START;
61     std::optional<float> layoutStartMainPos;
62     std::optional<float> layoutEndMainPos;
63     float referencePos = 0.0f;
64     bool forward;
65 };
66 
67 class ACE_EXPORT ListItemGroupPattern : public Pattern {
68     DECLARE_ACE_TYPE(ListItemGroupPattern, Pattern);
69 
70 public:
ListItemGroupPattern(const RefPtr<ShallowBuilder> & shallowBuilder,V2::ListItemGroupStyle listItemGroupStyle)71     explicit ListItemGroupPattern(
72         const RefPtr<ShallowBuilder>& shallowBuilder, V2::ListItemGroupStyle listItemGroupStyle)
73         : shallowBuilder_(shallowBuilder), listItemGroupStyle_(listItemGroupStyle)
74     {}
75     ~ListItemGroupPattern() override = default;
76 
77     void DumpAdvanceInfo() override;
IsAtomicNode()78     bool IsAtomicNode() const override
79     {
80         return false;
81     }
82 
83     void NotifyDataChange(int32_t index, int32_t count) override;
84 
CreateLayoutProperty()85     RefPtr<LayoutProperty> CreateLayoutProperty() override
86     {
87         return MakeRefPtr<ListItemGroupLayoutProperty>();
88     }
89 
CreateAccessibilityProperty()90     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
91     {
92         return MakeRefPtr<ListItemGroupAccessibilityProperty>();
93     }
94 
95     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override;
96 
97     RefPtr<NodePaintMethod> CreateNodePaintMethod() override;
98 
AddHeader(const RefPtr<NG::UINode> & header)99     void AddHeader(const RefPtr<NG::UINode>& header)
100     {
101         auto host = GetHost();
102         CHECK_NULL_VOID(host);
103         auto prevHeader = header_.Upgrade();
104         if (!prevHeader) {
105             host->AddChild(header, 0);
106             host->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
107         } else {
108             if (header != prevHeader) {
109                 host->ReplaceChild(prevHeader, header);
110                 host->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
111             }
112         }
113         header_ = header;
114     }
115 
AddFooter(const RefPtr<NG::UINode> & footer)116     void AddFooter(const RefPtr<NG::UINode>& footer)
117     {
118         auto host = GetHost();
119         CHECK_NULL_VOID(host);
120         auto prevFooter = footer_.Upgrade();
121         auto prevHeader = header_.Upgrade();
122         if (!prevFooter) {
123             if (prevHeader) {
124                 host->AddChildAfter(footer, prevHeader);
125             } else {
126                 host->AddChild(footer, 0);
127             }
128             host->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
129         } else {
130             if (footer != prevFooter) {
131                 host->ReplaceChild(prevFooter, footer);
132                 host->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
133             }
134         }
135         footer_ = footer;
136     }
137 
RemoveHeader()138     void RemoveHeader()
139     {
140         auto host = GetHost();
141         CHECK_NULL_VOID(host);
142         auto prevHeader = header_.Upgrade();
143         if (prevHeader && isHeaderComponentContentExist_) {
144             host->RemoveChild(prevHeader);
145             host->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
146             header_ = nullptr;
147             isHeaderComponentContentExist_ = false;
148         }
149     }
150 
RemoveFooter()151     void RemoveFooter()
152     {
153         auto host = GetHost();
154         CHECK_NULL_VOID(host);
155         auto prevFooter = footer_.Upgrade();
156         if (prevFooter && isFooterComponentContentExist_) {
157             host->RemoveChild(prevFooter);
158             host->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
159             footer_ = nullptr;
160             isFooterComponentContentExist_ = false;
161         }
162     }
163 
GetItemPosition()164     const ListItemGroupLayoutAlgorithm::PositionMap& GetItemPosition()
165     {
166         return itemPosition_;
167     }
168 
SetIndexInList(int32_t index)169     void SetIndexInList(int32_t index)
170     {
171         indexInList_ = index;
172     }
173 
SetHeaderComponentContentExist(bool isHeaderComponentContentExist)174     void SetHeaderComponentContentExist(bool isHeaderComponentContentExist)
175     {
176         isHeaderComponentContentExist_ = isHeaderComponentContentExist;
177     }
178 
SetFooterComponentContentExist(bool isFooterComponentContentExist)179     void SetFooterComponentContentExist(bool isFooterComponentContentExist)
180     {
181         isFooterComponentContentExist_ = isFooterComponentContentExist;
182     }
183 
GetIndexInList()184     int32_t GetIndexInList() const
185     {
186         return indexInList_;
187     }
188 
GetDisplayEndIndexInGroup()189     int32_t GetDisplayEndIndexInGroup() const
190     {
191         return itemDisplayEndIndex_;
192     }
193 
GetDisplayStartIndexInGroup()194     int32_t GetDisplayStartIndexInGroup() const
195     {
196         return itemDisplayStartIndex_;
197     }
198 
GetItemStartIndex()199     int32_t GetItemStartIndex() const
200     {
201         return itemStartIndex_;
202     }
203 
GetEndIndexInGroup()204     int32_t GetEndIndexInGroup() const
205     {
206         return (itemTotalCount_ - 1);
207     }
208 
GetTotalItemCount()209     int32_t GetTotalItemCount() const
210     {
211         return itemTotalCount_;
212     }
213 
IsDisplayStart()214     bool IsDisplayStart() const
215     {
216         return itemDisplayStartIndex_ == 0;
217     }
218 
IsDisplayEnd()219     int32_t IsDisplayEnd() const
220     {
221         return itemTotalCount_ == 0 || itemDisplayEndIndex_ == (itemTotalCount_ - 1);
222     }
223 
GetLanesInGroup()224     int32_t GetLanesInGroup() const
225     {
226         return lanes_;
227     }
228 
GetListItemGroupStyle()229     V2::ListItemGroupStyle GetListItemGroupStyle()
230     {
231         return listItemGroupStyle_;
232     }
233 
GetHeaderMainSize()234     float GetHeaderMainSize() const
235     {
236         return headerMainSize_;
237     }
238 
GetFooterMainSize()239     float GetFooterMainSize() const
240     {
241         return footerMainSize_;
242     }
243 
244     float GetEstimateOffset(float height, const std::pair<float, float>& targetPos) const;
245     float GetEstimateHeight(float& averageHeight) const;
HasLayoutedItem()246     bool HasLayoutedItem() const
247     {
248         return layouted_ && (layoutedItemInfo_.has_value() || itemTotalCount_ == 0);
249     }
250 
SetItemPressed(bool isPressed,int32_t id)251     void SetItemPressed(bool isPressed, int32_t id)
252     {
253         if (isPressed) {
254             pressedItem_.emplace(id);
255         } else {
256             pressedItem_.erase(id);
257         }
258     }
259 
260     void SetListItemGroupStyle(V2::ListItemGroupStyle style);
261     RefPtr<ListChildrenMainSize> GetOrCreateListChildrenMainSize();
262     void SetListChildrenMainSize(float defaultSize, const std::vector<float>& mainSize);
263     void OnChildrenSizeChanged(std::tuple<int32_t, int32_t, int32_t> change, ListChangeFlag flag);
264     bool ListChildrenSizeExist();
265     RefPtr<FrameNode> GetListFrameNode() const;
266     VisibleContentInfo GetStartListItemIndex();
267     VisibleContentInfo GetEndListItemIndex();
268     void ResetChildrenSize();
269 
270     void ClearItemPosition();
271     void CalculateItemStartIndex();
272     void UpdateActiveChildRange(bool forward, int32_t cacheCount);
273     int32_t UpdateForwardCachedIndex(int32_t cacheCount, bool outOfView);
274     int32_t UpdateBackwardCachedIndex(int32_t cacheCount, bool outOfView);
275     void LayoutCache(const LayoutConstraintF& constraint, bool forward, int64_t deadline, int32_t cached,
276         ListMainSizeValues listSizeValues);
277 
278 private:
IsNeedInitClickEventRecorder()279     bool IsNeedInitClickEventRecorder() const override
280     {
281         return true;
282     }
283 
284     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
285     void OnAttachToFrameNode() override;
286     void SetListItemGroupDefaultAttributes(const RefPtr<FrameNode>& itemGroupNode);
287     void OnColorConfigurationUpdate() override;
288     void CheckListDirectionInCardStyle();
289     float GetPaddingAndMargin() const;
290     float GetListPaddingOffset(const RefPtr<FrameNode>& listNode) const;
291     bool FirstItemFullVisible(const RefPtr<FrameNode>& listNode) const;
292     bool CheckDataChangeOutOfStart(int32_t index, int32_t count, int32_t startIndex);
293 
294     RefPtr<ShallowBuilder> shallowBuilder_;
295     RefPtr<ListPositionMap> posMap_;
296     RefPtr<ListChildrenMainSize> childrenSize_;
297     V2::ListItemGroupStyle listItemGroupStyle_ = V2::ListItemGroupStyle::NONE;
298 
299     int32_t indexInList_ = 0;
300 
301     WeakPtr<UINode> header_;
302     WeakPtr<UINode> footer_;
303     bool isHeaderComponentContentExist_ = false;
304     bool isFooterComponentContentExist_ = false;
305     int32_t itemStartIndex_ = 0;
306     int32_t headerIndex_ = -1;
307     int32_t footerIndex_ = -1;
308     int32_t itemTotalCount_ = -1;
309     int32_t itemDisplayEndIndex_ = -1;
310     int32_t itemDisplayStartIndex_ = -1;
311     float_t headerMainSize_ = 0.0f;
312     float_t footerMainSize_ = 0.0f;
313 
314     std::optional<LayoutedItemInfo> layoutedItemInfo_;
315     std::set<int32_t> pressedItem_;
316     bool layouted_ = false;
317     LayoutConstraintF layoutConstraint_;
318 
319     int32_t backwardCachedIndex_ = INT_MAX;
320     int32_t forwardCachedIndex_ = -1;
321 
322     ListItemGroupLayoutAlgorithm::PositionMap itemPosition_;
323     float spaceWidth_ = 0.0f;
324     Axis axis_ = Axis::VERTICAL;
325     int32_t lanes_ = 1;
326     float laneGutter_ = 0.0f;
327     float startHeaderPos_ = 0.0f;
328     float endFooterPos_ = 0.0f;
329     TextDirection layoutDirection_ = TextDirection::LTR;
330     float mainSize_ = 0.0f;
331     ACE_DISALLOW_COPY_AND_MOVE(ListItemGroupPattern);
332 };
333 } // namespace OHOS::Ace::NG
334 
335 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_LIST_LIST_ITEM_PATTERN_H
336