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 CreateNodePaintMethod()71 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 72 { 73 auto swiperNode = GetSwiperNode(); 74 CHECK_NULL_RETURN(swiperNode, nullptr); 75 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>(); 76 CHECK_NULL_RETURN(swiperPattern, nullptr); 77 if (swiperPattern->GetIndicatorType() == SwiperIndicatorType::DOT) { 78 if (!dotIndicatorModifier_) { 79 dotIndicatorModifier_ = AceType::MakeRefPtr<DotIndicatorModifier>(); 80 } 81 auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>(); 82 CHECK_NULL_RETURN(swiperLayoutProperty, nullptr); 83 auto paintMethod = MakeRefPtr<DotIndicatorPaintMethod>(dotIndicatorModifier_); 84 paintMethod->SetAxis(swiperPattern->GetDirection()); 85 paintMethod->SetCurrentIndex(swiperPattern->GetCurrentFirstIndex()); 86 paintMethod->SetItemCount(swiperPattern->TotalCount()); 87 paintMethod->SetDisplayCount(swiperLayoutProperty->GetDisplayCount().value_or(1)); 88 paintMethod->SetTurnPageRate(swiperPattern->GetTurnPageRate()); 89 paintMethod->SetIsLoop(swiperPattern->IsLoop()); 90 paintMethod->SetIsHover(isHover_); 91 paintMethod->SetIsPressed(isPressed_); 92 paintMethod->SetHoverPoint(hoverPoint_); 93 paintMethod->SetMouseClickIndex(mouseClickIndex_); 94 paintMethod->SetIsTouchBottom(touchBottomType_); 95 paintMethod->SetTouchBottomRate(swiperPattern->GetTouchBottomRate()); 96 mouseClickIndex_ = std::nullopt; 97 98 auto geometryNode = swiperNode->GetGeometryNode(); 99 CHECK_NULL_RETURN(geometryNode, nullptr); 100 auto host = GetHost(); 101 CHECK_NULL_RETURN(host, nullptr); 102 auto indicatorGeometryNode = host->GetGeometryNode(); 103 CHECK_NULL_RETURN(indicatorGeometryNode, nullptr); 104 auto boundsValue = 105 (geometryNode->GetFrameSize().Width() - indicatorGeometryNode->GetFrameSize().Width()) * 0.5f; 106 auto boundsRectOriginX = -boundsValue; 107 auto boundsRectOriginY = 0.0f; 108 auto boundsRectWidth = geometryNode->GetFrameSize().Width(); 109 auto boundsRectHeight = indicatorGeometryNode->GetFrameSize().Height(); 110 if (swiperPattern->GetDirection() == Axis::VERTICAL) { 111 boundsValue = 112 (geometryNode->GetFrameSize().Height() - indicatorGeometryNode->GetFrameSize().Height()) * 0.5f; 113 boundsRectOriginX = 0.0f; 114 boundsRectOriginY = -boundsValue; 115 boundsRectWidth = indicatorGeometryNode->GetFrameSize().Width(); 116 boundsRectHeight = geometryNode->GetFrameSize().Height(); 117 } 118 RectF boundsRect(boundsRectOriginX, boundsRectOriginY, boundsRectWidth, boundsRectHeight); 119 dotIndicatorModifier_->SetBoundsRect(boundsRect); 120 121 return paintMethod; 122 } else { 123 return nullptr; 124 } 125 } 126 GetSwiperNode()127 RefPtr<FrameNode> GetSwiperNode() const 128 { 129 auto host = GetHost(); 130 CHECK_NULL_RETURN(host, nullptr); 131 auto swiperNode = host->GetParent(); 132 CHECK_NULL_RETURN(swiperNode, nullptr); 133 return DynamicCast<FrameNode>(swiperNode); 134 } 135 GetFocusPattern()136 FocusPattern GetFocusPattern() const override 137 { 138 auto pipelineContext = PipelineBase::GetCurrentContext(); 139 CHECK_NULL_RETURN(pipelineContext, FocusPattern()); 140 auto swiperTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>(); 141 CHECK_NULL_RETURN(swiperTheme, FocusPattern()); 142 FocusPaintParam paintParam; 143 paintParam.SetPaintWidth(swiperTheme->GetFocusedBorderWidth()); 144 paintParam.SetPaintColor(swiperTheme->GetFocusedColor()); 145 return { FocusType::NODE, true, FocusStyleType::INNER_BORDER, paintParam }; 146 } 147 148 private: 149 void OnModifyDone() override; 150 void OnAttachToFrameNode() override; 151 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 152 void InitClickEvent(const RefPtr<GestureEventHub>& gestureHub); 153 void HandleClick(const GestureEvent& info); 154 void HandleMouseClick(const GestureEvent& info); 155 void HandleTouchClick(const GestureEvent& info); 156 void InitHoverMouseEvent(); 157 void InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub); 158 void HandleMouseEvent(const MouseInfo& info); 159 void HandleHoverEvent(bool isHover); 160 void HoverInAnimation(const Color& hoverColor); 161 void HoverOutAnimation(const Color& normalColor); 162 void HandleTouchEvent(const TouchEventInfo& info); 163 void HandleTouchDown(); 164 void HandleTouchUp(); 165 void HandleDragStart(const GestureEvent& info); 166 void HandleDragEnd(double dragVelocity); 167 void GetMouseClickIndex(); 168 void UpdateTextContent(const RefPtr<SwiperIndicatorLayoutProperty>& layoutProperty, 169 const RefPtr<FrameNode>& firstTextNode, const RefPtr<FrameNode>& lastTextNode); 170 void UpdateTextContentSub( 171 const RefPtr<SwiperIndicatorLayoutProperty>& layoutProperty, 172 const RefPtr<FrameNode>& firstTextNode, const RefPtr<FrameNode>& lastTextNode); 173 bool CheckIsTouchBottom(const GestureEvent& info); 174 void InitLongPressEvent(const RefPtr<GestureEventHub>& gestureHub); 175 void HandleLongPress(GestureEvent& info); 176 void HandleLongDragUpdate(const TouchLocationInfo& info); 177 bool CheckIsTouchBottom(const TouchLocationInfo& info); 178 float HandleTouchClickMargin(); 179 RefPtr<ClickEvent> clickEvent_; 180 RefPtr<InputEvent> hoverEvent_; 181 RefPtr<TouchEventImpl> touchEvent_; 182 RefPtr<InputEvent> mouseEvent_; 183 RefPtr<LongPressEvent> longPressEvent_; 184 bool isHover_ = false; 185 bool isPressed_ = false; 186 PointF hoverPoint_; 187 PointF dragStartPoint_; 188 TouchBottomType touchBottomType_ = TouchBottomType::NONE; 189 bool isClicked_ = false; 190 bool isRepeatClicked_ = false; 191 192 std::optional<int32_t> mouseClickIndex_ = std::nullopt; 193 RefPtr<DotIndicatorModifier> dotIndicatorModifier_; 194 SwiperIndicatorType swiperIndicatorType_ = SwiperIndicatorType::DOT; 195 ACE_DISALLOW_COPY_AND_MOVE(SwiperIndicatorPattern); 196 }; 197 } // namespace OHOS::Ace::NG 198 199 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_INDICATOR_SWIPER_INDICATOR_PATTERN_H 200