1 /*
2  * Copyright (c) 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_LIST_LIST_CHILDREN_MAIN_SIZE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_LIST_LIST_CHILDREN_MAIN_SIZE_H
18 
19 #include <cstddef>
20 #include <cstdint>
21 #include <functional>
22 #include <optional>
23 #include <tuple>
24 #include <vector>
25 
26 #include "base/geometry/dimension.h"
27 #include "core/components_ng/property/measure_property.h"
28 
29 namespace OHOS::Ace::NG {
30 
31 using ListChangeFlag = std::uint8_t;
32 
33 inline constexpr ListChangeFlag LIST_NO_CHANGE = 0;
34 inline constexpr ListChangeFlag LIST_UPDATE_DEFAULT_SIZE = 1;
35 inline constexpr ListChangeFlag LIST_UPDATE_CHILD_SIZE = 1 << 1;
36 inline constexpr ListChangeFlag LIST_UPDATE_LANES = 1 << 2;
37 inline constexpr ListChangeFlag LIST_UPDATE_SPACE = 1 << 3;
38 inline constexpr ListChangeFlag LIST_GROUP_UPDATE_HEADER_FOOTER = 1 << 4;
39 inline constexpr ListChangeFlag LIST_UPDATE_ITEM_COUNT = 1 << 5;
40 
41 namespace {
42 constexpr float DEFAULT_SIZE = -1.0f;
43 }
44 
45 class ListChildrenMainSize : public virtual AceType {
46     DECLARE_ACE_TYPE(ListChildrenMainSize, AceType)
47 public:
48     ListChildrenMainSize() = default;
ListChildrenMainSize(const std::vector<float> & mainSize,float defaulatMainSize)49     ListChildrenMainSize(const std::vector<float>& mainSize, float defaulatMainSize)
50         : childrenSize_(mainSize), defaultSize_(defaulatMainSize) {};
51     ~ListChildrenMainSize() override = default;
52 
SetOnDataChange(std::function<void (std::tuple<int32_t,int32_t,int32_t>,ListChangeFlag)> && func)53     void SetOnDataChange(std::function<void(std::tuple<int32_t, int32_t, int32_t>, ListChangeFlag)>&& func)
54     {
55         onChildrenSizeChange_ = func;
56     }
57 
ChangeData(const int32_t start,const int32_t deleteCount,const std::vector<float> & newChildrenSize)58     void ChangeData(const int32_t start, const int32_t deleteCount, const std::vector<float>& newChildrenSize)
59     {
60         if (deleteCount == -1) {
61             childrenSize_.resize(start, DEFAULT_SIZE);
62             if (onChildrenSizeChange_) {
63                 onChildrenSizeChange_(std::make_tuple(start, -1, -1), LIST_UPDATE_CHILD_SIZE);
64             }
65             return;
66         }
67         int32_t newChildrenSizeSize = static_cast<int32_t>(newChildrenSize.size());
68         int32_t replaceCount = std::min(deleteCount, newChildrenSizeSize);
69         int32_t cursor = 0;
70         if (static_cast<int32_t>(childrenSize_.size()) < start + replaceCount) {
71             childrenSize_.resize(start + replaceCount, DEFAULT_SIZE);
72         }
73         for (; cursor < replaceCount; cursor++) {
74             childrenSize_[start + cursor] = newChildrenSize[cursor];
75         }
76         if (deleteCount > newChildrenSizeSize) {
77             auto deleteStartPos = childrenSize_.begin() + start + cursor;
78             auto deleteEndPos = deleteStartPos;
79             int32_t needDeleteSpan = deleteCount - newChildrenSizeSize;
80             while (deleteEndPos != childrenSize_.end() && needDeleteSpan--) {
81                 deleteEndPos++;
82             }
83             childrenSize_.erase(deleteStartPos, deleteEndPos);
84         } else if (deleteCount < newChildrenSizeSize) {
85             auto insertStartPos = childrenSize_.begin() + start + cursor;
86             childrenSize_.insert(insertStartPos, newChildrenSize.begin() + cursor, newChildrenSize.end());
87         }
88         if (onChildrenSizeChange_) {
89             onChildrenSizeChange_(std::make_tuple(start, deleteCount, newChildrenSizeSize), LIST_UPDATE_CHILD_SIZE);
90         }
91     }
92 
UpdateDefaultSize(float defaultSize)93     void UpdateDefaultSize(float defaultSize)
94     {
95         if (NearEqual(defaultSize_, defaultSize)) {
96             return;
97         }
98         defaultSize_ = defaultSize;
99         if (onChildrenSizeChange_) {
100             // -1: default size changed.
101             onChildrenSizeChange_(std::make_tuple(-1, -1, -1), LIST_UPDATE_DEFAULT_SIZE);
102         }
103     }
104 
SyncChildrenSize(float childSize)105     void SyncChildrenSize(float childSize)
106     {
107         childrenSize_.emplace_back(childSize);
108     }
109 
SyncChildrenSizeOver()110     void SyncChildrenSizeOver()
111     {
112         if (onChildrenSizeChange_) {
113             onChildrenSizeChange_(std::make_tuple(-1, -1, -1), LIST_UPDATE_CHILD_SIZE);
114         }
115         initialized_ = true;
116     }
117 
NeedSync()118     bool NeedSync() const
119     {
120         return !initialized_;
121     }
122 
GetChildSize(int32_t index)123     float GetChildSize(int32_t index) const
124     {
125         if (index > (static_cast<int32_t>(childrenSize_.size()) - 1) || index < 0 ||
126             NearEqual(childrenSize_[index], DEFAULT_SIZE)) {
127             return defaultSize_;
128         }
129         if (Negative(childrenSize_[index])) {
130             TAG_LOGW(AceLogTag::ACE_LIST, "ChildrenMainSize child index:%{public}d, size:%{public}f.", index,
131                 childrenSize_[index]);
132         }
133         return childrenSize_[index];
134     }
135 
ResizeChildrenSize(int32_t size)136     void ResizeChildrenSize(int32_t size)
137     {
138         childrenSize_.resize(std::max(size, 0), DEFAULT_SIZE);
139     }
140 
141 private:
142     std::vector<float> childrenSize_;
143     float defaultSize_ = 0.0f;
144     bool initialized_ = false;
145     std::function<void(std::tuple<int32_t, int32_t, int32_t>, ListChangeFlag)> onChildrenSizeChange_;
146 };
147 
148 } // namespace OHOS::Ace::NG
149 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_LIST_LIST_CHILDREN_MAIN_SIZE_H