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_SLIDER_SLIDER_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SLIDER_SLIDER_PATTERN_H 18 19 #include <cstddef> 20 #include <optional> 21 22 #include "core/components_ng/pattern/pattern.h" 23 #include "core/components_ng/pattern/slider/slider_content_modifier.h" 24 #include "core/components_ng/pattern/slider/slider_event_hub.h" 25 #include "core/components_ng/pattern/slider/slider_layout_algorithm.h" 26 #include "core/components_ng/pattern/slider/slider_layout_property.h" 27 #include "core/components_ng/pattern/slider/slider_model_ng.h" 28 #include "core/components_ng/pattern/slider/slider_paint_method.h" 29 #include "core/components_ng/pattern/slider/slider_paint_property.h" 30 31 namespace OHOS::Ace::NG { 32 class SliderPattern : public Pattern { 33 DECLARE_ACE_TYPE(SliderPattern, Pattern); 34 35 public: 36 SliderPattern() = default; 37 ~SliderPattern() override = default; 38 CreateNodePaintMethod()39 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 40 { 41 if (!IsSliderVisible()) { 42 return nullptr; 43 } 44 auto paintParameters = UpdateContentParameters(); 45 if (!sliderContentModifier_) { 46 sliderContentModifier_ = AceType::MakeRefPtr<SliderContentModifier>( 47 paintParameters, 48 [weak = WeakClaim(this)](float x) { 49 auto pattern = weak.Upgrade(); 50 CHECK_NULL_VOID(pattern); 51 pattern->UpdateImagePositionX(x); 52 }, 53 [weak = WeakClaim(this)](float y) { 54 auto pattern = weak.Upgrade(); 55 CHECK_NULL_VOID(pattern); 56 pattern->UpdateImagePositionY(y); 57 }); 58 } 59 InitAccessibilityVirtualNodeTask(); 60 sliderContentModifier_->SetUseContentModifier(UseContentModifier()); 61 auto overlayGlobalOffset = CalculateGlobalSafeOffset(); 62 std::pair<OffsetF, float> BubbleVertex = GetBubbleVertexPosition(circleCenter_, trackThickness_, blockSize_); 63 SliderPaintMethod::TipParameters tipParameters { bubbleFlag_, BubbleVertex.first, overlayGlobalOffset }; 64 if (!sliderTipModifier_ && bubbleFlag_) { 65 sliderTipModifier_ = AceType::MakeRefPtr<SliderTipModifier>([weak = WeakClaim(this)]() { 66 auto pattern = weak.Upgrade(); 67 if (!pattern) { 68 return std::pair<OffsetF, float>(); 69 } 70 auto blockCenter = pattern->GetBlockCenter(); 71 auto trackThickness = pattern->sliderContentModifier_->GetTrackThickness(); 72 auto blockSize = pattern->sliderContentModifier_->GetBlockSize(); 73 return pattern->GetBubbleVertexPosition(blockCenter, trackThickness, blockSize); 74 }); 75 } 76 auto textDirection = TextDirection::AUTO; 77 auto layoutProperty = GetLayoutProperty<SliderLayoutProperty>(); 78 if (layoutProperty) { 79 textDirection = layoutProperty->GetLayoutDirection(); 80 } 81 return MakeRefPtr<SliderPaintMethod>(sliderContentModifier_, paintParameters, sliderLength_, borderBlank_, 82 sliderTipModifier_, tipParameters, textDirection); 83 } 84 CreateLayoutProperty()85 RefPtr<LayoutProperty> CreateLayoutProperty() override 86 { 87 return MakeRefPtr<SliderLayoutProperty>(); 88 } 89 CreatePaintProperty()90 RefPtr<PaintProperty> CreatePaintProperty() override 91 { 92 return MakeRefPtr<SliderPaintProperty>(); 93 } 94 CreateLayoutAlgorithm()95 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 96 { 97 return MakeRefPtr<SliderLayoutAlgorithm>(); 98 } 99 100 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override; 101 CreateEventHub()102 RefPtr<EventHub> CreateEventHub() override 103 { 104 return MakeRefPtr<SliderEventHub>(); 105 } 106 GetFocusPattern()107 FocusPattern GetFocusPattern() const override 108 { 109 return { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION }; 110 } 111 GetBlockCenter()112 const OffsetF& GetBlockCenter() const 113 { 114 return circleCenter_; 115 } 116 GetAnimatableBlockCenter()117 std::optional<OffsetF> GetAnimatableBlockCenter() const 118 { 119 if (sliderContentModifier_ != nullptr) { 120 auto blockCenter = sliderContentModifier_->GetBlockCenter(); 121 return OffsetF(blockCenter.GetX(), blockCenter.GetY()); 122 } 123 return std::nullopt; 124 } 125 GetValueRatio()126 float GetValueRatio() const 127 { 128 return valueRatio_; 129 } 130 131 std::string ProvideRestoreInfo() override; 132 void OnRestoreInfo(const std::string& restoreInfo) override; 133 OffsetF CalculateGlobalSafeOffset(); 134 void UpdateValue(float value); 135 void OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type) override; 136 SetBuilderFunc(SliderMakeCallback && makeFunc)137 void SetBuilderFunc(SliderMakeCallback&& makeFunc) 138 { 139 if (makeFunc == nullptr) { 140 makeFunc_ = std::nullopt; 141 OnModifyDone(); 142 return; 143 } 144 makeFunc_ = std::move(makeFunc); 145 if (sliderContentModifier_) { 146 sliderContentModifier_->SetUseContentModifier(true); 147 } 148 } 149 UseContentModifier()150 bool UseContentModifier() 151 { 152 return contentModifierNode_ != nullptr; 153 } 154 155 void SetSliderValue(double value, int32_t mode); 156 157 private: 158 void OnAttachToFrameNode() override; 159 void OnDetachFromFrameNode(FrameNode* frameNode) override; 160 void OnModifyDone() override; 161 void CalcSliderValue(); 162 void CancelExceptionValue(float& min, float& max, float& step); 163 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, bool skipMeasure, bool skipLayout) override; 164 bool UpdateParameters(); 165 void CreateParagraphFunc(); 166 void CreateParagraphAndLayout( 167 const TextStyle& textStyle, const std::string& content, const LayoutConstraintF& contentConstraint); 168 bool CreateParagraph(const TextStyle& textStyle, std::string content); 169 void UpdateCircleCenterOffset(); 170 void UpdateTipsValue(); 171 void UpdateBubbleSizeAndLayout(); 172 void UpdateBubble(); 173 void InitializeBubble(); 174 175 bool AtMousePanArea(const Offset& offsetInFrame); 176 bool AtTouchPanArea(const Offset& offsetInFrame); 177 bool AtPanArea(const Offset& offset, const SourceType& sourceType); 178 179 void UpdateMarkDirtyNode(const PropertyChangeFlag& Flag); 180 Axis GetDirection() const; 181 182 void InitClickEvent(const RefPtr<GestureEventHub>& gestureHub); 183 void InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub); 184 void HandleTouchEvent(const TouchEventInfo& info); 185 void HandleTouchDown(const Offset& location, SourceType sourceType); 186 void HandleTouchUp(const Offset& location, SourceType sourceType); 187 void InitMouseEvent(const RefPtr<InputEventHub>& inputEventHub); 188 void HandleMouseEvent(const MouseInfo& info); 189 void HandleHoverEvent(bool isHover); 190 void InitPanEvent(const RefPtr<GestureEventHub>& gestureHub); 191 void HandlingGestureStart(const GestureEvent& info); 192 void HandlingGestureEvent(const GestureEvent& info); 193 void HandledGestureEvent(); 194 195 void UpdateValueByLocalLocation(const std::optional<Offset>& localLocation); 196 void FireChangeEvent(int32_t mode); 197 198 void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub); 199 void GetInnerFocusPaintRect(RoundRect& paintRect); 200 void GetOutsetInnerFocusPaintRect(RoundRect& paintRect); 201 void GetInsetAndNoneInnerFocusPaintRect(RoundRect& paintRect); 202 bool OnKeyEvent(const KeyEvent& event); 203 void PaintFocusState(); 204 bool MoveStep(int32_t stepCount); 205 206 bool IsSliderVisible(); 207 void RegisterVisibleAreaChange(); 208 void OnWindowHide() override; 209 void OnWindowShow() override; 210 void StartAnimation(); 211 void StopAnimation(); 212 213 void OpenTranslateAnimation(SliderStatus status); 214 void CloseTranslateAnimation(); 215 SliderContentModifier::Parameters UpdateContentParameters(); 216 void GetSelectPosition(SliderContentModifier::Parameters& parameters, float centerWidth, const OffsetF& offset); 217 void GetBackgroundPosition(SliderContentModifier::Parameters& parameters, float centerWidth, const OffsetF& offset); 218 void GetCirclePosition(SliderContentModifier::Parameters& parameters, float centerWidth, const OffsetF& offset); 219 void UpdateBlock(); 220 void LayoutImageNode(); 221 void UpdateImagePositionX(float centerX); 222 void UpdateImagePositionY(float centerY); 223 std::pair<OffsetF, float> GetBubbleVertexPosition( 224 const OffsetF& blockCenter, float trackThickness, const SizeF& blockSize); 225 void SetAccessibilityAction(); 226 void UpdateTipState(); 227 void OnIsFocusActiveUpdate(bool isFocusActive); 228 void AddIsFocusActiveUpdateEvent(); 229 void RemoveIsFocusActiveUpdateEvent(); 230 bool isMinResponseExceed(const std::optional<Offset>& localLocation); 231 void FireBuilder(); 232 RefPtr<FrameNode> BuildContentModifierNode(); 233 float GetValueInValidRange(const RefPtr<SliderPaintProperty>& paintProperty, float value, float min, float max); 234 void UpdateToValidValue(); 235 void AccessibilityVirtualNodeRenderTask(); 236 void InitAccessibilityVirtualNodeTask(); 237 void InitAccessibilityHoverEvent(); 238 void HandleAccessibilityHoverEvent(bool state, const AccessibilityHoverInfo& info); 239 bool InitAccessibilityVirtualNode(); 240 void ModifyAccessibilityVirtualNode(); 241 void AddStepPointsAccessibilityVirtualNode(); 242 void HandleTextOnAccessibilityFocusCallback(); 243 void HandleSliderOnAccessibilityFocusCallback(); 244 void UpdateStepAccessibilityVirtualNode(); 245 void UpdateParentNodeSize(); 246 std::string GetPointAccessibilityTxt(uint32_t pointIndex, float stepRatio, float min, float max); 247 uint32_t GetCurrentStepIndex(); 248 SizeF GetStepPointAccessibilityVirtualNodeSize(); 249 void UpdateStepPointsAccessibilityVirtualNodeSelected(); 250 void SetStepPointsAccessibilityVirtualNodeEvent( 251 const RefPtr<FrameNode>& pointNode, uint32_t index, bool isClickAbled, bool reverse); 252 void SetStepPointAccessibilityVirtualNode( 253 const RefPtr<FrameNode>& pointNode, const SizeF& size, const PointF& point, const std::string& txt); 254 void SendAccessibilityValueEvent(int32_t mode); 255 256 std::optional<SliderMakeCallback> makeFunc_; 257 RefPtr<FrameNode> contentModifierNode_; SetSkipGestureEvents()258 void SetSkipGestureEvents() 259 { 260 skipGestureEvents_ = true; 261 } ResetSkipGestureEvents()262 void ResetSkipGestureEvents() 263 { 264 skipGestureEvents_ = false; 265 } IsSkipGestureEvents()266 bool IsSkipGestureEvents() 267 { 268 return skipGestureEvents_; 269 } 270 271 Axis direction_ = Axis::HORIZONTAL; 272 enum SliderChangeMode { Begin = 0, Moving = 1, End = 2, Click = 3 }; 273 float value_ = 0.0f; 274 float minResponse_ = 0.0f; 275 bool skipGestureEvents_ = false; 276 float minResponseStartValue_ = value_; 277 bool isMinResponseExceedFlag_ = false; 278 SourceType eventSourceDevice_ = SourceType::NONE; 279 Offset eventLocalLocation_ {}; 280 bool showTips_ = false; 281 bool hotFlag_ = false; // whether the mouse is hovering over the slider 282 bool valueChangeFlag_ = false; 283 bool mouseHoverFlag_ = false; 284 bool mousePressedFlag_ = false; 285 bool axisFlag_ = false; // Wheel operation flag 286 bool focusFlag_ = false; 287 bool panMoveFlag_ = false; 288 bool hasVisibleChangeRegistered_ = false; 289 bool isVisibleArea_ = true; 290 bool isShow_ = true; 291 SliderModelNG::SliderInteraction sliderInteractionMode_ = SliderModelNG::SliderInteraction::SLIDE_AND_CLICK; 292 bool allowDragEvents_ = true; 293 int32_t fingerId_ = -1; 294 std::optional<Offset> lastTouchLocation_ = std::nullopt; 295 296 float valueRatio_ = 0.0f; 297 float sliderLength_ = 0.0f; 298 float borderBlank_ = 0.0f; 299 float hotBlockShadowWidth_ = 0.0f; 300 double axisOffset_ = 0.0; 301 OffsetF circleCenter_ = { 0.0f, 0.0f }; // Relative to the content area 302 303 float trackThickness_ = 0.0f; 304 SizeF blockHotSize_; 305 SizeF blockSize_; 306 307 RefPtr<TouchEventImpl> touchEvent_; 308 RefPtr<ClickEvent> clickListener_; 309 RefPtr<PanEvent> panEvent_; 310 RefPtr<InputEvent> mouseEvent_; 311 RefPtr<InputEvent> hoverEvent_; 312 313 RefPtr<SliderContentModifier> sliderContentModifier_; 314 bool isTouchUpFlag_ = false; 315 316 // tip Parameters 317 bool bubbleFlag_ = false; 318 RefPtr<SliderTipModifier> sliderTipModifier_; 319 320 RefPtr<FrameNode> imageFrameNode_; 321 std::function<void(bool)> isFocusActiveUpdateEvent_; 322 bool isFocusActive_ = false; 323 324 RefPtr<FrameNode> parentAccessibilityNode_; 325 std::vector<RefPtr<FrameNode>> pointAccessibilityNodeVec_; 326 std::vector<GestureEventFunc> pointAccessibilityNodeEventVec_; 327 bool isInitAccessibilityVirtualNode_ = false; 328 uint64_t lastSendPostValueTime_ = 0; 329 float accessibilityValue_ = 0.0f; 330 331 ACE_DISALLOW_COPY_AND_MOVE(SliderPattern); 332 }; 333 } // namespace OHOS::Ace::NG 334 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SLIDER_SLIDER_PATTERN_H 335