• 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_SWITCH_SWITCH_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWITCH_SWITCH_PATTERN_H
18 
19 #include "base/geometry/axis.h"
20 #include "base/geometry/size.h"
21 #include "base/memory/referenced.h"
22 #include "core/components/checkable/checkable_theme.h"
23 #include "core/components_ng/base/frame_node.h"
24 #include "core/components_ng/event/event_hub.h"
25 #include "core/components_ng/pattern/pattern.h"
26 #include "core/components_ng/pattern/toggle/switch_accessibility_property.h"
27 #include "core/components_ng/pattern/toggle/switch_event_hub.h"
28 #include "core/components_ng/pattern/toggle/switch_layout_algorithm.h"
29 #include "core/components_ng/pattern/toggle/switch_paint_method.h"
30 #include "core/components_ng/pattern/toggle/switch_paint_property.h"
31 #include "core/components_ng/pattern/toggle/toggle_model_ng.h"
32 #include "core/components/theme/app_theme.h"
33 
34 namespace OHOS::Ace::NG {
35 
36 class SwitchPattern : public Pattern {
37     DECLARE_ACE_TYPE(SwitchPattern, Pattern);
38 
39 public:
40     SwitchPattern() = default;
41 
42     ~SwitchPattern() override = default;
43 
IsAtomicNode()44     bool IsAtomicNode() const override
45     {
46         return false;
47     }
48 
CreateEventHub()49     RefPtr<EventHub> CreateEventHub() override
50     {
51         return MakeRefPtr<SwitchEventHub>();
52     }
53 
CreateLayoutAlgorithm()54     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
55     {
56         return MakeRefPtr<SwitchLayoutAlgorithm>();
57     }
58 
CreatePaintProperty()59     RefPtr<PaintProperty> CreatePaintProperty() override
60     {
61         return MakeRefPtr<SwitchPaintProperty>();
62     }
63 
CreateNodePaintMethod()64     RefPtr<NodePaintMethod> CreateNodePaintMethod() override
65     {
66         auto host = GetHost();
67         CHECK_NULL_RETURN(host, nullptr);
68         if (!paintMethod_) {
69             paintMethod_ = MakeRefPtr<SwitchPaintMethod>();
70         }
71         paintMethod_->SetUseContentModifier(UseContentModifier());
72         paintMethod_->SetDirection(direction_);
73         paintMethod_->SetIsSelect(isOn_.value_or(false));
74         paintMethod_->SetDragOffsetX(dragOffsetX_);
75         paintMethod_->SetTouchHoverAnimationType(touchHoverType_);
76         paintMethod_->SetIsDragEvent(isDragEvent_);
77         paintMethod_->SetShowHoverEffect(showHoverEffect_);
78         paintMethod_->SetUseContentModifier(UseContentModifier());
79         return paintMethod_;
80     }
81 
CreateAccessibilityProperty()82     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
83     {
84         return MakeRefPtr<SwitchAccessibilityProperty>();
85     }
86 
GetFocusPattern()87     FocusPattern GetFocusPattern() const override
88     {
89         FocusPaintParam focusPaintParams;
90 
91         auto pipelineContext = PipelineBase::GetCurrentContext();
92         CHECK_NULL_RETURN(pipelineContext, FocusPattern());
93         auto switchTheme = pipelineContext->GetTheme<SwitchTheme>(GetThemeScopeId());
94         CHECK_NULL_RETURN(switchTheme, FocusPattern());
95 
96         auto focusPaintcolor = switchTheme->GetActiveColor();
97         focusPaintParams.SetPaintColor(focusPaintcolor);
98         focusPaintParams.SetFocusPadding(switchTheme->GetSwitchFocuPadding());
99 
100         return { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION, focusPaintParams };
101     }
102 
IsChecked()103     bool IsChecked()
104     {
105         return isOn_.value_or(false);
106     }
107 
108     void MarkIsSelected(bool isSelected);
109 
SetIsUserSetResponseRegion(bool isUserSetResponseRegion)110     void SetIsUserSetResponseRegion(bool isUserSetResponseRegion)
111     {
112         isUserSetResponseRegion_ = isUserSetResponseRegion;
113     }
114 
SetShowHoverEffect(bool showHoverEffect)115     void SetShowHoverEffect(bool showHoverEffect)
116     {
117         showHoverEffect_ = showHoverEffect;
118     }
119 
120     std::string ProvideRestoreInfo() override;
121 
122     void OnRestoreInfo(const std::string& restoreInfo) override;
123     void OnColorConfigurationUpdate() override;
SetBuilderFunc(SwitchMakeCallback && makeFunc)124     void SetBuilderFunc(SwitchMakeCallback&& makeFunc)
125     {
126         if (makeFunc == nullptr) {
127             makeFunc_ = std::nullopt;
128             contentModifierNode_ = nullptr;
129             OnModifyDone();
130             return;
131         }
132         makeFunc_ = std::move(makeFunc);
133     }
134 
GetBuilderId()135     int32_t GetBuilderId()
136     {
137         return nodeId_;
138     }
139 
UseContentModifier()140     bool UseContentModifier()
141     {
142         return contentModifierNode_ != nullptr;
143     }
144 
145     void SetSwitchIsOn(bool value);
146     bool OnThemeScopeUpdate(int32_t themeScopeId) override;
147 
148 private:
149     void OnAttachToFrameNode() override;
150     void OnModifyDone() override;
151     void SetAccessibilityAction();
152     void UpdateSelectStatus(bool isSelected);
153     void OnAfterModifyDone() override;
154     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, bool skipMeasure, bool skipLayout) override;
155     RefPtr<Curve> GetCurve() const;
156     int32_t GetDuration() const;
157     int32_t nodeId_ = -1;
158     void UpdateChangeEvent() const;
159     void OnChange();
160     void OnTouchDown();
161     void OnTouchUp();
162     void HandleMouseEvent(bool isHover);
163     void HandleFocusEvent();
164     void HandleBlurEvent();
165     void UpdateColorWhenIsOn(bool isOn);
166     float GetSwitchWidth() const;
167     float GetSwitchContentOffsetX() const;
168 
169     // Init pan recognizer to move items when drag update, play translate animation when drag end.
170     void HandleEnabled();
171     void InitPanEvent(const RefPtr<GestureEventHub>& gestureHub);
172     void InitClickEvent();
173     void InitTouchEvent();
174     void InitMouseEvent();
175     void InitFocusEvent();
176 
177     void AddIsFocusActiveUpdateEvent();
178     void RemoveIsFocusActiveUpdateEvent();
179     void OnIsFocusActiveUpdate(bool isFocusAcitve);
180     void UpdateSwitchStyle();
181 
182     // Init key event
183     void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub);
184     void GetInnerFocusPaintRect(RoundRect& paintRect);
185 
186     void HandleDragStart();
187     void HandleDragUpdate(const GestureEvent& info);
188     void HandleDragEnd();
189 
190     bool IsOutOfBoundary(double mainOffset) const;
191     void OnClick();
192     void AddHotZoneRect();
193     void RemoveLastHotZoneRect() const;
194     void UpdateSwitchPaintProperty();
195     void UpdateSwitchLayoutProperty();
196     void FireBuilder();
197     bool OnKeyEvent(const KeyEvent& keyEventInfo);
198     RefPtr<FrameNode> BuildContentModifierNode();
199     std::optional<SwitchMakeCallback> makeFunc_;
200     RefPtr<FrameNode> contentModifierNode_;
201 
202     RefPtr<PanEvent> panEvent_;
203     RefPtr<SwitchTheme> switchTheme_;
204     RefPtr<ClickEvent> clickListener_;
205     std::optional<bool> isOn_;
206     float currentOffset_ = 0.0f;
207     float dragOffsetX_ = 0.0f;
208 
209     RefPtr<TouchEventImpl> touchListener_;
210     RefPtr<InputEvent> mouseEvent_;
211     bool isTouch_ = false;
212     bool isHover_ = false;
213     bool isFocus_ = false;
214     bool isBgColorUnselectFocus_ = false;
215     bool isUserSetResponseRegion_ = false;
216     bool showHoverEffect_ = true;
217 
218     float width_ = 0.0f;
219     float height_ = 0.0f;
220     Dimension hotZoneHorizontalPadding_;
221     Dimension hotZoneVerticalPadding_;
222     OffsetF offset_;
223     SizeF size_;
224     OffsetF hotZoneOffset_;
225     SizeF hotZoneSize_;
226     TouchHoverAnimationType touchHoverType_ = TouchHoverAnimationType::NONE;
227     TextDirection direction_ = TextDirection::AUTO;
228     bool isDragEvent_ = false;
229     RefPtr<SwitchPaintMethod> paintMethod_;
230     ACE_DISALLOW_COPY_AND_MOVE(SwitchPattern);
231     std::function<void(bool)> isFocusActiveUpdateEvent_;
232     Dimension hotZoneHorizontalSize_;
233     Dimension hotZoneVerticalSize_;
234 };
235 } // namespace OHOS::Ace::NG
236 
237 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWITCH_SWITCH_PATTERN_H
238