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_GRID_GRID_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRID_GRID_PATTERN_H 18 19 #include "core/components_ng/pattern/grid/grid_accessibility_property.h" 20 #include "core/components_ng/pattern/grid/grid_content_modifier.h" 21 #include "core/components_ng/pattern/grid/grid_event_hub.h" 22 #include "core/components_ng/pattern/grid/grid_layout_info.h" 23 #include "core/components_ng/pattern/grid/grid_layout_property.h" 24 #include "core/components_ng/pattern/grid/grid_paint_method.h" 25 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h" 26 27 namespace OHOS::Ace::NG { 28 class InspectorFilter; 29 30 struct GridItemIndexInfo { 31 int32_t mainIndex = -1; 32 int32_t crossIndex = -1; 33 int32_t mainSpan = -1; 34 int32_t crossSpan = -1; 35 int32_t mainStart = -1; 36 int32_t mainEnd = -1; 37 int32_t crossStart = -1; 38 int32_t crossEnd = -1; 39 }; 40 41 class ACE_EXPORT GridPattern : public ScrollablePattern { 42 DECLARE_ACE_TYPE(GridPattern, ScrollablePattern); 43 44 public: 45 GridPattern() = default; 46 CreateLayoutProperty()47 RefPtr<LayoutProperty> CreateLayoutProperty() override 48 { 49 return MakeRefPtr<GridLayoutProperty>(); 50 } 51 52 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override; 53 54 void BeforeCreateLayoutWrapper() override; 55 56 RefPtr<PaintProperty> CreatePaintProperty() override; 57 58 RefPtr<NodePaintMethod> CreateNodePaintMethod() override; 59 CreateAccessibilityProperty()60 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 61 { 62 return MakeRefPtr<GridAccessibilityProperty>(); 63 } 64 IsScrollable()65 bool IsScrollable() const override 66 { 67 return isConfigScrollable_; 68 } 69 70 DisplayMode GetDefaultScrollBarDisplayMode() const override; 71 SetMultiSelectable(bool multiSelectable)72 void SetMultiSelectable(bool multiSelectable) 73 { 74 multiSelectable_ = multiSelectable; 75 } 76 MultiSelectable()77 bool MultiSelectable() const 78 { 79 return multiSelectable_; 80 } 81 SetSupportAnimation(bool supportAnimation)82 void SetSupportAnimation(bool supportAnimation) 83 { 84 supportAnimation_ = supportAnimation; 85 } 86 SupportAnimation()87 bool SupportAnimation() const 88 { 89 return supportAnimation_; 90 } 91 GetFocusPattern()92 FocusPattern GetFocusPattern() const override 93 { 94 return { FocusType::SCOPE, true }; 95 } 96 GetScopeFocusAlgorithm()97 ScopeFocusAlgorithm GetScopeFocusAlgorithm() override 98 { 99 auto property = GetLayoutProperty<GridLayoutProperty>(); 100 if (!property) { 101 return ScopeFocusAlgorithm(); 102 } 103 return ScopeFocusAlgorithm(property->IsVertical(), true, ScopeType::OTHERS, 104 [wp = WeakClaim(this)]( 105 FocusStep step, const WeakPtr<FocusHub>& currFocusNode, WeakPtr<FocusHub>& nextFocusNode) { 106 auto grid = wp.Upgrade(); 107 if (grid) { 108 nextFocusNode = grid->GetNextFocusNode(step, currFocusNode); 109 } 110 }); 111 } 112 113 int32_t GetFocusNodeIndex(const RefPtr<FocusHub>& focusNode) override; 114 115 void ScrollToFocusNodeIndex(int32_t index) override; 116 117 ScrollOffsetAbility GetScrollOffsetAbility() override; 118 119 std::function<bool(int32_t)> GetScrollIndexAbility() override; 120 121 bool ScrollToNode(const RefPtr<FrameNode>& focusFrameNode) override; 122 CreateEventHub()123 RefPtr<EventHub> CreateEventHub() override 124 { 125 return MakeRefPtr<GridEventHub>(); 126 } 127 UsResRegion()128 bool UsResRegion() override 129 { 130 return false; 131 } 132 GetGridLayoutInfo()133 const GridLayoutInfo& GetGridLayoutInfo() const 134 { 135 return gridLayoutInfo_; 136 } 137 138 /* caution when using mutable reference */ GetMutableLayoutInfo()139 GridLayoutInfo& GetMutableLayoutInfo() 140 { 141 return gridLayoutInfo_; 142 } 143 ResetGridLayoutInfo()144 void ResetGridLayoutInfo() 145 { 146 gridLayoutInfo_.lineHeightMap_.clear(); 147 gridLayoutInfo_.gridMatrix_.clear(); 148 gridLayoutInfo_.endIndex_ = gridLayoutInfo_.startIndex_ - 1; 149 gridLayoutInfo_.endMainLineIndex_ = 0; 150 gridLayoutInfo_.ResetPositionFlags(); 151 gridLayoutInfo_.irregularItemsPosition_.clear(); 152 gridLayoutInfo_.clearStretch_ = true; 153 } 154 SetIrregular(bool value)155 void SetIrregular(bool value) 156 { 157 irregular_ = value; 158 } 159 ResetPositionFlags()160 void ResetPositionFlags() 161 { 162 gridLayoutInfo_.ResetPositionFlags(); 163 } 164 165 void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override; 166 167 bool UpdateCurrentOffset(float offset, int32_t source) override; 168 IsAtTop()169 bool IsAtTop() const override 170 { 171 return gridLayoutInfo_.reachStart_; 172 } 173 IsAtBottom()174 bool IsAtBottom() const override 175 { 176 return gridLayoutInfo_.offsetEnd_; 177 } 178 179 bool IsFadingBottom() const override; 180 181 OverScrollOffset GetOverScrollOffset(double delta) const override; 182 void GetEndOverScrollIrregular(OverScrollOffset& offset, float delta) const; 183 184 void ScrollPage(bool reverse, bool smooth = false, 185 AccessibilityScrollType scrollType = AccessibilityScrollType::SCROLL_FULL) override; 186 187 bool UpdateStartIndex(int32_t index); 188 189 bool UpdateStartIndex(int32_t index, ScrollAlign align); 190 GetTotalOffset()191 float GetTotalOffset() const override 192 { 193 return EstimateHeight(); 194 } 195 196 float GetTotalHeight() const override; 197 198 void OnAnimateStop() override; 199 200 void AnimateTo( 201 float position, float duration, const RefPtr<Curve>& curve, bool smooth, bool canOverScroll = false, 202 bool useTotalOffset = true) override; 203 void ScrollTo(float position) override; 204 205 void ScrollBy(float offset); 206 GetDefaultScrollAlign()207 ScrollAlign GetDefaultScrollAlign() const override 208 { 209 return ScrollAlign::AUTO; 210 } 211 212 void ScrollToEdge(ScrollEdgeType scrollEdgeType, bool smooth) override; 213 214 void ScrollToIndex(int32_t index, bool smooth = false, ScrollAlign align = ScrollAlign::AUTO, 215 std::optional<float> extraOffset = std::nullopt) override; 216 void AnimateToTarget(ScrollAlign align, const RefPtr<LayoutAlgorithmWrapper>& algo); 217 bool AnimateToTargetImpl(ScrollAlign align, const RefPtr<LayoutAlgorithmWrapper>& algo); 218 219 int32_t GetOriginalIndex() const; 220 int32_t GetCrossCount() const; 221 int32_t GetChildrenCount() const; 222 void MoveItems(int32_t itemIndex, int32_t insertIndex); 223 void ClearDragState(); 224 float EstimateHeight() const; 225 float GetAverageHeight() const; 226 227 void DumpAdvanceInfo() override; 228 229 std::string ProvideRestoreInfo() override; 230 void OnRestoreInfo(const std::string& restoreInfo) override; 231 Rect GetItemRect(int32_t index) const override; 232 int32_t GetItemIndex(double x, double y) const override; 233 IsNeedInitClickEventRecorder()234 bool IsNeedInitClickEventRecorder() const override 235 { 236 return true; 237 } 238 HasPreloadItemList()239 bool HasPreloadItemList() const 240 { 241 return !preloadItemList_.empty(); 242 } 243 MovePreloadItemList()244 std::list<GridPreloadItem> MovePreloadItemList() 245 { 246 return std::move(preloadItemList_); 247 } 248 SetPreloadItemList(std::list<GridPreloadItem> && list)249 void SetPreloadItemList(std::list<GridPreloadItem>&& list) 250 { 251 preloadItemList_ = std::move(list); 252 } 253 254 std::vector<RefPtr<FrameNode>> GetVisibleSelectedItems() override; 255 256 void StopAnimate() override; 257 258 bool IsPredictOutOfRange(int32_t index) const; 259 260 bool IsReverse() const override; 261 GetAxis()262 Axis GetAxis() const override 263 { 264 return gridLayoutInfo_.axis_; 265 } 266 GetDefaultCachedCount()267 int32_t GetDefaultCachedCount() const 268 { 269 return gridLayoutInfo_.defCachedCount_; 270 } 271 272 SizeF GetChildrenExpandedSize() override; 273 274 private: 275 /** 276 * @brief calculate where startMainLine_ should be after spring animation. 277 * @return main axis position relative to viewport, positive when below viewport. 278 */ 279 float GetEndOffset(); 280 float GetMainGap() const; 281 float GetAllDelta(); 282 void CheckScrollable(); 283 bool IsOutOfBoundary(bool useCurrentDelta) override; 284 void SetEdgeEffectCallback(const RefPtr<ScrollEdgeEffect>& scrollEffect) override; 285 SizeF GetContentSize() const; 286 void OnModifyDone() override; 287 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 288 WeakPtr<FocusHub> GetNextFocusNode(FocusStep step, const WeakPtr<FocusHub>& currentFocusNode); 289 std::pair<int32_t, int32_t> GetNextIndexByStep( 290 int32_t curMainIndex, int32_t curCrossIndex, int32_t curMainSpan, int32_t curCrossSpan, FocusStep step); 291 WeakPtr<FocusHub> SearchFocusableChildInCross(int32_t tarMainIndex, int32_t tarCrossIndex, int32_t maxCrossCount, 292 int32_t curMainIndex = -1, int32_t curCrossIndex = -1); 293 WeakPtr<FocusHub> SearchIrregularFocusableChild(int32_t tarMainIndex, int32_t tarCrossIndex); 294 WeakPtr<FocusHub> GetChildFocusNodeByIndex(int32_t tarMainIndex, int32_t tarCrossIndex, int32_t tarIndex = -1); 295 std::unordered_set<int32_t> GetFocusableChildCrossIndexesAt(int32_t tarMainIndex); 296 void ScrollToFocusNode(const WeakPtr<FocusHub>& focusNode); 297 void FlushFocusOnScroll(const GridLayoutInfo& gridLayoutInfo); 298 std::pair<bool, bool> IsFirstOrLastFocusableChild(int32_t curMainIndex, int32_t curCrossIndex); 299 std::pair<FocusStep, FocusStep> GetFocusSteps(int32_t curMainIndex, int32_t curCrossIndex, FocusStep step); 300 void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub); 301 bool OnKeyEvent(const KeyEvent& event); 302 bool HandleDirectionKey(KeyCode code); 303 304 void ClearMultiSelect() override; 305 bool IsItemSelected(const GestureEvent& info) override; 306 void MultiSelectWithoutKeyboard(const RectF& selectedZone) override; 307 void UpdateScrollBarOffset() override; 308 void UpdateRectOfDraggedInItem(int32_t insertIndex); 309 310 void ProcessEvent(bool indexChanged, float finalOffset); 311 void MarkDirtyNodeSelf(); 312 void OnScrollEndCallback() override; 313 314 /** 315 * @brief preform a layout if LayoutInfo is out of sync before calculating spring positions. 316 * INVARIANT: overScroll always enabled in the scope of this function. Because this function only runs in the 317 * context of spring animation. 318 */ 319 void SyncLayoutBeforeSpring(); 320 321 void FireOnScrollStart() override; 322 void FireOnReachStart(const OnReachEvent& onReachStart) override; 323 void FireOnReachEnd(const OnReachEvent& onReachEnd) override; 324 void FireOnScrollIndex(bool indexChanged, const ScrollIndexFunc& onScrollIndex); 325 326 inline bool UseIrregularLayout() const; 327 328 int32_t CalcIntersectAreaInTargetDirectionShadow(GridItemIndexInfo itemIndexInfo, bool isFindInMainAxis); 329 double GetNearestDistanceFromChildToCurFocusItemInMainAxis(int32_t targetIndex, GridItemIndexInfo itemIndexInfo); 330 double GetNearestDistanceFromChildToCurFocusItemInCrossAxis(int32_t targetIndex, GridItemIndexInfo itemIndexInfo); 331 void ResetAllDirectionsStep(); 332 333 std::string GetIrregularIndexesString() const; 334 335 bool supportAnimation_ = false; 336 bool isConfigScrollable_ = false; 337 338 bool scrollable_ = true; 339 bool forceOverScroll_ = false; 340 341 RefPtr<GridContentModifier> gridContentModifier_; 342 343 float endHeight_ = 0.0f; 344 bool isLeftStep_ = false; 345 bool isRightStep_ = false; 346 bool isUpStep_ = false; 347 bool isDownStep_ = false; 348 bool isLeftEndStep_ = false; 349 bool isRightEndStep_ = false; 350 bool isSmoothScrolling_ = false; 351 bool irregular_ = false; // true if LayoutOptions require running IrregularLayout 352 353 ScrollAlign scrollAlign_ = ScrollAlign::AUTO; 354 std::optional<int32_t> targetIndex_; 355 std::pair<std::optional<float>, std::optional<float>> scrollbarInfo_; 356 GridItemIndexInfo curFocusIndexInfo_; 357 GridLayoutInfo scrollGridLayoutInfo_; 358 GridLayoutInfo gridLayoutInfo_; 359 std::list<GridPreloadItem> preloadItemList_; // list of GridItems to build preemptively in IdleTask 360 ACE_DISALLOW_COPY_AND_MOVE(GridPattern); 361 }; 362 363 } // namespace OHOS::Ace::NG 364 365 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRID_GRID_PATTERN_H 366