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 InitIndicatorController()60 void InitIndicatorController() 61 { 62 CHECK_NULL_VOID(indicatorController_); 63 indicatorController_->SetIndicatorPattern(AceType::Claim(this)); 64 indicatorController_->ResetJSIndicatorController(); 65 } 66 GetIndicatorController()67 const RefPtr<IndicatorController>& GetIndicatorController() const 68 { 69 return indicatorController_; 70 } 71 ResetSwiperNode()72 void ResetSwiperNode() const 73 { 74 CHECK_NULL_VOID(indicatorController_); 75 indicatorController_->ResetSwiperNode(); 76 } 77 ResetJSIndicatorController()78 void ResetJSIndicatorController() 79 { 80 CHECK_NULL_VOID(indicatorController_); 81 indicatorController_->ResetJSIndicatorController(); 82 } 83 UpdateChangeEvent(ChangeEvent && event)84 void UpdateChangeEvent(ChangeEvent&& event) 85 { 86 if (!changeEvent_) { 87 changeEvent_ = std::make_shared<ChangeEvent>(event); 88 auto eventHub = GetOrCreateEventHub<IndicatorEventHub>(); 89 CHECK_NULL_VOID(eventHub); 90 eventHub->AddOnChangeEvent(changeEvent_); 91 } else { 92 (*changeEvent_).swap(event); 93 } 94 } 95 SetSwiperParameters(const SwiperParameters & swiperParameters)96 void SetSwiperParameters(const SwiperParameters& swiperParameters) 97 { 98 swiperParameters_ = std::make_shared<SwiperParameters>(swiperParameters); 99 } 100 101 void SetSwiperDigitalParameters(const SwiperDigitalParameters& swiperDigitalParameters); 102 bool GetDigitFrameSize(RefPtr<GeometryNode>& geoNode, SizeF& frameSize) const override; 103 bool GetDotCurrentOffset(OffsetF& offset, float indicatorWidth, float indicatorHeight) override; 104 WeakUINode2RefFrameNode(WeakPtr<NG::UINode> & weakUINode)105 RefPtr<FrameNode> WeakUINode2RefFrameNode(WeakPtr<NG::UINode>& weakUINode) const 106 { 107 auto refUINode = weakUINode.Upgrade(); 108 CHECK_NULL_RETURN(refUINode, nullptr); 109 auto frameNode = DynamicCast<FrameNode>(refUINode); 110 CHECK_NULL_RETURN(frameNode, nullptr); 111 return frameNode; 112 } 113 GetBindSwiperNode()114 RefPtr<FrameNode> GetBindSwiperNode() const 115 { 116 auto controller = GetIndicatorController(); 117 CHECK_NULL_RETURN(controller, nullptr); 118 auto weakUINode = controller->GetSwiperNode(); 119 return weakUINode.Upgrade(); 120 } 121 CreateLayoutAlgorithm()122 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 123 { 124 if (GetBindSwiperNode()) { 125 return SwiperIndicatorPattern::CreateLayoutAlgorithm(); 126 } 127 128 if (GetIndicatorType() == SwiperIndicatorType::DOT) { 129 auto indicatorLayoutAlgorithm = MakeRefPtr<DotIndicatorLayoutAlgorithm>(); 130 indicatorLayoutAlgorithm->SetIsHoverOrPress(IsHover() || IsPressed()); 131 indicatorLayoutAlgorithm->SetHoverPoint(GetHoverPoint()); 132 indicatorLayoutAlgorithm->SetIndicatorDisplayCount(GetCountFromProperty()); 133 indicatorLayoutAlgorithm->SetIsSingle(true); 134 return indicatorLayoutAlgorithm; 135 } else { 136 auto indicatorLayoutAlgorithm = MakeRefPtr<DigitIndicatorLayoutAlgorithm>(); 137 indicatorLayoutAlgorithm->SetIsHoverOrPress(IsHover() || IsPressed()); 138 indicatorLayoutAlgorithm->SetHoverPoint(GetHoverPoint()); 139 indicatorLayoutAlgorithm->SetIsSingle(true); 140 return indicatorLayoutAlgorithm; 141 } 142 } 143 GetSwiperNode()144 RefPtr<FrameNode> GetSwiperNode() const override 145 { 146 return GetBindSwiperNode(); 147 } 148 CreateNodePaintMethod()149 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 150 { 151 if (GetBindSwiperNode()) { 152 return SwiperIndicatorPattern::CreateNodePaintMethod(); 153 } 154 155 if (GetIndicatorType() == SwiperIndicatorType::DOT) { 156 return CreateDotIndicatorPaintMethodInSingleMode(); 157 } 158 return nullptr; 159 } 160 SetCurrentIndexInSingleMode(int32_t index)161 void SetCurrentIndexInSingleMode(int32_t index) 162 { 163 currentIndexInSingleMode_ = index; 164 } 165 CreateDotIndicatorPaintMethodInSingleMode()166 RefPtr<DotIndicatorPaintMethod> CreateDotIndicatorPaintMethodInSingleMode() 167 { 168 ResetOverlongModifier(); 169 170 if (!GetDotIndicatorModifier()) { 171 SetDotIndicatorModifier(AceType::MakeRefPtr<DotIndicatorModifier>()); 172 singleGestureState_ = GestureState::GESTURE_STATE_INIT; 173 } 174 GetDotIndicatorModifier()->SetAnimationDuration(INDICATOR_DEFAULT_DURATION); 175 float motionVelocity = 0.0f; 176 GetDotIndicatorModifier()->SetLongPointHeadCurve(DEFAULT_CURVE, motionVelocity); 177 178 auto paintMethod = MakeRefPtr<DotIndicatorPaintMethod>(GetDotIndicatorModifier()); 179 SetDotIndicatorPaintMethodInfoInSingleMode(paintMethod); 180 181 GetDotIndicatorModifier()->SetBoundsRect(CalcBoundsRect()); 182 return paintMethod; 183 } 184 SetDotIndicatorPaintMethodInfoInSingleMode(RefPtr<DotIndicatorPaintMethod> & paintMethod)185 void SetDotIndicatorPaintMethodInfoInSingleMode(RefPtr<DotIndicatorPaintMethod>& paintMethod) 186 { 187 paintMethod->SetAxis(GetDirection()); 188 paintMethod->SetCurrentIndex(GetLoopIndex(currentIndexInSingleMode_)); 189 paintMethod->SetCurrentIndexActual(GetLoopIndex(currentIndexInSingleMode_)); 190 paintMethod->SetHorizontalAndRightToLeft(GetNonAutoLayoutDirection()); 191 paintMethod->SetItemCount(RealTotalCount()); 192 paintMethod->SetGestureState(singleGestureState_); 193 singleGestureState_ = GestureState::GESTURE_STATE_INIT; 194 paintMethod->SetIsLoop(IsLoop()); 195 paintMethod->SetIsHover(IsHover()); 196 paintMethod->SetIsPressed(IsPressed()); 197 paintMethod->SetHoverPoint(GetHoverPoint()); 198 if (GetOptinalMouseClickIndex()) { 199 SetMouseClickIndex(GetLoopIndex(GetOptinalMouseClickIndex().value())); 200 } 201 paintMethod->SetMouseClickIndex(GetOptinalMouseClickIndex()); 202 paintMethod->SetIsTouchBottom(GetTouchBottomType()); 203 paintMethod->SetTouchBottomRate(touchBottomRate_); 204 paintMethod->SetTouchBottomTypeLoop(singleIndicatorTouchBottomTypeLoop_); 205 singleIndicatorTouchBottomTypeLoop_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE; 206 paintMethod->SetFirstIndex(lastIndex_); 207 ResetOptinalMouseClickIndex(); 208 } 209 IsIndicatorCustomSize()210 const bool& IsIndicatorCustomSize() const 211 { 212 return isCustomSize_; 213 } 214 SetIsIndicatorCustomSize(bool isCustomSize)215 void SetIsIndicatorCustomSize(bool isCustomSize) 216 { 217 isCustomSize_ = isCustomSize; 218 } 219 void OnIndexChangeInSingleMode(int32_t index); 220 void ShowPrevious() override; 221 void ShowNext() override; 222 void ChangeIndex(int32_t index, bool useAnimation) override; 223 int32_t GetCurrentIndex() const override; 224 int32_t GetCurrentShownIndex() const override; 225 int32_t DisplayIndicatorTotalCount() const override; 226 int32_t RealTotalCount() const override; 227 Axis GetDirection() const override; 228 bool IsHorizontalAndRightToLeft() const override; 229 TextDirection GetNonAutoLayoutDirection() const override; 230 bool IsLoop() const override; 231 void GetTextContentSub(std::string& firstContent, std::string& lastContent) const override; 232 void SwipeTo(std::optional<int32_t> mouseClickIndex) override; 233 void OnModifyDone() override; 234 int32_t GetTouchCurrentIndex() const override; 235 std::pair<int32_t, int32_t> CalMouseClickIndexStartAndEnd(int32_t itemCount, int32_t currentIndex) override; 236 bool CheckIsTouchBottom(const TouchLocationInfo& info); 237 void HandleDragEnd(double dragVelocity) override; 238 void InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub) override; 239 void HandleLongDragUpdate(const TouchLocationInfo& info) override; 240 RectF CalcBoundsRect() const override; 241 void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub); 242 bool OnKeyEvent(const KeyEvent& event); GetIndicatorParameters()243 std::shared_ptr<SwiperParameters> GetIndicatorParameters() const 244 { 245 return swiperParameters_; 246 } 247 std::shared_ptr<SwiperDigitalParameters> GetSwiperDigitalParameters(); 248 void OnColorModeChange(uint32_t colorMode) override; 249 250 int32_t currentIndexInSingleMode_ = 0; 251 int32_t hasSetInitialIndex_ = false; 252 253 protected: 254 void FireChangeEvent() const override; 255 void FireIndicatorIndexChangeEvent(int32_t index) const override; 256 SwiperIndicatorType GetIndicatorTypeFromProperty() const; 257 Axis GetDirectionFromProperty() const; 258 int32_t GetInitialIndexFromProperty() const; 259 int32_t GetCountFromProperty() const; 260 bool IsLoopFromProperty() const; 261 262 private: 263 std::shared_ptr<SwiperParameters> GetSwiperParameters(); 264 void SaveDotIndicatorProperty(); 265 void SaveDigitIndicatorProperty(); 266 void UpdatePaintProperty(); 267 void UpdateDefaultColor(); 268 RefPtr<IndicatorController> indicatorController_; 269 mutable std::shared_ptr<SwiperParameters> swiperParameters_; 270 mutable std::shared_ptr<SwiperDigitalParameters> swiperDigitalParameters_; 271 ChangeEventPtr changeEvent_; 272 GestureState singleGestureState_ = GestureState::GESTURE_STATE_INIT; 273 bool isCustomSize_ = false; 274 TouchBottomTypeLoop singleIndicatorTouchBottomTypeLoop_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE; 275 int32_t lastIndex_ = 0; 276 float touchBottomRate_ = 1.0f; 277 }; 278 } // namespace OHOS::Ace::NG 279 280 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_INDICATOR_PATTERN_H 281