• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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