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_NG_PATTERN_SWIPER_SWIPER_LAYOUT_ALGORITHM_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SWIPER_SWIPER_LAYOUT_ALGORITHM_H 18 19 #include <cstdint> 20 #include <optional> 21 22 #include "base/geometry/axis.h" 23 #include "base/geometry/ng/offset_t.h" 24 #include "base/memory/referenced.h" 25 #include "core/components_ng/layout/layout_algorithm.h" 26 #include "core/components_ng/layout/layout_wrapper.h" 27 28 namespace OHOS::Ace::NG { 29 30 struct SwiperItemInfo { 31 float startPos = 0.0f; 32 float endPos = 0.0f; 33 RefPtr<FrameNode> node; 34 OffsetF finialOffset; 35 }; 36 37 class ACE_EXPORT SwiperLayoutAlgorithm : public LayoutAlgorithm { 38 DECLARE_ACE_TYPE(SwiperLayoutAlgorithm, LayoutAlgorithm); 39 40 public: 41 using PositionMap = std::map<int32_t, SwiperItemInfo>; 42 43 SwiperLayoutAlgorithm() = default; 44 ~SwiperLayoutAlgorithm() override = default; 45 OnReset()46 void OnReset() override {} 47 void Measure(LayoutWrapper* layoutWrapper) override; 48 void Layout(LayoutWrapper* layoutWrapper) override; 49 50 void LayoutForward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, Axis axis, 51 int32_t startIndex, float startPos); 52 void LayoutBackward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, Axis axis, 53 int32_t endIndex, float endPos); 54 bool LayoutForwardItem(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, Axis axis, 55 int32_t& currentIndex, float startPos, float& endPos); 56 bool LayoutBackwardItem(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, Axis axis, 57 int32_t& currentIndex, float endPos, float& startPos); 58 float GetChildMaxSize(LayoutWrapper* layoutWrapper, Axis axis, bool isMainAxis) const; 59 int32_t GetLoopIndex(int32_t originalIndex) const; 60 SetItemsPosition(const PositionMap & itemPosition)61 void SetItemsPosition(const PositionMap& itemPosition) 62 { 63 itemPosition_ = itemPosition; 64 } 65 GetItemPosition()66 PositionMap&& GetItemPosition() 67 { 68 return std::move(itemPosition_); 69 } 70 SetJumpIndex(int32_t index)71 void SetJumpIndex(int32_t index) 72 { 73 jumpIndex_ = index; 74 } 75 SetCurrentDelta(float offset)76 void SetCurrentDelta(float offset) 77 { 78 currentDelta_ = offset; 79 currentOffset_ = offset; 80 } 81 SetOverScrollFeature()82 void SetOverScrollFeature() 83 { 84 overScrollFeature_ = true; 85 } 86 SetCanOverScroll(bool canOverScroll)87 void SetCanOverScroll(bool canOverScroll) 88 { 89 canOverScroll_ = canOverScroll; 90 } 91 SetTotalItemCount(int32_t totalItemCount)92 void SetTotalItemCount(int32_t totalItemCount) 93 { 94 totalItemCount_ = totalItemCount; 95 } 96 GetContentMainSize()97 float GetContentMainSize() const 98 { 99 return contentMainSize_; 100 } 101 SetContentMainSize(float contentMainSize)102 void SetContentMainSize(float contentMainSize) 103 { 104 contentMainSize_ = contentMainSize; 105 } 106 GetContentCrossSize()107 float GetContentCrossSize() const 108 { 109 return contentCrossSize_; 110 } 111 SetContentCrossSize(float contentCrossSize)112 void SetContentCrossSize(float contentCrossSize) 113 { 114 contentCrossSize_ = contentCrossSize; 115 } 116 SetCurrentOffset(float offset)117 void SetCurrentOffset(float offset) 118 { 119 currentOffset_ = offset; 120 } 121 GetCurrentOffset()122 float GetCurrentOffset() const 123 { 124 return currentOffset_; 125 } 126 SetTargetIndex(std::optional<int32_t> targetIndex)127 void SetTargetIndex(std::optional<int32_t> targetIndex) 128 { 129 targetIndex_ = targetIndex; 130 } 131 SetIsLoop(bool isLoop)132 void SetIsLoop(bool isLoop) 133 { 134 isLoop_ = isLoop; 135 } 136 GetStartIndex()137 int32_t GetStartIndex() const 138 { 139 return itemPosition_.empty() ? 0 : itemPosition_.begin()->first; 140 } 141 GetEndIndex()142 int32_t GetEndIndex() const 143 { 144 return itemPosition_.empty() ? 0 : itemPosition_.rbegin()->first; 145 } 146 GetStartPosition()147 float GetStartPosition() const 148 { 149 if (itemPosition_.empty()) { 150 return 0.0f; 151 } 152 if (GetStartIndex() == 0) { 153 return itemPosition_.begin()->second.startPos; 154 } 155 return itemPosition_.begin()->second.startPos - spaceWidth_; 156 } 157 GetEndPosition()158 float GetEndPosition() const 159 { 160 if (itemPosition_.empty()) { 161 return 0.0f; 162 } 163 if (GetEndIndex() == totalItemCount_ - 1) { 164 return itemPosition_.rbegin()->second.endPos; 165 } 166 return itemPosition_.rbegin()->second.endPos + spaceWidth_; 167 } 168 SetMainSizeIsMeasured(bool mainSizeIsMeasured)169 void SetMainSizeIsMeasured(bool mainSizeIsMeasured) 170 { 171 mainSizeIsMeasured_ = mainSizeIsMeasured; 172 } 173 GetMainSizeIsMeasured()174 bool GetMainSizeIsMeasured() const 175 { 176 return mainSizeIsMeasured_; 177 } 178 GetCurrentIndex()179 int32_t GetCurrentIndex() const 180 { 181 return currentIndex_; 182 } 183 SetIsNeedResetPrevMarginAndNextMargin()184 void SetIsNeedResetPrevMarginAndNextMargin() 185 { 186 isNeedResetPrevMarginAndNextMargin_ = false; 187 } 188 GetIsNeedResetPrevMarginAndNextMargin()189 bool GetIsNeedResetPrevMarginAndNextMargin() const 190 { 191 return isNeedResetPrevMarginAndNextMargin_; 192 } 193 IsCrossMatchChild()194 bool IsCrossMatchChild() const 195 { 196 return crossMatchChild_; 197 } 198 SetUseCustomAnimation(bool useCustomAnimation)199 void SetUseCustomAnimation(bool useCustomAnimation) 200 { 201 useCustomAnimation_ = useCustomAnimation; 202 } 203 SetCustomAnimationToIndex(std::optional<int32_t> customAnimationToIndex)204 void SetCustomAnimationToIndex(std::optional<int32_t> customAnimationToIndex) 205 { 206 customAnimationToIndex_ = customAnimationToIndex; 207 } 208 SetRemoveFromRSTreeIndex(std::optional<int32_t> removeFromRSTreeIndex)209 void SetRemoveFromRSTreeIndex(std::optional<int32_t> removeFromRSTreeIndex) 210 { 211 removeFromRSTreeIndex_ = removeFromRSTreeIndex; 212 } 213 SetIndexsInAnimation(const std::set<int32_t> & indexsInAnimation)214 void SetIndexsInAnimation(const std::set<int32_t>& indexsInAnimation) 215 { 216 indexsInAnimation_ = indexsInAnimation; 217 } 218 SetNeedUnmountIndexs(const std::set<int32_t> & needUnmountIndexs)219 void SetNeedUnmountIndexs(const std::set<int32_t>& needUnmountIndexs) 220 { 221 needUnmountIndexs_ = needUnmountIndexs; 222 } 223 GetNeedUnmountIndexs()224 std::set<int32_t> GetNeedUnmountIndexs() const 225 { 226 return needUnmountIndexs_; 227 } 228 SetSwipeByGroup(bool swipeByGroup)229 void SetSwipeByGroup(bool swipeByGroup) 230 { 231 swipeByGroup_ = swipeByGroup; 232 } 233 SetRealTotalCount(int32_t realTotalCount)234 void SetRealTotalCount(int32_t realTotalCount) 235 { 236 realTotalCount_ = realTotalCount; 237 } 238 SetPlaceItemWidth(std::optional<float> placeItemWidth)239 void SetPlaceItemWidth(std::optional<float> placeItemWidth) 240 { 241 placeItemWidth_ = placeItemWidth; 242 } 243 244 private: 245 void MeasureSwiper(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, Axis axis); 246 void MeasureCustomAnimation(LayoutWrapper* layoutWrapper); 247 void LayoutCustomAnimation(LayoutWrapper* layoutWrapper) const; 248 void SetInactive( 249 LayoutWrapper* layoutWrapper, float startMainPos, float endMainPos, std::optional<int32_t> targetIndex); 250 251 void PlaceDigitChild(const RefPtr<LayoutWrapper>& indicatorWrapper, const RefPtr<LayoutProperty>& layoutProperty); 252 RefPtr<LayoutWrapper> GetNodeLayoutWrapperByTag(LayoutWrapper* layoutWrapper, const std::string& tagName) const; 253 void MeasureArrow(const RefPtr<LayoutWrapper>& arrowWrapper, const RefPtr<LayoutProperty>& layoutProperty) const; 254 void ArrowLayout( 255 LayoutWrapper* layoutWrapper, const RefPtr<LayoutWrapper>& arrowWrapper, const PaddingPropertyF padding) const; 256 void ResetOffscreenItemPosition(LayoutWrapper* layoutWrapper, int32_t index, bool isForward, Axis axis) const; 257 int32_t GetDisplayCount(LayoutWrapper* layoutWrapper) const; 258 void SetInactiveOnForward(LayoutWrapper* layoutWrapper, Axis axis); 259 void SetInactiveOnBackward(LayoutWrapper* layoutWrapper, Axis axis); 260 void AdjustStartInfoOnSwipeByGroup( 261 int32_t startIndex, const PositionMap& itemPosition, int32_t& startIndexInVisibleWindow, float& startPos); 262 bool HasCustomIndicatorOffset(const RefPtr<LayoutWrapper>& indicatorWrapper); 263 const OffsetF CalculateCustomOffset( 264 const RefPtr<LayoutWrapper>& indicatorWrapper, const OffsetF& currentOffset); 265 266 bool isLoop_ = true; 267 float prevMargin_ = 0.0f; 268 float nextMargin_ = 0.0f; 269 270 PositionMap itemPosition_; 271 PositionMap prevItemPosition_; 272 float currentOffset_ = 0.0f; 273 float currentDelta_ = 0.0f; 274 float startMainPos_ = 0.0f; 275 float endMainPos_ = 0.0f; 276 277 float paddingBeforeContent_ = 0.0f; 278 float paddingAfterContent_ = 0.0f; 279 float contentMainSize_ = 0.0f; 280 float contentCrossSize_ = 0.0f; 281 int32_t totalItemCount_ = 0; 282 bool mainSizeIsDefined_ = false; 283 284 float spaceWidth_ = 0.0f; 285 bool overScrollFeature_ = false; 286 bool canOverScroll_ = false; 287 288 bool mainSizeIsMeasured_ = false; 289 bool crossMatchChild_ = false; 290 bool measured_ = false; // to distinguish first and second measure in flex layout 291 292 std::optional<int32_t> jumpIndex_; 293 std::optional<int32_t> targetIndex_; 294 std::optional<int32_t> currentTargetIndex_; 295 std::optional<int32_t> customAnimationToIndex_; 296 std::optional<int32_t> removeFromRSTreeIndex_; 297 int32_t currentIndex_ = 0; 298 bool targetIsSameWithStartFlag_ = false; 299 bool isNeedResetPrevMarginAndNextMargin_ = false; 300 bool useCustomAnimation_ = false; 301 std::set<int32_t> indexsInAnimation_; 302 std::set<int32_t> needUnmountIndexs_; 303 bool swipeByGroup_ = false; 304 int32_t realTotalCount_ = 0; 305 std::optional<float> placeItemWidth_; 306 bool useCustomIndicatorOffset = false; 307 }; 308 309 } // namespace OHOS::Ace::NG 310 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SWIPER_SWIPER_LAYOUT_ALGORITHM_H 311