1 /* 2 * Copyright (c) 2021-2022 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_SLIDER_RENDER_SLIDER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SLIDER_RENDER_SLIDER_H 18 19 #include <functional> 20 21 #include "core/animation/animator.h" 22 #include "core/animation/curve_animation.h" 23 #include "core/components/slider/block_component.h" 24 #include "core/components/slider/render_block.h" 25 #include "core/components/slider/slider_component.h" 26 #include "core/components/text/render_text.h" 27 #include "core/components/common/rotation/rotation_node.h" 28 #include "core/components/text/text_component.h" 29 #include "core/components/track/render_track.h" 30 #include "core/gestures/click_recognizer.h" 31 #include "core/gestures/drag_recognizer.h" 32 #include "core/gestures/raw_recognizer.h" 33 #include "core/pipeline/base/render_node.h" 34 35 namespace OHOS::Ace { 36 37 constexpr double DEFAULT_VALUE = 0.0; 38 constexpr double DEFAULT_MAX = 1.0; 39 constexpr double DEFAULT_MIN = 0.0; 40 constexpr double DEFAULT_STEP = 1.0; 41 constexpr Dimension FOCUS_PADDING = 2.0_vp; 42 const Dimension SLIDER_PADDING_DP = 13.5_vp; 43 44 enum class SliderEvent { 45 MOVE_START = 0, 46 MOVE_MOVING = 1, 47 MOVE_END = 2, 48 CLICK = 3, 49 ACCESSIBILITY = 4, 50 FOCUS = 5, 51 }; 52 53 using TouchRegionPoint = Offset; 54 using Vertex = Offset; 55 56 // The region layout is shown below, and only needs two point can settle the rectangle. 57 // (0,0)------------(10,0) 58 // | | 59 // | .(5,5)| 60 // | | 61 // (0,10)------------(10,10) 62 class TouchRegion { 63 public: 64 TouchRegion() = default; TouchRegion(TouchRegionPoint topLeftPoint,TouchRegionPoint bottomRightPoint)65 TouchRegion(TouchRegionPoint topLeftPoint, TouchRegionPoint bottomRightPoint) 66 : bottomRightPoint_(bottomRightPoint), topLeftPoint_(topLeftPoint) 67 {} 68 ~TouchRegion() = default; 69 ContainsInRegion(double x,double y)70 bool ContainsInRegion(double x, double y) 71 { 72 return LessOrEqual(topLeftPoint_.GetX(), x) && LessOrEqual(topLeftPoint_.GetY(), y) && 73 GreatOrEqual(bottomRightPoint_.GetX(), x) && GreatOrEqual(bottomRightPoint_.GetY(), y); 74 } 75 76 private: 77 TouchRegionPoint bottomRightPoint_; 78 TouchRegionPoint topLeftPoint_; 79 }; 80 81 // The render node of slider component. 82 class RenderSlider : public RenderNode, public RotationNode { 83 DECLARE_ACE_TYPE(RenderSlider, RenderNode, RotationNode); 84 85 public: 86 RenderSlider(); 87 ~RenderSlider() override = default; 88 89 static RefPtr<RenderNode> Create(); 90 91 void Update(const RefPtr<Component>& component) override; 92 93 void PerformLayout() override; 94 95 void OnPaintFinish() override; 96 97 bool HandleFocusEvent(const KeyEvent& keyEvent); 98 GetValue()99 double GetValue() const 100 { 101 return value_; 102 } 103 GetMax()104 double GetMax() const 105 { 106 return max_; 107 } 108 GetMin()109 double GetMin() const 110 { 111 return min_; 112 } 113 GetStep()114 double GetStep() const 115 { 116 return step_; 117 } 118 GetMode()119 SliderMode GetMode() const 120 { 121 return mode_; 122 } 123 GetDirection()124 Axis GetDirection() const 125 { 126 return direction_; 127 } 128 GetShowSteps()129 bool GetShowSteps() const 130 { 131 return showSteps_; 132 } 133 GetShowTips()134 bool GetShowTips() const 135 { 136 return showTips_; 137 } 138 GetIsReverse()139 bool GetIsReverse() const 140 { 141 return isReverse_; 142 } 143 GetOnMovedEndId()144 std::function<void(const std::string&)> GetOnMovedEndId() const 145 { 146 return onMoveEnd_; 147 } 148 GetErrorBit()149 bool GetErrorBit() const 150 { 151 return isError_; 152 } 153 GetFocus()154 bool GetFocus() const 155 { 156 return isFocus_; 157 } 158 GetSliderComponent()159 const WeakPtr<SliderComponent>& GetSliderComponent() const 160 { 161 return sliderComponent_; 162 } 163 SetFocus(bool isFocus)164 void SetFocus(bool isFocus) 165 { 166 isFocus_ = isFocus; 167 MarkNeedLayout(); 168 } 169 SyncValueToComponent(double value)170 void SyncValueToComponent(double value) 171 { 172 value_ = value; 173 auto slider = sliderComponent_.Upgrade(); 174 if (slider) { 175 slider->SetCurrentValue(value); 176 } 177 } 178 SetTotalRatio(double ratio)179 void SetTotalRatio(double ratio) 180 { 181 if (ratio > 1.0) { 182 totalRatio_ = 1.0; 183 } else { 184 totalRatio_ = ratio; 185 } 186 if (showTips_) { 187 UpdateTipText(totalRatio_); 188 } 189 } 190 NeedSmoothMoving()191 bool NeedSmoothMoving() const 192 { 193 return mode_ == SliderMode::INSET && GreatNotEqual(step_, DEFAULT_STEP); 194 } 195 GetThickness()196 double GetThickness() 197 { 198 return thickness_; 199 } 200 GetPress()201 bool GetPress() const 202 { 203 return isPress_; 204 } 205 GetHover()206 bool GetHover() const 207 { 208 return isHover_; 209 } 210 211 std::string ProvideRestoreInfo() override; 212 bool OnRotation(const RotationEvent& event) override; 213 214 protected: 215 static TouchRegionPoint GetTopTouchRegion(const Vertex& center, double width, double height); 216 static TouchRegionPoint GetBotTouchRegion(const Vertex& center, double width, double height); 217 218 Size Measure(); 219 void HandleDragStart(const Offset& startPoint); 220 void HandleDragUpdate(const Offset& startPoint); 221 void HandleDragEnd(); 222 void OnTouchTestHit( 223 const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) override; 224 bool MouseHoverTest(const Point& parentLocalPoint) override; OnMouseHoverEnterTest()225 void OnMouseHoverEnterTest() override {} OnMouseHoverExitTest()226 void OnMouseHoverExitTest() override {} 227 bool HandleMouseEvent(const MouseEvent& event) override; 228 void AnimateMouseHoverExit() override; 229 SetOnChange(const std::function<void (double,int32_t)> & value)230 void SetOnChange(const std::function<void(double, int32_t)>& value) 231 { 232 onChange_ = value; 233 } 234 235 void HandleClick(const Offset& clickPosition); 236 237 void FireMoveEndEvent(); 238 void FireMovingEvent(SliderEvent mode); 239 void UpdateAnimation(); 240 void StartMoveAnimation(double from, double to, bool isClick = false); 241 void RestartMoveAnimation(double value, bool isClick = false); 242 void ResetMoveAnimation(double from, double to); 243 void CalculateTotalRadio(); 244 void UpdateTipText(double value); 245 246 void Initialize(const RefPtr<SliderComponent>& sliderComponent); 247 void RenderBlockPosition(const Offset& touchPosition); 248 void UpdateBlockPosition(const Offset& touchPosition, bool isAnimation); 249 Vertex FindCenterVertex(double x, double y, double objectHeight, double objectWidth); 250 void UpdateTouchRegion(); 251 void UpdateAccessibilityAttr(); 252 void InitAccessibilityEventListener(); 253 void HandleScrollUpdate(double delta); 254 void HandleFocus(); 255 RefPtr<RawRecognizer> touchDetector_; 256 257 bool renderWholeNode_ = true; 258 259 // Gesture event 260 RefPtr<DragRecognizer> dragDetector_; 261 RefPtr<ClickRecognizer> clickDetector_; 262 TouchRegion blockTouchRegion_; 263 bool insideBlockRegion_ = false; 264 bool blockActive_ = false; 265 266 // The size constrain is too small set this bit to show text 267 bool isError_ = false; 268 bool isValueError_ = false; 269 270 // bar length 271 double trackLength_ = 1.0; 272 double totalRatio_ = 0.0; 273 double cachedRatio_ = 0.0; 274 275 // the circle block radius scale 276 double radiusScale_ = 1.0; 277 double step_ = DEFAULT_STEP; 278 double max_ = DEFAULT_MAX; 279 double min_ = DEFAULT_MIN; 280 281 double scaleValue_ = 1.0; 282 double thickness_ = 0.0; 283 284 bool showSteps_ = false; 285 bool showTips_ = false; 286 bool isDragging_ = false; 287 bool isReverse_ = false; 288 SliderMode mode_ = SliderMode::OUTSET; 289 Dimension blockHotWidth_; 290 Dimension blockHotHeight_; 291 Dimension hotWidth_; 292 Axis direction_ = Axis::HORIZONTAL; 293 294 RefPtr<RenderNode> tip_; 295 RefPtr<RenderNode> renderText_; 296 RefPtr<TextComponent> tipText_; 297 WeakPtr<SliderComponent> sliderComponent_; 298 299 std::function<void(double, int32_t)> onChange_; 300 RefPtr<RenderNode> block_ = AceType::MakeRefPtr<RenderBlock>(); 301 RefPtr<RenderNode> track_ = AceType::MakeRefPtr<RenderTrack>(); 302 303 double accumulatedValue_ = 0.0; 304 private: 305 void ApplyRestoreInfo(); 306 307 // Slider render information 308 double value_ = DEFAULT_VALUE; 309 double preMovingValue_ = DEFAULT_VALUE; 310 std::function<void(const std::string&)> onMoveEnd_; 311 std::function<void(const std::string&)> onMoving_; 312 313 // focus information 314 bool isFocus_ = false; 315 bool isPress_ = false; 316 bool isHover_ = false; 317 bool disable_ = false; 318 319 double animationEnd_ = 0.0; 320 321 // animation attr 322 RefPtr<Animator> controller_; 323 RefPtr<CurveAnimation<double>> translate_; 324 RefPtr<Animator> moveController_; 325 RefPtr<CurveAnimation<double>> moveAnimation_; 326 }; 327 328 } // namespace OHOS::Ace 329 330 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SLIDER_RENDER_SLIDER_H 331