• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "core/components_ng/pattern/toggle/toggle_model_ng.h"
17 
18 #include "base/memory/ace_type.h"
19 #include "base/memory/referenced.h"
20 #include "base/utils/utils.h"
21 #include "core/components_ng/base/frame_node.h"
22 #include "core/components_ng/base/ui_node.h"
23 #include "core/components_ng/base/view_stack_processor.h"
24 #include "core/components_ng/base/view_abstract.h"
25 #include "core/components_ng/pattern/button/toggle_button_model_ng.h"
26 #include "core/components_ng/pattern/button/toggle_button_pattern.h"
27 #include "core/components_ng/pattern/checkbox/checkbox_model_ng.h"
28 #include "core/components_ng/pattern/checkbox/checkbox_pattern.h"
29 #include "core/components_ng/pattern/toggle/switch_paint_property.h"
30 #include "core/components_ng/pattern/toggle/switch_pattern.h"
31 #include "core/components_v2/inspector/inspector_constants.h"
32 #include "core/pipeline/base/element_register.h"
33 #include "core/pipeline_ng/ui_task_scheduler.h"
34 #include "core/components/toggle/toggle_theme.h"
35 
36 namespace OHOS::Ace::NG {
37 
Create(NG::ToggleType toggleType,bool isOn)38 void ToggleModelNG::Create(NG::ToggleType toggleType, bool isOn)
39 {
40     auto* stack = ViewStackProcessor::GetInstance();
41     int nodeId = stack->ClaimNodeId();
42     auto childFrameNode = FrameNode::GetFrameNode(V2::TOGGLE_ETS_TAG, nodeId);
43     if (!childFrameNode) {
44         switch (toggleType) {
45             case ToggleType::CHECKBOX: {
46                 CheckBoxModelNG checkBoxModelNG;
47                 CreateCheckbox(nodeId);
48                 checkBoxModelNG.SetSelect(isOn);
49                 break;
50             }
51             case ToggleType::SWITCH: {
52                 CreateSwitch(nodeId);
53                 ACE_UPDATE_PAINT_PROPERTY(SwitchPaintProperty, IsOn, isOn);
54                 break;
55             }
56             case ToggleType::BUTTON: {
57                 CreateButton(nodeId);
58                 ToggleButtonModelNG::SetIsOn(isOn);
59                 break;
60             }
61             default:
62                 break;
63         }
64         return;
65     }
66     auto pattern = childFrameNode->GetPattern();
67     if (AceType::InstanceOf<CheckBoxPattern>(pattern)) {
68         if (toggleType == ToggleType::CHECKBOX) {
69             stack->Push(childFrameNode);
70             CheckBoxModelNG checkBoxModelNG;
71             checkBoxModelNG.SetSelect(isOn);
72             return;
73         }
74         if (toggleType == ToggleType::SWITCH) {
75             auto parentFrame = childFrameNode->GetParent();
76             CHECK_NULL_VOID(parentFrame);
77             auto index = RemoveNode(childFrameNode, nodeId);
78             childFrameNode->SetUndefinedNodeId();
79             CreateSwitch(nodeId);
80             ACE_UPDATE_PAINT_PROPERTY(SwitchPaintProperty, IsOn, isOn);
81             AddNewChild(parentFrame, nodeId, index);
82             return;
83         }
84         auto parentFrame = childFrameNode->GetParent();
85         CHECK_NULL_VOID(parentFrame);
86         auto index = RemoveNode(childFrameNode, nodeId);
87         childFrameNode->SetUndefinedNodeId();
88         CreateButton(nodeId);
89         ToggleButtonModelNG::SetIsOn(isOn);
90         AddNewChild(parentFrame, nodeId, index);
91         return;
92     }
93     if (AceType::InstanceOf<SwitchPattern>(pattern)) {
94         if (toggleType == ToggleType::SWITCH) {
95             stack->Push(childFrameNode);
96             ACE_UPDATE_PAINT_PROPERTY(SwitchPaintProperty, IsOn, isOn);
97             return;
98         }
99         if (toggleType == ToggleType::CHECKBOX) {
100             auto parentFrame = childFrameNode->GetParent();
101             CHECK_NULL_VOID(parentFrame);
102             auto index = RemoveNode(childFrameNode, nodeId);
103             childFrameNode->SetUndefinedNodeId();
104             CheckBoxModelNG checkBoxModelNG;
105             CreateCheckbox(nodeId);
106             checkBoxModelNG.SetSelect(isOn);
107             AddNewChild(parentFrame, nodeId, index);
108             return;
109         }
110         auto parentFrame = childFrameNode->GetParent();
111         CHECK_NULL_VOID(parentFrame);
112         auto index = RemoveNode(childFrameNode, nodeId);
113         childFrameNode->SetUndefinedNodeId();
114         CreateButton(nodeId);
115         ToggleButtonModelNG::SetIsOn(isOn);
116         AddNewChild(parentFrame, nodeId, index);
117         return;
118     }
119     if (AceType::InstanceOf<ToggleButtonPattern>(pattern)) {
120         if (toggleType == ToggleType::BUTTON) {
121             stack->Push(childFrameNode);
122             ToggleButtonModelNG::SetIsOn(isOn);
123             return;
124         }
125         if (toggleType == ToggleType::CHECKBOX) {
126             auto parentFrame = childFrameNode->GetParent();
127             CHECK_NULL_VOID(parentFrame);
128             auto index = RemoveNode(childFrameNode, nodeId);
129             childFrameNode->SetUndefinedNodeId();
130             CheckBoxModelNG checkBoxModelNG;
131             CreateCheckbox(nodeId);
132             checkBoxModelNG.SetSelect(isOn);
133             AddNewChild(parentFrame, nodeId, index);
134             return;
135         }
136         auto parentFrame = childFrameNode->GetParent();
137         CHECK_NULL_VOID(parentFrame);
138         auto index = RemoveNode(childFrameNode, nodeId);
139         childFrameNode->SetUndefinedNodeId();
140         CreateSwitch(nodeId);
141         ACE_UPDATE_PAINT_PROPERTY(SwitchPaintProperty, IsOn, isOn);
142         AddNewChild(parentFrame, nodeId, index);
143     }
144 }
145 
SetSelectedColor(const std::optional<Color> & selectedColor)146 void ToggleModelNG::SetSelectedColor(const std::optional<Color>& selectedColor)
147 {
148     auto* stack = ViewStackProcessor::GetInstance();
149     CHECK_NULL_VOID(stack);
150     auto pipeline = PipelineBase::GetCurrentContext();
151     CHECK_NULL_VOID(pipeline);
152     Color color;
153     if (selectedColor.has_value()) {
154         color = selectedColor.value();
155     }
156 
157     auto checkboxPattern = stack->GetMainFrameNodePattern<CheckBoxPattern>();
158     if (checkboxPattern) {
159         if (!selectedColor.has_value()) {
160             auto theme = pipeline->GetTheme<CheckboxTheme>();
161             CHECK_NULL_VOID(theme);
162             color = theme->GetActiveColor();
163         }
164         CheckBoxModelNG checkBoxModelNG;
165         checkBoxModelNG.SetSelectedColor(color);
166         return;
167     }
168     auto buttonPattern = stack->GetMainFrameNodePattern<ToggleButtonPattern>();
169     if (buttonPattern) {
170         if (!selectedColor.has_value()) {
171             auto theme = pipeline->GetTheme<ToggleTheme>();
172             CHECK_NULL_VOID(theme);
173             color = theme->GetCheckedColor();
174         }
175         ToggleButtonModelNG::SetSelectedColor(color);
176         return;
177     }
178 
179     if (!selectedColor.has_value()) {
180         auto theme = pipeline->GetTheme<SwitchTheme>();
181         CHECK_NULL_VOID(theme);
182         color = theme->GetActiveColor();
183     }
184     ACE_UPDATE_PAINT_PROPERTY(SwitchPaintProperty, SelectedColor, color);
185 }
186 
SetSwitchPointColor(const Color & switchPointColor)187 void ToggleModelNG::SetSwitchPointColor(const Color& switchPointColor)
188 {
189     ACE_UPDATE_PAINT_PROPERTY(SwitchPaintProperty, SwitchPointColor, switchPointColor);
190 }
OnChange(ChangeEvent && onChange)191 void ToggleModelNG::OnChange(ChangeEvent&& onChange)
192 {
193     auto* stack = ViewStackProcessor::GetInstance();
194     CHECK_NULL_VOID(stack);
195     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
196     CHECK_NULL_VOID(frameNode);
197     auto checkboxPattern = stack->GetMainFrameNodePattern<CheckBoxPattern>();
198     if (checkboxPattern) {
199         auto eventHub = frameNode->GetEventHub<CheckBoxEventHub>();
200         CHECK_NULL_VOID(eventHub);
201         eventHub->SetOnChange(std::move(onChange));
202         return;
203     }
204     auto buttonPattern = stack->GetMainFrameNodePattern<ToggleButtonPattern>();
205     if (buttonPattern) {
206         auto eventHub = frameNode->GetEventHub<ToggleButtonEventHub>();
207         CHECK_NULL_VOID(eventHub);
208         eventHub->SetOnChange(std::move(onChange));
209         return;
210     }
211     auto eventHub = frameNode->GetEventHub<SwitchEventHub>();
212     CHECK_NULL_VOID(eventHub);
213     eventHub->SetOnChange(std::move(onChange));
214 }
215 
SetWidth(const Dimension & width)216 void ToggleModelNG::SetWidth(const Dimension& width)
217 {
218     NG::ViewAbstract::SetWidth(NG::CalcLength(width));
219 }
220 
SetHeight(const Dimension & height)221 void ToggleModelNG::SetHeight(const Dimension& height)
222 {
223     NG::ViewAbstract::SetHeight(NG::CalcLength(height));
224 }
225 
SetBackgroundColor(const Color & color)226 void ToggleModelNG::SetBackgroundColor(const Color& color)
227 {
228     ToggleButtonModelNG::SetBackgroundColor(color);
229 }
230 
IsToggle()231 bool ToggleModelNG::IsToggle()
232 {
233     return false;
234 }
235 
SetPadding(const NG::PaddingPropertyF &,const NG::PaddingProperty & newArgs)236 void ToggleModelNG::SetPadding(const NG::PaddingPropertyF& /*args*/, const NG::PaddingProperty& newArgs)
237 {
238     NG::ViewAbstract::SetPadding(newArgs);
239 }
240 
CreateCheckbox(int32_t nodeId)241 void ToggleModelNG::CreateCheckbox(int32_t nodeId)
242 {
243     auto* stack = ViewStackProcessor::GetInstance();
244     auto frameNode = FrameNode::GetOrCreateFrameNode(
245         V2::CHECKBOX_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<CheckBoxPattern>(); });
246     stack->Push(frameNode);
247 }
248 
CreateSwitch(int32_t nodeId)249 void ToggleModelNG::CreateSwitch(int32_t nodeId)
250 {
251     auto* stack = ViewStackProcessor::GetInstance();
252     auto frameNode = FrameNode::GetOrCreateFrameNode(
253         V2::TOGGLE_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<SwitchPattern>(); });
254     stack->Push(frameNode);
255 }
256 
CreateButton(int32_t nodeId)257 void ToggleModelNG::CreateButton(int32_t nodeId)
258 {
259     auto* stack = ViewStackProcessor::GetInstance();
260     auto frameNode = FrameNode::GetOrCreateFrameNode(
261         V2::TOGGLE_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<ToggleButtonPattern>(); });
262     stack->Push(frameNode);
263 }
264 
AddNewChild(const RefPtr<UINode> & parentFrame,int32_t nodeId,int32_t index)265 void ToggleModelNG::AddNewChild(const RefPtr<UINode>& parentFrame, int32_t nodeId, int32_t index)
266 {
267     auto newFrameNode = FrameNode::GetFrameNode(V2::TOGGLE_ETS_TAG, nodeId);
268     parentFrame->AddChild(newFrameNode, index);
269     newFrameNode->MarkModifyDone();
270 }
271 
RemoveNode(const RefPtr<FrameNode> & childFrameNode,int32_t nodeId)272 int32_t ToggleModelNG::RemoveNode(const RefPtr<FrameNode>& childFrameNode, int32_t nodeId)
273 {
274     ElementRegister::GetInstance()->RemoveItemSilently(nodeId);
275     auto parentFrame = childFrameNode->GetParent();
276     CHECK_NULL_RETURN(parentFrame, 0);
277     return parentFrame->RemoveChildAndReturnIndex(childFrameNode);
278 }
279 
OnChangeEvent(ChangeEvent && onChangeEvent)280 void ToggleModelNG::OnChangeEvent(ChangeEvent&& onChangeEvent)
281 {
282     auto* stack = ViewStackProcessor::GetInstance();
283     CHECK_NULL_VOID(stack);
284     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
285     CHECK_NULL_VOID(frameNode);
286     auto checkboxPattern = stack->GetMainFrameNodePattern<CheckBoxPattern>();
287     if (checkboxPattern) {
288         auto eventHub = frameNode->GetEventHub<CheckBoxEventHub>();
289         CHECK_NULL_VOID(eventHub);
290         eventHub->SetChangeEvent(std::move(onChangeEvent));
291         return;
292     }
293     auto buttonPattern = stack->GetMainFrameNodePattern<ToggleButtonPattern>();
294     if (buttonPattern) {
295         auto eventHub = frameNode->GetEventHub<ToggleButtonEventHub>();
296         CHECK_NULL_VOID(eventHub);
297         eventHub->SetOnChangeEvent(std::move(onChangeEvent));
298         return;
299     }
300     auto eventHub = frameNode->GetEventHub<SwitchEventHub>();
301     CHECK_NULL_VOID(eventHub);
302     eventHub->SetOnChangeEvent(std::move(onChangeEvent));
303 }
304 
SetResponseRegion(const std::vector<DimensionRect> & responseRegion)305 void ToggleModelNG::SetResponseRegion(const std::vector<DimensionRect>& responseRegion)
306 {
307     NG::ViewAbstract::SetResponseRegion(responseRegion);
308     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
309     CHECK_NULL_VOID(frameNode);
310     auto pattern = frameNode->GetPattern<SwitchPattern>();
311     CHECK_NULL_VOID(pattern);
312     pattern->SetIsUserSetResponseRegion(true);
313 }
314 } // namespace OHOS::Ace::NG
315