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_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/dot_indicator/dot_indicator_layout_algorithm.h" 25 #include "core/components_ng/pattern/swiper_indicator/dot_indicator/dot_indicator_paint_method.h" 26 #include "core/components_ng/pattern/swiper_indicator/digit_indicator/digit_indicator_layout_algorithm.h" 27 #include "core/components_ng/pattern/swiper_indicator/indicator_common/swiper_indicator_layout_property.h" 28 #include "core/components_ng/pattern/swiper_indicator/indicator_common/swiper_indicator_utils.h" 29 #include "core/components_ng/pattern/text/text_layout_property.h" 30 #include "core/components_ng/pattern/text/text_pattern.h" 31 namespace OHOS::Ace::NG { 32 class SwiperIndicatorPattern : public Pattern { 33 DECLARE_ACE_TYPE(SwiperIndicatorPattern, Pattern); 34 public: 35 SwiperIndicatorPattern() = default; 36 ~SwiperIndicatorPattern() override = default; 37 CreateLayoutProperty()38 RefPtr<LayoutProperty> CreateLayoutProperty() override 39 { 40 return MakeRefPtr<SwiperIndicatorLayoutProperty>(); 41 } 42 CreatePaintProperty()43 RefPtr<PaintProperty> CreatePaintProperty() override 44 { 45 if (SwiperIndicatorUtils::GetSwiperIndicatorType() == SwiperIndicatorType::DOT) { 46 return MakeRefPtr<DotIndicatorPaintProperty>(); 47 } else { 48 return MakeRefPtr<PaintProperty>(); 49 } 50 } 51 CreateLayoutAlgorithm()52 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 53 { 54 auto swiperNode = GetSwiperNode(); 55 CHECK_NULL_RETURN(swiperNode, nullptr); 56 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>(); 57 CHECK_NULL_RETURN(swiperPattern, nullptr); 58 if (swiperPattern->GetIndicatorType() == SwiperIndicatorType::DOT) { 59 auto indicatorLayoutAlgorithm = MakeRefPtr<DotIndicatorLayoutAlgorithm>(); 60 indicatorLayoutAlgorithm->SetIsHoverOrPress(isHover_ || isPressed_); 61 indicatorLayoutAlgorithm->SetHoverPoint(hoverPoint_); 62 return indicatorLayoutAlgorithm; 63 } else { 64 auto indicatorLayoutAlgorithm = MakeRefPtr<DigitIndicatorLayoutAlgorithm>(); 65 indicatorLayoutAlgorithm->SetIsHoverOrPress(isHover_ || isPressed_); 66 indicatorLayoutAlgorithm->SetHoverPoint(hoverPoint_); 67 return indicatorLayoutAlgorithm; 68 } 69 } 70 CreateDotIndicatorPaintMethod(RefPtr<SwiperPattern> swiperPattern)71 RefPtr<DotIndicatorPaintMethod> CreateDotIndicatorPaintMethod(RefPtr<SwiperPattern> swiperPattern) 72 { 73 auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>(); 74 CHECK_NULL_RETURN(swiperLayoutProperty, nullptr); 75 auto paintMethod = MakeRefPtr<DotIndicatorPaintMethod>(dotIndicatorModifier_); 76 paintMethod->SetAxis(swiperPattern->GetDirection()); 77 paintMethod->SetCurrentIndex(swiperPattern->GetLoopIndex(swiperPattern->GetCurrentFirstIndex())); 78 paintMethod->SetCurrentIndexActual(swiperPattern->GetLoopIndex(swiperPattern->GetCurrentIndex())); 79 paintMethod->SetNextValidIndex(swiperPattern->GetNextValidIndex()); 80 paintMethod->SetItemCount(swiperPattern->RealTotalCount()); 81 paintMethod->SetDisplayCount(swiperLayoutProperty->GetDisplayCount().value_or(1)); 82 paintMethod->SetGestureState(swiperPattern->GetGestureState()); 83 paintMethod->SetTurnPageRate(swiperPattern->GetTurnPageRate()); 84 paintMethod->SetIsLoop(swiperPattern->IsLoop()); 85 paintMethod->SetTouchBottomTypeLoop(swiperPattern->GetTouchBottomTypeLoop()); 86 paintMethod->SetIsHover(isHover_); 87 paintMethod->SetIsPressed(isPressed_); 88 paintMethod->SetHoverPoint(hoverPoint_); 89 if (mouseClickIndex_) { 90 mouseClickIndex_ = swiperPattern->GetLoopIndex(mouseClickIndex_.value()); 91 } 92 paintMethod->SetMouseClickIndex(mouseClickIndex_); 93 paintMethod->SetIsTouchBottom(touchBottomType_); 94 paintMethod->SetTouchBottomRate(swiperPattern->GetTouchBottomRate()); 95 mouseClickIndex_ = std::nullopt; 96 return paintMethod; 97 } 98 CreateNodePaintMethod()99 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 100 { 101 auto swiperNode = GetSwiperNode(); 102 CHECK_NULL_RETURN(swiperNode, nullptr); 103 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>(); 104 CHECK_NULL_RETURN(swiperPattern, nullptr); 105 if (swiperPattern->GetIndicatorType() == SwiperIndicatorType::DOT) { 106 if (!dotIndicatorModifier_) { 107 dotIndicatorModifier_ = AceType::MakeRefPtr<DotIndicatorModifier>(); 108 } 109 dotIndicatorModifier_->SetAnimationDuration(swiperPattern->GetDuration()); 110 dotIndicatorModifier_->SetLongPointHeadCurve( 111 swiperPattern->GetCurveIncludeMotion(), swiperPattern->GetMotionVelocity()); 112 113 auto paintMethod = CreateDotIndicatorPaintMethod(swiperPattern); 114 auto geometryNode = swiperNode->GetGeometryNode(); 115 CHECK_NULL_RETURN(geometryNode, nullptr); 116 auto host = GetHost(); 117 CHECK_NULL_RETURN(host, nullptr); 118 auto indicatorGeometryNode = host->GetGeometryNode(); 119 CHECK_NULL_RETURN(indicatorGeometryNode, nullptr); 120 auto boundsValue = 121 (geometryNode->GetFrameSize().Width() - indicatorGeometryNode->GetFrameSize().Width()) * 0.5f; 122 auto boundsRectOriginX = -boundsValue; 123 auto boundsRectOriginY = 0.0f; 124 auto boundsRectWidth = geometryNode->GetFrameSize().Width(); 125 auto boundsRectHeight = indicatorGeometryNode->GetFrameSize().Height(); 126 if (swiperPattern->GetDirection() == Axis::VERTICAL) { 127 boundsValue = 128 (geometryNode->GetFrameSize().Height() - indicatorGeometryNode->GetFrameSize().Height()) * 0.5f; 129 boundsRectOriginX = 0.0f; 130 boundsRectOriginY = -boundsValue; 131 boundsRectWidth = indicatorGeometryNode->GetFrameSize().Width(); 132 boundsRectHeight = geometryNode->GetFrameSize().Height(); 133 } 134 RectF boundsRect(boundsRectOriginX, boundsRectOriginY, boundsRectWidth, boundsRectHeight); 135 dotIndicatorModifier_->SetBoundsRect(boundsRect); 136 137 return paintMethod; 138 } else { 139 return nullptr; 140 } 141 } 142 GetSwiperNode()143 RefPtr<FrameNode> GetSwiperNode() const 144 { 145 auto host = GetHost(); 146 CHECK_NULL_RETURN(host, nullptr); 147 auto swiperNode = host->GetParent(); 148 CHECK_NULL_RETURN(swiperNode, nullptr); 149 return DynamicCast<FrameNode>(swiperNode); 150 } 151 GetFocusPattern()152 FocusPattern GetFocusPattern() const override 153 { 154 auto pipelineContext = PipelineBase::GetCurrentContext(); 155 CHECK_NULL_RETURN(pipelineContext, FocusPattern()); 156 auto swiperTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>(); 157 CHECK_NULL_RETURN(swiperTheme, FocusPattern()); 158 FocusPaintParam paintParam; 159 paintParam.SetPaintWidth(swiperTheme->GetFocusedBorderWidth()); 160 paintParam.SetPaintColor(swiperTheme->GetFocusedColor()); 161 return { FocusType::NODE, true, FocusStyleType::INNER_BORDER, paintParam }; 162 } 163 164 void DumpAdvanceInfo() override; 165 166 private: 167 void OnModifyDone() override; 168 void OnAttachToFrameNode() override; 169 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 170 void InitClickEvent(const RefPtr<GestureEventHub>& gestureHub); 171 void HandleClick(const GestureEvent& info); 172 void HandleMouseClick(const GestureEvent& info); 173 void HandleTouchClick(const GestureEvent& info); 174 void InitHoverMouseEvent(); 175 void InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub); 176 void HandleMouseEvent(const MouseInfo& info); 177 void HandleHoverEvent(bool isHover); 178 void HoverInAnimation(const Color& hoverColor); 179 void HoverOutAnimation(const Color& normalColor); 180 void HandleTouchEvent(const TouchEventInfo& info); 181 void HandleTouchDown(); 182 void HandleTouchUp(); 183 void HandleDragStart(const GestureEvent& info); 184 void HandleDragEnd(double dragVelocity); 185 void GetMouseClickIndex(); 186 void UpdateTextContent(const RefPtr<SwiperIndicatorLayoutProperty>& layoutProperty, 187 const RefPtr<FrameNode>& firstTextNode, const RefPtr<FrameNode>& lastTextNode); 188 void UpdateTextContentSub( 189 const RefPtr<SwiperIndicatorLayoutProperty>& layoutProperty, 190 const RefPtr<FrameNode>& firstTextNode, const RefPtr<FrameNode>& lastTextNode); 191 bool CheckIsTouchBottom(const GestureEvent& info); 192 void InitLongPressEvent(const RefPtr<GestureEventHub>& gestureHub); 193 void HandleLongPress(GestureEvent& info); 194 void HandleLongDragUpdate(const TouchLocationInfo& info); 195 bool CheckIsTouchBottom(const TouchLocationInfo& info); 196 float HandleTouchClickMargin(); 197 RefPtr<ClickEvent> clickEvent_; 198 RefPtr<InputEvent> hoverEvent_; 199 RefPtr<TouchEventImpl> touchEvent_; 200 RefPtr<InputEvent> mouseEvent_; 201 RefPtr<LongPressEvent> longPressEvent_; 202 bool isHover_ = false; 203 bool isPressed_ = false; 204 PointF hoverPoint_; 205 PointF dragStartPoint_; 206 TouchBottomType touchBottomType_ = TouchBottomType::NONE; 207 bool isClicked_ = false; 208 bool isRepeatClicked_ = false; 209 210 std::optional<int32_t> mouseClickIndex_ = std::nullopt; 211 RefPtr<DotIndicatorModifier> dotIndicatorModifier_; 212 SwiperIndicatorType swiperIndicatorType_ = SwiperIndicatorType::DOT; 213 ACE_DISALLOW_COPY_AND_MOVE(SwiperIndicatorPattern); 214 }; 215 } // namespace OHOS::Ace::NG 216 217 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_INDICATOR_SWIPER_INDICATOR_PATTERN_H 218