• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_NG_PATTERNS_SLIDER_SLIDER_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SLIDER_SLIDER_PATTERN_H
18 
19 #include <cstddef>
20 #include <optional>
21 
22 #include "core/components_ng/pattern/pattern.h"
23 #include "core/components_ng/pattern/slider/slider_content_modifier.h"
24 #include "core/components_ng/pattern/slider/slider_event_hub.h"
25 #include "core/components_ng/pattern/slider/slider_layout_algorithm.h"
26 #include "core/components_ng/pattern/slider/slider_layout_property.h"
27 #include "core/components_ng/pattern/slider/slider_model_ng.h"
28 #include "core/components_ng/pattern/slider/slider_paint_method.h"
29 #include "core/components_ng/pattern/slider/slider_paint_property.h"
30 
31 namespace OHOS::Ace::NG {
32 class SliderPattern : public Pattern {
33     DECLARE_ACE_TYPE(SliderPattern, Pattern);
34 
35 public:
36     SliderPattern() = default;
37     ~SliderPattern() override = default;
38 
CreateNodePaintMethod()39     RefPtr<NodePaintMethod> CreateNodePaintMethod() override
40     {
41         if (!IsSliderVisible()) {
42             return nullptr;
43         }
44         auto paintParameters = UpdateContentParameters();
45         if (!sliderContentModifier_) {
46             sliderContentModifier_ = AceType::MakeRefPtr<SliderContentModifier>(
47                 paintParameters,
48                 [weak = WeakClaim(this)](float x) {
49                     auto pattern = weak.Upgrade();
50                     CHECK_NULL_VOID(pattern);
51                     pattern->UpdateImagePositionX(x);
52                 },
53                 [weak = WeakClaim(this)](float y) {
54                     auto pattern = weak.Upgrade();
55                     CHECK_NULL_VOID(pattern);
56                     pattern->UpdateImagePositionY(y);
57                 });
58         }
59         InitAccessibilityVirtualNodeTask();
60         sliderContentModifier_->SetUseContentModifier(UseContentModifier());
61         auto overlayGlobalOffset = CalculateGlobalSafeOffset();
62         std::pair<OffsetF, float> BubbleVertex = GetBubbleVertexPosition(circleCenter_, trackThickness_, blockSize_);
63         SliderPaintMethod::TipParameters tipParameters { bubbleFlag_, BubbleVertex.first, overlayGlobalOffset };
64         if (!sliderTipModifier_ && bubbleFlag_) {
65             sliderTipModifier_ = AceType::MakeRefPtr<SliderTipModifier>([weak = WeakClaim(this)]() {
66                 auto pattern = weak.Upgrade();
67                 if (!pattern) {
68                     return std::pair<OffsetF, float>();
69                 }
70                 auto blockCenter = pattern->GetBlockCenter();
71                 auto trackThickness = pattern->sliderContentModifier_->GetTrackThickness();
72                 auto blockSize = pattern->sliderContentModifier_->GetBlockSize();
73                 return pattern->GetBubbleVertexPosition(blockCenter, trackThickness, blockSize);
74             });
75         }
76         auto textDirection = TextDirection::AUTO;
77         auto layoutProperty = GetLayoutProperty<SliderLayoutProperty>();
78         if (layoutProperty) {
79             textDirection = layoutProperty->GetLayoutDirection();
80         }
81         return MakeRefPtr<SliderPaintMethod>(sliderContentModifier_, paintParameters, sliderLength_, borderBlank_,
82             sliderTipModifier_, tipParameters, textDirection);
83     }
84 
CreateLayoutProperty()85     RefPtr<LayoutProperty> CreateLayoutProperty() override
86     {
87         return MakeRefPtr<SliderLayoutProperty>();
88     }
89 
CreatePaintProperty()90     RefPtr<PaintProperty> CreatePaintProperty() override
91     {
92         return MakeRefPtr<SliderPaintProperty>();
93     }
94 
CreateLayoutAlgorithm()95     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
96     {
97         return MakeRefPtr<SliderLayoutAlgorithm>();
98     }
99 
100     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override;
101 
CreateEventHub()102     RefPtr<EventHub> CreateEventHub() override
103     {
104         return MakeRefPtr<SliderEventHub>();
105     }
106 
GetFocusPattern()107     FocusPattern GetFocusPattern() const override
108     {
109         return { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION };
110     }
111 
GetBlockCenter()112     const OffsetF& GetBlockCenter() const
113     {
114         return circleCenter_;
115     }
116 
GetAnimatableBlockCenter()117     std::optional<OffsetF> GetAnimatableBlockCenter() const
118     {
119         if (sliderContentModifier_ != nullptr) {
120             auto blockCenter = sliderContentModifier_->GetBlockCenter();
121             return OffsetF(blockCenter.GetX(), blockCenter.GetY());
122         }
123         return std::nullopt;
124     }
125 
GetValueRatio()126     float GetValueRatio() const
127     {
128         return valueRatio_;
129     }
130 
131     std::string ProvideRestoreInfo() override;
132     void OnRestoreInfo(const std::string& restoreInfo) override;
133     OffsetF CalculateGlobalSafeOffset();
134     void UpdateValue(float value);
135     void OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type) override;
136 
SetBuilderFunc(SliderMakeCallback && makeFunc)137     void SetBuilderFunc(SliderMakeCallback&& makeFunc)
138     {
139         if (makeFunc == nullptr) {
140             makeFunc_ = std::nullopt;
141             OnModifyDone();
142             return;
143         }
144         makeFunc_ = std::move(makeFunc);
145         if (sliderContentModifier_) {
146             sliderContentModifier_->SetUseContentModifier(true);
147         }
148     }
149 
UseContentModifier()150     bool UseContentModifier()
151     {
152         return contentModifierNode_ != nullptr;
153     }
154 
SetEnableHapticFeedback(bool value)155     void SetEnableHapticFeedback(bool value)
156     {
157         isEnableHaptic_ = value;
158     }
159 
GetEnableHapticFeedback()160     bool GetEnableHapticFeedback() const
161     {
162         return isEnableHaptic_;
163     }
164 
165     void SetSliderValue(double value, int32_t mode);
166     void InitAccessibilityVirtualNodeTask();
SetIsAccessibilityOn(bool value)167     void SetIsAccessibilityOn(bool value)
168     {
169         isAccessibilityOn_ = value;
170     }
171     void PlayHapticFeedback(bool isShowSteps, float step, float oldValue);
172 
173 #ifdef SUPPORT_DIGITAL_CROWN
SetDigitalCrownSensitivity(CrownSensitivity sensitivity)174     void SetDigitalCrownSensitivity(CrownSensitivity sensitivity)
175     {
176         crownSensitivity_ = sensitivity;
177     }
178 
GetDigitalCrownSensitivity()179     CrownSensitivity GetDigitalCrownSensitivity()
180     {
181         return crownSensitivity_;
182     }
183 #endif
184 
185 private:
186     void OnAttachToFrameNode() override;
187     void OnDetachFromFrameNode(FrameNode* frameNode) override;
188     void OnModifyDone() override;
189     void CalcSliderValue();
190     void CancelExceptionValue(float& min, float& max, float& step);
191     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, bool skipMeasure, bool skipLayout) override;
192     bool UpdateParameters();
193     void CreateParagraphFunc();
194     void CreateParagraphAndLayout(
195         const TextStyle& textStyle, const std::string& content, const LayoutConstraintF& contentConstraint);
196     bool CreateParagraph(const TextStyle& textStyle, std::string content);
197     void UpdateCircleCenterOffset();
198     void UpdateTipsValue();
199     void UpdateBubbleSizeAndLayout();
200     void UpdateBubble();
201     void InitializeBubble();
202     void UpdatePaintRect(RefPtr<SliderTheme> theme, SliderModel::SliderMode& sliderMode, RoundRect& paintRect,
203         const RectF& rect, float rectRadius);
204 
205     bool AtMousePanArea(const Offset& offsetInFrame);
206     bool AtTouchPanArea(const Offset& offsetInFrame);
207     bool AtPanArea(const Offset& offset, const SourceType& sourceType);
208 
209     void UpdateMarkDirtyNode(const PropertyChangeFlag& Flag);
210     Axis GetDirection() const;
211 
212     void InitClickEvent(const RefPtr<GestureEventHub>& gestureHub);
213     void InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub);
214     void HandleTouchEvent(const TouchEventInfo& info);
215     void HandleTouchDown(const Offset& location, SourceType sourceType);
216     void HandleTouchUp(const Offset& location, SourceType sourceType);
217     void InitMouseEvent(const RefPtr<InputEventHub>& inputEventHub);
218     void HandleMouseEvent(const MouseInfo& info);
219     void HandleHoverEvent(bool isHover);
220     void HandleEnabled();
221     void InitPanEvent(const RefPtr<GestureEventHub>& gestureHub);
222     void HandlingGestureStart(const GestureEvent& info);
223     void HandlingGestureEvent(const GestureEvent& info);
224     void HandledGestureEvent();
225 
226     void UpdateValueByLocalLocation(const std::optional<Offset>& localLocation);
227     void FireChangeEvent(int32_t mode);
228 
229     void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub);
230     void GetInnerFocusPaintRect(RoundRect& paintRect);
231     void GetOutsetInnerFocusPaintRect(RoundRect& paintRect);
232     void GetInsetAndNoneInnerFocusPaintRect(RoundRect& paintRect);
233     bool OnKeyEvent(const KeyEvent& event);
234     void PaintFocusState();
235     bool MoveStep(int32_t stepCount);
236     void InitHapticController();
237 #ifdef SUPPORT_DIGITAL_CROWN
InitDigitalCrownEvent(const RefPtr<FocusHub> & focusHub)238     void InitDigitalCrownEvent(const RefPtr<FocusHub>& focusHub)
239     {
240         auto pipeline = GetContext();
241         CHECK_NULL_VOID(pipeline);
242         auto sliderTheme = pipeline->GetTheme<SliderTheme>();
243         CHECK_NULL_VOID(sliderTheme);
244         crownDisplayControlRatio_ = sliderTheme->GetCrownDisplayControlRatio();
245 
246         auto onCrownEvent = [weak = WeakClaim(this)](const CrownEvent& event) -> bool {
247             auto pattern = weak.Upgrade();
248             CHECK_NULL_RETURN(pattern, false);
249             pattern->HandleCrownEvent(event);
250             return true;
251         };
252         focusHub->SetOnCrownEventInternal(std::move(onCrownEvent));
253     }
HandleCrownEvent(const CrownEvent & event)254     void HandleCrownEvent(const CrownEvent& event)
255     {
256         TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT,
257             "slider HandleCrownEvent event.action %{public}d event.degree %{public}f",
258             event.action, event.degree);
259         double mainDelta = GetCrownRotatePx(event);
260         switch (event.action) {
261             case CrownAction::BEGIN:
262                 crownMovingLength_ = valueRatio_ * sliderLength_;
263                 crownEventNum_ = 0;
264                 reachBoundary_ = false;
265                 HandleCrownAction(mainDelta);
266                 timeStampPre_ = GetCurrentTimestamp();
267                 UpdateMarkDirtyNode(PROPERTY_UPDATE_RENDER);
268                 FireChangeEvent(SliderChangeMode::Begin);
269                 OpenTranslateAnimation(SliderStatus::MOVE);
270                 break;
271             case CrownAction::UPDATE:
272                 HandleCrownAction(mainDelta);
273                 StartVibrateFeedback();
274                 UpdateMarkDirtyNode(PROPERTY_UPDATE_RENDER);
275                 FireChangeEvent(SliderChangeMode::Moving);
276                 OpenTranslateAnimation(SliderStatus::MOVE);
277                 break;
278             case CrownAction::END:
279             default:
280                 bubbleFlag_ = false;
281                 UpdateMarkDirtyNode(PROPERTY_UPDATE_RENDER);
282                 FireChangeEvent(SliderChangeMode::End);
283                 CloseTranslateAnimation();
284                 break;
285         }
286     }
287     double GetCrownRotatePx(const CrownEvent& event) const;
288     void HandleCrownAction(double mainDelta);
289     void StartVibrateFeedback();
290 #endif
291     bool IsSliderVisible();
292     void RegisterVisibleAreaChange();
293     void OnWindowHide() override;
294     void OnWindowShow() override;
295     void StartAnimation();
296     void StopAnimation();
297 
298     void OpenTranslateAnimation(SliderStatus status);
299     void CloseTranslateAnimation();
300     SliderContentModifier::Parameters UpdateContentParameters();
301     void GetSelectPosition(SliderContentModifier::Parameters& parameters, float centerWidth, const OffsetF& offset);
302     void GetBackgroundPosition(SliderContentModifier::Parameters& parameters, float centerWidth, const OffsetF& offset);
303     void GetCirclePosition(SliderContentModifier::Parameters& parameters, float centerWidth, const OffsetF& offset);
304     void UpdateBlock();
305     void LayoutImageNode();
306     void UpdateImagePositionX(float centerX);
307     void UpdateImagePositionY(float centerY);
308     std::pair<OffsetF, float> GetBubbleVertexPosition(
309         const OffsetF& blockCenter, float trackThickness, const SizeF& blockSize);
310     void SetAccessibilityAction();
311     void UpdateTipState();
312     void OnIsFocusActiveUpdate(bool isFocusActive);
313     void AddIsFocusActiveUpdateEvent();
314     void RemoveIsFocusActiveUpdateEvent();
315     bool isMinResponseExceed(const std::optional<Offset>& localLocation);
316     void FireBuilder();
317     RefPtr<FrameNode> BuildContentModifierNode();
318     float GetValueInValidRange(const RefPtr<SliderPaintProperty>& paintProperty, float value, float min, float max);
319     void UpdateToValidValue();
320     void InitSliderAccessibilityEnabledRegister();
321     void AccessibilityVirtualNodeRenderTask();
322     bool CheckCreateAccessibilityVirtualNode();
323     void InitAccessibilityHoverEvent();
324     bool InitAccessibilityVirtualNode();
325     void ModifyAccessibilityVirtualNode();
326     void AddStepPointsAccessibilityVirtualNode();
327     void UpdateStepAccessibilityVirtualNode();
328     void UpdateParentNodeSize();
329     std::string GetPointAccessibilityTxt(uint32_t pointIndex, float stepRatio, float min, float max);
330     uint32_t GetCurrentStepIndex();
331     SizeF GetStepPointAccessibilityVirtualNodeSize();
332     void UpdateStepPointsAccessibilityVirtualNodeSelected();
333     void SetStepPointsAccessibilityVirtualNodeEvent(
334         const RefPtr<FrameNode>& pointNode, uint32_t index, bool isClickAbled, bool reverse);
335     void SetStepPointAccessibilityVirtualNode(
336         const RefPtr<FrameNode>& pointNode, const SizeF& size, const PointF& point, const std::string& txt);
337     void SendAccessibilityValueEvent(int32_t mode);
338     void ClearSliderVirtualNode();
339     void InitOrRefreshSlipFactor();
340     RefPtr<PanEvent> CreatePanEvent();
341 
342     std::optional<SliderMakeCallback> makeFunc_;
343     RefPtr<FrameNode> contentModifierNode_;
SetSkipGestureEvents()344     void SetSkipGestureEvents()
345     {
346         skipGestureEvents_ = true;
347     }
ResetSkipGestureEvents()348     void ResetSkipGestureEvents()
349     {
350         skipGestureEvents_ = false;
351     }
IsSkipGestureEvents()352     bool IsSkipGestureEvents()
353     {
354         return skipGestureEvents_;
355     }
356 
357     Axis direction_ = Axis::HORIZONTAL;
358     enum SliderChangeMode { Begin = 0, Moving = 1, End = 2, Click = 3 };
359     float value_ = 0.0f;
360     float minResponse_ = 0.0f;
361     bool skipGestureEvents_ = false;
362     float minResponseStartValue_ = value_;
363     bool isMinResponseExceedFlag_ = false;
364     SourceType eventSourceDevice_ = SourceType::NONE;
365     Offset eventLocalLocation_ {};
366     bool showTips_ = false;
367     bool hotFlag_ = false; // whether the mouse is hovering over the slider
368     bool valueChangeFlag_ = false;
369     bool mouseHoverFlag_ = false;
370     bool mousePressedFlag_ = false;
371     bool axisFlag_ = false; // Wheel operation flag
372     bool focusFlag_ = false;
373     bool panMoveFlag_ = false;
374     bool hasVisibleChangeRegistered_ = false;
375     bool isVisibleArea_ = true;
376     bool isShow_ = true;
377     SliderModelNG::SliderInteraction sliderInteractionMode_ = SliderModelNG::SliderInteraction::SLIDE_AND_CLICK;
378     bool allowDragEvents_ = true;
379     int32_t fingerId_ = -1;
380     std::optional<Offset> lastTouchLocation_ = std::nullopt;
381 
382     float valueRatio_ = 0.0f;
383     float sliderLength_ = 0.0f;
384     float borderBlank_ = 0.0f;
385     float hotBlockShadowWidth_ = 0.0f;
386     double axisOffset_ = 0.0;
387     OffsetF circleCenter_ = { 0.0f, 0.0f }; // Relative to the content area
388 
389     float trackThickness_ = 0.0f;
390     SizeF blockHotSize_;
391     SizeF blockSize_;
392 #ifdef SUPPORT_DIGITAL_CROWN
393     CrownSensitivity crownSensitivity_ = CrownSensitivity::MEDIUM;
394     double crownDisplayControlRatio_ = 1.0;
395     double crownMovingLength_ = 0.0;
396     int32_t crownEventNum_ = 0;
397     bool reachBoundary_ = false;
398     int64_t timeStampCur_ = 0;
399     int64_t timeStampPre_ = 0;
400 #endif
401 
402     RefPtr<TouchEventImpl> touchEvent_;
403     RefPtr<ClickEvent> clickListener_;
404     RefPtr<PanEvent> panEvent_;
405     RefPtr<InputEvent> mouseEvent_;
406     RefPtr<InputEvent> hoverEvent_;
407 
408     RefPtr<SliderContentModifier> sliderContentModifier_;
409     bool isTouchUpFlag_ = false;
410 
411     // tip Parameters
412     bool bubbleFlag_ = false;
413     RefPtr<SliderTipModifier> sliderTipModifier_;
414 
415     RefPtr<FrameNode> imageFrameNode_;
416     std::function<void(bool)> isFocusActiveUpdateEvent_;
417     bool isFocusActive_ = false;
418     SliderModel::SliderMode sliderMode_ = SliderModel::SliderMode::OUTSET;
419     bool isAccessibilityOn_ = AceApplicationInfo::GetInstance().IsAccessibilityEnabled();
420 
421     std::shared_ptr<AccessibilitySAObserverCallback> accessibilitySAObserverCallback_;
422     RefPtr<FrameNode> parentAccessibilityNode_;
423     std::vector<RefPtr<FrameNode>> pointAccessibilityNodeVec_;
424     std::vector<GestureEventFunc> pointAccessibilityNodeEventVec_;
425     bool isInitAccessibilityVirtualNode_ = false;
426     uint64_t lastSendPostValueTime_ = 0;
427     float accessibilityValue_ = 0.0f;
428     bool isEnableHaptic_ = true;
429     bool hapticApiEnabled = false;
430     double slipfactor_ = 0;
431     ACE_DISALLOW_COPY_AND_MOVE(SliderPattern);
432 };
433 } // namespace OHOS::Ace::NG
434 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SLIDER_SLIDER_PATTERN_H
435