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