1 /* 2 * Copyright (c) 2022-2024 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_SWIPER_INDICATOR_SWIPER_INDICATOR_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_INDICATOR_SWIPER_INDICATOR_PATTERN_H 18 19 #include "base/memory/ace_type.h" 20 #include "base/utils/utils.h" 21 #include "core/components_ng/base/frame_node.h" 22 #include "core/components_ng/pattern/pattern.h" 23 #include "core/components_ng/pattern/swiper/swiper_pattern.h" 24 #include "core/components_ng/pattern/swiper_indicator/digit_indicator/digit_indicator_layout_algorithm.h" 25 #include "core/components_ng/pattern/swiper_indicator/dot_indicator/overlength_dot_indicator_paint_method.h" 26 #include "core/components_ng/pattern/swiper_indicator/dot_indicator/dot_indicator_layout_algorithm.h" 27 #include "core/components_ng/pattern/swiper_indicator/dot_indicator/dot_indicator_paint_method.h" 28 #include "core/components_ng/pattern/swiper_indicator/indicator_common/swiper_indicator_accessibility_property.h" 29 #include "core/components_ng/pattern/swiper_indicator/indicator_common/swiper_indicator_layout_property.h" 30 #include "core/components_ng/pattern/swiper_indicator/indicator_common/swiper_indicator_utils.h" 31 #include "core/components_ng/pattern/text/text_layout_property.h" 32 #include "core/components_ng/pattern/text/text_pattern.h" 33 namespace OHOS::Ace::NG { 34 class SwiperIndicatorPattern : public Pattern { 35 DECLARE_ACE_TYPE(SwiperIndicatorPattern, Pattern); 36 public: 37 SwiperIndicatorPattern() = default; 38 ~SwiperIndicatorPattern() override = default; 39 CreateLayoutProperty()40 RefPtr<LayoutProperty> CreateLayoutProperty() override 41 { 42 return MakeRefPtr<SwiperIndicatorLayoutProperty>(); 43 } 44 CreatePaintProperty()45 RefPtr<PaintProperty> CreatePaintProperty() override 46 { 47 if (GetIndicatorType() == SwiperIndicatorType::DOT) { 48 return MakeRefPtr<DotIndicatorPaintProperty>(); 49 } else { 50 return MakeRefPtr<PaintProperty>(); 51 } 52 } 53 CreateAccessibilityProperty()54 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 55 { 56 return MakeRefPtr<SwiperIndicatorAccessibilityProperty>(); 57 } 58 CreateLayoutAlgorithm()59 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 60 { 61 auto swiperNode = GetSwiperNode(); 62 CHECK_NULL_RETURN(swiperNode, nullptr); 63 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>(); 64 CHECK_NULL_RETURN(swiperPattern, nullptr); 65 if (GetIndicatorType() == SwiperIndicatorType::DOT) { 66 auto indicatorLayoutAlgorithm = MakeRefPtr<DotIndicatorLayoutAlgorithm>(); 67 indicatorLayoutAlgorithm->SetIsHoverOrPress(isHover_ || isPressed_); 68 indicatorLayoutAlgorithm->SetHoverPoint(hoverPoint_); 69 70 auto maxDisplayCount = swiperPattern->GetMaxDisplayCount(); 71 maxDisplayCount > 0 ? indicatorLayoutAlgorithm->SetIndicatorDisplayCount(maxDisplayCount) 72 : indicatorLayoutAlgorithm->SetIndicatorDisplayCount(swiperPattern->TotalCount()); 73 return indicatorLayoutAlgorithm; 74 } else { 75 auto indicatorLayoutAlgorithm = MakeRefPtr<DigitIndicatorLayoutAlgorithm>(); 76 indicatorLayoutAlgorithm->SetIsHoverOrPress(isHover_ || isPressed_); 77 indicatorLayoutAlgorithm->SetHoverPoint(hoverPoint_); 78 return indicatorLayoutAlgorithm; 79 } 80 } 81 SetDotIndicatorPaintMethodInfo(const RefPtr<SwiperPattern> & swiperPattern,RefPtr<DotIndicatorPaintMethod> & paintMethod,RefPtr<SwiperLayoutProperty> & swiperLayoutProperty)82 void SetDotIndicatorPaintMethodInfo(const RefPtr<SwiperPattern>& swiperPattern, 83 RefPtr<DotIndicatorPaintMethod>& paintMethod, 84 RefPtr<SwiperLayoutProperty>& swiperLayoutProperty) 85 { 86 paintMethod->SetAxis(swiperPattern->GetDirection()); 87 paintMethod->SetCurrentIndex(swiperPattern->GetLoopIndex(swiperPattern->GetCurrentFirstIndex())); 88 paintMethod->SetCurrentIndexActual(swiperPattern->GetLoopIndex(swiperPattern->GetCurrentIndex())); 89 paintMethod->SetItemCount(swiperPattern->TotalCount()); 90 paintMethod->SetHorizontalAndRightToLeft(swiperLayoutProperty->GetNonAutoLayoutDirection()); 91 paintMethod->SetDisplayCount(swiperLayoutProperty->GetDisplayCount().value_or(1)); 92 gestureState_ = swiperPattern->GetGestureState(); 93 paintMethod->SetGestureState(gestureState_); 94 paintMethod->SetTurnPageRate(swiperPattern->GetTurnPageRate()); 95 paintMethod->SetIsLoop(swiperPattern->IsLoop()); 96 paintMethod->SetTouchBottomTypeLoop(swiperPattern->GetTouchBottomTypeLoop()); 97 paintMethod->SetIsHover(isHover_); 98 paintMethod->SetIsPressed(isPressed_); 99 paintMethod->SetHoverPoint(hoverPoint_); 100 if (mouseClickIndex_) { 101 mouseClickIndex_ = swiperPattern->GetLoopIndex(mouseClickIndex_.value()); 102 } 103 paintMethod->SetMouseClickIndex(mouseClickIndex_); 104 paintMethod->SetIsTouchBottom(touchBottomType_); 105 paintMethod->SetTouchBottomRate(swiperPattern->GetTouchBottomRate()); 106 mouseClickIndex_ = std::nullopt; 107 } 108 CreateNodePaintMethod()109 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 110 { 111 auto swiperNode = GetSwiperNode(); 112 CHECK_NULL_RETURN(swiperNode, nullptr); 113 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>(); 114 CHECK_NULL_RETURN(swiperPattern, nullptr); 115 if (GetIndicatorType() == SwiperIndicatorType::DOT) { 116 if (swiperPattern->GetMaxDisplayCount() > 0) { 117 SetIndicatorInteractive(false); 118 return CreateOverlongDotIndicatorPaintMethod(swiperPattern); 119 } 120 121 SetIndicatorInteractive(swiperPattern->IsIndicatorInteractive()); 122 return CreateDotIndicatorPaintMethod(swiperPattern); 123 } else { 124 return nullptr; 125 } 126 } 127 GetSwiperNode()128 virtual RefPtr<FrameNode> GetSwiperNode() const 129 { 130 auto host = GetHost(); 131 CHECK_NULL_RETURN(host, nullptr); 132 auto swiperNode = host->GetParent(); 133 CHECK_NULL_RETURN(swiperNode, nullptr); 134 return DynamicCast<FrameNode>(swiperNode); 135 } 136 GetFocusPattern()137 FocusPattern GetFocusPattern() const override 138 { 139 auto pipelineContext = PipelineBase::GetCurrentContext(); 140 CHECK_NULL_RETURN(pipelineContext, FocusPattern()); 141 auto swiperTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>(); 142 CHECK_NULL_RETURN(swiperTheme, FocusPattern()); 143 FocusPaintParam paintParam; 144 paintParam.SetPaintWidth(swiperTheme->GetFocusedBorderWidth()); 145 paintParam.SetPaintColor(swiperTheme->GetFocusedColor()); 146 return { FocusType::NODE, true, FocusStyleType::INNER_BORDER, paintParam }; 147 } 148 SetChangeIndexWithAnimation(bool withAnimation)149 void SetChangeIndexWithAnimation(bool withAnimation) 150 { 151 changeIndexWithAnimation_ = withAnimation; 152 } 153 SetJumpIndex(std::optional<int32_t> jumpIndex)154 void SetJumpIndex(std::optional<int32_t> jumpIndex) 155 { 156 jumpIndex_ = jumpIndex; 157 } 158 SetStartIndex(std::optional<int32_t> startIndex)159 void SetStartIndex(std::optional<int32_t> startIndex) 160 { 161 startIndex_ = startIndex; 162 } 163 164 void DumpAdvanceInfo() override; 165 void SetIndicatorInteractive(bool isInteractive); 166 virtual Axis GetDirection() const; 167 virtual bool GetDotCurrentOffset(OffsetF& offset, float indicatorWidth, float indicatorHeight); 168 void OnModifyDone() override; 169 void IndicatorOnChange(); 170 void InitIndicatorEvent(); 171 virtual bool GetDigitFrameSize(RefPtr<GeometryNode>& geoNode, SizeF& frameSize) const; 172 virtual int32_t RealTotalCount() const; 173 virtual int32_t GetCurrentIndex() const; 174 175 private: 176 void OnAttachToFrameNode() override; 177 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 178 void InitClickEvent(const RefPtr<GestureEventHub>& gestureHub); 179 void HandleClick(const GestureEvent& info); 180 void HandleMouseClick(const GestureEvent& info); 181 void HandleTouchClick(const GestureEvent& info); 182 void InitHoverMouseEvent(); 183 void InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub); 184 void HandleMouseEvent(const MouseInfo& info); 185 void HandleHoverEvent(bool isHover); 186 void HoverInAnimation(const Color& hoverColor); 187 void HoverOutAnimation(const Color& normalColor); 188 void HandleTouchEvent(const TouchEventInfo& info); 189 void HandleTouchDown(); 190 void HandleTouchUp(); 191 void HandleDragStart(const GestureEvent& info); 192 void HandleDragEnd(double dragVelocity); 193 void GetMouseClickIndex(); 194 void UpdateTextContent(const RefPtr<SwiperIndicatorLayoutProperty>& layoutProperty, 195 const RefPtr<FrameNode>& firstTextNode, const RefPtr<FrameNode>& lastTextNode); 196 void UpdateTextContentSub( 197 const RefPtr<SwiperIndicatorLayoutProperty>& layoutProperty, 198 const RefPtr<FrameNode>& firstTextNode, const RefPtr<FrameNode>& lastTextNode); 199 bool CheckIsTouchBottom(const GestureEvent& info); 200 void InitLongPressEvent(const RefPtr<GestureEventHub>& gestureHub); 201 void HandleLongPress(GestureEvent& info); 202 bool CheckIsTouchBottom(const TouchLocationInfo& info); 203 float HandleTouchClickMargin(); 204 int32_t GetInitialIndex() const; 205 RefPtr<OverlengthDotIndicatorPaintMethod> CreateOverlongDotIndicatorPaintMethod( 206 RefPtr<SwiperPattern> swiperPattern); 207 RefPtr<DotIndicatorPaintMethod> CreateDotIndicatorPaintMethod(RefPtr<SwiperPattern> swiperPattern); 208 void UpdateOverlongPaintMethod( 209 const RefPtr<SwiperPattern>& swiperPattern, RefPtr<OverlengthDotIndicatorPaintMethod>& overlongPaintMethod); 210 void UpdateDigitalIndicator(); 211 void RegisterIndicatorChangeEvent(); 212 int32_t GetDisplayCurrentIndex() const; 213 214 RefPtr<ClickEvent> clickEvent_; 215 RefPtr<InputEvent> hoverEvent_; 216 RefPtr<TouchEventImpl> touchEvent_; 217 RefPtr<InputEvent> mouseEvent_; 218 RefPtr<LongPressEvent> longPressEvent_; 219 bool isHover_ = false; 220 bool isPressed_ = false; 221 PointF hoverPoint_; 222 PointF dragStartPoint_; 223 TouchBottomType touchBottomType_ = TouchBottomType::NONE; 224 bool isClicked_ = false; 225 bool isRepeatClicked_ = false; 226 227 std::optional<int32_t> mouseClickIndex_ = std::nullopt; 228 RefPtr<DotIndicatorModifier> dotIndicatorModifier_; 229 RefPtr<OverlengthDotIndicatorModifier> overlongDotIndicatorModifier_; 230 231 std::optional<int32_t> jumpIndex_; 232 std::optional<int32_t> startIndex_; 233 std::optional<bool> changeIndexWithAnimation_; 234 GestureState gestureState_ = GestureState::GESTURE_STATE_INIT; 235 ACE_DISALLOW_COPY_AND_MOVE(SwiperIndicatorPattern); 236 protected: FireChangeEvent()237 virtual void FireChangeEvent() const {} FireIndicatorIndexChangeEvent(int32_t index)238 virtual void FireIndicatorIndexChangeEvent(int32_t index) const {} 239 virtual void SwipeTo(std::optional<int32_t> mouseClickIndex); 240 virtual void ShowPrevious(); 241 virtual void ShowNext(); 242 virtual void ChangeIndex(int32_t index, bool useAnimation); 243 virtual bool IsHorizontalAndRightToLeft() const; 244 virtual TextDirection GetNonAutoLayoutDirection() const; 245 virtual void GetTextContentSub(std::string& firstContent, std::string& lastContent) const; 246 virtual int32_t GetCurrentShownIndex() const; 247 virtual bool IsLoop() const; 248 virtual int32_t GetTouchCurrentIndex() const; 249 virtual void HandleLongDragUpdate(const TouchLocationInfo& info); 250 GetSwiperPattern()251 RefPtr<SwiperPattern> GetSwiperPattern() const 252 { 253 auto swiperNode = GetSwiperNode(); 254 CHECK_NULL_RETURN(swiperNode, nullptr); 255 return swiperNode->GetPattern<SwiperPattern>(); 256 } 257 GetIndicatorType()258 virtual SwiperIndicatorType GetIndicatorType() const 259 { 260 auto swiperPattern = GetSwiperPattern(); 261 CHECK_NULL_RETURN(swiperPattern, SwiperIndicatorType::DOT); 262 return swiperPattern->GetIndicatorType(); 263 } 264 IsHover()265 const bool& IsHover() const 266 { 267 return isHover_; 268 } 269 IsPressed()270 const bool& IsPressed() const 271 { 272 return isPressed_; 273 } 274 GetHoverPoint()275 const PointF& GetHoverPoint() const 276 { 277 return hoverPoint_; 278 } 279 GetOptinalMouseClickIndex()280 std::optional<int32_t> GetOptinalMouseClickIndex() const 281 { 282 return mouseClickIndex_; 283 } 284 SetMouseClickIndex(int32_t mouseClickIndex)285 void SetMouseClickIndex(int32_t mouseClickIndex) 286 { 287 if (mouseClickIndex_) { 288 mouseClickIndex_ = mouseClickIndex; 289 } 290 } 291 ResetOptinalMouseClickIndex()292 void ResetOptinalMouseClickIndex() 293 { 294 mouseClickIndex_ = std::nullopt; 295 } 296 GetTouchBottomType()297 const TouchBottomType& GetTouchBottomType() const 298 { 299 return touchBottomType_; 300 } 301 GetDotIndicatorModifier()302 const RefPtr<DotIndicatorModifier>& GetDotIndicatorModifier() const 303 { 304 return dotIndicatorModifier_; 305 } 306 SetDotIndicatorModifier(RefPtr<DotIndicatorModifier> dotIndicatorModifier)307 void SetDotIndicatorModifier(RefPtr<DotIndicatorModifier> dotIndicatorModifier) 308 { 309 dotIndicatorModifier_ = dotIndicatorModifier; 310 } 311 GetOverlengthDotIndicatorModifier()312 const RefPtr<OverlengthDotIndicatorModifier>& GetOverlengthDotIndicatorModifier() const 313 { 314 return overlongDotIndicatorModifier_; 315 } 316 SetOverlengthDotIndicatorModifier(RefPtr<OverlengthDotIndicatorModifier> overlongDotIndicatorModifier)317 void SetOverlengthDotIndicatorModifier(RefPtr<OverlengthDotIndicatorModifier> overlongDotIndicatorModifier) 318 { 319 overlongDotIndicatorModifier_ = overlongDotIndicatorModifier; 320 } 321 GetDragStartPoint()322 const PointF& GetDragStartPoint() const 323 { 324 return dragStartPoint_; 325 } 326 SetDragStartPoint(PointF dragStartPoint)327 void SetDragStartPoint(PointF dragStartPoint) 328 { 329 dragStartPoint_ = dragStartPoint; 330 } 331 332 RectF CalcBoundsRect() const; 333 int32_t GetLoopIndex(int32_t originalIndex) const; 334 }; 335 } // namespace OHOS::Ace::NG 336 337 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_INDICATOR_SWIPER_INDICATOR_PATTERN_H 338