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