1 /* 2 * Copyright (c) 2021 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_LIST_LAYOUT_MANAGER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_LIST_LAYOUT_MANAGER_H 18 19 #include <map> 20 21 #include "base/geometry/dimension.h" 22 #include "base/geometry/offset.h" 23 #include "base/memory/ace_type.h" 24 #include "base/utils/system_properties.h" 25 #include "core/event/touch_event.h" 26 #include "core/pipeline/base/component.h" 27 #include "core/pipeline/base/render_node.h" 28 29 namespace OHOS::Ace { 30 31 const double DEFAULT_SCALE = 1.0; 32 const double TV_ITEM_SCALE = 1.05; 33 const double HALF_ITEM_SIZE = 0.5; 34 const int32_t LIST_PARAM_INVAID = -2; 35 const int32_t LIST_LENGTH_INFINITE = -1; 36 const double INFINITE_POSITION = 0.0; 37 38 // first bool mean if vertical, second bool mean if reverse 39 // false, false --> RIGHT 40 // false, true --> LEFT 41 // true, false --> DOWN 42 // true, true ---> UP 43 // This map will adapter the Grid FlexDirection with Key Direction. 44 extern const std::map<bool, std::map<FlexDirection, std::map<bool, std::map<bool, KeyDirection>>>> DIRECTION_MAP; 45 46 class LayoutManager : public virtual AceType { 47 DECLARE_ACE_TYPE(LayoutManager, AceType); 48 49 public: 50 LayoutManager() = default; 51 ~LayoutManager() override = default; 52 53 virtual void Update() = 0; 54 55 virtual void PerformLayout() = 0; 56 57 virtual void RefreshLayout() = 0; 58 59 virtual void CalculateCachedRange(int32_t viewBegin, int32_t viewEnd, int32_t cachedCount, int32_t& cachedBegin, 60 int32_t& cachedEnd) = 0; 61 62 virtual void RequestMoreItemsIfNeeded(int32_t viewBegin, int32_t viewEnd) = 0; 63 64 virtual int32_t focusMove(KeyDirection key) = 0; 65 CalculateFocusIndexPosition()66 virtual void CalculateFocusIndexPosition() {} 67 MoveItemToViewPort(double position)68 virtual void MoveItemToViewPort(double position) {} 69 MoveItemGroupToViewPort(double position,double size)70 virtual void MoveItemGroupToViewPort(double position, double size) {} 71 LayoutToItem(int32_t toIndex)72 virtual void LayoutToItem(int32_t toIndex) {} 73 LayoutToPosition(double position)74 virtual void LayoutToPosition(double position) {} 75 LayoutMore(double incDistance)76 virtual void LayoutMore(double incDistance) {} 77 NotifyNeedRefresh()78 virtual void NotifyNeedRefresh() {} 79 RequestNextFocus(bool vertical,bool reverse)80 int32_t RequestNextFocus(bool vertical, bool reverse) 81 { 82 KeyDirection key = DIRECTION_MAP.at(rightToLeft_).at(direction_).at(vertical).at(reverse); 83 int32_t index = focusMove(key); 84 LOGD("Focus move from %{public}d to %{public}d", focusIndex_, index); 85 if (index < 0) { 86 focusMove_ = focusIndex_; 87 return index; 88 } 89 focusMove_ = index; 90 focusIndex_ = index; 91 return focusMove_; 92 } 93 ListItemFocused(int32_t focusIndex)94 void ListItemFocused(int32_t focusIndex) 95 { 96 focusIndex_ = focusIndex; 97 focusMove_ = focusIndex; 98 } 99 MarkNeedRefresh()100 void MarkNeedRefresh() 101 { 102 needRefresh_ = true; 103 NotifyNeedRefresh(); 104 } 105 ResetLayoutRange(double head,double tail,Offset position,Size viewPort)106 void ResetLayoutRange(double head, double tail, Offset position, Size viewPort) 107 { 108 head_ = head; 109 tail_ = tail; 110 position_ = position; 111 viewPort_ = viewPort; 112 } 113 GetPosition()114 const Offset& GetPosition() const 115 { 116 return position_; 117 } 118 FlushChainAnimation()119 virtual double FlushChainAnimation() 120 { 121 return 0.0; 122 } 123 IsRowReverse()124 bool IsRowReverse() const 125 { 126 return rightToLeft_ && direction_ == FlexDirection::ROW; 127 } 128 GetItemGrid(int32_t index)129 int32_t GetItemGrid(int32_t index) const 130 { 131 auto iter = itemGrid_.find(index); 132 if (iter == itemGrid_.end()) { 133 return 0; 134 } 135 return iter->second; 136 } 137 CheckItemPosition(int32_t index)138 bool CheckItemPosition(int32_t index) const 139 { 140 return itemPosition_.find(index) != itemPosition_.end(); 141 } 142 GetItemAnimationValue(int32_t index)143 virtual double GetItemAnimationValue(int32_t index) const 144 { 145 return 0.0; 146 } 147 GetItemPosition(int32_t index)148 double GetItemPosition(int32_t index) const 149 { 150 auto iter = itemPosition_.find(index); 151 if (iter == itemPosition_.end()) { 152 return 0.0; 153 } 154 return iter->second; 155 } 156 GetChainInterval()157 double GetChainInterval() const 158 { 159 return enableChain_ ? chainInterval_ : 0.0; 160 } 161 GetChainItemRange(int32_t index,double & start,double & end)162 void GetChainItemRange(int32_t index, double& start, double& end) const 163 { 164 if (!enableChain_) { 165 return; 166 } 167 start = GetItemPosition(index) - GetChainInterval() * HALF_ITEM_SIZE; 168 double nextStartPosition = GetItemPosition(index + 1); 169 if (!NearZero(nextStartPosition)) { 170 end = nextStartPosition - GetChainInterval() * HALF_ITEM_SIZE; 171 } 172 } 173 GetIndexByPosition(double position)174 int32_t GetIndexByPosition(double position) const 175 { 176 int32_t index = 0; 177 double curPosition = 0.0; 178 for (const auto& item : itemPosition_) { 179 double correctedPosition = item.second + GetItemAnimationValue(item.first); 180 if (NearEqual(correctedPosition, position)) { 181 return item.first; 182 } else { 183 if (NearEqual(curPosition, correctedPosition)) { 184 continue; 185 } 186 curPosition = correctedPosition; 187 if (correctedPosition < position) { 188 index = item.first; 189 } else { 190 return index; 191 } 192 } 193 } 194 return index; 195 } 196 CalculateRepeatedIndex(int32_t cachedIndex)197 int32_t CalculateRepeatedIndex(int32_t cachedIndex) 198 { 199 int32_t repeatedIndex; 200 if (repeatedLength_ == LIST_LENGTH_INFINITE) { 201 repeatedIndex = ((cachedIndex - indexOffset_) > 0 ? (cachedIndex - indexOffset_) : 0); 202 } else { 203 if (cachedIndex < indexOffset_) { 204 repeatedIndex = 0; 205 } else { 206 if (cachedIndex > indexOffset_ + repeatedLength_) { 207 repeatedIndex = repeatedLength_; 208 } else { 209 repeatedIndex = cachedIndex - indexOffset_; 210 } 211 } 212 } 213 return repeatedIndex; 214 } 215 GetExpandStatus(int32_t groupIndex)216 bool GetExpandStatus(int32_t groupIndex) const 217 { 218 auto iter = itemGroupsExpand_.find(groupIndex); 219 if (iter != itemGroupsExpand_.end()) { 220 return iter->second; 221 } else { 222 return expandAll_; 223 } 224 } 225 GetItemGroupFocusIndex(int32_t groupIndex)226 int32_t GetItemGroupFocusIndex(int32_t groupIndex) const 227 { 228 auto iter = itemGroupsFocusIndex_.find(groupIndex); 229 if (iter != itemGroupsFocusIndex_.end()) { 230 return iter->second; 231 } 232 return 0; 233 } 234 SetExpandAll(bool expandAll)235 void SetExpandAll(bool expandAll) 236 { 237 expandAll_ = expandAll; 238 } 239 ClearItemGroupsExpand()240 void ClearItemGroupsExpand() 241 { 242 itemGroupsExpand_.clear(); 243 } 244 ClearItemPosition()245 void ClearItemPosition() 246 { 247 itemPosition_.clear(); 248 } 249 AddItemGroupExpand(int32_t index,bool expand)250 void AddItemGroupExpand(int32_t index, bool expand) 251 { 252 itemGroupsExpand_[index] = expand; 253 } 254 AddItemGroupFocusIndex(int32_t index,int32_t groupFocusIndex)255 void AddItemGroupFocusIndex(int32_t index, int32_t groupFocusIndex) 256 { 257 itemGroupsFocusIndex_[index] = groupFocusIndex; 258 } 259 GetFriction()260 double GetFriction() const 261 { 262 return friction_; 263 } 264 SetFriction(double friction)265 void SetFriction(double friction) 266 { 267 friction_ = friction; 268 } 269 GetSlipFactor()270 double GetSlipFactor() const 271 { 272 return slipFactor_; 273 } 274 275 protected: 276 double head_ = 0.0; 277 double tail_ = 0.0; 278 double lastHead_ = 0.0; 279 double lastTail_ = 0.0; 280 int32_t focusMove_ = 0; // Record the focus move path. 281 int32_t focusIndex_ = 0; // Record the index of focus item. 282 Offset position_; 283 Size viewPort_; 284 bool needRefresh_ = false; 285 bool firstLayout_ = true; 286 Dimension itemExtent_; 287 288 bool rightToLeft_ = false; 289 bool isVertical_ = false; 290 FlexDirection direction_ { FlexDirection::COLUMN }; 291 FlexAlign crossAxisAlign_ { FlexAlign::STRETCH }; 292 int32_t beginIndex_ = LIST_PARAM_INVAID; 293 int32_t endIndex_ = LIST_PARAM_INVAID; 294 int32_t length_ = 0; 295 int32_t repeatedLength_ = 0; 296 int32_t indexOffset_ = 0; 297 298 std::map<int32_t, int32_t> itemGrid_; 299 std::map<int32_t, double> itemPosition_; 300 std::map<int32_t, bool> itemGroupsExpand_; 301 std::map<int32_t, int32_t> itemGroupsFocusIndex_; 302 303 RefPtr<Animator> controller_; 304 std::vector<int32_t> needRemoveItems_; 305 std::map<int32_t, RefPtr<RenderNode>> newItems_; 306 bool isAnimating_ = false; 307 double friction_ = 1.0; 308 bool expandAll_ = false; 309 bool enableChain_ = false; // whether enables spring chain effect. 310 double chainInterval_ = 0.0; 311 int32_t itemCountOfPage_ = 0; 312 double slipFactor_ = 0.0; 313 }; 314 315 } // namespace OHOS::Ace 316 317 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_LIST_LAYOUT_MANAGER_H 318