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 (SwiperIndicatorUtils::GetSwiperIndicatorType() == 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 (swiperPattern->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 (swiperPattern->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 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 167 private: 168 void OnModifyDone() override; 169 void OnAttachToFrameNode() override; 170 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 171 void InitClickEvent(const RefPtr<GestureEventHub>& gestureHub); 172 void HandleClick(const GestureEvent& info); 173 void HandleMouseClick(const GestureEvent& info); 174 void HandleTouchClick(const GestureEvent& info); 175 void InitHoverMouseEvent(); 176 void InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub); 177 void HandleMouseEvent(const MouseInfo& info); 178 void HandleHoverEvent(bool isHover); 179 void HoverInAnimation(const Color& hoverColor); 180 void HoverOutAnimation(const Color& normalColor); 181 void HandleTouchEvent(const TouchEventInfo& info); 182 void HandleTouchDown(); 183 void HandleTouchUp(); 184 void HandleDragStart(const GestureEvent& info); 185 void HandleDragEnd(double dragVelocity); 186 void GetMouseClickIndex(); 187 void UpdateTextContent(const RefPtr<SwiperIndicatorLayoutProperty>& layoutProperty, 188 const RefPtr<FrameNode>& firstTextNode, const RefPtr<FrameNode>& lastTextNode); 189 void UpdateTextContentSub( 190 const RefPtr<SwiperIndicatorLayoutProperty>& layoutProperty, 191 const RefPtr<FrameNode>& firstTextNode, const RefPtr<FrameNode>& lastTextNode); 192 bool CheckIsTouchBottom(const GestureEvent& info); 193 void InitLongPressEvent(const RefPtr<GestureEventHub>& gestureHub); 194 void HandleLongPress(GestureEvent& info); 195 void HandleLongDragUpdate(const TouchLocationInfo& info); 196 bool CheckIsTouchBottom(const TouchLocationInfo& info); 197 float HandleTouchClickMargin(); 198 int32_t GetCurrentIndex() const; 199 RefPtr<OverlengthDotIndicatorPaintMethod> CreateOverlongDotIndicatorPaintMethod( 200 RefPtr<SwiperPattern> swiperPattern); 201 RefPtr<DotIndicatorPaintMethod> CreateDotIndicatorPaintMethod(RefPtr<SwiperPattern> swiperPattern); 202 RectF CalcBoundsRect() const; 203 void UpdateOverlongPaintMethod( 204 const RefPtr<SwiperPattern>& swiperPattern, RefPtr<OverlengthDotIndicatorPaintMethod>& overlongPaintMethod); 205 int32_t GetDisplayCurrentIndex() const; 206 207 RefPtr<ClickEvent> clickEvent_; 208 RefPtr<InputEvent> hoverEvent_; 209 RefPtr<TouchEventImpl> touchEvent_; 210 RefPtr<InputEvent> mouseEvent_; 211 RefPtr<LongPressEvent> longPressEvent_; 212 bool isHover_ = false; 213 bool isPressed_ = false; 214 PointF hoverPoint_; 215 PointF dragStartPoint_; 216 TouchBottomType touchBottomType_ = TouchBottomType::NONE; 217 bool isClicked_ = false; 218 bool isRepeatClicked_ = false; 219 220 std::optional<int32_t> mouseClickIndex_ = std::nullopt; 221 RefPtr<DotIndicatorModifier> dotIndicatorModifier_; 222 RefPtr<OverlengthDotIndicatorModifier> overlongDotIndicatorModifier_; 223 SwiperIndicatorType swiperIndicatorType_ = SwiperIndicatorType::DOT; 224 225 std::optional<int32_t> jumpIndex_; 226 std::optional<int32_t> startIndex_; 227 std::optional<bool> changeIndexWithAnimation_; 228 GestureState gestureState_ = GestureState::GESTURE_STATE_INIT; 229 ACE_DISALLOW_COPY_AND_MOVE(SwiperIndicatorPattern); 230 }; 231 } // namespace OHOS::Ace::NG 232 233 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_INDICATOR_SWIPER_INDICATOR_PATTERN_H 234