• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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