1 /*
2  * Copyright (c) 2023-2024 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 #include "core/interfaces/native/node/node_timepicker_modifier.h"
16 
17 #include "base/utils/utils.h"
18 #include "base/i18n/localization.h"
19 #include "bridge/common/utils/utils.h"
20 #include "core/components/common/layout/constants.h"
21 #include "core/components/common/properties/text_style.h"
22 #include "core/components_ng/base/frame_node.h"
23 #include "core/components_ng/pattern/tabs/tabs_model.h"
24 #include "core/components_ng/pattern/time_picker/timepicker_model_ng.h"
25 #include "core/interfaces/arkoala/arkoala_api.h"
26 #include "core/interfaces/native/node/node_api.h"
27 #include "core/interfaces/native/node/node_textpicker_modifier.h"
28 #include "core/pipeline/base/element_register.h"
29 
30 namespace OHOS::Ace::NG {
31 namespace {
32 constexpr uint32_t DEFAULT_BG_COLOR = 0xFF007DFF;
33 const int32_t ERROR_INT_CODE = -1;
34 constexpr int32_t POS_0 = 0;
35 constexpr int32_t POS_1 = 1;
36 constexpr int32_t POS_2 = 2;
37 constexpr int NUM_3 = 3;
38 const char DEFAULT_DELIMITER = '|';
39 const std::vector<OHOS::Ace::FontStyle> FONT_STYLES = { OHOS::Ace::FontStyle::NORMAL, OHOS::Ace::FontStyle::ITALIC };
40 std::string g_strValue;
41 
SetTimepickerSelected(ArkUINodeHandle node,ArkUI_Uint32 hour,ArkUI_Uint32 minute)42 void SetTimepickerSelected(ArkUINodeHandle node, ArkUI_Uint32 hour, ArkUI_Uint32 minute)
43 {
44     auto* frameNode = reinterpret_cast<FrameNode*>(node);
45     CHECK_NULL_VOID(frameNode);
46     TimePickerModelNG::SetSelectedTime(frameNode, PickerTime(hour, minute, 0));
47 }
48 
ResetTimepickerSelected(ArkUINodeHandle node)49 void ResetTimepickerSelected(ArkUINodeHandle node)
50 {
51     auto* frameNode = reinterpret_cast<FrameNode*>(node);
52     CHECK_NULL_VOID(frameNode);
53     time_t now = time(nullptr);
54     auto currentTm = localtime(&now);
55     CHECK_NULL_VOID(currentTm);
56     PickerTime pickerTime(currentTm->tm_hour, currentTm->tm_min, 0);
57 
58     TimePickerModelNG::SetSelectedTime(frameNode, pickerTime);
59 }
60 
SetTimepickerBackgroundColor(ArkUINodeHandle node,uint32_t color)61 void SetTimepickerBackgroundColor(ArkUINodeHandle node, uint32_t color)
62 {
63     auto* frameNode = reinterpret_cast<FrameNode*>(node);
64     CHECK_NULL_VOID(frameNode);
65     TimePickerModelNG::SetBackgroundColor(frameNode, Color(color));
66 }
67 
ResetTimepickerBackgroundColor(ArkUINodeHandle node)68 void ResetTimepickerBackgroundColor(ArkUINodeHandle node)
69 {
70     auto* frameNode = reinterpret_cast<FrameNode*>(node);
71     CHECK_NULL_VOID(frameNode);
72     TimePickerModelNG::SetBackgroundColor(frameNode, Color(DEFAULT_BG_COLOR));
73 }
74 
SetTimepickerTextStyle(ArkUINodeHandle node,uint32_t color,const char * fontInfo,int32_t style)75 void SetTimepickerTextStyle(ArkUINodeHandle node, uint32_t color, const char* fontInfo, int32_t style)
76 {
77     auto* frameNode = reinterpret_cast<FrameNode*>(node);
78     CHECK_NULL_VOID(frameNode);
79     auto pipeline = frameNode->GetContext();
80     CHECK_NULL_VOID(pipeline);
81     auto themeManager = pipeline->GetThemeManager();
82     CHECK_NULL_VOID(themeManager);
83     auto theme = themeManager->GetTheme<PickerTheme>();
84     CHECK_NULL_VOID(theme);
85 
86     NG::PickerTextStyle textStyle;
87     std::vector<std::string> res;
88     std::string fontValues = std::string(fontInfo);
89     StringUtils::StringSplitter(fontValues, DEFAULT_DELIMITER, res);
90     if (res.size() != NUM_3) {
91         return;
92     }
93     textStyle.fontSize = StringUtils::StringToCalcDimension(res[POS_0], false, DimensionUnit::FP);
94     if (style >= 0 && style < static_cast<int32_t>(FONT_STYLES.size())) {
95         textStyle.fontStyle = FONT_STYLES[style];
96     } else {
97         textStyle.fontStyle = FONT_STYLES[0];
98     }
99     textStyle.fontFamily = Framework::ConvertStrToFontFamilies(res[POS_2]);
100     textStyle.fontWeight = StringUtils::StringToFontWeight(res[POS_1]);
101     textStyle.textColor = Color(color);
102     TimePickerModelNG::SetNormalTextStyle(frameNode, theme, textStyle);
103 }
104 
ResetTimepickerTextStyle(ArkUINodeHandle node)105 void ResetTimepickerTextStyle(ArkUINodeHandle node)
106 {
107     auto* frameNode = reinterpret_cast<FrameNode*>(node);
108     CHECK_NULL_VOID(frameNode);
109 
110     NG::PickerTextStyle pickerTextStyle;
111     auto context = frameNode->GetContext();
112     CHECK_NULL_VOID(context);
113     auto themeManager = context->GetThemeManager();
114     CHECK_NULL_VOID(themeManager);
115     auto pickerTheme = themeManager->GetTheme<PickerTheme>();
116     TimePickerModelNG::SetNormalTextStyle(frameNode, pickerTheme, pickerTextStyle);
117 }
118 
SetTimepickerSelectedTextStyle(ArkUINodeHandle node,uint32_t color,const char * fontInfo,int32_t style)119 void SetTimepickerSelectedTextStyle(ArkUINodeHandle node, uint32_t color, const char* fontInfo, int32_t style)
120 {
121     auto* frameNode = reinterpret_cast<FrameNode*>(node);
122     CHECK_NULL_VOID(frameNode);
123     auto pipeline = frameNode->GetContext();
124     CHECK_NULL_VOID(pipeline);
125     auto themeManager = pipeline->GetThemeManager();
126     CHECK_NULL_VOID(themeManager);
127     auto theme = themeManager->GetTheme<PickerTheme>();
128     CHECK_NULL_VOID(theme);
129     NG::PickerTextStyle textStyle;
130     std::vector<std::string> res;
131     std::string fontValues = std::string(fontInfo);
132     StringUtils::StringSplitter(fontValues, DEFAULT_DELIMITER, res);
133     if (res.size() != NUM_3) {
134         return;
135     }
136     textStyle.fontSize = StringUtils::StringToCalcDimension(res[POS_0], false, DimensionUnit::FP);
137     if (style >= 0 && style < static_cast<int32_t>(FONT_STYLES.size())) {
138         textStyle.fontStyle = FONT_STYLES[style];
139     } else {
140         textStyle.fontStyle = FONT_STYLES[0];
141     }
142     textStyle.fontFamily = Framework::ConvertStrToFontFamilies(res[POS_2]);
143     textStyle.fontWeight = StringUtils::StringToFontWeight(res[POS_1]);
144     textStyle.textColor = Color(color);
145     TimePickerModelNG::SetSelectedTextStyle(frameNode, theme, textStyle);
146 }
147 
ResetTimepickerSelectedTextStyle(ArkUINodeHandle node)148 void ResetTimepickerSelectedTextStyle(ArkUINodeHandle node)
149 {
150     auto* frameNode = reinterpret_cast<FrameNode*>(node);
151     CHECK_NULL_VOID(frameNode);
152 
153     NG::PickerTextStyle pickerTextStyle;
154     auto context = frameNode->GetContext();
155     CHECK_NULL_VOID(context);
156     auto themeManager = context->GetThemeManager();
157     CHECK_NULL_VOID(themeManager);
158     auto pickerTheme = themeManager->GetTheme<PickerTheme>();
159     TimePickerModelNG::SetSelectedTextStyle(frameNode, pickerTheme, pickerTextStyle);
160 }
161 
SetTimepickerDisappearTextStyle(ArkUINodeHandle node,uint32_t color,const char * fontInfo,int32_t style)162 void SetTimepickerDisappearTextStyle(ArkUINodeHandle node, uint32_t color, const char* fontInfo, int32_t style)
163 {
164     auto* frameNode = reinterpret_cast<FrameNode*>(node);
165     CHECK_NULL_VOID(frameNode);
166     auto pipeline = frameNode->GetContext();
167     CHECK_NULL_VOID(pipeline);
168     auto themeManager = pipeline->GetThemeManager();
169     CHECK_NULL_VOID(themeManager);
170     auto theme = themeManager->GetTheme<PickerTheme>();
171     CHECK_NULL_VOID(theme);
172 
173     NG::PickerTextStyle textStyle;
174     std::vector<std::string> res;
175     std::string fontValues = std::string(fontInfo);
176     StringUtils::StringSplitter(fontValues, DEFAULT_DELIMITER, res);
177     if (res.size() != NUM_3) {
178         return;
179     }
180     textStyle.fontSize = StringUtils::StringToCalcDimension(res[POS_0], false, DimensionUnit::FP);
181     if (style >= 0 && style < static_cast<int32_t>(FONT_STYLES.size())) {
182         textStyle.fontStyle = FONT_STYLES[style];
183     } else {
184         textStyle.fontStyle = FONT_STYLES[0];
185     }
186     textStyle.fontFamily = Framework::ConvertStrToFontFamilies(res[POS_2]);
187     textStyle.fontWeight = StringUtils::StringToFontWeight(res[POS_1]);
188     textStyle.textColor = Color(color);
189     TimePickerModelNG::SetDisappearTextStyle(frameNode, theme, textStyle);
190 }
191 
ResetTimepickerDisappearTextStyle(ArkUINodeHandle node)192 void ResetTimepickerDisappearTextStyle(ArkUINodeHandle node)
193 {
194     auto* frameNode = reinterpret_cast<FrameNode*>(node);
195     CHECK_NULL_VOID(frameNode);
196 
197     NG::PickerTextStyle pickerTextStyle;
198     auto context = frameNode->GetContext();
199     CHECK_NULL_VOID(context);
200     auto themeManager = context->GetThemeManager();
201     CHECK_NULL_VOID(themeManager);
202     auto pickerTheme = themeManager->GetTheme<PickerTheme>();
203 
204     TimePickerModelNG::SetDisappearTextStyle(frameNode, pickerTheme, pickerTextStyle);
205 }
206 
SetTimepickerUseMilitaryTime(ArkUINodeHandle node,int isUseMilitaryTime)207 void SetTimepickerUseMilitaryTime(ArkUINodeHandle node, int isUseMilitaryTime)
208 {
209     auto* frameNode = reinterpret_cast<FrameNode*>(node);
210     CHECK_NULL_VOID(frameNode);
211     TimePickerModelNG::SetHour24(frameNode, isUseMilitaryTime);
212 }
213 
ResetTimepickerUseMilitaryTime(ArkUINodeHandle node)214 void ResetTimepickerUseMilitaryTime(ArkUINodeHandle node)
215 {
216     auto* frameNode = reinterpret_cast<FrameNode*>(node);
217     CHECK_NULL_VOID(frameNode);
218     TimePickerModelNG::SetHour24(frameNode, false);
219 }
220 
SetTimepickerLoop(ArkUINodeHandle node,int isLoop)221 void SetTimepickerLoop(ArkUINodeHandle node, int isLoop)
222 {
223     auto* frameNode = reinterpret_cast<FrameNode*>(node);
224     CHECK_NULL_VOID(frameNode);
225     TimePickerModelNG::SetWheelModeEnabled(frameNode, isLoop);
226 }
227 
ResetTimepickerLoop(ArkUINodeHandle node)228 void ResetTimepickerLoop(ArkUINodeHandle node)
229 {
230     auto* frameNode = reinterpret_cast<FrameNode*>(node);
231     CHECK_NULL_VOID(frameNode);
232     TimePickerModelNG::SetWheelModeEnabled(frameNode, true);
233 }
234 
SetTimepickerDateTimeOptions(ArkUINodeHandle node,ArkUI_Int32 hourType,ArkUI_Int32 minuteType,ArkUI_Int32 secondType)235 void SetTimepickerDateTimeOptions(
236     ArkUINodeHandle node, ArkUI_Int32 hourType, ArkUI_Int32 minuteType, ArkUI_Int32 secondType)
237 {
238     auto* frameNode = reinterpret_cast<FrameNode*>(node);
239     CHECK_NULL_VOID(frameNode);
240     ZeroPrefixType hour = static_cast<ZeroPrefixType>(hourType);
241     ZeroPrefixType minute = static_cast<ZeroPrefixType>(minuteType);
242     ZeroPrefixType second = static_cast<ZeroPrefixType>(secondType);
243     TimePickerModelNG::SetDateTimeOptions(frameNode, hour, minute, second);
244 }
245 
ResetTimepickerDateTimeOptions(ArkUINodeHandle node)246 void ResetTimepickerDateTimeOptions(ArkUINodeHandle node)
247 {
248     auto* frameNode = reinterpret_cast<FrameNode*>(node);
249     CHECK_NULL_VOID(frameNode);
250     ZeroPrefixType hourType = ZeroPrefixType::AUTO;
251     ZeroPrefixType minuteType = ZeroPrefixType::AUTO;
252     ZeroPrefixType secondType = ZeroPrefixType::AUTO;
253     TimePickerModelNG::SetDateTimeOptions(frameNode, hourType, minuteType, secondType);
254 }
255 
GetTimepickerSelectedTextStyle(ArkUINodeHandle node)256 ArkUI_CharPtr GetTimepickerSelectedTextStyle(ArkUINodeHandle node)
257 {
258     auto* frameNode = reinterpret_cast<FrameNode*>(node);
259     CHECK_NULL_RETURN(frameNode, "");
260     PickerTextStyle pickerTextStyle = TimePickerModelNG::getSelectedTextStyle(frameNode);
261     std::vector<std::string> fontFamilies = pickerTextStyle.fontFamily.value_or(std::vector<std::string>());
262     std::string families;
263     if (fontFamilies.size() == 0) {
264         fontFamilies.emplace_back("HarmonyOS Sans");
265     }
266     //set index start
267     int index = 0;
268     for (auto& family : fontFamilies) {
269         families += family;
270         if (index != static_cast<int>(fontFamilies.size()) - 1) {
271             families += ",";
272         }
273         index++;
274     }
275     g_strValue = pickerTextStyle.textColor->ColorToString() + ";";
276     g_strValue = g_strValue + std::to_string(static_cast<int>(pickerTextStyle.fontSize->ConvertToFp())) + ";";
277     g_strValue = g_strValue + StringUtils::ToString(pickerTextStyle.fontWeight.value_or(FontWeight::W100)) + ";";
278     g_strValue = g_strValue + families + ";";
279     g_strValue =
280         g_strValue + StringUtils::ToStringNDK(pickerTextStyle.fontStyle.value_or(OHOS::Ace::FontStyle::NORMAL));
281     return g_strValue.c_str();
282 }
283 
GetTimepickerTextStyle(ArkUINodeHandle node)284 ArkUI_CharPtr GetTimepickerTextStyle(ArkUINodeHandle node)
285 {
286     auto* frameNode = reinterpret_cast<FrameNode*>(node);
287     CHECK_NULL_RETURN(frameNode, "");
288     PickerTextStyle pickerTextStyle = TimePickerModelNG::getNormalTextStyle(frameNode);
289     std::vector<std::string> fontFamilies = pickerTextStyle.fontFamily.value_or(std::vector<std::string>());
290     std::string families;
291     if (fontFamilies.size() == 0) {
292         fontFamilies.emplace_back("HarmonyOS Sans");
293     }
294     //set index start
295     int index = 0;
296     for (auto& family : fontFamilies) {
297         families += family;
298         if (index != static_cast<int>(fontFamilies.size()) - 1) {
299             families += ",";
300         }
301         index++;
302     }
303     g_strValue = pickerTextStyle.textColor->ColorToString() + ";";
304     g_strValue = g_strValue + std::to_string(static_cast<int>(pickerTextStyle.fontSize->ConvertToFp())) + ";";
305     g_strValue = g_strValue + StringUtils::ToString(pickerTextStyle.fontWeight.value_or(FontWeight::W100)) + ";";
306     g_strValue = g_strValue + families + ";";
307     g_strValue =
308         g_strValue + StringUtils::ToStringNDK(pickerTextStyle.fontStyle.value_or(OHOS::Ace::FontStyle::NORMAL));
309     return g_strValue.c_str();
310 }
311 
GetTimepickerDisappearTextStyle(ArkUINodeHandle node)312 ArkUI_CharPtr GetTimepickerDisappearTextStyle(ArkUINodeHandle node)
313 {
314     auto* frameNode = reinterpret_cast<FrameNode*>(node);
315     CHECK_NULL_RETURN(frameNode, "");
316     PickerTextStyle pickerTextStyle = TimePickerModelNG::getDisappearTextStyle(frameNode);
317     std::vector<std::string> fontFamilies = pickerTextStyle.fontFamily.value_or(std::vector<std::string>());
318     std::string families;
319     if (fontFamilies.size() == 0) {
320         fontFamilies.emplace_back("HarmonyOS Sans");
321     }
322     //set index start
323     int index = 0;
324     for (auto& family : fontFamilies) {
325         families += family;
326         if (index != static_cast<int>(fontFamilies.size()) - 1) {
327             families += ",";
328         }
329         index++;
330     }
331     g_strValue = pickerTextStyle.textColor->ColorToString() + ";";
332     g_strValue = g_strValue + std::to_string(static_cast<int>(pickerTextStyle.fontSize->ConvertToFp())) + ";";
333     g_strValue = g_strValue + StringUtils::ToString(pickerTextStyle.fontWeight.value_or(FontWeight::W100)) + ";";
334     g_strValue = g_strValue + families + ";";
335     g_strValue =
336         g_strValue + StringUtils::ToStringNDK(pickerTextStyle.fontStyle.value_or(OHOS::Ace::FontStyle::NORMAL));
337     return g_strValue.c_str();
338 }
339 
GetTimepickerSelected(ArkUINodeHandle node)340 ArkUI_CharPtr GetTimepickerSelected(ArkUINodeHandle node)
341 {
342     auto* frameNode = reinterpret_cast<FrameNode*>(node);
343     CHECK_NULL_RETURN(frameNode, "");
344     PickerTime pickerTime = TimePickerModelNG::getTimepickerSelected(frameNode);
345     g_strValue = std::to_string(static_cast<uint32_t>(pickerTime.GetHour())) + ",";
346     g_strValue = g_strValue + std::to_string(static_cast<uint32_t>(pickerTime.GetMinute())) + ",";
347     g_strValue = g_strValue + std::to_string(static_cast<uint32_t>(pickerTime.GetSecond()));
348     return g_strValue.c_str();
349 }
350 
GetTimepickerBackgroundColor(ArkUINodeHandle node)351 ArkUI_Uint32 GetTimepickerBackgroundColor(ArkUINodeHandle node)
352 {
353     auto* frameNode = reinterpret_cast<FrameNode*>(node);
354     CHECK_NULL_RETURN(frameNode, ERROR_INT_CODE);
355     return TimePickerModelNG::getTimepickerBackgroundColor(frameNode);
356 }
357 
GetTimepickerUseMilitaryTime(ArkUINodeHandle node)358 ArkUI_Int32 GetTimepickerUseMilitaryTime(ArkUINodeHandle node)
359 {
360     auto* frameNode = reinterpret_cast<FrameNode*>(node);
361     CHECK_NULL_RETURN(frameNode, ERROR_INT_CODE);
362     return TimePickerModelNG::getTimepickerUseMilitaryTime(frameNode);
363 }
364 
365 } // namespace
366 
367 namespace NodeModifier {
GetTimepickerModifier()368 const ArkUITimepickerModifier* GetTimepickerModifier()
369 {
370     static const ArkUITimepickerModifier modifier = { GetTimepickerSelected, SetTimepickerSelected,
371         ResetTimepickerSelected, GetTimepickerBackgroundColor, SetTimepickerBackgroundColor,
372         GetTimepickerDisappearTextStyle, SetTimepickerDisappearTextStyle, GetTimepickerTextStyle,
373         SetTimepickerTextStyle, GetTimepickerSelectedTextStyle, SetTimepickerSelectedTextStyle,
374         ResetTimepickerDisappearTextStyle, ResetTimepickerTextStyle, ResetTimepickerSelectedTextStyle,
375         ResetTimepickerBackgroundColor, GetTimepickerUseMilitaryTime, SetTimepickerUseMilitaryTime,
376         ResetTimepickerUseMilitaryTime, SetTimepickerLoop, ResetTimepickerLoop, SetTimepickerDateTimeOptions,
377         ResetTimepickerDateTimeOptions };
378 
379     return &modifier;
380 }
381 
GetCJUITimepickerModifier()382 const CJUITimepickerModifier* GetCJUITimepickerModifier()
383 {
384     static const CJUITimepickerModifier modifier = { GetTimepickerSelected, SetTimepickerSelected,
385         ResetTimepickerSelected, GetTimepickerBackgroundColor, SetTimepickerBackgroundColor,
386         GetTimepickerDisappearTextStyle, SetTimepickerDisappearTextStyle, GetTimepickerTextStyle,
387         SetTimepickerTextStyle, GetTimepickerSelectedTextStyle, SetTimepickerSelectedTextStyle,
388         ResetTimepickerDisappearTextStyle, ResetTimepickerTextStyle, ResetTimepickerSelectedTextStyle,
389         ResetTimepickerBackgroundColor, GetTimepickerUseMilitaryTime, SetTimepickerUseMilitaryTime,
390         ResetTimepickerUseMilitaryTime, SetTimepickerLoop, ResetTimepickerLoop, SetTimepickerDateTimeOptions,
391         ResetTimepickerDateTimeOptions };
392 
393     return &modifier;
394 }
395 
SetTimePickerOnChange(ArkUINodeHandle node,void * extraParam)396 void SetTimePickerOnChange(ArkUINodeHandle node, void* extraParam)
397 {
398     auto* frameNode = reinterpret_cast<FrameNode*>(node);
399     CHECK_NULL_VOID(frameNode);
400     auto onChange = [extraParam](const BaseEventInfo* info) {
401         ArkUINodeEvent event;
402         event.kind = COMPONENT_ASYNC_EVENT;
403         event.componentAsyncEvent.subKind = ON_TIME_PICKER_CHANGE;
404         event.extraParam = reinterpret_cast<intptr_t>(extraParam);
405         const auto* eventInfo = TypeInfoHelper::DynamicCast<DatePickerChangeEvent>(info);
406         std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(eventInfo->GetSelectedStr());
407         if (!argsPtr) {
408             event.componentAsyncEvent.data[0].i32 = 0;
409             event.componentAsyncEvent.data[1].i32 = 0;
410         }
411         auto hour = argsPtr->GetValue("hour");
412         auto minute = argsPtr->GetValue("minute");
413         if (hour && hour->IsNumber()) {
414             event.componentAsyncEvent.data[0].i32 = hour->GetInt();
415         }
416         if (minute && minute->IsNumber()) {
417             event.componentAsyncEvent.data[1].i32 = minute->GetInt();
418         }
419         SendArkUIAsyncEvent(&event);
420     };
421     TimePickerModelNG::SetOnChange(frameNode, std::move(onChange));
422 }
423 } // namespace NodeModifier
424 } // namespace OHOS::Ace::NG
425