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/counter/counter_model_ng.h"
17 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(OHOS_PLATFORM)
18 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
19 #endif
20 
21 #include "core/components_ng/base/view_stack_processor.h"
22 #include "core/components_ng/pattern/button/button_pattern.h"
23 #include "core/components_ng/pattern/text/text_pattern.h"
24 #include "core/components_v2/inspector/inspector_constants.h"
25 
26 namespace OHOS::Ace::NG {
27 namespace {
28 constexpr char sub[] = "-";
29 constexpr char add[] = "+";
30 } // namespace
Create()31 void CounterModelNG::Create()
32 {
33     auto* stack = ViewStackProcessor::GetInstance();
34     auto nodeId = stack->ClaimNodeId();
35     ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::COUNTER_ETS_TAG, nodeId);
36     auto counterNode = CounterNode::GetOrCreateCounterNode(
37         V2::COUNTER_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<CounterPattern>(); });
38     auto counterPattern = counterNode->GetPattern<CounterPattern>();
39     CHECK_NULL_VOID(counterPattern);
40     auto pipeline = PipelineBase::GetCurrentContext();
41     CHECK_NULL_VOID(pipeline);
42     auto counterTheme = pipeline->GetTheme<CounterTheme>();
43     CHECK_NULL_VOID(counterTheme);
44     counterNode->GetLayoutProperty()->UpdateUserDefinedIdealSize(
45         CalcSize(CalcLength(counterTheme->GetWidth()), CalcLength(counterTheme->GetHeight())));
46     counterNode->GetRenderContext()->SetClipToFrame(true);
47     counterNode->GetLayoutProperty<LinearLayoutProperty>()->UpdateMainAxisAlign(FlexAlign::CENTER);
48 
49     bool hasSubNode = counterPattern->HasSubNode();
50     bool hasContentNode = counterPattern->HasContentNode();
51     bool hasAddNode = counterPattern->HasAddNode();
52     auto subId = counterPattern->GetSubId();
53     auto contentId = counterPattern->GetContentId();
54     auto addId = counterPattern->GetAddId();
55     if (!hasSubNode) {
56         auto subNode = CreateButtonChild(subId, sub, counterTheme);
57         subNode->MountToParent(counterNode);
58     }
59     if (!hasContentNode) {
60         auto contentNode = CreateContentNodeChild(contentId, counterTheme);
61         contentNode->MountToParent(counterNode);
62     }
63     if (!hasAddNode) {
64         auto addNode = CreateButtonChild(addId, add, counterTheme);
65         addNode->MountToParent(counterNode);
66     }
67     stack->Push(counterNode);
68 }
69 
CreateButtonChild(int32_t id,const std::string & symbol,const RefPtr<CounterTheme> & counterTheme)70 RefPtr<FrameNode> CounterModelNG::CreateButtonChild(
71     int32_t id, const std::string& symbol, const RefPtr<CounterTheme>& counterTheme)
72 {
73     auto buttonNode =
74         FrameNode::GetOrCreateFrameNode(V2::BUTTON_ETS_TAG, id, []() { return AceType::MakeRefPtr<ButtonPattern>(); });
75     buttonNode->GetEventHub<ButtonEventHub>()->SetStateEffect(true);
76     buttonNode->GetLayoutProperty<ButtonLayoutProperty>()->UpdateType(ButtonType::NORMAL);
77     buttonNode->GetLayoutProperty()->UpdateUserDefinedIdealSize(
78         CalcSize(CalcLength(counterTheme->GetControlWidth()), CalcLength(counterTheme->GetHeight())));
79     buttonNode->GetRenderContext()->UpdateBackgroundColor(Color::TRANSPARENT);
80     buttonNode->GetLayoutProperty()->UpdateBorderWidth(counterTheme->GetBorderWidth());
81     buttonNode->GetRenderContext()->UpdateBorderStyle(counterTheme->GetBorderStyle());
82     buttonNode->GetRenderContext()->UpdateBorderColor(counterTheme->GetBorderColor());
83     buttonNode->MarkModifyDone();
84 
85     auto textNode = FrameNode::GetOrCreateFrameNode(V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
86         []() { return AceType::MakeRefPtr<TextPattern>(); });
87     textNode->GetRenderContext()->UpdateBackgroundColor(Color::TRANSPARENT);
88     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateContent(symbol);
89     textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateTextAlign(TextAlign::CENTER);
90     textNode->GetLayoutProperty()->UpdateUserDefinedIdealSize(
91         CalcSize(CalcLength(counterTheme->GetControlWidth()), CalcLength(counterTheme->GetHeight())));
92     textNode->GetLayoutProperty()->UpdateAlignment(Alignment::CENTER);
93     textNode->MarkModifyDone();
94 
95     textNode->MountToParent(buttonNode);
96     return buttonNode;
97 }
98 
CreateContentNodeChild(int32_t contentId,const RefPtr<CounterTheme> & counterTheme)99 RefPtr<FrameNode> CounterModelNG::CreateContentNodeChild(int32_t contentId, const RefPtr<CounterTheme>& counterTheme)
100 {
101     auto contentNode = FrameNode::GetOrCreateFrameNode(
102         V2::ROW_ETS_TAG, contentId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(false); });
103     contentNode->GetLayoutProperty<LinearLayoutProperty>()->UpdateMainAxisAlign(FlexAlign::CENTER);
104     contentNode->GetLayoutProperty()->UpdateLayoutWeight(1);
105     contentNode->GetRenderContext()->SetClipToFrame(true);
106     contentNode->GetLayoutProperty()->UpdateUserDefinedIdealSize(
107         CalcSize(std::nullopt, CalcLength(counterTheme->GetHeight())));
108     contentNode->GetLayoutProperty()->UpdateBorderWidth(counterTheme->GetContentBorderWidth());
109     contentNode->GetRenderContext()->UpdateBorderStyle(counterTheme->GetBorderStyle());
110     contentNode->GetRenderContext()->UpdateBorderColor(counterTheme->GetBorderColor());
111     contentNode->GetRenderContext()->UpdateBackgroundColor(Color::TRANSPARENT);
112     contentNode->MarkModifyDone();
113     return contentNode;
114 }
115 
SetEnableDec(bool enableDec)116 void CounterModelNG::SetEnableDec(bool enableDec)
117 {
118     auto* stack = ViewStackProcessor::GetInstance();
119     auto frameNode = stack->GetMainFrameNode();
120     CHECK_NULL_VOID(frameNode);
121     auto subId = frameNode->GetPattern<CounterPattern>()->GetSubId();
122     auto subNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(frameNode->GetChildIndexById(subId)));
123     CHECK_NULL_VOID(subNode);
124     auto eventHub = subNode->GetEventHub<ButtonEventHub>();
125     CHECK_NULL_VOID(eventHub);
126     eventHub->SetEnabled(enableDec);
127     if (!eventHub->IsEnabled()) {
128         auto pipeline = PipelineBase::GetCurrentContext();
129         CHECK_NULL_VOID(pipeline);
130         auto counterTheme = pipeline->GetTheme<CounterTheme>();
131         CHECK_NULL_VOID(counterTheme);
132         subNode->GetRenderContext()->UpdateOpacity(counterTheme->GetAlphaDisabled());
133     } else {
134         subNode->GetRenderContext()->UpdateOpacity(1.0);
135     }
136 }
137 
SetEnableInc(bool enableInc)138 void CounterModelNG::SetEnableInc(bool enableInc)
139 {
140     auto* stack = ViewStackProcessor::GetInstance();
141     auto frameNode = stack->GetMainFrameNode();
142     CHECK_NULL_VOID(frameNode);
143     auto addId = frameNode->GetPattern<CounterPattern>()->GetAddId();
144     auto addNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(frameNode->GetChildIndexById(addId)));
145     CHECK_NULL_VOID(addNode);
146     auto eventHub = addNode->GetEventHub<ButtonEventHub>();
147     CHECK_NULL_VOID(eventHub);
148     eventHub->SetEnabled(enableInc);
149     if (!eventHub->IsEnabled()) {
150         auto pipeline = PipelineBase::GetCurrentContext();
151         CHECK_NULL_VOID(pipeline);
152         auto counterTheme = pipeline->GetTheme<CounterTheme>();
153         CHECK_NULL_VOID(counterTheme);
154         addNode->GetRenderContext()->UpdateOpacity(counterTheme->GetAlphaDisabled());
155     } else {
156         addNode->GetRenderContext()->UpdateOpacity(1.0);
157     }
158 }
159 
SetOnInc(CounterEventFunc && onInc)160 void CounterModelNG::SetOnInc(CounterEventFunc&& onInc)
161 {
162     CHECK_NULL_VOID(onInc);
163     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
164     CHECK_NULL_VOID(frameNode);
165     auto addId = frameNode->GetPattern<CounterPattern>()->GetAddId();
166     auto addNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(frameNode->GetChildIndexById(addId)));
167     CHECK_NULL_VOID(addNode);
168     auto gestureHub = addNode->GetOrCreateGestureEventHub();
169     GestureEventFunc gestureEventFunc = [clickEvent = std::move(onInc)](GestureEvent& /*unused*/) {
170                         clickEvent();
171 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(OHOS_PLATFORM)
172                         UiSessionManager::GetInstance().ReportComponentChangeEvent("event", "onInc");
173 #endif
174                     };
175     gestureHub->SetUserOnClick(std::move(gestureEventFunc));
176 }
177 
SetOnDec(CounterEventFunc && onDec)178 void CounterModelNG::SetOnDec(CounterEventFunc&& onDec)
179 {
180     CHECK_NULL_VOID(onDec);
181     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
182     CHECK_NULL_VOID(frameNode);
183     auto subId = frameNode->GetPattern<CounterPattern>()->GetSubId();
184     auto subNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(frameNode->GetChildIndexById(subId)));
185     CHECK_NULL_VOID(subNode);
186     auto gestureHub = subNode->GetOrCreateGestureEventHub();
187     GestureEventFunc gestureEventFunc = [clickEvent = std::move(onDec)](GestureEvent& /*unused*/) {
188                         clickEvent();
189 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(OHOS_PLATFORM)
190                         UiSessionManager::GetInstance().ReportComponentChangeEvent("event", "onDec");
191 #endif
192                     };
193     gestureHub->SetUserOnClick(std::move(gestureEventFunc));
194 }
195 
SetHeight(const Dimension & value)196 void CounterModelNG::SetHeight(const Dimension& value)
197 {
198     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
199     CHECK_NULL_VOID(frameNode);
200     auto layoutProperty = frameNode->GetLayoutProperty();
201     CHECK_NULL_VOID(layoutProperty);
202     layoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(value)));
203 
204     int32_t subId = frameNode->GetPattern<CounterPattern>()->GetSubId();
205     auto subNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(frameNode->GetChildIndexById(subId)));
206     CHECK_NULL_VOID(subNode);
207     auto subLayoutProperty = subNode->GetLayoutProperty();
208     subLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(value)));
209     auto subTextNode = AceType::DynamicCast<FrameNode>(subNode->GetFirstChild());
210     CHECK_NULL_VOID(subTextNode);
211     auto subTextLayoutProperty = subTextNode->GetLayoutProperty();
212     subTextLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(value)));
213 
214     int32_t contentId = frameNode->GetPattern<CounterPattern>()->GetContentId();
215     auto contentNode =
216         AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(frameNode->GetChildIndexById(contentId)));
217     CHECK_NULL_VOID(contentNode);
218     auto contentLayoutProperty = contentNode->GetLayoutProperty();
219     contentLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(value)));
220 
221     int32_t addId = frameNode->GetPattern<CounterPattern>()->GetAddId();
222     auto addNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(frameNode->GetChildIndexById(addId)));
223     CHECK_NULL_VOID(addNode);
224     auto addLayoutProperty = addNode->GetLayoutProperty();
225     addLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(value)));
226     auto addTextNode = AceType::DynamicCast<FrameNode>(addNode->GetFirstChild());
227     CHECK_NULL_VOID(addTextNode);
228     auto addTextLayoutProperty = addTextNode->GetLayoutProperty();
229     addTextLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(value)));
230 }
231 
SetWidth(const Dimension & value)232 void CounterModelNG::SetWidth(const Dimension& value)
233 {
234     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
235     CHECK_NULL_VOID(frameNode);
236     auto layoutProperty = frameNode->GetLayoutProperty();
237     CHECK_NULL_VOID(layoutProperty);
238     layoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(value), std::nullopt));
239 }
240 
SetControlWidth(const Dimension & value)241 void CounterModelNG::SetControlWidth(const Dimension& value) {}
242 
SetStateChange(bool value)243 void CounterModelNG::SetStateChange(bool value) {}
244 
SetBackgroundColor(const Color & value)245 void CounterModelNG::SetBackgroundColor(const Color& value)
246 {
247     ACE_UPDATE_RENDER_CONTEXT(BackgroundColor, value);
248 }
249 
SetEnableDec(FrameNode * frameNode,bool enableDec)250 void CounterModelNG::SetEnableDec(FrameNode* frameNode, bool enableDec)
251 {
252     CHECK_NULL_VOID(frameNode);
253     auto subId = frameNode->GetPattern<CounterPattern>()->GetSubId();
254     auto subNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(frameNode->GetChildIndexById(subId)));
255     CHECK_NULL_VOID(subNode);
256     auto eventHub = subNode->GetEventHub<ButtonEventHub>();
257     CHECK_NULL_VOID(eventHub);
258     eventHub->SetEnabled(enableDec);
259     if (!eventHub->IsEnabled()) {
260         auto pipeline = PipelineBase::GetCurrentContext();
261         CHECK_NULL_VOID(pipeline);
262         auto counterTheme = pipeline->GetTheme<CounterTheme>();
263         CHECK_NULL_VOID(counterTheme);
264         subNode->GetRenderContext()->UpdateOpacity(counterTheme->GetAlphaDisabled());
265     } else {
266         subNode->GetRenderContext()->UpdateOpacity(1.0);
267     }
268 }
269 
SetEnableInc(FrameNode * frameNode,bool enableInc)270 void CounterModelNG::SetEnableInc(FrameNode* frameNode, bool enableInc)
271 {
272     CHECK_NULL_VOID(frameNode);
273     auto addId = frameNode->GetPattern<CounterPattern>()->GetAddId();
274     auto addNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(frameNode->GetChildIndexById(addId)));
275     CHECK_NULL_VOID(addNode);
276     auto eventHub = addNode->GetEventHub<ButtonEventHub>();
277     CHECK_NULL_VOID(eventHub);
278     eventHub->SetEnabled(enableInc);
279     if (!eventHub->IsEnabled()) {
280         auto pipeline = PipelineBase::GetCurrentContext();
281         CHECK_NULL_VOID(pipeline);
282         auto counterTheme = pipeline->GetTheme<CounterTheme>();
283         CHECK_NULL_VOID(counterTheme);
284         addNode->GetRenderContext()->UpdateOpacity(counterTheme->GetAlphaDisabled());
285     } else {
286         addNode->GetRenderContext()->UpdateOpacity(1.0);
287     }
288 }
SetHeight(FrameNode * frameNode,const Dimension & value)289 void CounterModelNG::SetHeight(FrameNode* frameNode, const Dimension& value)
290 {
291     CHECK_NULL_VOID(frameNode);
292     auto layoutProperty = frameNode->GetLayoutProperty();
293     CHECK_NULL_VOID(layoutProperty);
294     layoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(value)));
295 
296     int32_t subId = frameNode->GetPattern<CounterPattern>()->GetSubId();
297     auto subNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(frameNode->GetChildIndexById(subId)));
298     CHECK_NULL_VOID(subNode);
299     auto subLayoutProperty = subNode->GetLayoutProperty();
300     subLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(value)));
301     auto subTextNode = AceType::DynamicCast<FrameNode>(subNode->GetFirstChild());
302     CHECK_NULL_VOID(subTextNode);
303     auto subTextLayoutProperty = subTextNode->GetLayoutProperty();
304     subTextLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(value)));
305 
306     int32_t contentId = frameNode->GetPattern<CounterPattern>()->GetContentId();
307     auto contentNode =
308         AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(frameNode->GetChildIndexById(contentId)));
309     CHECK_NULL_VOID(contentNode);
310     auto contentLayoutProperty = contentNode->GetLayoutProperty();
311     contentLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(value)));
312 
313     int32_t addId = frameNode->GetPattern<CounterPattern>()->GetAddId();
314     auto addNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(frameNode->GetChildIndexById(addId)));
315     CHECK_NULL_VOID(addNode);
316     auto addLayoutProperty = addNode->GetLayoutProperty();
317     addLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(value)));
318     auto addTextNode = AceType::DynamicCast<FrameNode>(addNode->GetFirstChild());
319     CHECK_NULL_VOID(addTextNode);
320     auto addTextLayoutProperty = addTextNode->GetLayoutProperty();
321     addTextLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(value)));
322 }
323 
SetWidth(FrameNode * frameNode,const Dimension & value)324 void CounterModelNG::SetWidth(FrameNode* frameNode, const Dimension& value)
325 {
326     CHECK_NULL_VOID(frameNode);
327     auto layoutProperty = frameNode->GetLayoutProperty();
328     CHECK_NULL_VOID(layoutProperty);
329     layoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(value), std::nullopt));
330 }
331 
SetBackgroundColor(FrameNode * frameNode,const Color & value)332 void CounterModelNG::SetBackgroundColor(FrameNode* frameNode, const Color& value)
333 {
334     ACE_UPDATE_NODE_RENDER_CONTEXT(BackgroundColor, value, frameNode);
335 }
336 } // namespace OHOS::Ace::NG
337