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/referenced.h"
19 #include "base/utils/utils.h"
20 #include "core/components_ng/base/frame_node.h"
21 #include "core/components_ng/base/ui_node.h"
22 #include "core/components_ng/base/view_stack_processor.h"
23 #include "core/components_ng/base/view_abstract.h"
24 #include "core/components_ng/pattern/button/toggle_button_model_ng.h"
25 #include "core/components_ng/pattern/button/toggle_button_pattern.h"
26 #include "core/components_ng/pattern/checkbox/checkbox_model_ng.h"
27 #include "core/components_ng/pattern/checkbox/checkbox_pattern.h"
28 #include "core/components_ng/pattern/toggle/switch_paint_property.h"
29 #include "core/components_ng/pattern/toggle/switch_pattern.h"
30 #include "core/components_v2/inspector/inspector_constants.h"
31 #include "core/pipeline/base/element_register.h"
32 #include "core/pipeline_ng/ui_task_scheduler.h"
33
34 namespace OHOS::Ace::NG {
35
Create(NG::ToggleType toggleType,bool isOn)36 void ToggleModelNG::Create(NG::ToggleType toggleType, bool isOn)
37 {
38 auto* stack = ViewStackProcessor::GetInstance();
39 int nodeId = (stack == nullptr ? 0 : stack->ClaimNodeId());
40 auto childFrameNode = FrameNode::GetFrameNode(V2::TOGGLE_ETS_TAG, nodeId);
41 if (!childFrameNode) {
42 switch (toggleType) {
43 case ToggleType::CHECKBOX: {
44 CheckBoxModelNG checkBoxModelNG;
45 CreateCheckbox(nodeId);
46 checkBoxModelNG.SetSelect(isOn);
47 break;
48 }
49 case ToggleType::SWITCH: {
50 CreateSwitch(nodeId);
51 ACE_UPDATE_PAINT_PROPERTY(SwitchPaintProperty, IsOn, isOn);
52 break;
53 }
54 case ToggleType::BUTTON: {
55 CreateButton(nodeId);
56 ToggleButtonModelNG::SetIsOn(isOn);
57 break;
58 }
59 default:
60 break;
61 }
62 return;
63 }
64 auto pattern = childFrameNode->GetPattern();
65 if (AceType::InstanceOf<CheckBoxPattern>(pattern)) {
66 if (toggleType == ToggleType::CHECKBOX) {
67 stack->Push(childFrameNode);
68 CheckBoxModelNG checkBoxModelNG;
69 checkBoxModelNG.SetSelect(isOn);
70 return;
71 }
72 if (toggleType == ToggleType::SWITCH) {
73 auto parentFrame = childFrameNode->GetParent();
74 CHECK_NULL_VOID(parentFrame);
75 auto index = RemoveNode(childFrameNode, nodeId);
76 childFrameNode->SetUndefinedNodeId();
77 CreateSwitch(nodeId);
78 ACE_UPDATE_PAINT_PROPERTY(SwitchPaintProperty, IsOn, isOn);
79 AddNewChild(parentFrame, nodeId, index);
80 return;
81 }
82 auto parentFrame = childFrameNode->GetParent();
83 CHECK_NULL_VOID(parentFrame);
84 auto index = RemoveNode(childFrameNode, nodeId);
85 childFrameNode->SetUndefinedNodeId();
86 CreateButton(nodeId);
87 ToggleButtonModelNG::SetIsOn(isOn);
88 AddNewChild(parentFrame, nodeId, index);
89 return;
90 }
91 if (AceType::InstanceOf<SwitchPattern>(pattern)) {
92 if (toggleType == ToggleType::SWITCH) {
93 stack->Push(childFrameNode);
94 ACE_UPDATE_PAINT_PROPERTY(SwitchPaintProperty, IsOn, isOn);
95 return;
96 }
97 if (toggleType == ToggleType::CHECKBOX) {
98 auto parentFrame = childFrameNode->GetParent();
99 CHECK_NULL_VOID(parentFrame);
100 auto index = RemoveNode(childFrameNode, nodeId);
101 childFrameNode->SetUndefinedNodeId();
102 CheckBoxModelNG checkBoxModelNG;
103 CreateCheckbox(nodeId);
104 checkBoxModelNG.SetSelect(isOn);
105 AddNewChild(parentFrame, nodeId, index);
106 return;
107 }
108 auto parentFrame = childFrameNode->GetParent();
109 CHECK_NULL_VOID(parentFrame);
110 auto index = RemoveNode(childFrameNode, nodeId);
111 childFrameNode->SetUndefinedNodeId();
112 CreateButton(nodeId);
113 ToggleButtonModelNG::SetIsOn(isOn);
114 AddNewChild(parentFrame, nodeId, index);
115 return;
116 }
117 if (AceType::InstanceOf<ToggleButtonPattern>(pattern)) {
118 if (toggleType == ToggleType::BUTTON) {
119 stack->Push(childFrameNode);
120 ToggleButtonModelNG::SetIsOn(isOn);
121 return;
122 }
123 if (toggleType == ToggleType::CHECKBOX) {
124 auto parentFrame = childFrameNode->GetParent();
125 CHECK_NULL_VOID(parentFrame);
126 auto index = RemoveNode(childFrameNode, nodeId);
127 childFrameNode->SetUndefinedNodeId();
128 CheckBoxModelNG checkBoxModelNG;
129 CreateCheckbox(nodeId);
130 checkBoxModelNG.SetSelect(isOn);
131 AddNewChild(parentFrame, nodeId, index);
132 return;
133 }
134 auto parentFrame = childFrameNode->GetParent();
135 CHECK_NULL_VOID(parentFrame);
136 auto index = RemoveNode(childFrameNode, nodeId);
137 childFrameNode->SetUndefinedNodeId();
138 CreateSwitch(nodeId);
139 ACE_UPDATE_PAINT_PROPERTY(SwitchPaintProperty, IsOn, isOn);
140 AddNewChild(parentFrame, nodeId, index);
141 }
142 }
143
SetSelectedColor(const Color & selectedColor)144 void ToggleModelNG::SetSelectedColor(const Color& selectedColor)
145 {
146 auto* stack = ViewStackProcessor::GetInstance();
147 CHECK_NULL_VOID(stack);
148 auto checkboxPattern = stack->GetMainFrameNodePattern<CheckBoxPattern>();
149 if (checkboxPattern) {
150 CheckBoxModelNG checkBoxModelNG;
151 checkBoxModelNG.SetSelectedColor(selectedColor);
152 return;
153 }
154 auto buttonPattern = stack->GetMainFrameNodePattern<ToggleButtonPattern>();
155 if (buttonPattern) {
156 ToggleButtonModelNG::SetSelectedColor(selectedColor);
157 return;
158 }
159
160 ACE_UPDATE_PAINT_PROPERTY(SwitchPaintProperty, SelectedColor, selectedColor);
161 }
162
SetSwitchPointColor(const Color & switchPointColor)163 void ToggleModelNG::SetSwitchPointColor(const Color& switchPointColor)
164 {
165 ACE_UPDATE_PAINT_PROPERTY(SwitchPaintProperty, SwitchPointColor, switchPointColor);
166 }
OnChange(ChangeEvent && onChange)167 void ToggleModelNG::OnChange(ChangeEvent&& onChange)
168 {
169 auto* stack = ViewStackProcessor::GetInstance();
170 CHECK_NULL_VOID(stack);
171 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
172 CHECK_NULL_VOID(frameNode);
173 auto checkboxPattern = stack->GetMainFrameNodePattern<CheckBoxPattern>();
174 if (checkboxPattern) {
175 auto eventHub = frameNode->GetEventHub<CheckBoxEventHub>();
176 CHECK_NULL_VOID(eventHub);
177 eventHub->SetOnChange(std::move(onChange));
178 return;
179 }
180 auto buttonPattern = stack->GetMainFrameNodePattern<ToggleButtonPattern>();
181 if (buttonPattern) {
182 auto eventHub = frameNode->GetEventHub<ToggleButtonEventHub>();
183 CHECK_NULL_VOID(eventHub);
184 eventHub->SetOnChange(std::move(onChange));
185 return;
186 }
187 auto eventHub = frameNode->GetEventHub<SwitchEventHub>();
188 CHECK_NULL_VOID(eventHub);
189 eventHub->SetOnChange(std::move(onChange));
190 }
191
SetWidth(const Dimension & width)192 void ToggleModelNG::SetWidth(const Dimension& width) {}
193
SetHeight(const Dimension & height)194 void ToggleModelNG::SetHeight(const Dimension& height) {}
195
SetBackgroundColor(const Color & color)196 void ToggleModelNG::SetBackgroundColor(const Color& color)
197 {
198 ToggleButtonModelNG::SetBackgroundColor(color);
199 }
200
IsToggle()201 bool ToggleModelNG::IsToggle()
202 {
203 return false;
204 }
205
SetPadding(const NG::PaddingPropertyF & args)206 void ToggleModelNG::SetPadding(const NG::PaddingPropertyF& args) {}
207
CreateCheckbox(int32_t nodeId)208 void ToggleModelNG::CreateCheckbox(int32_t nodeId)
209 {
210 auto* stack = ViewStackProcessor::GetInstance();
211 auto frameNode = FrameNode::GetOrCreateFrameNode(
212 V2::CHECKBOX_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<CheckBoxPattern>(); });
213 stack->Push(frameNode);
214 }
215
CreateSwitch(int32_t nodeId)216 void ToggleModelNG::CreateSwitch(int32_t nodeId)
217 {
218 auto* stack = ViewStackProcessor::GetInstance();
219 auto frameNode = FrameNode::GetOrCreateFrameNode(
220 V2::TOGGLE_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<SwitchPattern>(); });
221 stack->Push(frameNode);
222 }
223
CreateButton(int32_t nodeId)224 void ToggleModelNG::CreateButton(int32_t nodeId)
225 {
226 auto* stack = ViewStackProcessor::GetInstance();
227 auto frameNode = FrameNode::GetOrCreateFrameNode(
228 V2::TOGGLE_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<ToggleButtonPattern>(); });
229 stack->Push(frameNode);
230 NG::ViewAbstract::SetHoverEffectAuto(HoverEffectType::SCALE);
231 }
232
AddNewChild(const RefPtr<UINode> & parentFrame,int32_t nodeId,int32_t index)233 void ToggleModelNG::AddNewChild(const RefPtr<UINode>& parentFrame, int32_t nodeId, int32_t index)
234 {
235 auto newFrameNode = FrameNode::GetFrameNode(V2::TOGGLE_ETS_TAG, nodeId);
236 parentFrame->AddChild(newFrameNode, index);
237 newFrameNode->MarkModifyDone();
238 }
239
RemoveNode(const RefPtr<FrameNode> & childFrameNode,int32_t nodeId)240 int32_t ToggleModelNG::RemoveNode(const RefPtr<FrameNode>& childFrameNode, int32_t nodeId)
241 {
242 ElementRegister::GetInstance()->RemoveItemSilently(nodeId);
243 auto parentFrame = childFrameNode->GetParent();
244 CHECK_NULL_RETURN(parentFrame, 0);
245 return parentFrame->RemoveChildAndReturnIndex(childFrameNode);
246 }
247
248 } // namespace OHOS::Ace::NG