1 /* 2 * Copyright (c) 2024-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_INDICATOR_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_INDICATOR_PATTERN_H 18 19 #include "core/components_ng/pattern/swiper_indicator/indicator_common/indicator_controller.h" 20 #include "core/components_ng/pattern/swiper_indicator/indicator_common/indicator_event_hub.h" 21 #include "core/components_ng/pattern/swiper_indicator/indicator_common/swiper_indicator_layout_property.h" 22 #include "core/components_ng/pattern/swiper_indicator/indicator_common/swiper_indicator_pattern.h" 23 #include "core/components_ng/pattern/swiper_indicator/indicator_common/indicator_accessibility.h" 24 namespace OHOS::Ace::NG { 25 namespace { 26 constexpr int32_t INDICATOR_DEFAULT_DURATION = 400; 27 const auto DEFAULT_CURVE = AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 328.0f, 34.0f); 28 } // namespace 29 class IndicatorPattern : public SwiperIndicatorPattern { 30 DECLARE_ACE_TYPE(IndicatorPattern, SwiperIndicatorPattern); 31 32 public: 33 IndicatorPattern(); 34 ~IndicatorPattern() override = default; 35 CreateAccessibilityProperty()36 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 37 { 38 return MakeRefPtr<IndicatorAccessibilityProperty>(); 39 } 40 CreatePaintProperty()41 RefPtr<PaintProperty> CreatePaintProperty() override 42 { 43 if (GetIndicatorType() == SwiperIndicatorType::DOT) { 44 return MakeRefPtr<DotIndicatorPaintProperty>(); 45 } else { 46 return MakeRefPtr<PaintProperty>(); 47 } 48 } 49 GetIndicatorType()50 SwiperIndicatorType GetIndicatorType() const override 51 { 52 return GetIndicatorTypeFromProperty(); 53 } 54 CreateEventHub()55 RefPtr<EventHub> CreateEventHub() override 56 { 57 return MakeRefPtr<IndicatorEventHub>(); 58 } 59 GetIndicatorController()60 const RefPtr<IndicatorController>& GetIndicatorController() const 61 { 62 return indicatorController_; 63 } 64 UpdateChangeEvent(ChangeEvent && event)65 void UpdateChangeEvent(ChangeEvent&& event) 66 { 67 if (!changeEvent_) { 68 changeEvent_ = std::make_shared<ChangeEvent>(event); 69 auto eventHub = GetEventHub<IndicatorEventHub>(); 70 CHECK_NULL_VOID(eventHub); 71 eventHub->AddOnChangeEvent(changeEvent_); 72 } else { 73 (*changeEvent_).swap(event); 74 } 75 } 76 SetSwiperParameters(const SwiperParameters & swiperParameters)77 void SetSwiperParameters(const SwiperParameters& swiperParameters) 78 { 79 swiperParameters_ = std::make_shared<SwiperParameters>(swiperParameters); 80 } 81 82 void SetSwiperDigitalParameters(const SwiperDigitalParameters& swiperDigitalParameters); 83 bool GetDigitFrameSize(RefPtr<GeometryNode>& geoNode, SizeF& frameSize) const override; 84 bool GetDotCurrentOffset(OffsetF& offset, float indicatorWidth, float indicatorHeight) override; 85 WeakUINode2RefFrameNode(WeakPtr<NG::UINode> & weakUINode)86 RefPtr<FrameNode> WeakUINode2RefFrameNode(WeakPtr<NG::UINode>& weakUINode) const 87 { 88 auto refUINode = weakUINode.Upgrade(); 89 CHECK_NULL_RETURN(refUINode, nullptr); 90 auto frameNode = DynamicCast<FrameNode>(refUINode); 91 CHECK_NULL_RETURN(frameNode, nullptr); 92 return frameNode; 93 } 94 GetBindSwiperNode()95 RefPtr<FrameNode> GetBindSwiperNode() const 96 { 97 auto controller = GetIndicatorController(); 98 CHECK_NULL_RETURN(controller, nullptr); 99 auto weakUINode = controller->GetSwiperNode(); 100 return WeakUINode2RefFrameNode(weakUINode); 101 } 102 CreateLayoutAlgorithm()103 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 104 { 105 if (GetBindSwiperNode()) { 106 return SwiperIndicatorPattern::CreateLayoutAlgorithm(); 107 } 108 109 if (GetIndicatorType() == SwiperIndicatorType::DOT) { 110 auto indicatorLayoutAlgorithm = MakeRefPtr<DotIndicatorLayoutAlgorithm>(); 111 indicatorLayoutAlgorithm->SetIsHoverOrPress(IsHover() || IsPressed()); 112 indicatorLayoutAlgorithm->SetHoverPoint(GetHoverPoint()); 113 indicatorLayoutAlgorithm->SetIndicatorDisplayCount(GetCountFromProperty()); 114 indicatorLayoutAlgorithm->SetIsSingle(true); 115 return indicatorLayoutAlgorithm; 116 } else { 117 auto indicatorLayoutAlgorithm = MakeRefPtr<DigitIndicatorLayoutAlgorithm>(); 118 indicatorLayoutAlgorithm->SetIsHoverOrPress(IsHover() || IsPressed()); 119 indicatorLayoutAlgorithm->SetHoverPoint(GetHoverPoint()); 120 indicatorLayoutAlgorithm->SetIsSingle(true); 121 return indicatorLayoutAlgorithm; 122 } 123 } 124 GetSwiperNode()125 RefPtr<FrameNode> GetSwiperNode() const override 126 { 127 return GetBindSwiperNode(); 128 } 129 CreateNodePaintMethod()130 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 131 { 132 if (GetBindSwiperNode()) { 133 return SwiperIndicatorPattern::CreateNodePaintMethod(); 134 } 135 136 if (GetIndicatorType() == SwiperIndicatorType::DOT) { 137 return CreateDotIndicatorPaintMethodInSingleMode(); 138 } 139 return nullptr; 140 } 141 SetCurrentIndexInSingleMode(int32_t index)142 void SetCurrentIndexInSingleMode(int32_t index) 143 { 144 currentIndexInSingleMode_ = index; 145 } 146 CreateDotIndicatorPaintMethodInSingleMode()147 RefPtr<DotIndicatorPaintMethod> CreateDotIndicatorPaintMethodInSingleMode() 148 { 149 ResetOverlongModifier(); 150 151 if (!GetDotIndicatorModifier()) { 152 SetDotIndicatorModifier(AceType::MakeRefPtr<DotIndicatorModifier>()); 153 singleGestureState_ = GestureState::GESTURE_STATE_INIT; 154 } 155 GetDotIndicatorModifier()->SetAnimationDuration(INDICATOR_DEFAULT_DURATION); 156 float motionVelocity = 0.0f; 157 GetDotIndicatorModifier()->SetLongPointHeadCurve(DEFAULT_CURVE, motionVelocity); 158 159 auto paintMethod = MakeRefPtr<DotIndicatorPaintMethod>(GetDotIndicatorModifier()); 160 SetDotIndicatorPaintMethodInfoInSingleMode(paintMethod); 161 162 GetDotIndicatorModifier()->SetBoundsRect(CalcBoundsRect()); 163 return paintMethod; 164 } 165 SetDotIndicatorPaintMethodInfoInSingleMode(RefPtr<DotIndicatorPaintMethod> & paintMethod)166 void SetDotIndicatorPaintMethodInfoInSingleMode(RefPtr<DotIndicatorPaintMethod>& paintMethod) 167 { 168 paintMethod->SetAxis(GetDirection()); 169 paintMethod->SetCurrentIndex(GetLoopIndex(currentIndexInSingleMode_)); 170 paintMethod->SetCurrentIndexActual(GetLoopIndex(currentIndexInSingleMode_)); 171 paintMethod->SetHorizontalAndRightToLeft(GetNonAutoLayoutDirection()); 172 paintMethod->SetItemCount(RealTotalCount()); 173 paintMethod->SetGestureState(singleGestureState_); 174 singleGestureState_ = GestureState::GESTURE_STATE_INIT; 175 paintMethod->SetIsLoop(IsLoop()); 176 paintMethod->SetIsHover(IsHover()); 177 paintMethod->SetIsPressed(IsPressed()); 178 paintMethod->SetHoverPoint(GetHoverPoint()); 179 if (GetOptinalMouseClickIndex()) { 180 SetMouseClickIndex(GetLoopIndex(GetOptinalMouseClickIndex().value())); 181 } 182 paintMethod->SetMouseClickIndex(GetOptinalMouseClickIndex()); 183 paintMethod->SetIsTouchBottom(GetTouchBottomType()); 184 paintMethod->SetTouchBottomRate(touchBottomRate_); 185 paintMethod->SetTouchBottomTypeLoop(singleIndicatorTouchBottomTypeLoop_); 186 singleIndicatorTouchBottomTypeLoop_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE; 187 paintMethod->SetFirstIndex(lastIndex_); 188 ResetOptinalMouseClickIndex(); 189 } 190 IsIndicatorCustomSize()191 const bool& IsIndicatorCustomSize() const 192 { 193 return isCustomSize_; 194 } 195 SetIsIndicatorCustomSize(bool isCustomSize)196 void SetIsIndicatorCustomSize(bool isCustomSize) 197 { 198 isCustomSize_ = isCustomSize; 199 } 200 void OnIndexChangeInSingleMode(int32_t index); 201 void ShowPrevious() override; 202 void ShowNext() override; 203 void ChangeIndex(int32_t index, bool useAnimation) override; 204 int32_t GetCurrentIndex() const override; 205 int32_t GetCurrentShownIndex() const override; 206 int32_t DisplayIndicatorTotalCount() const override; 207 int32_t RealTotalCount() const override; 208 Axis GetDirection() const override; 209 bool IsHorizontalAndRightToLeft() const override; 210 TextDirection GetNonAutoLayoutDirection() const override; 211 bool IsLoop() const override; 212 void GetTextContentSub(std::string& firstContent, std::string& lastContent) const override; 213 void SwipeTo(std::optional<int32_t> mouseClickIndex) override; 214 void OnModifyDone() override; 215 int32_t GetTouchCurrentIndex() const override; 216 std::pair<int32_t, int32_t> CalMouseClickIndexStartAndEnd(int32_t itemCount, int32_t currentIndex) override; 217 bool CheckIsTouchBottom(const TouchLocationInfo& info); 218 void HandleDragEnd(double dragVelocity) override; 219 void HandleLongDragUpdate(const TouchLocationInfo& info) override; 220 void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub); 221 bool OnKeyEvent(const KeyEvent& event); GetIndicatorParameters()222 std::shared_ptr<SwiperParameters> GetIndicatorParameters() const 223 { 224 return swiperParameters_; 225 } 226 227 int32_t currentIndexInSingleMode_ = 0; 228 int32_t hasSetInitialIndex_ = false; 229 230 protected: 231 void FireChangeEvent() const override; 232 void FireIndicatorIndexChangeEvent(int32_t index) const override; 233 SwiperIndicatorType GetIndicatorTypeFromProperty() const; 234 Axis GetDirectionFromProperty() const; 235 int32_t GetInitialIndexFromProperty() const; 236 int32_t GetCountFromProperty() const; 237 bool IsLoopFromProperty() const; 238 239 private: 240 void InitIndicatorController(); 241 std::shared_ptr<SwiperParameters> GetSwiperParameters(); 242 std::shared_ptr<SwiperDigitalParameters> GetSwiperDigitalParameters(); 243 void SaveDotIndicatorProperty(); 244 void SaveDigitIndicatorProperty(); 245 void UpdatePaintProperty(); 246 RefPtr<IndicatorController> indicatorController_; 247 mutable std::shared_ptr<SwiperParameters> swiperParameters_; 248 mutable std::shared_ptr<SwiperDigitalParameters> swiperDigitalParameters_; 249 ChangeEventPtr changeEvent_; 250 GestureState singleGestureState_ = GestureState::GESTURE_STATE_INIT; 251 bool isCustomSize_ = false; 252 TouchBottomTypeLoop singleIndicatorTouchBottomTypeLoop_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE; 253 int32_t lastIndex_ = 0; 254 float touchBottomRate_ = 1.0f; 255 }; 256 } // namespace OHOS::Ace::NG 257 258 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_INDICATOR_PATTERN_H 259