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