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