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 #include "core/components_ng/pattern/text_picker/textpicker_dialog_view.h"
17
18 #include <securec.h>
19
20 #include "base/i18n/localization.h"
21 #include "base/utils/utils.h"
22 #include "core/components_ng/base/view_abstract_model.h"
23 #include "core/components_ng/base/view_stack_processor.h"
24 #include "core/components_ng/pattern/button/button_pattern.h"
25 #include "core/components_ng/pattern/dialog/dialog_view.h"
26 #include "core/components_ng/pattern/divider/divider_pattern.h"
27 #include "core/components_ng/pattern/image/image_pattern.h"
28 #include "core/components_ng/pattern/stack/stack_pattern.h"
29 #include "core/components_ng/pattern/text/text_pattern.h"
30 #include "core/components_ng/pattern/text_picker/textpicker_column_pattern.h"
31 #include "core/components_ng/pattern/text_picker/textpicker_event_hub.h"
32 #include "core/components_ng/pattern/text_picker/textpicker_pattern.h"
33 #include "core/components_v2/inspector/inspector_constants.h"
34 #include "core/pipeline_ng/pipeline_context.h"
35
36 namespace OHOS::Ace::NG {
37
38 RefPtr<FrameNode> TextPickerDialogView::dialogNode_ = nullptr;
39
Show(const DialogProperties & dialogProperties,const TextPickerSettingData & settingData,std::map<std::string,NG::DialogTextEvent> dialogEvent,std::map<std::string,NG::DialogGestureEvent> dialogCancelEvent)40 RefPtr<FrameNode> TextPickerDialogView::Show(const DialogProperties& dialogProperties,
41 const TextPickerSettingData& settingData, std::map<std::string, NG::DialogTextEvent> dialogEvent,
42 std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent)
43 {
44 if (settingData.rangeVector.empty() && settingData.options.empty()) {
45 LOGI("Dialog input parameter range vector is empty, not display dialog.");
46 return nullptr;
47 }
48 if (settingData.options.empty()) {
49 return RangeShow(dialogProperties, settingData, dialogEvent, dialogCancelEvent);
50 } else {
51 return OptionsShow(dialogProperties, settingData, dialogEvent, dialogCancelEvent);
52 }
53 }
54
RangeShow(const DialogProperties & dialogProperties,const TextPickerSettingData & settingData,std::map<std::string,NG::DialogTextEvent> & dialogEvent,std::map<std::string,NG::DialogGestureEvent> & dialogCancelEvent)55 RefPtr<FrameNode> TextPickerDialogView::RangeShow(const DialogProperties& dialogProperties,
56 const TextPickerSettingData& settingData, std::map<std::string, NG::DialogTextEvent>& dialogEvent,
57 std::map<std::string, NG::DialogGestureEvent>& dialogCancelEvent)
58 {
59 auto contentColumn = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
60 AceType::MakeRefPtr<LinearLayoutPattern>(true));
61 auto textNodeId = ElementRegister::GetInstance()->MakeUniqueId();
62 auto textPickerNode = FrameNode::GetOrCreateFrameNode(
63 V2::TEXT_PICKER_ETS_TAG, textNodeId, []() { return AceType::MakeRefPtr<TextPickerPattern>(); });
64 ViewStackProcessor::GetInstance()->Push(textPickerNode);
65 auto textPickerPattern = textPickerNode->GetPattern<TextPickerPattern>();
66 CHECK_NULL_RETURN(textPickerPattern, nullptr);
67 textPickerPattern->SetColumnsKind(settingData.columnKind);
68 textPickerPattern->SetIsShowInDialog(true);
69 textPickerPattern->SetPickerTag(false);
70 auto context = textPickerNode->GetContext();
71 CHECK_NULL_RETURN(context, nullptr);
72 auto themeManager = context->GetThemeManager();
73 CHECK_NULL_RETURN(themeManager, nullptr);
74 auto dialogTheme = themeManager->GetTheme<DialogTheme>();
75 CHECK_NULL_RETURN(dialogTheme, nullptr);
76 textPickerPattern->SetBackgroundColor(dialogTheme->GetBackgroundColor());
77 auto pickerTheme = themeManager->GetTheme<PickerTheme>();
78 CHECK_NULL_RETURN(pickerTheme, nullptr);
79 auto pickerNodeLayout = textPickerNode->GetLayoutProperty<TextPickerLayoutProperty>();
80 CHECK_NULL_RETURN(pickerNodeLayout, nullptr);
81 pickerNodeLayout->UpdateUserDefinedIdealSize(
82 CalcSize(NG::CalcLength(Dimension(1.0, DimensionUnit::PERCENT)), std::nullopt));
83 pickerNodeLayout->UpdateCanLoop(settingData.canLoop);
84 uint32_t showCount = pickerTheme->GetShowOptionCount();
85 OptionsCreateNode(textPickerPattern, settingData, textPickerNode, showCount, 1, pickerTheme);
86 SetDefaultPickerItemHeight(settingData.height);
87 SetTextProperties(pickerTheme, settingData.properties);
88 auto changeEvent = dialogEvent["changeId"];
89 SetDialogChange(textPickerNode, std::move(changeEvent));
90 ViewStackProcessor::GetInstance()->Finish();
91 textPickerNode->MountToParent(contentColumn);
92 auto dialogNode = DialogView::CreateDialogNode(dialogProperties, contentColumn);
93 CHECK_NULL_RETURN(dialogNode, nullptr);
94 auto closeCallback = [dialogNode](const GestureEvent& /* info */) {
95 auto pipeline = PipelineContext::GetCurrentContext();
96 auto overlayManager = pipeline->GetOverlayManager();
97 overlayManager->CloseDialog(dialogNode);
98 };
99 auto contentRow = CreateButtonNode(textPickerNode, dialogEvent, std::move(dialogCancelEvent), closeCallback);
100 textPickerPattern->SetContentRowNode(contentRow);
101 contentRow->SetNeedCallChildrenUpdate(false);
102 contentRow->AddChild(CreateDividerNode(textPickerNode), 1);
103 contentRow->MountToParent(contentColumn);
104 auto focusHub = contentColumn->GetFocusHub();
105 CHECK_NULL_RETURN(focusHub, nullptr);
106 InitOnKeyEvent(focusHub);
107 dialogNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
108 dialogNode_ = dialogNode;
109 return dialogNode;
110 }
111
OptionsCreateNode(const RefPtr<TextPickerPattern> & textPickerPattern,const TextPickerSettingData & settingData,const RefPtr<FrameNode> & textPickerNode,uint32_t showCount,uint32_t columnCount,RefPtr<PickerTheme> pickerTheme)112 void TextPickerDialogView::OptionsCreateNode(const RefPtr<TextPickerPattern>& textPickerPattern,
113 const TextPickerSettingData& settingData, const RefPtr<FrameNode>& textPickerNode, uint32_t showCount,
114 uint32_t columnCount, RefPtr<PickerTheme> pickerTheme)
115 {
116 if (textPickerNode->GetChildren().empty()) {
117 for (size_t i = 0; i < columnCount; i++) {
118 auto columnNode = CreateColumnNode(settingData.columnKind, showCount, pickerTheme);
119 auto stackNode = CreateStackNode();
120 auto buttonNode = CreateButtonNode();
121 buttonNode->MountToParent(stackNode);
122 columnNode->MountToParent(stackNode);
123 columnNode->MarkModifyDone();
124 columnNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
125 auto layoutProperty = stackNode->GetLayoutProperty<LayoutProperty>();
126 layoutProperty->UpdateAlignment(Alignment::CENTER);
127 stackNode->MountToParent(textPickerNode);
128 }
129 }
130 if (settingData.options.size() > 0) {
131 SetSelectedValues(textPickerPattern, settingData.selectedValues);
132 SetValues(textPickerPattern, settingData.values);
133 } else {
134 SetRange(textPickerPattern, settingData.rangeVector);
135 SetSelected(textPickerPattern, settingData.selected);
136 }
137 }
138
OptionsShowInternal(const RefPtr<TextPickerPattern> & textPickerPattern,const TextPickerSettingData & settingData,const RefPtr<FrameNode> & textPickerNode,uint32_t showCount,RefPtr<PickerTheme> pickerTheme)139 void TextPickerDialogView::OptionsShowInternal(const RefPtr<TextPickerPattern>& textPickerPattern,
140 const TextPickerSettingData& settingData, const RefPtr<FrameNode>& textPickerNode, uint32_t showCount,
141 RefPtr<PickerTheme> pickerTheme)
142 {
143 textPickerPattern->SetIsCascade(settingData.attr.isCascade);
144 textPickerPattern->SetHasSelectAttr(settingData.attr.isHasSelectAttr);
145 textPickerPattern->SetColumnsKind(settingData.columnKind);
146 if (settingData.attr.isCascade) {
147 std::vector<NG::TextCascadePickerOptions> reOptions;
148 uint32_t columnCount = settingData.options.empty() ? 0 : 1;
149 // Caculate max depth
150 for (size_t i = 0; i < settingData.options.size(); i++) {
151 size_t tmp = textPickerPattern->ProcessCascadeOptionDepth(settingData.options[i]);
152 if (tmp > columnCount) {
153 columnCount = tmp;
154 }
155 }
156 OptionsCreateNode(textPickerPattern, settingData, textPickerNode, showCount, columnCount, pickerTheme);
157 textPickerPattern->ProcessCascadeOptions(settingData.options, reOptions, 0);
158 if (reOptions.size() < columnCount) {
159 auto differ = columnCount - reOptions.size();
160 for (uint32_t i = 0; i < differ; i++) {
161 NG::TextCascadePickerOptions differOption;
162 memset_s(&differOption, sizeof(differOption), 0, sizeof(differOption));
163 reOptions.emplace_back(differOption);
164 }
165 }
166 textPickerPattern->SetCascadeOptions(settingData.options, reOptions);
167 } else {
168 OptionsCreateNode(
169 textPickerPattern, settingData, textPickerNode, showCount, settingData.options.size(), pickerTheme);
170 textPickerPattern->SetCascadeOptions(settingData.options, settingData.options);
171 }
172 }
173
OptionsShow(const DialogProperties & dialogProperties,const TextPickerSettingData & settingData,std::map<std::string,NG::DialogTextEvent> & dialogEvent,std::map<std::string,NG::DialogGestureEvent> & dialogCancelEvent)174 RefPtr<FrameNode> TextPickerDialogView::OptionsShow(const DialogProperties& dialogProperties,
175 const TextPickerSettingData& settingData, std::map<std::string, NG::DialogTextEvent>& dialogEvent,
176 std::map<std::string, NG::DialogGestureEvent>& dialogCancelEvent)
177 {
178 auto contentColumn = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
179 AceType::MakeRefPtr<LinearLayoutPattern>(true));
180 auto textNodeId = ElementRegister::GetInstance()->MakeUniqueId();
181 auto textPickerNode = FrameNode::GetOrCreateFrameNode(
182 V2::TEXT_PICKER_ETS_TAG, textNodeId, []() { return AceType::MakeRefPtr<TextPickerPattern>(); });
183 ViewStackProcessor::GetInstance()->Push(textPickerNode);
184 auto textPickerPattern = textPickerNode->GetPattern<TextPickerPattern>();
185 CHECK_NULL_RETURN(textPickerPattern, nullptr);
186 textPickerPattern->SetIsShowInDialog(true);
187 textPickerPattern->SetPickerTag(false);
188 auto context = textPickerNode->GetContext();
189 CHECK_NULL_RETURN(context, nullptr);
190 auto themeManager = context->GetThemeManager();
191 CHECK_NULL_RETURN(themeManager, nullptr);
192 auto dialogTheme = themeManager->GetTheme<DialogTheme>();
193 CHECK_NULL_RETURN(dialogTheme, nullptr);
194 textPickerPattern->SetBackgroundColor(dialogTheme->GetBackgroundColor());
195 auto pickerTheme = themeManager->GetTheme<PickerTheme>();
196 CHECK_NULL_RETURN(pickerTheme, nullptr);
197 auto pickerNodeLayout = textPickerNode->GetLayoutProperty<TextPickerLayoutProperty>();
198 CHECK_NULL_RETURN(pickerNodeLayout, nullptr);
199 pickerNodeLayout->UpdateUserDefinedIdealSize(
200 CalcSize(NG::CalcLength(Dimension(1.0, DimensionUnit::PERCENT)), std::nullopt));
201 pickerNodeLayout->UpdateCanLoop(settingData.canLoop);
202 uint32_t showCount = pickerTheme->GetShowOptionCount();
203 OptionsShowInternal(textPickerPattern, settingData, textPickerNode, showCount, pickerTheme);
204 SetDefaultPickerItemHeight(settingData.height);
205 SetTextProperties(pickerTheme, settingData.properties);
206 auto changeEvent = dialogEvent["changeId"];
207 SetDialogChange(textPickerNode, std::move(changeEvent));
208
209 ViewStackProcessor::GetInstance()->Finish();
210 textPickerNode->MountToParent(contentColumn);
211 auto dialogNode = DialogView::CreateDialogNode(dialogProperties, contentColumn);
212 CHECK_NULL_RETURN(dialogNode, nullptr);
213
214 auto closeCallBack = [dialogNode](const GestureEvent& /* info */) {
215 auto pipeline = PipelineContext::GetCurrentContext();
216 auto overlayManager = pipeline->GetOverlayManager();
217 overlayManager->CloseDialog(dialogNode);
218 };
219 auto contentRow = CreateButtonNode(textPickerNode, dialogEvent, std::move(dialogCancelEvent), closeCallBack);
220 contentRow->AddChild(CreateDividerNode(textPickerNode), 1);
221 contentRow->MountToParent(contentColumn);
222 dialogNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
223 return dialogNode;
224 }
225
CreateIconItemNode(RefPtr<PickerTheme> pickerTheme)226 RefPtr<FrameNode> TextPickerDialogView::CreateIconItemNode(RefPtr<PickerTheme> pickerTheme)
227 {
228 auto row = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
229 AceType::MakeRefPtr<LinearLayoutPattern>(false));
230 CHECK_NULL_RETURN(row, nullptr);
231 auto layoutProps = row->GetLayoutProperty<LinearLayoutProperty>();
232 CHECK_NULL_RETURN(layoutProps, nullptr);
233 layoutProps->UpdateMainAxisAlign(FlexAlign::CENTER);
234 layoutProps->UpdateCrossAxisAlign(FlexAlign::CENTER);
235
236 MarginProperty marginProperty;
237 marginProperty.left = CalcLength(pickerTheme->GetPaddingHorizontal());
238 marginProperty.right = CalcLength(pickerTheme->GetPaddingHorizontal());
239 layoutProps->UpdateMargin(marginProperty);
240
241 auto imageNode = FrameNode::CreateFrameNode(
242 V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
243 CHECK_NULL_RETURN(imageNode, nullptr);
244 imageNode->MountToParent(row);
245
246 return row;
247 }
CreateTextItemNode(RefPtr<PickerTheme> pickerTheme)248 RefPtr<FrameNode> TextPickerDialogView::CreateTextItemNode(RefPtr<PickerTheme> pickerTheme)
249 {
250 auto textNode = FrameNode::CreateFrameNode(
251 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
252 CHECK_NULL_RETURN(textNode, nullptr);
253 auto textLayout = textNode->GetLayoutProperty<TextLayoutProperty>();
254 MarginProperty marginProperty;
255 marginProperty.left = CalcLength(pickerTheme->GetPaddingHorizontal());
256 marginProperty.right = CalcLength(pickerTheme->GetPaddingHorizontal());
257 textLayout->UpdateMargin(marginProperty);
258
259 return textNode;
260 }
CreateMixtureItemNode(RefPtr<PickerTheme> pickerTheme)261 RefPtr<FrameNode> TextPickerDialogView::CreateMixtureItemNode(RefPtr<PickerTheme> pickerTheme)
262 {
263 auto row = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
264 AceType::MakeRefPtr<LinearLayoutPattern>(false));
265 CHECK_NULL_RETURN(row, nullptr);
266
267 auto rowProperty = row->GetLayoutProperty<LinearLayoutProperty>();
268 MarginProperty marginProperty;
269 marginProperty.left = CalcLength(pickerTheme->GetPaddingHorizontal());
270 marginProperty.right = CalcLength(pickerTheme->GetPaddingHorizontal());
271 rowProperty->UpdateMargin(marginProperty);
272
273 auto imageNode = FrameNode::CreateFrameNode(
274 V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
275 CHECK_NULL_RETURN(imageNode, nullptr);
276 imageNode->MountToParent(row);
277
278 auto textNode = FrameNode::CreateFrameNode(
279 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
280 CHECK_NULL_RETURN(textNode, nullptr);
281 textNode->MountToParent(row);
282
283 return row;
284 }
285
CreateColumnNode(uint32_t columnKind,uint32_t showCount,RefPtr<PickerTheme> pickerTheme)286 RefPtr<FrameNode> TextPickerDialogView::CreateColumnNode(
287 uint32_t columnKind, uint32_t showCount, RefPtr<PickerTheme> pickerTheme)
288 {
289 auto columnNode =
290 FrameNode::GetOrCreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
291 []() { return AceType::MakeRefPtr<TextPickerColumnPattern>(); });
292
293 auto columnLayout = columnNode->GetLayoutProperty<LayoutProperty>();
294 MarginProperty marginProperty;
295 marginProperty.top = CalcLength(pickerTheme->GetContentMarginVertical());
296 marginProperty.bottom = CalcLength(pickerTheme->GetContentMarginVertical());
297 columnLayout->UpdateMargin(marginProperty);
298
299 if (columnKind == ICON) {
300 for (uint32_t index = 0; index < showCount; index++) {
301 auto row = CreateIconItemNode(pickerTheme);
302 CHECK_NULL_RETURN(row, nullptr);
303 row->MountToParent(columnNode);
304 }
305 } else if (columnKind == TEXT) {
306 for (uint32_t index = 0; index < showCount; index++) {
307 auto textNode = CreateTextItemNode(pickerTheme);
308 CHECK_NULL_RETURN(textNode, nullptr);
309 textNode->MountToParent(columnNode);
310 }
311 } else if (columnKind == MIXTURE) {
312 for (uint32_t index = 0; index < showCount; index++) {
313 auto row = CreateMixtureItemNode(pickerTheme);
314 CHECK_NULL_RETURN(row, nullptr);
315 row->MountToParent(columnNode);
316 }
317 }
318 return columnNode;
319 }
320
CreateStackNode()321 RefPtr<FrameNode> TextPickerDialogView::CreateStackNode()
322 {
323 auto stackId = ElementRegister::GetInstance()->MakeUniqueId();
324 return FrameNode::GetOrCreateFrameNode(
325 V2::STACK_ETS_TAG, stackId, []() { return AceType::MakeRefPtr<StackPattern>(); });
326 }
327
CreateButtonNode()328 RefPtr<FrameNode> TextPickerDialogView::CreateButtonNode()
329 {
330 auto buttonId = ElementRegister::GetInstance()->MakeUniqueId();
331 return FrameNode::GetOrCreateFrameNode(
332 V2::BUTTON_ETS_TAG, buttonId, []() { return AceType::MakeRefPtr<ButtonPattern>(); });
333 }
334
CreateDividerNode(const RefPtr<FrameNode> & dateNode)335 RefPtr<FrameNode> TextPickerDialogView::CreateDividerNode(const RefPtr<FrameNode>& dateNode)
336 {
337 auto pipeline = PipelineContext::GetCurrentContext();
338 CHECK_NULL_RETURN(pipeline, nullptr);
339 auto dialogTheme = pipeline->GetTheme<DialogTheme>();
340 auto dividerNode = FrameNode::GetOrCreateFrameNode(V2::DIVIDER_ETS_TAG,
341 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<DividerPattern>(); });
342 CHECK_NULL_RETURN(dividerNode, nullptr);
343
344 auto dividerPaintProps = dividerNode->GetPaintProperty<DividerRenderProperty>();
345 CHECK_NULL_RETURN(dividerPaintProps, nullptr);
346 dividerPaintProps->UpdateDividerColor(dialogTheme->GetDividerColor());
347
348 auto dividerLayoutProps = dividerNode->GetLayoutProperty<DividerLayoutProperty>();
349 CHECK_NULL_RETURN(dividerLayoutProps, nullptr);
350 dividerLayoutProps->UpdateVertical(true);
351
352 MarginProperty margin;
353 margin.top = CalcLength(dialogTheme->GetDividerHeight());
354 margin.bottom = CalcLength(dialogTheme->GetDividerPadding().Bottom());
355 dividerLayoutProps->UpdateMargin(margin);
356 dividerLayoutProps->UpdateUserDefinedIdealSize(
357 CalcSize(CalcLength(dialogTheme->GetDividerWidth()), CalcLength(dialogTheme->GetDividerHeight())));
358
359 return dividerNode;
360 }
361
CreateButtonNode(const RefPtr<FrameNode> & frameNode,std::map<std::string,NG::DialogTextEvent> dialogEvent,std::map<std::string,NG::DialogGestureEvent> dialogCancelEvent,GestureEventFunc callback)362 RefPtr<FrameNode> TextPickerDialogView::CreateButtonNode(const RefPtr<FrameNode>& frameNode,
363 std::map<std::string, NG::DialogTextEvent> dialogEvent,
364 std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent, GestureEventFunc callback)
365 {
366 auto acceptEvent = dialogEvent["acceptId"];
367 auto cancelEvent = dialogCancelEvent["cancelId"];
368 auto contentRow = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
369 AceType::MakeRefPtr<LinearLayoutPattern>(false));
370 CHECK_NULL_RETURN(contentRow, nullptr);
371 auto layoutProps = contentRow->GetLayoutProperty<LinearLayoutProperty>();
372 CHECK_NULL_RETURN(layoutProps, nullptr);
373 layoutProps->UpdateMainAxisAlign(FlexAlign::SPACE_AROUND);
374 layoutProps->UpdateMeasureType(MeasureType::MATCH_PARENT_MAIN_AXIS);
375
376 auto buttonCancelNode = CreateCancelNode(cancelEvent, frameNode);
377 auto buttonConfirmNode = CreateConfirmNode(frameNode, frameNode, acceptEvent);
378
379 buttonCancelNode->MountToParent(contentRow);
380 buttonConfirmNode->MountToParent(contentRow);
381
382 auto onClick = AceType::MakeRefPtr<NG::ClickEvent>(std::move(callback));
383 for (const auto& child : contentRow->GetChildren()) {
384 auto childNode = AceType::DynamicCast<FrameNode>(child);
385 CHECK_NULL_RETURN(childNode, nullptr);
386 auto gestureHub = childNode->GetOrCreateGestureEventHub();
387 CHECK_NULL_RETURN(gestureHub, nullptr);
388 gestureHub->AddClickEvent(onClick);
389 }
390
391 return contentRow;
392 }
393
UpdateButtonConfirmLayoutProperty(const RefPtr<FrameNode> & buttonConfirmNode,RefPtr<PickerTheme> pickerTheme)394 void TextPickerDialogView::UpdateButtonConfirmLayoutProperty(const RefPtr<FrameNode>& buttonConfirmNode,
395 RefPtr<PickerTheme> pickerTheme)
396 {
397 auto buttonConfirmLayoutProperty = buttonConfirmNode->GetLayoutProperty<ButtonLayoutProperty>();
398 CHECK_NULL_VOID(buttonConfirmLayoutProperty);
399 buttonConfirmLayoutProperty->UpdateLabel(Localization::GetInstance()->GetEntryLetters("common.ok"));
400 buttonConfirmLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT_MAIN_AXIS);
401 buttonConfirmLayoutProperty->UpdateType(ButtonType::CAPSULE);
402 buttonConfirmLayoutProperty->UpdateFlexShrink(1.0);
403 buttonConfirmLayoutProperty->UpdateUserDefinedIdealSize(
404 CalcSize(CalcLength(pickerTheme->GetButtonWidth()), CalcLength(pickerTheme->GetButtonHeight())));
405 }
406
CreateConfirmNode(const RefPtr<FrameNode> & dateNode,const RefPtr<FrameNode> & textPickerNode,DialogEvent & acceptEvent)407 RefPtr<FrameNode> TextPickerDialogView::CreateConfirmNode(
408 const RefPtr<FrameNode>& dateNode, const RefPtr<FrameNode>& textPickerNode, DialogEvent& acceptEvent)
409 {
410 auto pipeline = PipelineContext::GetCurrentContext();
411 CHECK_NULL_RETURN(pipeline, nullptr);
412 auto dialogTheme = pipeline->GetTheme<DialogTheme>();
413 auto pickerTheme = pipeline->GetTheme<PickerTheme>();
414
415 auto buttonConfirmNode = FrameNode::GetOrCreateFrameNode(V2::BUTTON_ETS_TAG,
416 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ButtonPattern>(); });
417 auto textConfirmNode = FrameNode::CreateFrameNode(
418 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
419 CHECK_NULL_RETURN(buttonConfirmNode, nullptr);
420 CHECK_NULL_RETURN(textConfirmNode, nullptr);
421 auto textLayoutProperty = textConfirmNode->GetLayoutProperty<TextLayoutProperty>();
422 CHECK_NULL_RETURN(textLayoutProperty, nullptr);
423 textLayoutProperty->UpdateContent(Localization::GetInstance()->GetEntryLetters("common.ok"));
424 textLayoutProperty->UpdateTextColor(pickerTheme->GetOptionStyle(true, false).GetTextColor());
425 textLayoutProperty->UpdateFontSize(pickerTheme->GetOptionStyle(false, false).GetFontSize());
426 textLayoutProperty->UpdateFontWeight(pickerTheme->GetOptionStyle(true, false).GetFontWeight());
427 auto textPattern = textPickerNode->GetPattern<TextPickerPattern>();
428 textPattern->SetConfirmNode(buttonConfirmNode);
429 auto buttonConfirmEventHub = buttonConfirmNode->GetEventHub<ButtonEventHub>();
430 CHECK_NULL_RETURN(buttonConfirmEventHub, nullptr);
431 buttonConfirmEventHub->SetStateEffect(true);
432
433 UpdateButtonConfirmLayoutProperty(buttonConfirmNode, pickerTheme);
434 auto buttonConfirmRenderContext = buttonConfirmNode->GetRenderContext();
435 buttonConfirmRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
436
437 MarginProperty margin;
438 margin.right = CalcLength(dialogTheme->GetDividerPadding().Right());
439 margin.top = CalcLength(dialogTheme->GetDividerHeight());
440 margin.bottom = CalcLength(dialogTheme->GetDividerPadding().Bottom());
441 buttonConfirmNode->GetLayoutProperty()->UpdateMargin(margin);
442
443 textConfirmNode->MountToParent(buttonConfirmNode);
444 auto eventConfirmHub = buttonConfirmNode->GetOrCreateGestureEventHub();
445 CHECK_NULL_RETURN(eventConfirmHub, nullptr);
446 CHECK_NULL_RETURN(dateNode, nullptr);
447 SetDialogAcceptEvent(dateNode, std::move(acceptEvent));
448 auto clickCallback = [dateNode](const GestureEvent& /* info */) {
449 auto pickerPattern = dateNode->GetPattern<TextPickerPattern>();
450 CHECK_NULL_VOID(pickerPattern);
451 auto str = pickerPattern->GetSelectedObject(false);
452 auto textPickerEventHub = pickerPattern->GetEventHub<TextPickerEventHub>();
453 CHECK_NULL_VOID(textPickerEventHub);
454 textPickerEventHub->FireDialogAcceptEvent(str);
455 };
456 eventConfirmHub->AddClickEvent(AceType::MakeRefPtr<NG::ClickEvent>(clickCallback));
457 buttonConfirmNode->MarkModifyDone();
458 return buttonConfirmNode;
459 }
460
CreateCancelNode(NG::DialogGestureEvent & cancelEvent,const RefPtr<FrameNode> & textPickerNode)461 RefPtr<FrameNode> TextPickerDialogView::CreateCancelNode(
462 NG::DialogGestureEvent& cancelEvent, const RefPtr<FrameNode>& textPickerNode)
463 {
464 auto pipeline = PipelineContext::GetCurrentContext();
465 CHECK_NULL_RETURN(pipeline, nullptr);
466 auto dialogTheme = pipeline->GetTheme<DialogTheme>();
467 auto pickerTheme = pipeline->GetTheme<PickerTheme>();
468 auto buttonCancelNode = FrameNode::GetOrCreateFrameNode(V2::BUTTON_ETS_TAG,
469 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ButtonPattern>(); });
470 CHECK_NULL_RETURN(buttonCancelNode, nullptr);
471 auto textCancelNode = FrameNode::CreateFrameNode(
472 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
473 CHECK_NULL_RETURN(textCancelNode, nullptr);
474 auto textCancelLayoutProperty = textCancelNode->GetLayoutProperty<TextLayoutProperty>();
475 CHECK_NULL_RETURN(textCancelLayoutProperty, nullptr);
476 textCancelLayoutProperty->UpdateContent(Localization::GetInstance()->GetEntryLetters("common.cancel"));
477 textCancelLayoutProperty->UpdateTextColor(pickerTheme->GetOptionStyle(true, false).GetTextColor());
478 textCancelLayoutProperty->UpdateFontSize(pickerTheme->GetOptionStyle(false, false).GetFontSize());
479 textCancelLayoutProperty->UpdateFontWeight(pickerTheme->GetOptionStyle(true, false).GetFontWeight());
480 auto textPattern = textPickerNode->GetPattern<TextPickerPattern>();
481 textPattern->SetCancelNode(buttonCancelNode);
482 textCancelNode->MountToParent(buttonCancelNode);
483 auto eventCancelHub = buttonCancelNode->GetOrCreateGestureEventHub();
484 CHECK_NULL_RETURN(eventCancelHub, nullptr);
485 eventCancelHub->AddClickEvent(AceType::MakeRefPtr<NG::ClickEvent>(std::move(cancelEvent)));
486
487 auto buttonCancelEventHub = buttonCancelNode->GetEventHub<ButtonEventHub>();
488 CHECK_NULL_RETURN(buttonCancelEventHub, nullptr);
489 buttonCancelEventHub->SetStateEffect(true);
490
491 MarginProperty margin;
492 margin.left = CalcLength(dialogTheme->GetDividerPadding().Left());
493 margin.top = CalcLength(dialogTheme->GetDividerHeight());
494 margin.bottom = CalcLength(dialogTheme->GetDividerPadding().Bottom());
495 buttonCancelNode->GetLayoutProperty()->UpdateMargin(margin);
496
497 auto buttonCancelLayoutProperty = buttonCancelNode->GetLayoutProperty<ButtonLayoutProperty>();
498 buttonCancelLayoutProperty->UpdateLabel(Localization::GetInstance()->GetEntryLetters("common.cancel"));
499 buttonCancelLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT_MAIN_AXIS);
500 buttonCancelLayoutProperty->UpdateType(ButtonType::CAPSULE);
501 buttonCancelLayoutProperty->UpdateFlexShrink(1.0);
502 buttonCancelLayoutProperty->UpdateUserDefinedIdealSize(
503 CalcSize(CalcLength(pickerTheme->GetButtonWidth()), CalcLength(pickerTheme->GetButtonHeight())));
504
505 auto buttonCancelRenderContext = buttonCancelNode->GetRenderContext();
506 buttonCancelRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
507 buttonCancelNode->MarkModifyDone();
508 return buttonCancelNode;
509 }
510
SetSelected(const RefPtr<TextPickerPattern> & textPickerPattern,uint32_t value)511 void TextPickerDialogView::SetSelected(const RefPtr<TextPickerPattern>& textPickerPattern, uint32_t value)
512 {
513 textPickerPattern->SetSelected(value);
514 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, Selected, value);
515 }
516
SetSelectedValues(const RefPtr<TextPickerPattern> & textPickerPattern,const std::vector<uint32_t> & values)517 void TextPickerDialogView::SetSelectedValues(
518 const RefPtr<TextPickerPattern>& textPickerPattern, const std::vector<uint32_t>& values)
519 {
520 textPickerPattern->SetSelecteds(values);
521 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, Selecteds, values);
522 }
523
SetValues(const RefPtr<TextPickerPattern> & textPickerPattern,const std::vector<std::string> & values)524 void TextPickerDialogView::SetValues(
525 const RefPtr<TextPickerPattern>& textPickerPattern, const std::vector<std::string>& values)
526 {
527 textPickerPattern->SetValues(values);
528 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, Values, values);
529 }
530
SetRange(const RefPtr<TextPickerPattern> & textPickerPattern,const std::vector<NG::RangeContent> & value)531 void TextPickerDialogView::SetRange(
532 const RefPtr<TextPickerPattern>& textPickerPattern, const std::vector<NG::RangeContent>& value)
533 {
534 textPickerPattern->SetRange(value);
535 }
536
SetTextProperties(const RefPtr<PickerTheme> & pickerTheme,const PickerTextProperties & properties)537 void TextPickerDialogView::SetTextProperties(
538 const RefPtr<PickerTheme>& pickerTheme, const PickerTextProperties& properties)
539 {
540 CHECK_NULL_VOID(pickerTheme);
541 auto selectedStyle = pickerTheme->GetOptionStyle(true, false);
542 auto disappearStyle = pickerTheme->GetDisappearOptionStyle();
543 auto normalStyle = pickerTheme->GetOptionStyle(false, false);
544
545 if (properties.disappearTextStyle_.fontSize.has_value() && properties.disappearTextStyle_.fontSize->IsValid()) {
546 ACE_UPDATE_LAYOUT_PROPERTY(
547 TextPickerLayoutProperty, DisappearFontSize, properties.disappearTextStyle_.fontSize.value());
548 } else {
549 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, DisappearFontSize, disappearStyle.GetFontSize());
550 }
551 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, DisappearColor,
552 properties.disappearTextStyle_.textColor.value_or(disappearStyle.GetTextColor()));
553 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, DisappearWeight,
554 properties.disappearTextStyle_.fontWeight.value_or(disappearStyle.GetFontWeight()));
555 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, DisappearFontFamily,
556 properties.disappearTextStyle_.fontFamily.value_or(disappearStyle.GetFontFamilies()));
557 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, DisappearFontStyle,
558 properties.disappearTextStyle_.fontStyle.value_or(disappearStyle.GetFontStyle()));
559
560 if (properties.normalTextStyle_.fontSize.has_value() && properties.normalTextStyle_.fontSize->IsValid()) {
561 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, FontSize, properties.normalTextStyle_.fontSize.value());
562 } else {
563 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, FontSize, normalStyle.GetFontSize());
564 }
565 ACE_UPDATE_LAYOUT_PROPERTY(
566 TextPickerLayoutProperty, Color, properties.normalTextStyle_.textColor.value_or(normalStyle.GetTextColor()));
567 ACE_UPDATE_LAYOUT_PROPERTY(
568 TextPickerLayoutProperty, Weight, properties.normalTextStyle_.fontWeight.value_or(normalStyle.GetFontWeight()));
569 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, FontFamily,
570 properties.normalTextStyle_.fontFamily.value_or(normalStyle.GetFontFamilies()));
571 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, FontStyle,
572 properties.normalTextStyle_.fontStyle.value_or(normalStyle.GetFontStyle()));
573
574 if (properties.selectedTextStyle_.fontSize.has_value() && properties.selectedTextStyle_.fontSize->IsValid()) {
575 ACE_UPDATE_LAYOUT_PROPERTY(
576 TextPickerLayoutProperty, SelectedFontSize, properties.selectedTextStyle_.fontSize.value());
577 } else {
578 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, SelectedFontSize, selectedStyle.GetFontSize());
579 }
580 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, SelectedColor,
581 properties.selectedTextStyle_.textColor.value_or(selectedStyle.GetTextColor()));
582 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, SelectedWeight,
583 properties.selectedTextStyle_.fontWeight.value_or(selectedStyle.GetFontWeight()));
584 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, SelectedFontFamily,
585 properties.selectedTextStyle_.fontFamily.value_or(selectedStyle.GetFontFamilies()));
586 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, SelectedFontStyle,
587 properties.selectedTextStyle_.fontStyle.value_or(selectedStyle.GetFontStyle()));
588 }
589
SetDialogChange(const RefPtr<FrameNode> & frameNode,DialogTextEvent && onChange)590 void TextPickerDialogView::SetDialogChange(const RefPtr<FrameNode>& frameNode, DialogTextEvent&& onChange)
591 {
592 CHECK_NULL_VOID(frameNode);
593 auto eventHub = frameNode->GetEventHub<TextPickerEventHub>();
594 CHECK_NULL_VOID(eventHub);
595 eventHub->SetDialogChange(std::move(onChange));
596 }
597
SetDefaultPickerItemHeight(const Dimension & value)598 void TextPickerDialogView::SetDefaultPickerItemHeight(const Dimension& value)
599 {
600 ACE_UPDATE_LAYOUT_PROPERTY(TextPickerLayoutProperty, DefaultPickerItemHeight, value);
601 }
602
SetDialogAcceptEvent(const RefPtr<FrameNode> & frameNode,DialogTextEvent && onChange)603 void TextPickerDialogView::SetDialogAcceptEvent(const RefPtr<FrameNode>& frameNode, DialogTextEvent&& onChange)
604 {
605 CHECK_NULL_VOID(frameNode);
606 auto eventHub = frameNode->GetEventHub<TextPickerEventHub>();
607 CHECK_NULL_VOID(eventHub);
608 eventHub->SetDialogAcceptEvent(std::move(onChange));
609 }
610
InitOnKeyEvent(const RefPtr<FocusHub> & focusHub)611 void TextPickerDialogView::InitOnKeyEvent(const RefPtr<FocusHub>& focusHub)
612 {
613 auto onKeyEvent = [](const KeyEvent& event) -> bool { return TextPickerDialogView::OnKeyEvent(event); };
614 focusHub->SetOnKeyEventInternal(std::move(onKeyEvent));
615 }
OnKeyEvent(const KeyEvent & event)616 bool TextPickerDialogView::OnKeyEvent(const KeyEvent& event)
617 {
618 if (event.action != KeyAction::DOWN) {
619 return false;
620 }
621
622 if (event.code == KeyCode::KEY_ESCAPE) {
623 auto pipeline = PipelineContext::GetCurrentContext();
624 auto overlayManager = pipeline->GetOverlayManager();
625 overlayManager->CloseDialog(dialogNode_);
626 return true;
627 }
628
629 return false;
630 }
631 } // namespace OHOS::Ace::NG
632