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_SCROLL_SCROLL_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_PATTERN_H 18 19 #include "base/geometry/axis.h" 20 #include "core/components/common/layout/constants.h" 21 #include "core/components_ng/event/event_hub.h" 22 #include "core/components_ng/pattern/pattern.h" 23 #include "core/components_ng/pattern/scroll/scroll_accessibility_property.h" 24 #include "core/components_ng/pattern/scroll/scroll_edge_effect.h" 25 #include "core/components_ng/pattern/scroll/scroll_event_hub.h" 26 #include "core/components_ng/pattern/scroll/scroll_layout_algorithm.h" 27 #include "core/components_ng/pattern/scroll/scroll_layout_property.h" 28 #include "core/components_ng/pattern/scroll/scroll_paint_property.h" 29 #include "core/components_ng/pattern/scroll/scroll_paint_method.h" 30 #include "core/components_ng/pattern/scroll/scroll_position_controller.h" 31 #include "core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.h" 32 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h" 33 #include "core/components_ng/pattern/scrollable/scrollable_properties.h" 34 35 namespace OHOS::Ace::NG { 36 37 class ScrollPattern : public ScrollablePattern { 38 DECLARE_ACE_TYPE(ScrollPattern, ScrollablePattern); 39 40 public: 41 ScrollPattern() = default; ~ScrollPattern()42 ~ScrollPattern() override 43 { 44 positionController_ = nullptr; 45 } 46 IsAtomicNode()47 bool IsAtomicNode() const override 48 { 49 return false; 50 } 51 UsResRegion()52 bool UsResRegion() override 53 { 54 return false; 55 } 56 CreateLayoutProperty()57 RefPtr<LayoutProperty> CreateLayoutProperty() override 58 { 59 return MakeRefPtr<ScrollLayoutProperty>(); 60 } 61 CreatePaintProperty()62 RefPtr<PaintProperty> CreatePaintProperty() override 63 { 64 return MakeRefPtr<ScrollPaintProperty>(); 65 } 66 CreateAccessibilityProperty()67 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 68 { 69 return MakeRefPtr<ScrollAccessibilityProperty>(); 70 } 71 CreateLayoutAlgorithm()72 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 73 { 74 auto layoutAlgorithm = MakeRefPtr<ScrollLayoutAlgorithm>(currentOffset_); 75 return layoutAlgorithm; 76 } 77 CreateNodePaintMethod()78 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 79 { 80 auto paint = MakeRefPtr<ScrollPaintMethod>(); 81 paint->SetScrollBar(GetScrollBar()); 82 CreateScrollBarOverlayModifier(); 83 paint->SetScrollBarOverlayModifier(GetScrollBarOverlayModifier()); 84 auto scrollEffect = GetScrollEdgeEffect(); 85 if (scrollEffect && scrollEffect->IsFadeEffect()) { 86 paint->SetEdgeEffect(scrollEffect); 87 } 88 return paint; 89 } 90 CreateEventHub()91 RefPtr<EventHub> CreateEventHub() override 92 { 93 return MakeRefPtr<ScrollEventHub>(); 94 } 95 ReachMaxCount()96 virtual bool ReachMaxCount() const 97 { 98 return true; 99 } 100 IsScrollable()101 bool IsScrollable() const override 102 { 103 return GetAxis() != Axis::NONE; 104 } 105 106 bool OnScrollCallback(float offset, int32_t source) override; 107 void OnScrollEndCallback() override; 108 GetCurrentPosition()109 double GetCurrentPosition() const 110 { 111 return currentOffset_; 112 } 113 GetTotalOffset()114 float GetTotalOffset() const override 115 { 116 return -currentOffset_; 117 } 118 119 void ResetPosition(); 120 GetCurrentOffset()121 Offset GetCurrentOffset() const 122 { 123 if (GetAxis() == Axis::HORIZONTAL) { 124 return Offset{currentOffset_, 0}; 125 } 126 return Offset{0, currentOffset_}; 127 } 128 GetScrollableDistance()129 float GetScrollableDistance() const 130 { 131 return scrollableDistance_; 132 } 133 IsRowReverse()134 bool IsRowReverse() const 135 { 136 // TODO: not consider rightToLeft 137 return direction_ == FlexDirection::ROW_REVERSE; 138 } 139 IsColReverse()140 bool IsColReverse() const 141 { 142 return direction_ == FlexDirection::COLUMN_REVERSE; 143 } 144 GetScrollPositionController()145 RefPtr<ScrollPositionController> GetScrollPositionController() const 146 { 147 return positionController_; 148 } 149 SetScrollPositionController(const RefPtr<ScrollPositionController> & positionController)150 void SetScrollPositionController(const RefPtr<ScrollPositionController>& positionController) 151 { 152 positionController_ = positionController; 153 } 154 SetDirection(FlexDirection direction)155 void SetDirection(FlexDirection direction) 156 { 157 direction_ = direction; 158 } 159 GetFocusPattern()160 FocusPattern GetFocusPattern() const override 161 { 162 return { FocusType::SCOPE, true }; 163 } 164 165 bool ScrollToNode(const RefPtr<FrameNode>& focusFrameNode) override; 166 167 bool IsAtTop() const override; 168 bool IsAtBottom() const override; 169 bool IsOutOfBoundary() const; 170 OverScrollOffset GetOverScrollOffset(double delta) const override; 171 172 void OnAnimateStop() override; 173 bool UpdateCurrentOffset(float offset, int32_t source) override; 174 void AnimateTo(float position, float duration, const RefPtr<Curve>& curve, bool smooth) override; 175 void ScrollToEdge(ScrollEdgeType scrollEdgeType, bool smooth); 176 void ScrollBy(float pixelX, float pixelY, bool smooth, const std::function<void()>& onFinish = nullptr); 177 bool ScrollPage(bool reverse, bool smooth, const std::function<void()>& onFinish = nullptr); 178 void ScrollTo(float position) override; 179 void JumpToPosition(float position, int32_t source = SCROLL_FROM_JUMP); 180 bool ScrollPageCheck(float delta, int32_t source); 181 void AdjustOffset(float& delta, int32_t source); 182 void ToJsonValue(std::unique_ptr<JsonValue>& json) const override; 183 184 // scrollSnap 185 std::optional<float> CalePredictSnapOffset(float delta) override; 186 bool NeedScrollSnapToSide(float delta) override; 187 void CaleSnapOffsets(); 188 void CaleSnapOffsetsByInterval(ScrollSnapAlign scrollSnapAlign); 189 void CaleSnapOffsetsByPaginations(); 190 IsSnapToInterval()191 bool IsSnapToInterval() const 192 { 193 return snapPaginations_.empty(); 194 } 195 GetSnapOffsets()196 std::vector<float> GetSnapOffsets() const 197 { 198 return snapOffsets_; 199 } 200 SetSnapOffsets(const std::vector<float> & snapOffset)201 void SetSnapOffsets(const std::vector<float>& snapOffset) 202 { 203 snapOffsets_ = snapOffset; 204 } 205 SetIntervalSize(const Dimension & intervalSize)206 void SetIntervalSize(const Dimension& intervalSize) 207 { 208 if (intervalSize_ != intervalSize) { 209 intervalSize_ = intervalSize; 210 scrollSnapUpdate_ = true; 211 } 212 } 213 GetIntervalSize()214 Dimension GetIntervalSize() const 215 { 216 return intervalSize_; 217 } 218 SetSnapPaginations(const std::vector<Dimension> & snapPaginations)219 void SetSnapPaginations(const std::vector<Dimension>& snapPaginations) 220 { 221 if (snapPaginations_ != snapPaginations) { 222 snapPaginations_ = snapPaginations; 223 scrollSnapUpdate_ = true; 224 } 225 } 226 GetSnapPaginations()227 std::vector<Dimension> GetSnapPaginations() const 228 { 229 return snapPaginations_; 230 } 231 SetEnableSnapToSide(const std::pair<bool,bool> & enableSnapToSide)232 void SetEnableSnapToSide(const std::pair<bool, bool>& enableSnapToSide) 233 { 234 enableSnapToSide_ = enableSnapToSide; 235 } 236 GetEnableSnapToSide()237 std::pair<bool, bool> GetEnableSnapToSide() const 238 { 239 return enableSnapToSide_; 240 } 241 SetScrollSnapUpdate(bool scrollSnapUpdate)242 void SetScrollSnapUpdate(bool scrollSnapUpdate) 243 { 244 scrollSnapUpdate_ = scrollSnapUpdate; 245 } 246 GetScrollSnapUpdate()247 bool GetScrollSnapUpdate() const 248 { 249 return scrollSnapUpdate_; 250 } 251 GetScrollSnapAlign()252 ScrollSnapAlign GetScrollSnapAlign() const 253 { 254 auto host = GetHost(); 255 CHECK_NULL_RETURN_NOLOG(host, ScrollSnapAlign::NONE); 256 auto scrollLayoutProperty = host->GetLayoutProperty<ScrollLayoutProperty>(); 257 CHECK_NULL_RETURN_NOLOG(scrollLayoutProperty, ScrollSnapAlign::NONE); 258 return scrollLayoutProperty->GetScrollSnapAlign().value_or(ScrollSnapAlign::NONE); 259 } 260 261 protected: 262 void DoJump(float position, int32_t source = SCROLL_FROM_JUMP); 263 264 private: 265 void OnModifyDone() override; 266 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 267 268 bool IsCrashTop() const; 269 bool IsCrashBottom() const; 270 bool IsScrollOutOnEdge(float delta) const; 271 void HandleCrashTop() const; 272 void HandleCrashBottom() const; 273 274 void RegisterScrollEventTask(); 275 void RegisterScrollBarEventTask(); 276 void HandleScrollEffect(); 277 void ValidateOffset(int32_t source); 278 void HandleScrollPosition(float scroll, int32_t scrollState); 279 void SetEdgeEffectCallback(const RefPtr<ScrollEdgeEffect>& scrollEffect) override; 280 void AddScrollEdgeEffect(RefPtr<ScrollEdgeEffect> scrollEffect); 281 void UpdateScrollBarOffset() override; 282 void FireOnScrollStart(); 283 void FireOnScrollStop(); 284 void SetAccessibilityAction(); 285 void CheckScrollable(); 286 OffsetF GetOffsetToScroll(const RefPtr<FrameNode>& childFrame) const; 287 288 RefPtr<ScrollPositionController> positionController_; 289 float currentOffset_ = 0.0f; 290 float lastOffset_ = 0.0f; 291 float scrollableDistance_ = 0.0f; 292 float viewPortLength_ = 0.0f; 293 SizeF viewPort_; 294 SizeF viewSize_; 295 SizeF viewPortExtent_; 296 FlexDirection direction_ { FlexDirection::COLUMN }; 297 bool scrollStop_ = false; 298 299 // scrollSnap 300 std::vector<float> snapOffsets_; 301 std::vector<Dimension> snapPaginations_; 302 std::pair<bool, bool> enableSnapToSide_ = { true, true }; 303 Dimension intervalSize_; 304 bool scrollSnapUpdate_ = false; 305 }; 306 307 } // namespace OHOS::Ace::NG 308 309 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_PATTERN_H 310