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