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