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_LIST_LIST_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_LIST_LIST_PATTERN_H 18 19 #include "core/animation/chain_animation.h" 20 #include "core/components_ng/event/event_hub.h" 21 #include "core/components_ng/pattern/list/list_accessibility_property.h" 22 #include "core/components_ng/pattern/list/list_content_modifier.h" 23 #include "core/components_ng/pattern/list/list_event_hub.h" 24 #include "core/components_ng/pattern/list/list_item_pattern.h" 25 #include "core/components_ng/pattern/list/list_layout_algorithm.h" 26 #include "core/components_ng/pattern/list/list_layout_property.h" 27 #include "core/components_ng/pattern/list/list_paint_method.h" 28 #include "core/components_ng/pattern/list/list_paint_property.h" 29 #include "core/components_ng/pattern/list/list_position_controller.h" 30 #include "core/components_ng/pattern/pattern.h" 31 #include "core/components_ng/pattern/scroll/inner/scroll_bar.h" 32 #include "core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.h" 33 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h" 34 #include "core/components_ng/render/render_context.h" 35 #include "core/pipeline_ng/pipeline_context.h" 36 37 namespace OHOS::Ace::NG { 38 struct ListItemGroupPara { 39 int32_t lanes = -1; 40 int32_t itemEndIndex = -1; 41 int32_t displayStartIndex = -1; 42 int32_t displayEndIndex = -1; 43 }; 44 45 class ListPattern : public ScrollablePattern { 46 DECLARE_ACE_TYPE(ListPattern, ScrollablePattern); 47 48 public: 49 ListPattern() = default; 50 ~ListPattern() override = default; 51 52 RefPtr<NodePaintMethod> CreateNodePaintMethod() override; 53 IsAtomicNode()54 bool IsAtomicNode() const override 55 { 56 return false; 57 } 58 CreateLayoutProperty()59 RefPtr<LayoutProperty> CreateLayoutProperty() override 60 { 61 return MakeRefPtr<ListLayoutProperty>(); 62 } 63 CreatePaintProperty()64 RefPtr<PaintProperty> CreatePaintProperty() override 65 { 66 return MakeRefPtr<ListPaintProperty>(); 67 } 68 CreateEventHub()69 RefPtr<EventHub> CreateEventHub() override 70 { 71 return MakeRefPtr<ListEventHub>(); 72 } 73 CreateAccessibilityProperty()74 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 75 { 76 return MakeRefPtr<ListAccessibilityProperty>(); 77 } 78 UsResRegion()79 bool UsResRegion() override 80 { 81 return false; 82 } 83 84 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override; 85 86 void ToJsonValue(std::unique_ptr<JsonValue>& json) const override; 87 88 void FromJson(const std::unique_ptr<JsonValue>& json) override; 89 90 bool UpdateCurrentOffset(float offset, int32_t source) override; 91 GetStartIndex()92 int32_t GetStartIndex() const 93 { 94 return startIndex_; 95 } 96 GetEndIndex()97 int32_t GetEndIndex() const 98 { 99 return endIndex_; 100 } 101 GetMaxListItemIndex()102 int32_t GetMaxListItemIndex() const 103 { 104 return maxListItemIndex_; 105 } 106 IsScrollable()107 bool IsScrollable() const override 108 { 109 return scrollable_; 110 } 111 112 bool IsAtTop() const override; 113 bool IsAtBottom() const override; 114 bool OutBoundaryCallback() override; 115 OverScrollOffset GetOverScrollOffset(double delta) const override; 116 GetFocusPattern()117 FocusPattern GetFocusPattern() const override 118 { 119 return { FocusType::SCOPE, true }; 120 } 121 GetScopeFocusAlgorithm()122 ScopeFocusAlgorithm GetScopeFocusAlgorithm() override 123 { 124 auto property = GetLayoutProperty<ListLayoutProperty>(); 125 if (!property) { 126 return {}; 127 } 128 return ScopeFocusAlgorithm(property->GetListDirection().value_or(Axis::VERTICAL) == Axis::VERTICAL, true, 129 ScopeType::OTHERS, 130 [wp = WeakClaim(this)]( 131 FocusStep step, const WeakPtr<FocusHub>& currFocusNode, WeakPtr<FocusHub>& nextFocusNode) { 132 auto list = wp.Upgrade(); 133 if (list) { 134 nextFocusNode = list->GetNextFocusNode(step, currFocusNode); 135 } 136 }); 137 } 138 139 bool ScrollToNode(const RefPtr<FrameNode>& focusFrameNode) override; 140 GetItemPosition()141 const ListLayoutAlgorithm::PositionMap& GetItemPosition() const 142 { 143 return itemPosition_; 144 } 145 SetPositionController(RefPtr<ListPositionController> control)146 void SetPositionController(RefPtr<ListPositionController> control) 147 { 148 positionController_ = control; 149 if (control) { 150 control->SetScrollPattern(AceType::WeakClaim<ListPattern>(this)); 151 } 152 } 153 GetTotalOffset()154 float GetTotalOffset() const override 155 { 156 return currentOffset_; 157 } 158 159 float GetTotalHeight() const override; 160 161 // scroller AnimateTo(float position,float duration,const RefPtr<Curve> & curve,bool smooth)162 void AnimateTo(float position, float duration, const RefPtr<Curve>& curve, bool smooth) override 163 { 164 ScrollablePattern::AnimateTo(position, duration, curve, smooth); 165 FireOnScrollStart(); 166 } 167 void ScrollTo(float position) override; 168 void ScrollToIndex(int32_t index, bool smooth = false, ScrollAlign align = ScrollAlign::START); 169 void ScrollToIndex(int32_t index, int32_t indexInGroup, ScrollAlign align); 170 void ScrollToEdge(ScrollEdgeType scrollEdgeType); 171 bool ScrollPage(bool reverse); 172 void ScrollBy(float offset); 173 Offset GetCurrentOffset() const; 174 void OnAnimateStop() override; 175 176 void UpdateScrollBarOffset() override; 177 // chain animation 178 void SetChainAnimation(); 179 void SetChainAnimationOptions(const ChainAnimationOptions& options); 180 float FlushChainAnimation(float dragOffset); 181 void ProcessDragStart(float startPosition); 182 void ProcessDragUpdate(float dragOffset, int32_t source); 183 float GetChainDelta(int32_t index) const; 184 185 // multiSelectable SetMultiSelectable(bool multiSelectable)186 void SetMultiSelectable(bool multiSelectable) 187 { 188 multiSelectable_ = multiSelectable; 189 } 190 191 void SetSwiperItem(WeakPtr<ListItemPattern> swiperItem); 192 SetPredictSnapOffset(float predictSnapOffset)193 void SetPredictSnapOffset(float predictSnapOffset) 194 { 195 predictSnapOffset_ = predictSnapOffset; 196 } 197 bool OnScrollSnapCallback(double targetOffset, double velocity) override; 198 199 int32_t GetItemIndexByPosition(float xOffset, float yOffset); 200 SetPredictLayoutParam(std::optional<ListPredictLayoutParam> param)201 void SetPredictLayoutParam(std::optional<ListPredictLayoutParam> param) 202 { 203 predictLayoutParam_ = param; 204 } GetPredictLayoutParam()205 std::optional<ListPredictLayoutParam> GetPredictLayoutParam() const 206 { 207 return predictLayoutParam_; 208 } 209 private: 210 void OnScrollEndCallback() override; 211 void OnScrollStartCallback() override; 212 213 void OnModifyDone() override; 214 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 215 float CalculateTargetPos(float startPos, float endPos, ScrollAutoType scrollAutoType); 216 217 void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub); 218 bool OnKeyEvent(const KeyEvent& event); 219 bool HandleDirectionKey(const KeyEvent& event); 220 WeakPtr<FocusHub> GetNextFocusNode(FocusStep step, const WeakPtr<FocusHub>& currentFocusNode); 221 WeakPtr<FocusHub> GetChildFocusNodeByIndex(int32_t tarMainIndex, int32_t tarGroupIndex); 222 WeakPtr<FocusHub> ScrollAndFindFocusNode(int32_t nextIndex, int32_t curIndex, int32_t& nextIndexInGroup, 223 int32_t curIndexInGroup, int32_t moveStep, FocusStep step); 224 bool ScrollListForFocus(int32_t nextIndex, int32_t curIndex, int32_t nextIndexInGroup); 225 bool ScrollListItemGroupForFocus(int32_t nextIndex, int32_t& nextIndexInGroup, int32_t curIndexInGroup, 226 int32_t moveStep, FocusStep step, bool isScrollIndex); 227 228 void MarkDirtyNodeSelf(); 229 SizeF GetContentSize() const; 230 void ProcessEvent(bool indexChanged, float finalOffset, bool isJump, float prevStartOffset, float prevEndOffset); 231 void CheckScrollable(); 232 bool IsOutOfBoundary(bool useCurrentDelta = true); 233 bool OnScrollCallback(float offset, int32_t source) override; 234 void InitScrollableEvent(); 235 void SetEdgeEffectCallback(const RefPtr<ScrollEdgeEffect>& scrollEffect) override; 236 void HandleScrollEffect(float offset); 237 void FireOnScrollStart(); 238 void CheckRestartSpring(); 239 void StartDefaultOrCustomSpringMotion(float start, float end, const RefPtr<InterpolatingSpring>& curve); 240 void UpdateScrollSnap(); 241 bool IsScrollSnapAlignCenter() const; 242 void SetChainAnimationLayoutAlgorithm( 243 RefPtr<ListLayoutAlgorithm> listLayoutAlgorithm, RefPtr<ListLayoutProperty> listLayoutProperty); 244 bool NeedScrollSnapAlignEffect() const; 245 ScrollAlign GetScrollAlignByScrollSnapAlign() const; 246 247 // multiSelectable 248 void ClearMultiSelect() override; 249 bool IsItemSelected(const MouseInfo& info) override; 250 void MultiSelectWithoutKeyboard(const RectF& selectedZone) override; 251 void HandleCardModeSelectedEvent( 252 const RectF& selectedZone, const RefPtr<FrameNode>& itemGroupNode, float itemGroupTop); 253 254 void DrivenRender(const RefPtr<LayoutWrapper>& layoutWrapper); 255 void SetAccessibilityAction(); 256 ListItemGroupPara GetListItemGroupParameter(const RefPtr<FrameNode>& node); 257 bool IsListItemGroup(int32_t listIndex, RefPtr<FrameNode>& node); 258 void GetListItemGroupEdge(bool& groupAtStart, bool& groupAtEnd) const; 259 void RefreshLanesItemRange(); 260 261 RefPtr<ListContentModifier> listContentModifier_; 262 263 RefPtr<ListPositionController> positionController_; 264 int32_t maxListItemIndex_ = 0; 265 int32_t startIndex_ = -1; 266 int32_t endIndex_ = -1; 267 int32_t centerIndex_ = -1; 268 float startMainPos_; 269 float endMainPos_; 270 bool isInitialized_ = false; 271 float currentOffset_ = 0.0f; 272 float spaceWidth_ = 0.0f; 273 float contentMainSize_ = 0.0f; 274 float contentStartOffset_ = 0.0f; 275 float contentEndOffset_ = 0.0f; 276 277 float currentDelta_ = 0.0f; 278 bool crossMatchChild_ = false; 279 bool smooth_ = false; 280 float scrollSnapVelocity_ = 0.0f; 281 282 std::optional<int32_t> jumpIndex_; 283 std::optional<int32_t> jumpIndexInGroup_; 284 std::optional<int32_t> targetIndex_; 285 std::optional<float> predictSnapOffset_; 286 ScrollAlign scrollAlign_ = ScrollAlign::START; 287 bool scrollable_ = true; 288 bool paintStateFlag_ = false; 289 bool isFramePaintStateValid_ = false; 290 291 ListLayoutAlgorithm::PositionMap itemPosition_; 292 bool scrollStop_ = false; 293 294 std::map<int32_t, int32_t> lanesItemRange_; 295 int32_t lanes_ = 1; 296 float laneGutter_ = 0.0f; 297 // chain animation 298 RefPtr<ChainAnimation> chainAnimation_; 299 bool dragFromSpring_ = false; 300 RefPtr<SpringProperty> springProperty_; 301 std::optional<ChainAnimationOptions> chainAnimationOptions_; 302 303 bool isOritationListenerRegisted_ = false; 304 305 // ListItem swiperAction 306 WeakPtr<ListItemPattern> swiperItem_; 307 RefPtr<SpringMotion> scrollToIndexMotion_; 308 RefPtr<SpringMotion> scrollSnapMotion_; 309 RefPtr<Scrollable> scrollableTouchEvent_; 310 311 bool isScrollEnd_ = false; 312 std::optional<ListPredictLayoutParam> predictLayoutParam_; 313 }; 314 } // namespace OHOS::Ace::NG 315 316 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_LIST_LIST_PATTERN_H 317