1 /*
2 * Copyright (c) 2022-2025 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/search/search_pattern.h"
17
18 #include <cstdint>
19 #include "base/geometry/dimension.h"
20 #include "base/utils/multi_thread.h"
21 #include "base/utils/utf_helper.h"
22 #include "core/components_ng/pattern/divider/divider_layout_property.h"
23 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
24 #include "base/geometry/rect.h"
25 #include "base/utils/system_properties.h"
26 #include "base/utils/utils.h"
27 #include "core/common/recorder/node_data_cache.h"
28 #include "core/components/search/search_theme.h"
29 #include "core/components/theme/icon_theme.h"
30 #include "core/components_ng/base/inspector_filter.h"
31 #include "core/components_ng/base/view_stack_processor.h"
32 #include "core/components_ng/pattern/button/button_pattern.h"
33 #include "core/components_ng/pattern/divider/divider_render_property.h"
34 #include "core/components_ng/pattern/image/image_pattern.h"
35 #include "core/components_ng/pattern/search/search_model.h"
36 #include "core/components_ng/pattern/search/search_text_field.h"
37 #include "core/components_ng/pattern/text/text_layout_property.h"
38 #include "core/components_ng/pattern/text/text_pattern.h"
39 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
40 #include "core/event/touch_event.h"
41 #include "core/components/theme/app_theme.h"
42
43 namespace OHOS::Ace::NG {
44
45 namespace {
46 constexpr int32_t TEXTFIELD_INDEX = 0;
47 constexpr int32_t IMAGE_INDEX = 1;
48 constexpr int32_t CANCEL_IMAGE_INDEX = 2;
49 constexpr int32_t CANCEL_BUTTON_INDEX = 3;
50 constexpr int32_t BUTTON_INDEX = 4;
51 constexpr int32_t DIVIDER_INDEX = 5;
52 constexpr int32_t DOUBLE = 2;
53 constexpr int32_t ERROR = -1;
54
55 // The focus state requires an 2vp inner stroke, which should be indented by 1vp when drawn.
56 constexpr Dimension FOCUS_OFFSET = 1.0_vp;
57 constexpr Dimension UP_AND_DOWN_PADDING = 8.0_vp;
58 constexpr Dimension SYMBOL_ICON_HEIGHT = 16.0_fp;
59 constexpr Dimension ICON_MAX_SIZE = 32.0_vp;
60 constexpr Dimension SEARCH_TEXTINPUT_BORDER_WIDTH = 0.0_vp;
61 constexpr float HOVER_OPACITY = 0.05f;
62 constexpr float TOUCH_OPACITY = 0.1f;
63 constexpr float MAX_FONT_SCALE = 2.0f;
64 constexpr int32_t HOVER_TO_TOUCH_DURATION = 100;
65 constexpr int32_t HOVER_DURATION = 250;
66 constexpr int32_t TOUCH_DURATION = 250;
67
68 const std::string INSPECTOR_PREFIX = "__SearchField__";
69 const std::vector<std::string> SPECICALIZED_INSPECTOR_INDEXS = { "", "Image__", "CancelImage__", "CancelButton__",
70 "Button__" };
71 } // namespace
72
NeedToRequestKeyboardOnFocus() const73 bool SearchPattern::NeedToRequestKeyboardOnFocus() const
74 {
75 auto textField = textField_.Upgrade();
76 CHECK_NULL_RETURN(textField, false);
77 auto pattern = textField->GetPattern();
78 CHECK_NULL_RETURN(pattern, false);
79 auto curPattern = DynamicCast<TextFieldPattern>(pattern);
80 return curPattern->NeedToRequestKeyboardOnFocus();
81 }
82
ConvertCopyOptionsToString(CopyOptions copyOptions)83 std::string SearchPattern::ConvertCopyOptionsToString(CopyOptions copyOptions)
84 {
85 std::string result;
86 switch (copyOptions) {
87 case CopyOptions::None:
88 result = "CopyOptions.None";
89 break;
90 case CopyOptions::InApp:
91 result = "CopyOptions.InApp";
92 break;
93 case CopyOptions::Local:
94 result = "CopyOptions.Local";
95 break;
96 case CopyOptions::Distributed:
97 result = "CopyOptions.Distributed";
98 break;
99 default:
100 break;
101 }
102 return result;
103 }
104
UpdateChangeEvent(const std::u16string & textValue,int16_t style)105 void SearchPattern::UpdateChangeEvent(const std::u16string& textValue, int16_t style)
106 {
107 auto frameNode = GetHost();
108 CHECK_NULL_VOID(frameNode);
109 auto buttonHost = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(CANCEL_BUTTON_INDEX));
110 CHECK_NULL_VOID(buttonHost);
111 auto imageHost = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(CANCEL_IMAGE_INDEX));
112 CHECK_NULL_VOID(imageHost);
113 if (style == ERROR) {
114 auto layoutProperty = frameNode->GetLayoutProperty<SearchLayoutProperty>();
115 CHECK_NULL_VOID(layoutProperty);
116 style = static_cast<int16_t>(layoutProperty->GetCancelButtonStyle().value_or(CancelButtonStyle::INPUT));
117 }
118 UpdateCancelButtonStatus(textValue, style);
119 buttonHost->MarkModifyDone();
120 imageHost->MarkModifyDone();
121 buttonHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
122 imageHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
123 if (imageHost->GetTag() == V2::SYMBOL_ETS_TAG) {
124 auto textLayoutProperty = imageHost->GetLayoutProperty<TextLayoutProperty>();
125 CHECK_NULL_VOID(textLayoutProperty);
126 auto layoutConstraint = textLayoutProperty->GetLayoutConstraint();
127 auto textLayoutWrapper = imageHost->CreateLayoutWrapper();
128 CHECK_NULL_VOID(textLayoutWrapper);
129 ScopedLayout scope(frameNode->GetContext());
130 textLayoutWrapper->Measure(layoutConstraint);
131 }
132 }
133
UpdateCancelButtonStatus(const std::u16string & textValue,int16_t style)134 void SearchPattern::UpdateCancelButtonStatus(const std::u16string& textValue, int16_t style)
135 {
136 auto frameNode = GetHost();
137 CHECK_NULL_VOID(frameNode);
138 auto buttonHost = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(CANCEL_BUTTON_INDEX));
139 CHECK_NULL_VOID(buttonHost);
140 auto imageHost = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(CANCEL_IMAGE_INDEX));
141 CHECK_NULL_VOID(imageHost);
142 auto cancelButtonRenderContext = buttonHost->GetRenderContext();
143 CHECK_NULL_VOID(cancelButtonRenderContext);
144 auto cancelImageRenderContext = imageHost->GetRenderContext();
145 CHECK_NULL_VOID(cancelImageRenderContext);
146 auto cancelButtonEvent = buttonHost->GetOrCreateEventHub<ButtonEventHub>();
147 CHECK_NULL_VOID(cancelButtonEvent);
148 auto buttonLayoutProperty = buttonHost->GetLayoutProperty<LayoutProperty>();
149 CHECK_NULL_VOID(buttonLayoutProperty);
150 auto imageLayoutProperty = imageHost->GetLayoutProperty<LayoutProperty>();
151 CHECK_NULL_VOID(imageLayoutProperty);
152 bool isEventEnabled = IsEventEnabled(textValue, style);
153 if (isEventEnabled) {
154 cancelButtonRenderContext->UpdateOpacity(1.0);
155 cancelImageRenderContext->UpdateOpacity(1.0);
156 cancelButtonEvent->SetEnabled(true);
157 buttonLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
158 imageLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
159 } else {
160 cancelButtonRenderContext->UpdateOpacity(0.0);
161 cancelImageRenderContext->UpdateOpacity(0.0);
162 cancelButtonEvent->SetEnabled(false);
163 buttonLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
164 imageLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
165 }
166 if (imageHost->GetTag() == V2::IMAGE_ETS_TAG) {
167 auto imageEvent = imageHost->GetOrCreateEventHub<ImageEventHub>();
168 CHECK_NULL_VOID(imageEvent);
169 imageEvent->SetEnabled(isEventEnabled);
170 }
171 }
172
UpdateDisable(const std::u16string & textValue)173 void SearchPattern::UpdateDisable(const std::u16string& textValue)
174 {
175 auto frameNode = GetHost();
176 CHECK_NULL_VOID(frameNode);
177 auto searchButtonFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(BUTTON_INDEX));
178 CHECK_NULL_VOID(searchButtonFrameNode);
179 auto searchButtonLayoutProperty = searchButtonFrameNode->GetLayoutProperty<ButtonLayoutProperty>();
180 CHECK_NULL_VOID(searchButtonLayoutProperty);
181 auto needToDisable = searchButtonLayoutProperty->GetAutoDisable().value_or(false);
182 if (!needToDisable) {
183 return;
184 }
185 bool isEmptyText = textValue.empty();
186 if (isSearchButtonEnabled_ && isEmptyText) {
187 UpdateEnable(false);
188 } else if (!isSearchButtonEnabled_ && !isEmptyText) {
189 UpdateEnable(true);
190 }
191 }
192
UpdateEnable(bool needToEnable)193 void SearchPattern::UpdateEnable(bool needToEnable)
194 {
195 auto frameNode = GetHost();
196 CHECK_NULL_VOID(frameNode);
197 auto searchButtonFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(BUTTON_INDEX));
198 CHECK_NULL_VOID(searchButtonFrameNode);
199 auto buttonEventHub = searchButtonFrameNode->GetOrCreateEventHub<ButtonEventHub>();
200 CHECK_NULL_VOID(buttonEventHub);
201 if (needToEnable) {
202 buttonEventHub->SetEnabled(true);
203 } else {
204 buttonEventHub->SetEnabled(false);
205 }
206 isSearchButtonEnabled_ = buttonEventHub->IsEnabled();
207 searchButtonFrameNode->MarkModifyDone();
208 }
209
IsEventEnabled(const std::u16string & textValue,int16_t style)210 bool SearchPattern::IsEventEnabled(const std::u16string& textValue, int16_t style)
211 {
212 return (style == static_cast<int16_t>(CancelButtonStyle::CONSTANT)) ||
213 ((style == static_cast<int16_t>(CancelButtonStyle::INPUT)) && !textValue.empty());
214 }
215
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig &)216 bool SearchPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& /*config*/)
217 {
218 auto host = GetHost();
219 CHECK_NULL_RETURN(host, true);
220 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
221 CHECK_NULL_RETURN(textFieldFrameNode, true);
222 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
223 CHECK_NULL_RETURN(textFieldPattern, true);
224 UpdateDisable(textFieldPattern->GetTextUtf16Value());
225 auto geometryNode = dirty->GetGeometryNode();
226 CHECK_NULL_RETURN(geometryNode, true);
227 searchSize_ = geometryNode->GetContentSize();
228 searchOffset_ = geometryNode->GetContentOffset();
229
230 auto textFieldLayoutWrapper = dirty->GetOrCreateChildByIndex(TEXTFIELD_INDEX);
231 CHECK_NULL_RETURN(textFieldLayoutWrapper, true);
232 auto textFieldGeometryNode = textFieldLayoutWrapper->GetGeometryNode();
233 CHECK_NULL_RETURN(textFieldGeometryNode, true);
234 textFieldOffset_ = textFieldGeometryNode->GetFrameOffset();
235 textFieldSize_ = textFieldGeometryNode->GetFrameSize();
236
237 auto buttonLayoutWrapper = dirty->GetOrCreateChildByIndex(BUTTON_INDEX);
238 CHECK_NULL_RETURN(buttonLayoutWrapper, true);
239 auto buttonGeometryNode = buttonLayoutWrapper->GetGeometryNode();
240 CHECK_NULL_RETURN(buttonGeometryNode, true);
241 buttonOffset_ = buttonGeometryNode->GetFrameOffset();
242
243 auto buttonNode = buttonLayoutWrapper->GetHostNode();
244 CHECK_NULL_RETURN(buttonNode, true);
245 auto searchButtonEvent = buttonNode->GetOrCreateEventHub<ButtonEventHub>();
246 CHECK_NULL_RETURN(searchButtonEvent, true);
247
248 if (!searchButtonEvent->IsEnabled()) {
249 buttonSize_.Reset();
250 } else {
251 buttonSize_ = buttonGeometryNode->GetFrameSize();
252 }
253
254 auto cancelButtonLayoutWrapper = dirty->GetOrCreateChildByIndex(CANCEL_BUTTON_INDEX);
255 CHECK_NULL_RETURN(cancelButtonLayoutWrapper, true);
256 auto cancelButtonGeometryNode = cancelButtonLayoutWrapper->GetGeometryNode();
257 CHECK_NULL_RETURN(cancelButtonGeometryNode, true);
258
259 auto cancelButtonNode = cancelButtonLayoutWrapper->GetHostNode();
260 CHECK_NULL_RETURN(cancelButtonNode, true);
261 auto cancelButtonEvent = cancelButtonNode->GetOrCreateEventHub<ButtonEventHub>();
262 CHECK_NULL_RETURN(cancelButtonEvent, true);
263 cancelButtonOffset_ = cancelButtonGeometryNode->GetFrameOffset();
264 if (!cancelButtonEvent->IsEnabled()) {
265 cancelButtonSize_.Reset();
266 } else {
267 cancelButtonSize_ = cancelButtonGeometryNode->GetFrameSize();
268 }
269 SetAccessibilityClearAction();
270 return true;
271 }
272
SetAccessibilityClearAction()273 void SearchPattern::SetAccessibilityClearAction()
274 {
275 auto host = GetHost();
276 CHECK_NULL_VOID(host);
277 auto cancelButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(CANCEL_BUTTON_INDEX));
278 CHECK_NULL_VOID(cancelButtonFrameNode);
279 auto textAccessibilityProperty = cancelButtonFrameNode->GetAccessibilityProperty<AccessibilityProperty>();
280 CHECK_NULL_VOID(textAccessibilityProperty);
281 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
282 CHECK_NULL_VOID(textFieldFrameNode);
283 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
284 CHECK_NULL_VOID(textFieldPattern);
285 auto layoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
286 CHECK_NULL_VOID(layoutProperty);
287 auto cleanNodeStyle = layoutProperty->GetCleanNodeStyleValue(CleanNodeStyle::INPUT);
288 auto hasContent = cleanNodeStyle == CleanNodeStyle::CONSTANT ||
289 (cleanNodeStyle == CleanNodeStyle::INPUT && textFieldPattern->HasText());
290 textAccessibilityProperty->SetAccessibilityText(hasContent ? textFieldPattern->GetCancelButton() : "");
291 }
292
OnModifyDone()293 void SearchPattern::OnModifyDone()
294 {
295 Pattern::OnModifyDone();
296 auto host = GetHost();
297 CHECK_NULL_VOID(host);
298 auto layoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
299 CHECK_NULL_VOID(layoutProperty);
300 InitMargin(layoutProperty);
301 InitSearchTheme();
302 HandleBackgroundColor();
303
304 auto searchButton = layoutProperty->GetSearchButton();
305 searchButton_ = searchButton.has_value() ? searchButton->value() : "";
306 InitSearchController();
307 auto imageFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(IMAGE_INDEX));
308 CHECK_NULL_VOID(imageFrameNode);
309 imageFrameNode->MarkModifyDone();
310 auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(BUTTON_INDEX));
311 CHECK_NULL_VOID(buttonFrameNode);
312 auto buttonLayoutProperty = buttonFrameNode->GetLayoutProperty<ButtonLayoutProperty>();
313 CHECK_NULL_VOID(buttonLayoutProperty);
314 buttonLayoutProperty->UpdateVisibility(searchButton.has_value() ? VisibleType::VISIBLE : VisibleType::GONE);
315 buttonLayoutProperty->UpdateLabel(searchButton_);
316 buttonLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
317 buttonFrameNode->MarkModifyDone();
318
319 auto searchButtonEvent = buttonFrameNode->GetOrCreateEventHub<ButtonEventHub>();
320 isSearchButtonEnabled_ = searchButtonEvent->IsEnabled();
321
322 UpdateCancelButton();
323 UpdateDivider();
324 InitAllEvent();
325 }
326
InitAllEvent()327 void SearchPattern::InitAllEvent()
328 {
329 InitButtonAndImageClickEvent();
330 InitCancelButtonClickEvent();
331 InitTextFieldValueChangeEvent();
332 InitTextFieldDragEvent();
333 InitTextFieldClickEvent();
334 InitButtonMouseAndTouchEvent();
335 HandleTouchableAndHitTestMode();
336 auto host = GetHost();
337 CHECK_NULL_VOID(host);
338 auto focusHub = host->GetFocusHub();
339 CHECK_NULL_VOID(focusHub);
340 InitOnKeyEvent(focusHub);
341 InitFocusEvent(focusHub);
342 InitClickEvent();
343 HandleEnabled();
344 SetAccessibilityAction();
345 }
346
UpdateCancelButton()347 void SearchPattern::UpdateCancelButton()
348 {
349 auto host = GetHost();
350 CHECK_NULL_VOID(host);
351 auto cancelButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(CANCEL_BUTTON_INDEX));
352 CHECK_NULL_VOID(cancelButtonFrameNode);
353 auto cancelButtonLayoutProperty = cancelButtonFrameNode->GetLayoutProperty<ButtonLayoutProperty>();
354 CHECK_NULL_VOID(cancelButtonLayoutProperty);
355 cancelButtonLayoutProperty->UpdateLabel("");
356 cancelButtonFrameNode->MarkModifyDone();
357 }
358
UpdateDivider()359 void SearchPattern::UpdateDivider()
360 {
361 auto host = GetHost();
362 CHECK_NULL_VOID(host);
363 auto layoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
364 CHECK_NULL_VOID(layoutProperty);
365 auto dividerFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(DIVIDER_INDEX));
366 CHECK_NULL_VOID(dividerFrameNode);
367 auto dividerLayoutProperty = dividerFrameNode->GetLayoutProperty<DividerLayoutProperty>();
368 CHECK_NULL_VOID(dividerLayoutProperty);
369 auto searchButton = layoutProperty->GetSearchButton();
370 dividerLayoutProperty->UpdateVisibility(searchButton.has_value() ? VisibleType::VISIBLE : VisibleType::GONE);
371 dividerFrameNode->MarkModifyDone();
372 }
373
SetAccessibilityAction()374 void SearchPattern::SetAccessibilityAction()
375 {
376 auto host = GetHost();
377 CHECK_NULL_VOID(host);
378 auto textAccessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
379 CHECK_NULL_VOID(textAccessibilityProperty);
380 textAccessibilityProperty->SetActionSetSelection(
381 [weak = WeakClaim(this)](int32_t start, int32_t end, bool isForward) {
382 auto pattern = weak.Upgrade();
383 CHECK_NULL_VOID(pattern);
384 auto host = pattern->GetHost();
385 CHECK_NULL_VOID(host);
386 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
387 CHECK_NULL_VOID(textFieldFrameNode);
388 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
389 CHECK_NULL_VOID(textFieldPattern);
390 textFieldPattern->SetSelectionFlag(start, end, std::nullopt, isForward);
391 });
392
393 textAccessibilityProperty->SetActionSetIndex([weakPtr = WeakClaim(this)](int32_t index) {
394 const auto& pattern = weakPtr.Upgrade();
395 CHECK_NULL_VOID(pattern);
396 pattern->HandleCaretPosition(index);
397 });
398
399 textAccessibilityProperty->SetActionGetIndex([weakPtr = WeakClaim(this)]() -> int32_t {
400 const auto& pattern = weakPtr.Upgrade();
401 CHECK_NULL_RETURN(pattern, -1);
402 auto index = pattern->HandleGetCaretIndex();
403 return index;
404 });
405 SetSearchFieldAccessibilityAction();
406 SetSearchButtonAccessibilityAction();
407 }
408
SetSearchFieldAccessibilityAction()409 void SearchPattern::SetSearchFieldAccessibilityAction()
410 {
411 auto host = GetHost();
412 CHECK_NULL_VOID(host);
413 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
414 auto textFieldAccessibilityProperty = textFieldFrameNode->GetAccessibilityProperty<AccessibilityProperty>();
415 textFieldAccessibilityProperty->SetActionClick([weak = WeakClaim(this)]() {
416 auto pattern = weak.Upgrade();
417 CHECK_NULL_VOID(pattern);
418 auto host = pattern->GetHost();
419 CHECK_NULL_VOID(host);
420 auto gesture = host->GetOrCreateGestureEventHub();
421 CHECK_NULL_VOID(gesture);
422 auto actuator = gesture->GetUserClickEventActuator();
423 CHECK_NULL_VOID(actuator);
424 auto callBack = actuator->GetClickEvent();
425 CHECK_NULL_VOID(callBack);
426 GestureEvent gestureEvent;
427 callBack(gestureEvent);
428 });
429
430 auto textAccessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
431 textAccessibilityProperty->SetActionSetText([weak = WeakClaim(this)](const std::string& value) {
432 auto pattern = weak.Upgrade();
433 CHECK_NULL_VOID(pattern);
434 auto host = pattern->GetHost();
435 CHECK_NULL_VOID(host);
436 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
437 CHECK_NULL_VOID(textFieldFrameNode);
438 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
439 CHECK_NULL_VOID(textFieldPattern);
440 textFieldPattern->InsertValue(value);
441 });
442 }
443
SetSearchButtonAccessibilityAction()444 void SearchPattern::SetSearchButtonAccessibilityAction()
445 {
446 auto host = GetHost();
447 CHECK_NULL_VOID(host);
448 auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(BUTTON_INDEX));
449 CHECK_NULL_VOID(buttonFrameNode);
450 auto searchButtonAccessibilityProperty = buttonFrameNode->GetAccessibilityProperty<AccessibilityProperty>();
451 CHECK_NULL_VOID(searchButtonAccessibilityProperty);
452 searchButtonAccessibilityProperty->SetAccessibilityLevel("yes");
453 searchButtonAccessibilityProperty->SetAccessibilityGroup(true);
454 }
455
HandleBackgroundColor()456 void SearchPattern::HandleBackgroundColor()
457 {
458 auto host = GetHost();
459 CHECK_NULL_VOID(host);
460 auto renderContext = host->GetRenderContext();
461 CHECK_NULL_VOID(renderContext);
462 auto pipeline = host->GetContext();
463 CHECK_NULL_VOID(pipeline);
464 auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>(host->GetThemeScopeId());
465 CHECK_NULL_VOID(textFieldTheme);
466 auto searchLayoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
467 CHECK_NULL_VOID(searchLayoutProperty);
468 if (!searchLayoutProperty->HasBackgroundColor()) {
469 renderContext->UpdateBackgroundColor(textFieldTheme->GetBgColor());
470 }
471 }
472
HandleEnabled()473 void SearchPattern::HandleEnabled()
474 {
475 auto host = GetHost();
476 CHECK_NULL_VOID(host);
477 auto searchEventHub = host->GetOrCreateEventHub<EventHub>();
478 CHECK_NULL_VOID(searchEventHub);
479 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
480 CHECK_NULL_VOID(textFieldFrameNode);
481 auto eventHub = textFieldFrameNode->GetOrCreateEventHub<TextFieldEventHub>();
482 eventHub->SetEnabled(searchEventHub->IsEnabled() ? true : false);
483 auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
484 CHECK_NULL_VOID(textFieldLayoutProperty);
485 auto searchLayoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
486 CHECK_NULL_VOID(searchLayoutProperty);
487 textFieldLayoutProperty->UpdateLayoutDirection(searchLayoutProperty->GetLayoutDirection());
488 textFieldFrameNode->MarkModifyDone();
489 }
490
HandleTouchableAndHitTestMode()491 void SearchPattern::HandleTouchableAndHitTestMode()
492 {
493 auto host = GetHost();
494 CHECK_NULL_VOID(host);
495 auto searchEventHub = host->GetOrCreateEventHub<EventHub>();
496 CHECK_NULL_VOID(searchEventHub);
497 auto searchGestureHub = searchEventHub->GetGestureEventHub();
498 CHECK_NULL_VOID(searchGestureHub);
499 bool searchTouchable = true;
500 HitTestMode searchHitTestMode = HitTestMode::HTMDEFAULT;
501 if (searchGestureHub) {
502 searchTouchable = searchGestureHub->GetTouchable();
503 searchHitTestMode = searchGestureHub->GetHitTestMode();
504 }
505 for (int32_t childIndex = TEXTFIELD_INDEX; childIndex <= BUTTON_INDEX; childIndex++) {
506 auto childFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childIndex));
507 CHECK_NULL_VOID(childFrameNode);
508 auto childEventHub = childFrameNode->GetOrCreateEventHub<EventHub>();
509 auto childGestureHub = childEventHub->GetOrCreateGestureEventHub();
510 CHECK_NULL_VOID(childGestureHub);
511 childGestureHub->SetTouchable(searchTouchable);
512 childGestureHub->SetHitTestMode(searchHitTestMode);
513 childFrameNode->MarkModifyDone();
514 }
515 }
516
InitButtonMouseAndTouchEvent()517 void SearchPattern::InitButtonMouseAndTouchEvent()
518 {
519 InitButtonMouseEvent(searchButtonMouseEvent_, BUTTON_INDEX);
520 InitButtonMouseEvent(cancelButtonMouseEvent_, CANCEL_BUTTON_INDEX);
521 InitButtonTouchEvent(searchButtonTouchListener_, BUTTON_INDEX);
522 InitButtonTouchEvent(cancelButtonTouchListener_, CANCEL_BUTTON_INDEX);
523 }
524
InitTextFieldValueChangeEvent()525 void SearchPattern::InitTextFieldValueChangeEvent()
526 {
527 auto host = GetHost();
528 CHECK_NULL_VOID(host);
529 auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
530 CHECK_NULL_VOID(textFieldFrameNode);
531 auto eventHub = textFieldFrameNode->GetOrCreateEventHub<TextFieldEventHub>();
532 CHECK_NULL_VOID(eventHub);
533 if (!eventHub->GetOnChange()) {
534 auto searchChangeFunc = [weak = AceType::WeakClaim(this)]
535 (const ChangeValueInfo& info) {
536 auto searchPattern = weak.Upgrade();
537 CHECK_NULL_VOID(searchPattern);
538 searchPattern->UpdateChangeEvent(info.value);
539 };
540 eventHub->SetOnChange(std::move(searchChangeFunc));
541 }
542 }
543
InitTextFieldDragEvent()544 void SearchPattern::InitTextFieldDragEvent()
545 {
546 auto host = GetHost();
547 CHECK_NULL_VOID(host);
548 auto searchEventHub = host->GetOrCreateEventHub<EventHub>();
549 CHECK_NULL_VOID(searchEventHub);
550 auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
551 CHECK_NULL_VOID(textFieldFrameNode);
552 auto textFieldEventHub = textFieldFrameNode->GetOrCreateEventHub<EventHub>();
553 CHECK_NULL_VOID(textFieldEventHub);
554
555 textFieldFrameNode->SetDragPreview(host->GetDragPreview());
556 if (host->GetDisallowDropForcedly()) {
557 textFieldFrameNode->SetDisallowDropForcedly(true);
558 textFieldFrameNode->SetAllowDrop(host->GetAllowDrop());
559 } else if (!host->GetAllowDrop().empty()) {
560 textFieldFrameNode->SetDisallowDropForcedly(false);
561 textFieldFrameNode->SetAllowDrop(host->GetAllowDrop());
562 } else {
563 textFieldFrameNode->SetDisallowDropForcedly(false);
564 }
565
566 auto dragStart = searchEventHub->GetOnDragStart();
567 if (dragStart != nullptr) {
568 textFieldEventHub->SetOnDragStart(std::move(dragStart));
569 }
570
571 auto customerDragEnter = searchEventHub->GetCustomerOnDragFunc(DragFuncType::DRAG_ENTER);
572 if (customerDragEnter != nullptr) {
573 textFieldEventHub->SetCustomerOnDragFunc(DragFuncType::DRAG_ENTER, std::move(customerDragEnter));
574 }
575
576 auto customerDragLeave = searchEventHub->GetCustomerOnDragFunc(DragFuncType::DRAG_LEAVE);
577 if (customerDragLeave != nullptr) {
578 textFieldEventHub->SetCustomerOnDragFunc(DragFuncType::DRAG_LEAVE, std::move(customerDragLeave));
579 }
580
581 auto customerDragMove = searchEventHub->GetCustomerOnDragFunc(DragFuncType::DRAG_MOVE);
582 if (customerDragMove != nullptr) {
583 textFieldEventHub->SetCustomerOnDragFunc(DragFuncType::DRAG_MOVE, std::move(customerDragMove));
584 }
585
586 auto customerDragDrop = searchEventHub->GetCustomerOnDragFunc(DragFuncType::DRAG_DROP);
587 if (customerDragDrop != nullptr) {
588 textFieldEventHub->SetCustomerOnDragFunc(DragFuncType::DRAG_DROP, std::move(customerDragDrop));
589 }
590
591 auto customerDragEnd = searchEventHub->GetCustomerOnDragEndFunc();
592 if (customerDragEnd != nullptr) {
593 textFieldEventHub->SetCustomerOnDragFunc(DragFuncType::DRAG_END, std::move(customerDragEnd));
594 }
595
596 searchEventHub->ClearCustomerOnDragFunc();
597 }
598
OnAfterModifyDone()599 void SearchPattern::OnAfterModifyDone()
600 {
601 auto host = GetHost();
602 CHECK_NULL_VOID(host);
603 auto inspectorId = host->GetInspectorId().value_or("");
604 if (!inspectorId.empty()) {
605 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
606 CHECK_NULL_VOID(textFieldFrameNode);
607 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
608 CHECK_NULL_VOID(textFieldPattern);
609 auto text = textFieldPattern->GetTextValue();
610 Recorder::NodeDataCache::Get().PutString(host, inspectorId, text);
611 }
612 }
613
InitButtonAndImageClickEvent()614 void SearchPattern::InitButtonAndImageClickEvent()
615 {
616 // Image click event
617 if (imageClickListener_) {
618 return;
619 }
620 auto host = GetHost();
621 CHECK_NULL_VOID(host);
622 auto imageFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(IMAGE_INDEX));
623 CHECK_NULL_VOID(imageFrameNode);
624 CHECK_NULL_VOID(!imageClickListener_);
625 auto imageGesture = imageFrameNode->GetOrCreateGestureEventHub();
626 CHECK_NULL_VOID(imageGesture);
627 auto imageClickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
628 auto searchPattern = weak.Upgrade();
629 CHECK_NULL_VOID(searchPattern);
630 searchPattern->OnClickButtonAndImage();
631 };
632 imageClickListener_ = MakeRefPtr<ClickEvent>(std::move(imageClickCallback));
633 imageGesture->AddClickEvent(imageClickListener_);
634 // Button click event
635 if (buttonClickListener_) {
636 return;
637 }
638 auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(BUTTON_INDEX));
639 CHECK_NULL_VOID(buttonFrameNode);
640 CHECK_NULL_VOID(!buttonClickListener_);
641 auto buttonGesture = buttonFrameNode->GetOrCreateGestureEventHub();
642 CHECK_NULL_VOID(buttonGesture);
643 auto buttonClickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
644 auto searchPattern = weak.Upgrade();
645 CHECK_NULL_VOID(searchPattern);
646 searchPattern->OnClickButtonAndImage();
647 };
648 buttonClickListener_ = MakeRefPtr<ClickEvent>(std::move(buttonClickCallback));
649 buttonGesture->AddClickEvent(buttonClickListener_);
650 }
651
InitCancelButtonClickEvent()652 void SearchPattern::InitCancelButtonClickEvent()
653 {
654 // CancelButton click event
655 if (cancelButtonClickListener_) {
656 return;
657 }
658 auto host = GetHost();
659 CHECK_NULL_VOID(host);
660 auto cancelButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(CANCEL_BUTTON_INDEX));
661 CHECK_NULL_VOID(cancelButtonFrameNode);
662 auto cancelButtonGesture = cancelButtonFrameNode->GetOrCreateGestureEventHub();
663 CHECK_NULL_VOID(cancelButtonGesture);
664 auto cancelButtonClickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
665 auto searchPattern = weak.Upgrade();
666 CHECK_NULL_VOID(searchPattern);
667 searchPattern->OnClickCancelButton();
668 };
669 cancelButtonClickListener_ = MakeRefPtr<ClickEvent>(std::move(cancelButtonClickCallback));
670 cancelButtonGesture->AddClickEvent(cancelButtonClickListener_);
671 }
672
InitTextFieldClickEvent()673 void SearchPattern::InitTextFieldClickEvent()
674 {
675 if (textFieldClickListener_) {
676 return;
677 }
678 auto host = GetHost();
679 CHECK_NULL_VOID(host);
680 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
681 CHECK_NULL_VOID(textFieldFrameNode);
682 auto textFieldGesture = textFieldFrameNode->GetOrCreateGestureEventHub();
683 CHECK_NULL_VOID(textFieldGesture);
684 auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
685 auto searchPattern = weak.Upgrade();
686 CHECK_NULL_VOID(searchPattern);
687 searchPattern->OnClickTextField();
688 };
689 textFieldClickListener_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
690 textFieldGesture->AddClickAfterEvent(textFieldClickListener_);
691 }
692
InitSearchController()693 void SearchPattern::InitSearchController()
694 {
695 searchController_->SetCaretPosition([weak = WeakClaim(this)](int32_t caretPosition) {
696 auto search = weak.Upgrade();
697 CHECK_NULL_VOID(search);
698 search->HandleCaretPosition(caretPosition);
699 });
700
701 searchController_->SetGetTextContentRect([weak = WeakClaim(this)]() {
702 auto search = weak.Upgrade();
703 CHECK_NULL_RETURN(search, Rect(0, 0, 0, 0));
704 auto rect = search->searchController_->GetTextContentRect();
705 search->HandleTextContentRect(rect);
706 return rect;
707 });
708
709 searchController_->SetGetTextContentLinesNum([weak = WeakClaim(this)]() {
710 auto search = weak.Upgrade();
711 CHECK_NULL_RETURN(search, 0);
712 return search->HandleTextContentLines();
713 });
714
715 searchController_->SetGetCaretIndex([weak = WeakClaim(this)]() {
716 auto search = weak.Upgrade();
717 CHECK_NULL_RETURN(search, ERROR);
718 return search->HandleGetCaretIndex();
719 });
720
721 searchController_->SetGetCaretPosition([weak = WeakClaim(this)]() {
722 auto search = weak.Upgrade();
723 CHECK_NULL_RETURN(search, NG::OffsetF(ERROR, ERROR));
724 return search->HandleGetCaretPosition();
725 });
726
727 searchController_->SetStopEditing([weak = WeakClaim(this)]() {
728 auto search = weak.Upgrade();
729 CHECK_NULL_VOID(search);
730 search->StopEditing();
731 });
732 }
733
HandleGetCaretIndex()734 int32_t SearchPattern::HandleGetCaretIndex()
735 {
736 auto host = GetHost();
737 CHECK_NULL_RETURN(host, ERROR);
738 auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
739 CHECK_NULL_RETURN(textFieldFrameNode, ERROR);
740 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
741 CHECK_NULL_RETURN(textFieldPattern, ERROR);
742 return textFieldPattern->GetCaretIndex();
743 }
744
HandleGetCaretPosition()745 NG::OffsetF SearchPattern::HandleGetCaretPosition()
746 {
747 auto host = GetHost();
748 CHECK_NULL_RETURN(host, NG::OffsetF(ERROR, ERROR));
749 auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
750 CHECK_NULL_RETURN(textFieldFrameNode, NG::OffsetF(ERROR, ERROR));
751 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
752 CHECK_NULL_RETURN(textFieldPattern, NG::OffsetF(ERROR, ERROR));
753 return textFieldPattern->GetCaretOffset();
754 }
755
HandleCaretPosition(int32_t caretPosition)756 void SearchPattern::HandleCaretPosition(int32_t caretPosition)
757 {
758 auto host = GetHost();
759 CHECK_NULL_VOID(host);
760 auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
761 CHECK_NULL_VOID(textFieldFrameNode);
762 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
763 CHECK_NULL_VOID(textFieldPattern);
764 textFieldPattern->SetCaretPosition(caretPosition);
765 }
766
HandleTextContentRect(Rect & rect)767 void SearchPattern::HandleTextContentRect(Rect& rect)
768 {
769 auto host = GetHost();
770 CHECK_NULL_VOID(host);
771 auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
772 CHECK_NULL_VOID(textFieldFrameNode);
773 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
774 CHECK_NULL_VOID(textFieldPattern);
775 RectF frameRect = textFieldPattern->GetFrameRect();
776 rect.SetLeft(rect.Left() + frameRect.Left());
777 rect.SetTop(rect.Top() + frameRect.Top());
778 }
779
HandleTextContentLines()780 int32_t SearchPattern::HandleTextContentLines()
781 {
782 int lines = 0;
783 auto host = GetHost();
784 CHECK_NULL_RETURN(host, lines);
785 auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
786 CHECK_NULL_RETURN(textFieldFrameNode, lines);
787 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
788 CHECK_NULL_RETURN(textFieldPattern, lines);
789 if (!textFieldPattern->HasText()) {
790 return lines;
791 }
792 RectF textRect = textFieldPattern->GetTextRect();
793
794 if ((int32_t)textFieldPattern->GetLineHeight() == 0) {
795 return lines;
796 }
797 lines = (int32_t)textRect.Height() / (int32_t)textFieldPattern->GetLineHeight();
798 return lines;
799 }
800
StopEditing()801 void SearchPattern::StopEditing()
802 {
803 auto host = GetHost();
804 CHECK_NULL_VOID(host);
805 auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
806 CHECK_NULL_VOID(textFieldFrameNode);
807 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
808 CHECK_NULL_VOID(textFieldPattern);
809 textFieldPattern->StopEditing();
810 }
811
OnClickButtonAndImage()812 void SearchPattern::OnClickButtonAndImage()
813 {
814 auto host = GetHost();
815 CHECK_NULL_VOID(host);
816 auto searchEventHub = host->GetOrCreateEventHub<SearchEventHub>();
817 CHECK_NULL_VOID(searchEventHub);
818 auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
819 CHECK_NULL_VOID(textFieldFrameNode);
820 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
821 CHECK_NULL_VOID(textFieldPattern);
822 auto text = textFieldPattern->GetTextUtf16Value();
823 // Enter key type callback
824 TextFieldCommonEvent event;
825 searchEventHub->FireOnSubmit(text, event);
826 // If the developer doesn't want to keep editing, close keyboard and select background color
827 if (!event.IsKeepEditable()) {
828 textFieldPattern->StopEditing();
829 }
830 UiSessionManager::GetInstance()->ReportComponentChangeEvent("event", "Search.onSubmit");
831 TAG_LOGI(AceLogTag::ACE_SEARCH, "nodeId:[%{public}d] Search reportComponentChangeEvent onSubmit", host->GetId());
832 }
833
OnClickCancelButton()834 void SearchPattern::OnClickCancelButton()
835 {
836 auto host = GetHost();
837 CHECK_NULL_VOID(host);
838 auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
839 CHECK_NULL_VOID(textFieldFrameNode);
840 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
841 CHECK_NULL_VOID(textFieldPattern);
842 CHECK_NULL_VOID(!textFieldPattern->IsDragging());
843 CHECK_NULL_VOID(!textFieldPattern->IsHandleDragging());
844 focusChoice_ = FocusChoice::SEARCH;
845 textFieldPattern->ClearTextContent();
846 textFieldPattern->SetTextChangedAtCreation(true);
847 auto textRect = textFieldPattern->GetTextRect();
848 textRect.SetLeft(0.0f);
849 textFieldPattern->SetTextRect(textRect);
850 auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
851 CHECK_NULL_VOID(textFieldLayoutProperty);
852 auto focusHub = host->GetOrCreateFocusHub();
853 CHECK_NULL_VOID(focusHub);
854 focusHub->RequestFocusImmediately();
855 textFieldPattern->HandleFocusEvent();
856 textFieldFrameNode->OnAccessibilityEvent(AccessibilityEventType::REQUEST_FOCUS);
857 host->MarkModifyDone();
858 textFieldFrameNode->MarkModifyDone();
859 }
860
OnClickTextField()861 void SearchPattern::OnClickTextField()
862 {
863 focusChoice_ = FocusChoice::SEARCH;
864 auto host = GetHost();
865 CHECK_NULL_VOID(host);
866 RoundRect focusRect;
867 GetInnerFocusPaintRect(focusRect);
868 auto focusHub = host->GetFocusHub();
869 CHECK_NULL_VOID(focusHub);
870 focusHub->PaintInnerFocusState(focusRect);
871 host->MarkModifyDone();
872 }
873
InitOnKeyEvent(const RefPtr<FocusHub> & focusHub)874 void SearchPattern::InitOnKeyEvent(const RefPtr<FocusHub>& focusHub)
875 {
876 auto onKeyEvent = [wp = WeakClaim(this)](const KeyEvent& event) -> bool {
877 auto pattern = wp.Upgrade();
878 CHECK_NULL_RETURN(pattern, false);
879 return pattern->OnKeyEvent(event);
880 };
881 focusHub->SetOnKeyEventInternal(std::move(onKeyEvent));
882
883 auto getInnerPaintRectCallback = [wp = WeakClaim(this)](RoundRect& paintRect) {
884 auto pattern = wp.Upgrade();
885 if (pattern) {
886 pattern->GetInnerFocusPaintRect(paintRect);
887 }
888 };
889 focusHub->SetInnerFocusPaintRectCallback(getInnerPaintRectCallback);
890 }
891
OnKeyEvent(const KeyEvent & event)892 bool SearchPattern::OnKeyEvent(const KeyEvent& event)
893 {
894 TAG_LOGI(AceLogTag::ACE_SEARCH, "KeyAction:%{public}d", static_cast<int>(event.action));
895 auto host = GetHost();
896 CHECK_NULL_RETURN(host, false);
897 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
898 CHECK_NULL_RETURN(textFieldFrameNode, false);
899 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
900 CHECK_NULL_RETURN(textFieldPattern, false);
901
902 bool isAllTextSelected = textFieldPattern->IsSelectAll();
903 bool isCaretVisible = textFieldPattern->GetCursorVisible();
904 bool isTextEmpty = textFieldPattern->GetTextUtf16Value().empty();
905 bool isOnlyTabPressed = event.pressedCodes.size() == 1 && event.code == KeyCode::KEY_TAB;
906
907 auto parentHub = host->GetOrCreateFocusHub()->GetParentFocusHub();
908 auto getMaxFocusableCount = [](auto self, const RefPtr<FocusHub>& focusHub) -> size_t {
909 CHECK_NULL_RETURN(focusHub, 0);
910 auto parentHub = focusHub->GetParentFocusHub();
911 return std::max(focusHub->GetFocusableCount(), self(self, parentHub));
912 };
913 constexpr int ONE = 1; // Only one focusable component on scene
914 bool isOnlyOneFocusableComponent = getMaxFocusableCount(getMaxFocusableCount, parentHub) == ONE;
915 auto container = Container::Current();
916 if (container && container->IsUIExtensionWindow()) {
917 isOnlyOneFocusableComponent = false; // UI Extension Window
918 }
919
920 if (event.action != KeyAction::DOWN) {
921 if ((event.code == KeyCode::KEY_TAB ||
922 event.code == KeyCode::KEY_SHIFT_LEFT ||
923 event.code == KeyCode::KEY_SHIFT_RIGHT) &&
924 focusChoice_ == FocusChoice::SEARCH) {
925 textFieldPattern->OnKeyEvent(event);
926 }
927 return false;
928 }
929
930 if (focusChoice_ == FocusChoice::SEARCH &&
931 (event.IsShiftWith(KeyCode::KEY_DPAD_LEFT) ||
932 event.IsShiftWith(KeyCode::KEY_DPAD_RIGHT))) {
933 return textFieldPattern->OnKeyEvent(event);
934 }
935
936 // If the focus is on the search, press Enter to request keyboard.
937 if (event.code == KeyCode::KEY_ENTER && focusChoice_ == FocusChoice::SEARCH && !IsSearchAttached()) {
938 RequestKeyboard();
939 return true;
940 }
941 // If the focus is on the search button, press Enter to submit the content.
942 if (event.code == KeyCode::KEY_ENTER && focusChoice_ == FocusChoice::SEARCH_BUTTON) {
943 OnClickButtonAndImage();
944 return true;
945 }
946 // If the focus is on the Delete button, press Enter to delete the content.
947 if (event.code == KeyCode::KEY_ENTER && focusChoice_ == FocusChoice::CANCEL_BUTTON) {
948 OnClickCancelButton();
949 PaintFocusState();
950 return true;
951 }
952 // When press '->' or '<-', focus delete button or search button according to whether there is text in the search.
953 if (event.code == KeyCode::KEY_DPAD_LEFT || event.IsShiftWith(KeyCode::KEY_TAB)) {
954 if (focusChoice_ == FocusChoice::CANCEL_BUTTON) {
955 focusChoice_ = FocusChoice::SEARCH;
956 PaintFocusState();
957 return true;
958 }
959 if (focusChoice_ == FocusChoice::SEARCH_BUTTON) {
960 if (NearZero(cancelButtonSize_.Height())) {
961 focusChoice_ = FocusChoice::SEARCH;
962 } else {
963 focusChoice_ = FocusChoice::CANCEL_BUTTON;
964 }
965 PaintFocusState();
966 return true;
967 }
968 if (focusChoice_ == FocusChoice::SEARCH && isOnlyOneFocusableComponent && event.IsShiftWith(KeyCode::KEY_TAB)) {
969 if (isSearchButtonEnabled_) {
970 focusChoice_ = FocusChoice::SEARCH_BUTTON;
971 } else if (!isTextEmpty) {
972 focusChoice_ = FocusChoice::CANCEL_BUTTON;
973 }
974 PaintFocusState();
975 return true;
976 }
977 if (focusChoice_ == FocusChoice::SEARCH && event.IsShiftWith(KeyCode::KEY_TAB)) {
978 return false;
979 }
980 if (focusChoice_ == FocusChoice::SEARCH && !isAllTextSelected && !isTextEmpty) {
981 return textFieldPattern->OnKeyEvent(event);
982 }
983 if (focusChoice_ == FocusChoice::SEARCH && isAllTextSelected && !isCaretVisible &&
984 event.code == KeyCode::KEY_DPAD_LEFT) {
985 return IsConsumeEvent();
986 }
987 }
988 if (event.code == KeyCode::KEY_DPAD_RIGHT || (event.pressedCodes.size() == 1 && event.code == KeyCode::KEY_TAB)) {
989 if (focusChoice_ == FocusChoice::SEARCH && (isAllTextSelected || isTextEmpty || isOnlyTabPressed)) {
990 if (NearZero(cancelButtonSize_.Height()) && !isSearchButtonEnabled_ &&
991 event.code == KeyCode::KEY_DPAD_RIGHT) {
992 return IsConsumeEvent();
993 } else if (NearZero(cancelButtonSize_.Height()) && !isSearchButtonEnabled_) {
994 return false;
995 }
996 if (NearZero(cancelButtonSize_.Height())) {
997 focusChoice_ = FocusChoice::SEARCH_BUTTON;
998 } else {
999 focusChoice_ = FocusChoice::CANCEL_BUTTON;
1000 }
1001 PaintFocusState();
1002 return true;
1003 } else if (focusChoice_ == FocusChoice::SEARCH && event.code == KeyCode::KEY_DPAD_RIGHT) {
1004 return textFieldPattern->OnKeyEvent(event);
1005 }
1006 if (focusChoice_ == FocusChoice::CANCEL_BUTTON) {
1007 if (!NearZero(cancelButtonSize_.Height()) && (!isSearchButtonEnabled_) &&
1008 (event.code == KeyCode::KEY_DPAD_RIGHT)) {
1009 return false; // Go out of Search
1010 }
1011 if (isOnlyOneFocusableComponent && isOnlyTabPressed && !isSearchButtonEnabled_) {
1012 focusChoice_ = FocusChoice::SEARCH;
1013 PaintFocusState();
1014 return true;
1015 }
1016 if (!isSearchButtonEnabled_) {
1017 return !isOnlyTabPressed; // go outside if Tab pressed, or no action if arrow pressed
1018 }
1019 focusChoice_ = FocusChoice::SEARCH_BUTTON;
1020 PaintFocusState();
1021 return true;
1022 }
1023 if (focusChoice_ == FocusChoice::SEARCH_BUTTON && isOnlyOneFocusableComponent && isOnlyTabPressed) {
1024 focusChoice_ = FocusChoice::SEARCH;
1025 PaintFocusState();
1026 return true;
1027 }
1028 if (focusChoice_ == FocusChoice::SEARCH_BUTTON &&
1029 (event.pressedCodes.size() == 1 && event.code == KeyCode::KEY_TAB)) {
1030 return false;
1031 }
1032 if (focusChoice_ == FocusChoice::SEARCH_BUTTON && isSearchButtonEnabled_ &&
1033 (event.code == KeyCode::KEY_DPAD_RIGHT)) {
1034 return false; // Go out of Search
1035 }
1036 }
1037
1038 if (focusChoice_ == FocusChoice::SEARCH) {
1039 return textFieldPattern->OnKeyEvent(event);
1040 } else {
1041 return true;
1042 }
1043 }
1044
IsSearchAttached()1045 bool SearchPattern::IsSearchAttached()
1046 {
1047 auto host = GetHost();
1048 CHECK_NULL_RETURN(host, false);
1049 auto context = host->GetContext();
1050 CHECK_NULL_RETURN(context, false);
1051 auto textFieldManager = DynamicCast<TextFieldManagerNG>(context->GetTextFieldManager());
1052 CHECK_NULL_RETURN(textFieldManager, false);
1053 return textFieldManager->GetIsImeAttached();
1054 }
1055
IsConsumeEvent()1056 bool SearchPattern::IsConsumeEvent()
1057 {
1058 return !directionKeysMoveFocusOut_;
1059 }
1060
PaintSearchFocusState()1061 void SearchPattern::PaintSearchFocusState()
1062 {
1063 auto host = GetHost();
1064 CHECK_NULL_VOID(host);
1065 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1066 CHECK_NULL_VOID(textFieldFrameNode);
1067 auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
1068 CHECK_NULL_VOID(textFieldLayoutProperty);
1069 auto searchTheme = GetTheme();
1070 CHECK_NULL_VOID(searchTheme);
1071 auto normalTextColor = searchTheme->GetTextColor();
1072 // 获焦态反色 可通过分层参数配置不同的色值达到反色的效果
1073 if (textFieldLayoutProperty->GetTextColorValue(normalTextColor) == normalTextColor) {
1074 textFieldLayoutProperty->UpdateTextColor(searchTheme->GetFocusTextColor());
1075 isFocusTextColorSet_ = true;
1076 }
1077 auto normalPlaceholderColor = searchTheme->GetPlaceholderColor();
1078 if (textFieldLayoutProperty->GetPlaceholderTextColorValue(normalPlaceholderColor) == normalPlaceholderColor) {
1079 textFieldLayoutProperty->UpdatePlaceholderTextColor(searchTheme->GetFocusPlaceholderColor());
1080 isFocusPlaceholderColorSet_ = true;
1081 }
1082 }
1083
PaintFocusState(bool recoverFlag)1084 void SearchPattern::PaintFocusState(bool recoverFlag)
1085 {
1086 TAG_LOGI(AceLogTag::ACE_SEARCH, "Focus Choice = %{public}d", static_cast<int>(focusChoice_));
1087 auto host = GetHost();
1088 CHECK_NULL_VOID(host);
1089 auto renderContext = host->GetRenderContext();
1090 CHECK_NULL_VOID(renderContext);
1091 auto searchTheme = GetTheme();
1092 CHECK_NULL_VOID(searchTheme);
1093 if (renderContext->GetBackgroundColor().value_or(searchNormalColor_) == searchNormalColor_) {
1094 renderContext->UpdateBackgroundColor(searchTheme->GetFocusBgColor());
1095 isFocusBgColorSet_ = true;
1096 }
1097 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1098 CHECK_NULL_VOID(textFieldFrameNode);
1099 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1100 CHECK_NULL_VOID(textFieldPattern);
1101 auto searchTextFieldPattern = DynamicCast<SearchTextFieldPattern>(textFieldPattern);
1102 CHECK_NULL_VOID(searchTextFieldPattern);
1103
1104 if (focusChoice_ == FocusChoice::SEARCH) {
1105 HandleFocusChoiceSearch(textFieldPattern, recoverFlag, searchTextFieldPattern);
1106 } else {
1107 textFieldPattern->CloseKeyboard(true);
1108 searchTextFieldPattern->SearchRequestStopTwinkling(); // Hide caret
1109 }
1110
1111 if (GetDefaultIconColor(IMAGE_INDEX) == searchTheme->GetSymbolIconColor()) {
1112 SetSymbolSearchIconColor(searchTheme->GetFocusIconColor());
1113 isFocusIconColorSet_ = true;
1114 }
1115
1116 auto context = host->GetContext();
1117 CHECK_NULL_VOID(context);
1118 RoundRect focusRect;
1119 GetInnerFocusPaintRect(focusRect);
1120 auto focusHub = host->GetFocusHub();
1121 CHECK_NULL_VOID(focusHub);
1122 focusHub->PaintInnerFocusState(focusRect, true);
1123 host->MarkModifyDone();
1124 }
1125
HandleFocusChoiceSearch(const RefPtr<TextFieldPattern> & textFieldPattern,bool recoverFlag,const RefPtr<SearchTextFieldPattern> & searchTextFieldPattern)1126 void SearchPattern::HandleFocusChoiceSearch(const RefPtr<TextFieldPattern>& textFieldPattern, bool recoverFlag,
1127 const RefPtr<SearchTextFieldPattern>& searchTextFieldPattern)
1128 {
1129 PaintSearchFocusState();
1130 if (directionKeysMoveFocusOut_ && !recoverFlag && !textFieldPattern->GetTextUtf16Value().empty()) {
1131 textFieldPattern->HandleFocusEvent();
1132 searchTextFieldPattern->SearchRequestStartTwinkling();
1133 return;
1134 }
1135 if (!recoverFlag) {
1136 if (!textFieldPattern->GetTextUtf16Value().empty()) {
1137 textFieldPattern->NeedRequestKeyboard();
1138 textFieldPattern->SearchRequestKeyboard();
1139 textFieldPattern->HandleOnSelectAll(false); // Select all text
1140 textFieldPattern->HandleFocusEvent(); // Show caret
1141 searchTextFieldPattern->ResetSearchRequestStopTwinkling(); // reset flag
1142 textFieldPattern->StopTwinkling(); // Hide caret
1143 } else {
1144 textFieldPattern->HandleFocusEvent(); // Show caret
1145 searchTextFieldPattern->SearchRequestStartTwinkling();
1146 }
1147 } else {
1148 textFieldPattern->HandleFocusEvent();
1149 searchTextFieldPattern->SearchRequestStartTwinkling();
1150 }
1151 }
1152
GetSearchFocusPaintRect(RoundRect & paintRect)1153 void SearchPattern::GetSearchFocusPaintRect(RoundRect& paintRect)
1154 {
1155 auto host = GetHost();
1156 CHECK_NULL_VOID(host);
1157 auto geometryNode = host->GetGeometryNode();
1158 CHECK_NULL_VOID(geometryNode);
1159 auto searchSize = geometryNode->GetFrameSize();
1160 auto searchTheme = GetTheme();
1161 CHECK_NULL_VOID(searchTheme);
1162
1163 // 焦点框与search边框间距
1164 auto searchFocusPadding = searchTheme->GetSearchFocusPadding().ConvertToPx();
1165 float width = searchSize.Width() + 2 * searchFocusPadding;
1166 float height = searchSize.Height() + 2 * searchFocusPadding;
1167 paintRect.SetRect({ -searchFocusPadding, -searchFocusPadding, width, height });
1168 auto renderContext = host->GetRenderContext();
1169 CHECK_NULL_VOID(renderContext);
1170 auto radius = renderContext->GetBorderRadius().value_or(BorderRadiusProperty());
1171 paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS,
1172 static_cast<float>(radius.radiusTopLeft->ConvertToPx() + searchFocusPadding),
1173 static_cast<float>(radius.radiusTopLeft->ConvertToPx() + searchFocusPadding));
1174 paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS,
1175 static_cast<float>(radius.radiusTopRight->ConvertToPx() + searchFocusPadding),
1176 static_cast<float>(radius.radiusTopRight->ConvertToPx() + searchFocusPadding));
1177 paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS,
1178 static_cast<float>(radius.radiusBottomLeft->ConvertToPx() + searchFocusPadding),
1179 static_cast<float>(radius.radiusBottomLeft->ConvertToPx() + searchFocusPadding));
1180 paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS,
1181 static_cast<float>(radius.radiusBottomRight->ConvertToPx() + searchFocusPadding),
1182 static_cast<float>(radius.radiusBottomRight->ConvertToPx() + searchFocusPadding));
1183 }
1184
GetInnerFocusPaintRect(RoundRect & paintRect)1185 void SearchPattern::GetInnerFocusPaintRect(RoundRect& paintRect)
1186 {
1187 float originX = 0.0f;
1188 float originY = 0.0f;
1189 float endX = 0.0f;
1190 float endY = 0.0f;
1191 float radiusTopLeft = 0.0f;
1192 float radiusTopRight = 0.0f;
1193 float radiusBottomLeft = 0.0f;
1194 float radiusBottomRight = 0.0f;
1195 float focusOffset = FOCUS_OFFSET.ConvertToPx();
1196 if (focusChoice_ == FocusChoice::SEARCH) {
1197 auto searchTheme = GetTheme();
1198 CHECK_NULL_VOID(searchTheme);
1199 // 分层参数控制是否需要绘制焦点框
1200 if (searchTheme->NeedFocusBox()) {
1201 GetSearchFocusPaintRect(paintRect);
1202 return;
1203 }
1204 }
1205 if (focusChoice_ == FocusChoice::CANCEL_BUTTON) {
1206 originX = cancelButtonOffset_.GetX() + focusOffset;
1207 originY = cancelButtonOffset_.GetY() + focusOffset;
1208 endX = cancelButtonSize_.Width() + originX - DOUBLE * focusOffset;
1209 endY = cancelButtonSize_.Height() + originY - DOUBLE * focusOffset;
1210 radiusTopLeft = cancelButtonSize_.Height() / DOUBLE - focusOffset;
1211 radiusTopRight = cancelButtonSize_.Height() / DOUBLE - focusOffset;
1212 radiusBottomLeft = cancelButtonSize_.Height() / DOUBLE - focusOffset;
1213 radiusBottomRight = cancelButtonSize_.Height() / DOUBLE - focusOffset;
1214 }
1215 if (focusChoice_ == FocusChoice::SEARCH_BUTTON) {
1216 originX = buttonOffset_.GetX() + focusOffset;
1217 originY = buttonOffset_.GetY() + focusOffset;
1218 endX = buttonSize_.Width() + originX - DOUBLE * focusOffset;
1219 endY = buttonSize_.Height() + originY - DOUBLE * focusOffset;
1220 radiusTopLeft = buttonSize_.Height() / DOUBLE - focusOffset;
1221 radiusTopRight = buttonSize_.Height() / DOUBLE - focusOffset;
1222 radiusBottomLeft = buttonSize_.Height() / DOUBLE - focusOffset;
1223 radiusBottomRight = buttonSize_.Height() / DOUBLE - focusOffset;
1224 }
1225
1226 paintRect.SetRect({ originX, originY, endX - originX, endY - originY });
1227 paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS, radiusTopLeft, radiusTopLeft);
1228 paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS, radiusTopRight, radiusTopRight);
1229 paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS, radiusBottomLeft, radiusBottomLeft);
1230 paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS, radiusBottomRight, radiusBottomRight);
1231 }
1232
GetFocusPattern() const1233 FocusPattern SearchPattern::GetFocusPattern() const
1234 {
1235 FocusPattern focusPattern = { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION };
1236 focusPattern.SetIsFocusActiveWhenFocused(true);
1237 return focusPattern;
1238 }
1239
RequestKeyboard()1240 void SearchPattern::RequestKeyboard()
1241 {
1242 auto host = GetHost();
1243 CHECK_NULL_VOID(host);
1244 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1245 CHECK_NULL_VOID(textFieldFrameNode);
1246 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1247 textFieldPattern->SearchRequestKeyboard();
1248 }
1249
InitButtonTouchEvent(RefPtr<TouchEventImpl> & touchEvent,int32_t childId)1250 void SearchPattern::InitButtonTouchEvent(RefPtr<TouchEventImpl>& touchEvent, int32_t childId)
1251 {
1252 if (touchEvent) {
1253 return;
1254 }
1255 auto host = GetHost();
1256 CHECK_NULL_VOID(host);
1257 auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1258 CHECK_NULL_VOID(buttonFrameNode);
1259 auto gesture = buttonFrameNode->GetOrCreateGestureEventHub();
1260 CHECK_NULL_VOID(gesture);
1261 auto eventHub = buttonFrameNode->GetOrCreateEventHub<ButtonEventHub>();
1262 CHECK_NULL_VOID(eventHub);
1263 eventHub->SetStateEffect(false);
1264 auto touchTask = [weak = WeakClaim(this), childId](const TouchEventInfo& info) {
1265 auto pattern = weak.Upgrade();
1266 CHECK_NULL_VOID(pattern);
1267 auto touchType = info.GetTouches().front().GetTouchType();
1268 if (touchType == TouchType::DOWN) {
1269 pattern->OnButtonTouchDown(childId);
1270 }
1271 if (touchType == TouchType::UP || touchType == TouchType::CANCEL) {
1272 pattern->OnButtonTouchUp(childId);
1273 }
1274 };
1275 touchEvent = MakeRefPtr<TouchEventImpl>(std::move(touchTask));
1276 gesture->AddTouchEvent(touchEvent);
1277 }
1278
InitButtonMouseEvent(RefPtr<InputEvent> & inputEvent,int32_t childId)1279 void SearchPattern::InitButtonMouseEvent(RefPtr<InputEvent>& inputEvent, int32_t childId)
1280 {
1281 if (inputEvent) {
1282 return;
1283 }
1284 auto host = GetHost();
1285 CHECK_NULL_VOID(host);
1286 auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1287 CHECK_NULL_VOID(buttonFrameNode);
1288 auto eventHub = buttonFrameNode->GetOrCreateEventHub<ButtonEventHub>();
1289 auto inputHub = eventHub->GetOrCreateInputEventHub();
1290 auto buttonPattern = buttonFrameNode->GetPattern<ButtonPattern>();
1291 CHECK_NULL_VOID(buttonPattern);
1292 auto buttonHoverListener = buttonPattern->GetHoverListener();
1293 inputHub->RemoveOnHoverEvent(buttonHoverListener);
1294 auto mouseTask = [weak = WeakClaim(this), childId](bool isHover) {
1295 auto pattern = weak.Upgrade();
1296 if (pattern) {
1297 pattern->HandleButtonMouseEvent(isHover, childId);
1298 }
1299 };
1300 inputEvent = MakeRefPtr<InputEvent>(std::move(mouseTask));
1301 inputHub->AddOnHoverEvent(inputEvent);
1302 }
1303
OnButtonTouchDown(int32_t childId)1304 void SearchPattern::OnButtonTouchDown(int32_t childId)
1305 {
1306 auto host = GetHost();
1307 CHECK_NULL_VOID(host);
1308 auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1309 CHECK_NULL_VOID(buttonFrameNode);
1310 auto renderContext = buttonFrameNode->GetRenderContext();
1311 CHECK_NULL_VOID(renderContext);
1312 if (childId == CANCEL_BUTTON_INDEX ? isCancelButtonHover_ : isSearchButtonHover_) {
1313 AnimateTouchAndHover(renderContext, HOVER_OPACITY, TOUCH_OPACITY, HOVER_TO_TOUCH_DURATION, Curves::SHARP);
1314 } else {
1315 AnimateTouchAndHover(renderContext, 0.0f, TOUCH_OPACITY, TOUCH_DURATION, Curves::FRICTION);
1316 }
1317 }
1318
OnButtonTouchUp(int32_t childId)1319 void SearchPattern::OnButtonTouchUp(int32_t childId)
1320 {
1321 auto host = GetHost();
1322 CHECK_NULL_VOID(host);
1323 auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1324 CHECK_NULL_VOID(buttonFrameNode);
1325 auto renderContext = buttonFrameNode->GetRenderContext();
1326 CHECK_NULL_VOID(renderContext);
1327 if (childId == CANCEL_BUTTON_INDEX ? isCancelButtonHover_ : isSearchButtonHover_) {
1328 AnimateTouchAndHover(renderContext, TOUCH_OPACITY, HOVER_OPACITY, HOVER_TO_TOUCH_DURATION, Curves::SHARP);
1329 } else {
1330 AnimateTouchAndHover(renderContext, TOUCH_OPACITY, 0.0f, TOUCH_DURATION, Curves::FRICTION);
1331 }
1332 }
1333
SetMouseStyle(MouseFormat format)1334 void SearchPattern::SetMouseStyle(MouseFormat format)
1335 {
1336 auto host = GetHost();
1337 CHECK_NULL_VOID(host);
1338 auto pipeline = host->GetContext();
1339 CHECK_NULL_VOID(pipeline);
1340 auto windowId = pipeline->GetWindowId();
1341 auto mouseStyle = MouseStyle::CreateMouseStyle();
1342 CHECK_NULL_VOID(mouseStyle);
1343
1344 int32_t currentPointerStyle = 0;
1345 mouseStyle->GetPointerStyle(windowId, currentPointerStyle);
1346 if (currentPointerStyle != static_cast<int32_t>(format)) {
1347 mouseStyle->SetPointerStyle(windowId, format);
1348 }
1349 }
1350
HandleButtonMouseEvent(bool isHover,int32_t childId)1351 void SearchPattern::HandleButtonMouseEvent(bool isHover, int32_t childId)
1352 {
1353 if (childId == CANCEL_BUTTON_INDEX) {
1354 isCancelButtonHover_ = isHover;
1355 } else {
1356 isSearchButtonHover_ = isHover;
1357 }
1358 auto host = GetHost();
1359 CHECK_NULL_VOID(host);
1360 auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1361 CHECK_NULL_VOID(buttonFrameNode);
1362 auto renderContext = buttonFrameNode->GetRenderContext();
1363 CHECK_NULL_VOID(renderContext);
1364 if (isHover) {
1365 AnimateTouchAndHover(renderContext, 0.0f, HOVER_OPACITY, HOVER_DURATION, Curves::FRICTION);
1366 } else {
1367 AnimateTouchAndHover(renderContext, HOVER_OPACITY, 0.0f, HOVER_DURATION, Curves::FRICTION);
1368 }
1369 }
1370
AnimateTouchAndHover(RefPtr<RenderContext> & renderContext,float startOpacity,float endOpacity,int32_t duration,const RefPtr<Curve> & curve)1371 void SearchPattern::AnimateTouchAndHover(RefPtr<RenderContext>& renderContext, float startOpacity, float endOpacity,
1372 int32_t duration, const RefPtr<Curve>& curve)
1373 {
1374 auto context = GetContext();
1375 CHECK_NULL_VOID(context);
1376 auto colorMode = context->GetColorMode();
1377 Color touchColorFrom = Color::FromRGBO(0, 0, 0, startOpacity);
1378 Color touchColorTo = Color::FromRGBO(0, 0, 0, endOpacity);
1379 if (colorMode == ColorMode::DARK) {
1380 touchColorFrom = Color::FromRGBO(255, 255, 255, startOpacity);
1381 touchColorTo = Color::FromRGBO(255, 255, 255, endOpacity);
1382 }
1383 Color highlightStart = renderContext->GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(touchColorFrom);
1384 Color highlightEnd = renderContext->GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(touchColorTo);
1385 renderContext->OnBackgroundColorUpdate(highlightStart);
1386 AnimationOption option = AnimationOption();
1387 option.SetDuration(duration);
1388 option.SetCurve(curve);
1389 AnimationUtils::Animate(
1390 option, [renderContext, highlightEnd]() { renderContext->OnBackgroundColorUpdate(highlightEnd); }, nullptr,
1391 nullptr, Claim(context));
1392 }
1393
AnimateSearchTouchAndHover(RefPtr<RenderContext> & renderContext,Color & blendColorFrom,Color & blendColorTo,int32_t duration,const RefPtr<Curve> & curve)1394 void SearchPattern::AnimateSearchTouchAndHover(RefPtr<RenderContext>& renderContext,
1395 Color& blendColorFrom, Color& blendColorTo, int32_t duration, const RefPtr<Curve>& curve)
1396 {
1397 Color highlightStart = renderContext->GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColorFrom);
1398 Color highlightEnd = renderContext->GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColorTo);
1399 renderContext->OnBackgroundColorUpdate(highlightStart);
1400 AnimationOption option = AnimationOption();
1401 option.SetDuration(duration);
1402 option.SetCurve(curve);
1403 AnimationUtils::Animate(
1404 option, [renderContext, highlightEnd]() { renderContext->OnBackgroundColorUpdate(highlightEnd); }, nullptr,
1405 nullptr, Claim(GetContext()));
1406 }
1407
ResetDragOption()1408 void SearchPattern::ResetDragOption()
1409 {
1410 ClearButtonStyle(BUTTON_INDEX);
1411 ClearButtonStyle(CANCEL_BUTTON_INDEX);
1412 }
1413
ClearButtonStyle(int32_t childId)1414 void SearchPattern::ClearButtonStyle(int32_t childId)
1415 {
1416 auto host = GetHost();
1417 CHECK_NULL_VOID(host);
1418 auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1419 CHECK_NULL_VOID(buttonFrameNode);
1420 auto renderContext = buttonFrameNode->GetRenderContext();
1421 CHECK_NULL_VOID(renderContext);
1422 AnimateTouchAndHover(renderContext, TOUCH_OPACITY, 0.0f, HOVER_TO_TOUCH_DURATION, Curves::SHARP);
1423 }
1424
InitSearchTheme()1425 void SearchPattern::InitSearchTheme()
1426 {
1427 auto host = GetHost();
1428 CHECK_NULL_VOID(host);
1429 auto pipeline = host->GetContext();
1430 CHECK_NULL_VOID(pipeline);
1431 auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>(host->GetThemeScopeId());
1432 CHECK_NULL_VOID(textFieldTheme);
1433 searchNormalColor_ = textFieldTheme->GetBgColor();
1434 directionKeysMoveFocusOut_ = textFieldTheme->GetDirectionKeysMoveFocusOut();
1435 searchTheme_ = pipeline->GetTheme<SearchTheme>(host->GetThemeScopeId());
1436
1437 // 使用分层参数控制是否需要注册相关事件以适配悬浮态、按压态的变化
1438 auto hoverAndPressBgColorEnabled = textFieldTheme->GetHoverAndPressBgColorEnabled();
1439 if (hoverAndPressBgColorEnabled) {
1440 InitHoverEvent();
1441 InitTouchEvent();
1442 }
1443 }
1444
GetTheme() const1445 RefPtr<SearchTheme> SearchPattern::GetTheme() const
1446 {
1447 if (searchTheme_.Upgrade()) {
1448 return searchTheme_.Upgrade();
1449 }
1450 auto tmpHost = GetHost();
1451 CHECK_NULL_RETURN(tmpHost, nullptr);
1452 auto context = tmpHost->GetContext();
1453 CHECK_NULL_RETURN(context, nullptr);
1454 auto theme = context->GetTheme<SearchTheme>(tmpHost->GetThemeScopeId());
1455 return theme;
1456 }
1457
InitHoverEvent()1458 void SearchPattern::InitHoverEvent()
1459 {
1460 if (searchHoverListener_) {
1461 return;
1462 }
1463 auto host = GetHost();
1464 CHECK_NULL_VOID(host);
1465 auto eventHub = host->GetOrCreateEventHub<SearchEventHub>();
1466 auto inputHub = eventHub->GetOrCreateInputEventHub();
1467
1468 auto mouseTask = [weak = WeakClaim(this)](bool isHover) {
1469 auto pattern = weak.Upgrade();
1470 CHECK_NULL_VOID(pattern);
1471 pattern->HandleHoverEvent(isHover);
1472 };
1473 searchHoverListener_ = MakeRefPtr<InputEvent>(std::move(mouseTask));
1474 inputHub->AddOnHoverEvent(searchHoverListener_);
1475 }
1476
HandleHoverEvent(bool isHover)1477 void SearchPattern::HandleHoverEvent(bool isHover)
1478 {
1479 isSearchHover_ = isHover;
1480 auto host = GetHost();
1481 CHECK_NULL_VOID(host);
1482 auto eventHub = host->GetOrCreateEventHub<EventHub>();
1483 CHECK_NULL_VOID(eventHub);
1484 auto enabled = eventHub->IsEnabled();
1485 auto inputEventHub = host->GetOrCreateInputEventHub();
1486 auto hoverEffect = inputEventHub->GetHoverEffect();
1487 if (hoverEffect == HoverEffectType::NONE || hoverEffect == HoverEffectType::SCALE) {
1488 return;
1489 }
1490 if (!isSearchPress_ && (enabled || !isHover)) {
1491 auto renderContext = host->GetRenderContext();
1492 CHECK_NULL_VOID(renderContext);
1493 auto searchTheme = GetTheme();
1494 CHECK_NULL_VOID(searchTheme);
1495 auto searchHoverColor = searchTheme->GetHoverColor();
1496 AnimateSearchTouchAndHover(renderContext, isHover ? transparentColor_ : searchHoverColor,
1497 isHover ? searchHoverColor : transparentColor_, HOVER_DURATION, Curves::FRICTION);
1498 }
1499 }
1500
InitTouchEvent()1501 void SearchPattern::InitTouchEvent()
1502 {
1503 if (searchTouchListener_) {
1504 return;
1505 }
1506 auto host = GetHost();
1507 CHECK_NULL_VOID(host);
1508 auto gesture = host->GetOrCreateGestureEventHub();
1509 CHECK_NULL_VOID(gesture);
1510 auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
1511 auto pattern = weak.Upgrade();
1512 CHECK_NULL_VOID(pattern);
1513 auto infoTouches = info.GetTouches();
1514 CHECK_EQUAL_VOID(infoTouches.empty(), true);
1515 auto touchType = infoTouches.front().GetTouchType();
1516 if (touchType == TouchType::MOVE) {
1517 return;
1518 }
1519 pattern->OnTouchDownOrUp(touchType == TouchType::DOWN);
1520 };
1521 searchTouchListener_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
1522 gesture->AddTouchEvent(searchTouchListener_);
1523 }
1524
OnTouchDownOrUp(bool isDown)1525 void SearchPattern::OnTouchDownOrUp(bool isDown)
1526 {
1527 isSearchPress_ = isDown;
1528 auto host = GetHost();
1529 CHECK_NULL_VOID(host);
1530 auto searchEventHub = GetOrCreateEventHub<SearchEventHub>();
1531 CHECK_NULL_VOID(searchEventHub);
1532 auto renderContext = host->GetRenderContext();
1533 auto searchTheme = GetTheme();
1534 CHECK_NULL_VOID(searchTheme);
1535 auto searchTouchColor = searchTheme->GetTouchColor();
1536 AnimateSearchTouchAndHover(renderContext, isDown ? transparentColor_ : searchTouchColor,
1537 isDown ? searchTouchColor : transparentColor_, TOUCH_DURATION, Curves::FRICTION);
1538 }
1539
InitFocusEvent(const RefPtr<FocusHub> & focusHub)1540 void SearchPattern::InitFocusEvent(const RefPtr<FocusHub>& focusHub)
1541 {
1542 auto focusTask = [weak = WeakClaim(this)](FocusReason reason) {
1543 auto pattern = weak.Upgrade();
1544 if (!pattern) {
1545 return;
1546 }
1547 bool backwardFocusMovement = false;
1548 bool forwardFocusMovement = false;
1549 auto host = pattern->GetHost();
1550 if (host) {
1551 auto rootHub = host->GetOrCreateFocusHub()->GetRootFocusHub();
1552 backwardFocusMovement = rootHub && rootHub->HasBackwardFocusMovementInChildren();
1553 forwardFocusMovement = rootHub && rootHub->HasForwardFocusMovementInChildren();
1554 if (rootHub) {
1555 rootHub->ClearFocusMovementFlagsInChildren();
1556 }
1557 }
1558 pattern->HandleFocusEvent(forwardFocusMovement, backwardFocusMovement);
1559 };
1560 focusHub->SetOnFocusInternal(focusTask);
1561 auto blurTask = [weak = WeakClaim(this)]() {
1562 auto pattern = weak.Upgrade();
1563 CHECK_NULL_VOID(pattern);
1564 pattern->HandleBlurEvent();
1565 };
1566 focusHub->SetOnBlurInternal(blurTask);
1567 }
1568
HandleFocusEvent(bool forwardFocusMovement,bool backwardFocusMovement)1569 void SearchPattern::HandleFocusEvent(bool forwardFocusMovement, bool backwardFocusMovement)
1570 {
1571 auto host = GetHost();
1572 CHECK_NULL_VOID(host);
1573 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1574 CHECK_NULL_VOID(textFieldFrameNode);
1575 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1576 CHECK_NULL_VOID(textFieldPattern);
1577 textFieldPattern->SetIsFocusedBeforeClick(true);
1578
1579 focusChoice_ = FocusChoice::SEARCH;
1580 if (forwardFocusMovement || backwardFocusMovement) { // Don't update focus if no factical focus movement
1581 focusChoice_ = backwardFocusMovement ? FocusChoice::SEARCH_BUTTON : FocusChoice::SEARCH;
1582 if (focusChoice_ == FocusChoice::SEARCH_BUTTON && !isSearchButtonEnabled_) {
1583 bool isCancelHidden = NearZero(cancelButtonSize_.Height());
1584 focusChoice_ = isCancelHidden ? FocusChoice::SEARCH : FocusChoice::CANCEL_BUTTON;
1585 }
1586 }
1587 PaintFocusState(!(forwardFocusMovement || backwardFocusMovement));
1588 }
1589
HandleBlurEvent()1590 void SearchPattern::HandleBlurEvent()
1591 {
1592 auto host = GetHost();
1593 CHECK_NULL_VOID(host);
1594 auto searchTheme = GetTheme();
1595 CHECK_NULL_VOID(searchTheme);
1596 // 失焦时判断是否进行了获焦反色,恢复默认态
1597 if (isFocusBgColorSet_) {
1598 auto renderContext = host->GetRenderContext();
1599 CHECK_NULL_VOID(renderContext);
1600 renderContext->UpdateBackgroundColor(searchNormalColor_);
1601 isFocusBgColorSet_ = false;
1602 }
1603 if (isFocusIconColorSet_) {
1604 SetSymbolSearchIconColor(searchTheme->GetSymbolIconColor());
1605 isFocusIconColorSet_ = false;
1606 }
1607 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1608 CHECK_NULL_VOID(textFieldFrameNode);
1609 auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
1610 CHECK_NULL_VOID(textFieldLayoutProperty);
1611 auto textFieldPaintProperty = textFieldFrameNode->GetPaintProperty<TextFieldPaintProperty>();
1612 CHECK_NULL_VOID(textFieldPaintProperty);
1613 if (isFocusTextColorSet_ && !textFieldPaintProperty->HasTextColorFlagByUser()) {
1614 textFieldLayoutProperty->UpdateTextColor(searchTheme->GetTextColor());
1615 }
1616 if (isFocusPlaceholderColorSet_ && !textFieldPaintProperty->GetPlaceholderColorFlagByUserValue(false)) {
1617 textFieldLayoutProperty->UpdatePlaceholderTextColor(searchTheme->GetPlaceholderColor());
1618 }
1619 isFocusTextColorSet_ = false;
1620 isFocusPlaceholderColorSet_ = false;
1621 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1622 CHECK_NULL_VOID(textFieldPattern);
1623 textFieldPattern->HandleBlurEvent();
1624 BorderWidthProperty borderWidth;
1625 borderWidth.SetBorderWidth(SEARCH_TEXTINPUT_BORDER_WIDTH);
1626 textFieldLayoutProperty->UpdateBorderWidth(borderWidth);
1627 }
1628
InitClickEvent()1629 void SearchPattern::InitClickEvent()
1630 {
1631 if (clickListener_) {
1632 return;
1633 }
1634 auto host = GetHost();
1635 CHECK_NULL_VOID(host);
1636 auto gesture = host->GetOrCreateGestureEventHub();
1637 CHECK_NULL_VOID(gesture);
1638 auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
1639 auto pattern = weak.Upgrade();
1640 CHECK_NULL_VOID(pattern);
1641 pattern->HandleClickEvent(info);
1642 };
1643 clickListener_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
1644 gesture->AddClickEvent(clickListener_);
1645 }
1646
HandleClickEvent(GestureEvent & info)1647 void SearchPattern::HandleClickEvent(GestureEvent& info)
1648 {
1649 auto host = GetHost();
1650 CHECK_NULL_VOID(host);
1651 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1652 CHECK_NULL_VOID(textFieldFrameNode);
1653 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1654 CHECK_NULL_VOID(textFieldPattern);
1655 auto textFieldGeometryNode = textFieldFrameNode->GetGeometryNode();
1656 CHECK_NULL_VOID(textFieldGeometryNode);
1657 auto textFieldFrameRect = textFieldGeometryNode->GetFrameRect();
1658 auto relTextFieldLocalLocation = Offset(info.GetLocalLocation().GetX() - textFieldFrameRect.GetX(),
1659 info.GetLocalLocation().GetY() - textFieldFrameRect.GetY());
1660 info.SetLocalLocation(relTextFieldLocalLocation);
1661 textFieldPattern->HandleClickEvent(info);
1662 }
1663
HandleInputChildOnFocus() const1664 bool SearchPattern::HandleInputChildOnFocus() const
1665 {
1666 #if !defined(PREVIEW)
1667 return false;
1668 #endif
1669 auto focusHub = GetHost()->GetOrCreateFocusHub();
1670 focusHub->RequestFocusImmediately();
1671 return true;
1672 }
1673
ToJsonValueForTextField(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1674 void SearchPattern::ToJsonValueForTextField(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1675 {
1676 /* no fixed attr below, just return */
1677 if (filter.IsFastFilter()) {
1678 return;
1679 }
1680 auto host = GetHost();
1681 CHECK_NULL_VOID(host);
1682 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1683 CHECK_NULL_VOID(textFieldFrameNode);
1684 auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
1685 CHECK_NULL_VOID(textFieldLayoutProperty);
1686 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1687 CHECK_NULL_VOID(textFieldPattern);
1688 auto searchTheme = GetTheme();
1689 CHECK_NULL_VOID(searchTheme);
1690 auto searchTextFieldPattern = DynamicCast<SearchTextFieldPattern>(textFieldPattern);
1691 CHECK_NULL_VOID(searchTextFieldPattern);
1692
1693 json->PutExtAttr("value", textFieldPattern->GetTextValue().c_str(), filter);
1694 json->PutExtAttr("placeholder", UtfUtils::Str16DebugToStr8(textFieldPattern->GetPlaceHolder()).c_str(), filter);
1695 json->PutExtAttr("placeholderColor",
1696 textFieldLayoutProperty->GetPlaceholderTextColorValue(searchTheme->GetPlaceholderColor())
1697 .ColorToString()
1698 .c_str(),
1699 filter);
1700 json->PutExtAttr("placeholderFont", searchTextFieldPattern->GetPlaceholderFont().c_str(), filter);
1701 json->PutExtAttr("textAlign", V2::ConvertWrapTextAlignToString(textFieldPattern->GetTextAlign()).c_str(), filter);
1702 auto textColor = textFieldLayoutProperty->GetTextColor().value_or(searchTheme->GetTextColor());
1703 json->PutExtAttr("fontColor", textColor.ColorToString().c_str(), filter);
1704 auto textFontJson = JsonUtil::Create(true);
1705 textFontJson->Put(
1706 "fontSize", textFieldLayoutProperty->GetFontSizeValue(searchTheme->GetFontSize()).ToString().c_str());
1707 textFontJson->Put("fontStyle",
1708 textFieldPattern->GetItalicFontStyle() == Ace::FontStyle::NORMAL ? "FontStyle.Normal" : "FontStyle.Italic");
1709 textFontJson->Put("fontWeight", V2::ConvertWrapFontWeightToStirng(textFieldPattern->GetFontWeight()).c_str());
1710 textFontJson->Put("fontFamily", textFieldPattern->GetFontFamily().c_str());
1711 json->PutExtAttr("textFont", textFontJson->ToString().c_str(), filter);
1712 json->PutExtAttr("copyOption",
1713 ConvertCopyOptionsToString(textFieldLayoutProperty->GetCopyOptionsValue(CopyOptions::Local)).c_str(), filter);
1714 auto maxLength = GetMaxLength();
1715 json->PutExtAttr(
1716 "maxLength", GreatOrEqual(maxLength, Infinity<uint32_t>()) ? "INF" : std::to_string(maxLength).c_str(), filter);
1717 json->PutExtAttr("type", SearchTypeToString().c_str(), filter);
1718 textFieldLayoutProperty->HasCopyOptions();
1719 json->PutExtAttr(
1720 "letterSpacing", textFieldLayoutProperty->GetLetterSpacing().value_or(Dimension()).ToString().c_str(), filter);
1721 json->PutExtAttr(
1722 "lineHeight", textFieldLayoutProperty->GetLineHeight().value_or(0.0_vp).ToString().c_str(), filter);
1723 json->PutExtAttr("halfLeading", textFieldLayoutProperty->GetHalfLeading().value_or(false), filter);
1724 auto jsonDecoration = JsonUtil::Create(true);
1725 std::string type = V2::ConvertWrapTextDecorationToStirng(
1726 textFieldLayoutProperty->GetTextDecoration().value_or(std::vector<TextDecoration>({TextDecoration::NONE})));
1727 jsonDecoration->Put("type", type.c_str());
1728 jsonDecoration->Put(
1729 "color", textFieldLayoutProperty->GetTextDecorationColor().value_or(Color::BLACK).ColorToString().c_str());
1730 std::string style = V2::ConvertWrapTextDecorationStyleToString(
1731 textFieldLayoutProperty->GetTextDecorationStyle().value_or(TextDecorationStyle::SOLID));
1732 jsonDecoration->Put("style", style.c_str());
1733 json->PutExtAttr("decoration", jsonDecoration->ToString().c_str(), filter);
1734 json->PutExtAttr(
1735 "minFontSize", textFieldLayoutProperty->GetAdaptMinFontSize().value_or(Dimension()).ToString().c_str(), filter);
1736 json->PutExtAttr(
1737 "maxFontSize", textFieldLayoutProperty->GetAdaptMaxFontSize().value_or(Dimension()).ToString().c_str(), filter);
1738 json->PutExtAttr(
1739 "minFontScale", std::to_string(textFieldLayoutProperty->GetMinFontScale().value_or(0.0f)).c_str(), filter);
1740 json->PutExtAttr(
1741 "maxFontScale", std::to_string(textFieldLayoutProperty->GetMaxFontScale().value_or(
1742 static_cast<float>(INT32_MAX))).c_str(), filter);
1743 json->PutExtAttr("inputFilter", textFieldLayoutProperty->GetInputFilterValue("").c_str(), filter);
1744 json->PutExtAttr(
1745 "textIndent", textFieldLayoutProperty->GetTextIndent().value_or(0.0_vp).ToString().c_str(), filter);
1746 json->PutExtAttr("enablePreviewText", textFieldPattern->GetSupportPreviewText(), filter);
1747 textFieldPattern->ToJsonValueSelectOverlay(json, filter);
1748 json->PutExtAttr("stopBackPress", textFieldLayoutProperty->GetStopBackPressValue(true), filter);
1749 json->PutExtAttr("keyboardAppearance", static_cast<int32_t>(textFieldPattern->GetKeyboardAppearance()), filter);
1750 json->PutExtAttr("enableHapticFeedback", textFieldPattern->GetEnableHapticFeedback() ? "true" : "false", filter);
1751 json->PutExtAttr("autoCapitalizationMode", textFieldPattern->AutoCapTypeToString().c_str(), filter);
1752 textFieldPattern->ToJsonValueForStroke(json, filter);
1753 json->PutExtAttr("enableAutoSpacing", std::to_string(
1754 textFieldLayoutProperty->GetEnableAutoSpacing().value_or(false)).c_str(), filter);
1755 }
1756
SearchTypeToString() const1757 std::string SearchPattern::SearchTypeToString() const
1758 {
1759 auto host = GetHost();
1760 CHECK_NULL_RETURN(host, "");
1761 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1762 CHECK_NULL_RETURN(textFieldFrameNode, "");
1763 auto layoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
1764 CHECK_NULL_RETURN(layoutProperty, "");
1765 switch (layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED)) {
1766 case TextInputType::NUMBER:
1767 return "SearchType.NUMBER";
1768 case TextInputType::EMAIL_ADDRESS:
1769 return "SearchType.EMAIL";
1770 case TextInputType::PHONE:
1771 return "SearchType.PHONE_NUMBER";
1772 case TextInputType::URL:
1773 return "SearchType.URL";
1774 case TextInputType::NUMBER_DECIMAL:
1775 return "SearchType.NUMBER_DECIMAL";
1776 case TextInputType::ONE_TIME_CODE:
1777 return "SearchType.ONE_TIME_CODE";
1778 default:
1779 return "SearchType.NORMAL";
1780 }
1781 }
1782
ToJsonValueForSearchIcon(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1783 void SearchPattern::ToJsonValueForSearchIcon(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1784 {
1785 /* no fixed attr below, just return */
1786 if (filter.IsFastFilter()) {
1787 return;
1788 }
1789 auto host = GetHost();
1790 CHECK_NULL_VOID(host);
1791 auto searchIconFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(IMAGE_INDEX));
1792 CHECK_NULL_VOID(searchIconFrameNode);
1793 auto searchIconJson = JsonUtil::Create(true);
1794
1795 // icon size
1796 auto searchIconGeometryNode = searchIconFrameNode->GetGeometryNode();
1797 CHECK_NULL_VOID(searchIconGeometryNode);
1798 auto searchIconFrameSize = searchIconGeometryNode->GetFrameSize().Width();
1799 auto searchLayoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
1800 CHECK_NULL_VOID(searchLayoutProperty);
1801 auto searchIconSize = searchLayoutProperty->GetSearchIconUDSizeValue(Dimension(searchIconFrameSize)).ConvertToPx();
1802 searchIconJson->Put("size", Dimension(searchIconSize, DimensionUnit::PX).ToString().c_str());
1803
1804 if (searchIconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
1805 auto symbolLayoutProperty = searchIconFrameNode->GetLayoutProperty<TextLayoutProperty>();
1806 CHECK_NULL_VOID(symbolLayoutProperty);
1807 // icon color
1808 auto searchIconColor = symbolLayoutProperty->GetSymbolColorList();
1809 if (searchIconColor.has_value()) {
1810 searchIconJson->Put("color", SymbolColorToString(searchIconColor.value()).c_str());
1811 } else {
1812 searchIconJson->Put("color", std::string("").c_str());
1813 }
1814
1815 // icon path
1816 auto symbolSourceInfo = symbolLayoutProperty->GetSymbolSourceInfo().value_or(SymbolSourceInfo());
1817 searchIconJson->Put("src", static_cast<int64_t>(symbolSourceInfo.GetUnicode()));
1818 json->PutExtAttr("icon", static_cast<int64_t>(symbolSourceInfo.GetUnicode()), filter);
1819 json->PutExtAttr("searchIcon", searchIconJson, filter);
1820 } else {
1821 auto imageLayoutProperty = searchIconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
1822 CHECK_NULL_VOID(imageLayoutProperty);
1823 // icon color
1824 auto searchIconColor = imageLayoutProperty->GetImageSourceInfo()->GetFillColor().value_or(Color());
1825 searchIconJson->Put("color", searchIconColor.ColorToString().c_str());
1826
1827 // icon path
1828 auto searchIconPath = imageLayoutProperty->GetImageSourceInfo()->GetSrc();
1829 searchIconJson->Put("src", searchIconPath.c_str());
1830 json->PutExtAttr("icon", searchIconPath.c_str(), filter);
1831 json->PutExtAttr("searchIcon", searchIconJson, filter);
1832 }
1833 }
1834
ToJsonValueForCancelButton(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1835 void SearchPattern::ToJsonValueForCancelButton(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1836 {
1837 /* no fixed attr below, just return */
1838 if (filter.IsFastFilter()) {
1839 return;
1840 }
1841 auto host = GetHost();
1842 CHECK_NULL_VOID(host);
1843 auto layoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
1844 CHECK_NULL_VOID(layoutProperty);
1845 auto cancelImageFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(CANCEL_IMAGE_INDEX));
1846 CHECK_NULL_VOID(cancelImageFrameNode);
1847 auto cancelButtonJson = JsonUtil::Create(true);
1848 ToJsonValueForCancelButtonStyle(
1849 cancelButtonJson, layoutProperty->GetCancelButtonStyle().value_or(CancelButtonStyle::INPUT));
1850 auto cancelIconJson = JsonUtil::Create(true);
1851 // icon size
1852 auto cancelIconGeometryNode = cancelImageFrameNode->GetGeometryNode();
1853 CHECK_NULL_VOID(cancelIconGeometryNode);
1854 auto cancelIconFrameSize = cancelIconGeometryNode->GetFrameSize().Width();
1855 auto searchLayoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
1856 CHECK_NULL_VOID(searchLayoutProperty);
1857 auto cancelIconSize =
1858 searchLayoutProperty->GetCancelButtonUDSizeValue(Dimension(cancelIconFrameSize)).ConvertToPx();
1859 cancelIconJson->Put("size", Dimension(cancelIconSize, DimensionUnit::PX).ToString().c_str());
1860 if (cancelImageFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
1861 auto symbolLayoutProperty = cancelImageFrameNode->GetLayoutProperty<TextLayoutProperty>();
1862 CHECK_NULL_VOID(symbolLayoutProperty);
1863 // icon color & right icon src path
1864 auto searchIconColor = symbolLayoutProperty->GetSymbolColorList();
1865 if (searchIconColor.has_value()) {
1866 cancelIconJson->Put("color", SymbolColorToString(searchIconColor.value()).c_str());
1867 } else {
1868 cancelIconJson->Put("color", std::string("").c_str());
1869 }
1870 auto symbolSourceInfo = symbolLayoutProperty->GetSymbolSourceInfo().value_or(SymbolSourceInfo());
1871 cancelIconJson->Put("src", static_cast<int64_t>(symbolSourceInfo.GetUnicode()));
1872 cancelButtonJson->Put("icon", cancelIconJson);
1873 json->PutExtAttr("cancelButton", cancelButtonJson, filter);
1874 } else {
1875 auto cancelImageLayoutProperty = cancelImageFrameNode->GetLayoutProperty<ImageLayoutProperty>();
1876 CHECK_NULL_VOID(cancelImageLayoutProperty);
1877 // icon color
1878 auto cancelImageRenderProperty = cancelImageFrameNode->GetPaintProperty<ImageRenderProperty>();
1879 CHECK_NULL_VOID(cancelImageRenderProperty);
1880 auto cancelIconColor = cancelImageRenderProperty->GetSvgFillColor().value_or(Color());
1881 cancelIconJson->Put("color", cancelIconColor.ColorToString().c_str());
1882 // right icon src path
1883 auto cancelImageSrc = cancelImageLayoutProperty->GetImageSourceInfo()->GetSrc();
1884 cancelIconJson->Put("src", cancelImageSrc.c_str());
1885 cancelButtonJson->Put("icon", cancelIconJson);
1886 json->PutExtAttr("cancelButton", cancelButtonJson, filter);
1887 }
1888 }
1889
ToJsonValueForSearchButtonOption(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1890 void SearchPattern::ToJsonValueForSearchButtonOption(
1891 std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1892 {
1893 /* no fixed attr below, just return */
1894 if (filter.IsFastFilter()) {
1895 return;
1896 }
1897 auto host = GetHost();
1898 CHECK_NULL_VOID(host);
1899 auto searchButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(BUTTON_INDEX));
1900 CHECK_NULL_VOID(searchButtonFrameNode);
1901 auto searchButtonLayoutProperty = searchButtonFrameNode->GetLayoutProperty<ButtonLayoutProperty>();
1902 CHECK_NULL_VOID(searchButtonLayoutProperty);
1903 auto searchTheme = GetTheme();
1904 CHECK_NULL_VOID(searchTheme);
1905 auto searchButtonJson = JsonUtil::Create(true);
1906
1907 // font size
1908 auto searchButtonFontSize = searchButtonLayoutProperty->GetFontSize().value_or(Dimension(0, DimensionUnit::VP));
1909 searchButtonJson->Put("fontSize", searchButtonFontSize.ToString().c_str());
1910
1911 // font color
1912 auto searchButtonFontColor = searchButtonLayoutProperty->GetFontColor().value_or(
1913 searchTheme->GetSearchButtonTextColor());
1914 searchButtonJson->Put("fontColor", searchButtonFontColor.ColorToString().c_str());
1915 auto searchButtonAutoDisable = searchButtonLayoutProperty->GetAutoDisable().value_or(false);
1916 searchButtonJson->Put("autoDisable", searchButtonAutoDisable);
1917 json->PutExtAttr("searchButtonOption", searchButtonJson, filter);
1918 }
1919
ToJsonValueForCursor(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1920 void SearchPattern::ToJsonValueForCursor(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1921 {
1922 /* no fixed attr below, just return */
1923 if (filter.IsFastFilter()) {
1924 return;
1925 }
1926 auto host = GetHost();
1927 CHECK_NULL_VOID(host);
1928 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1929 CHECK_NULL_VOID(textFieldFrameNode);
1930 auto textFieldPaintProperty = textFieldFrameNode->GetPaintProperty<TextFieldPaintProperty>();
1931 CHECK_NULL_VOID(textFieldPaintProperty);
1932 auto pipeline = host->GetContext();
1933 CHECK_NULL_VOID(pipeline);
1934 auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>(host->GetThemeScopeId());
1935 CHECK_NULL_VOID(textFieldTheme);
1936 auto cursorJson = JsonUtil::Create(true);
1937
1938 // color
1939 auto caretColor = textFieldPaintProperty->GetCursorColor().value_or(textFieldTheme->GetCursorColor());
1940 cursorJson->Put("color", caretColor.ColorToString().c_str());
1941 auto caretWidth = textFieldPaintProperty->GetCursorWidth().value_or(Dimension(0, DimensionUnit::VP));
1942 cursorJson->Put("width", caretWidth.ToString().c_str());
1943 json->PutExtAttr("caretStyle", cursorJson, filter);
1944 auto selectedBackgroundColor = textFieldPaintProperty->GetSelectedBackgroundColor().value_or(Color());
1945 json->PutExtAttr("selectedBackgroundColor", selectedBackgroundColor.ColorToString().c_str(), filter);
1946 }
1947
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1948 void SearchPattern::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1949 {
1950 Pattern::ToJsonValue(json, filter);
1951
1952 ToJsonValueForTextField(json, filter);
1953 ToJsonValueForSearchIcon(json, filter);
1954 ToJsonValueForCancelButton(json, filter);
1955 ToJsonValueForCursor(json, filter);
1956 ToJsonValueForSearchButtonOption(json, filter);
1957 }
1958
UpdateDividerColorMode()1959 void SearchPattern::UpdateDividerColorMode()
1960 {
1961 auto host = GetHost();
1962 CHECK_NULL_VOID(host);
1963 auto dividerFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(DIVIDER_INDEX));
1964 CHECK_NULL_VOID(dividerFrameNode);
1965 auto searchTheme = GetTheme();
1966 CHECK_NULL_VOID(searchTheme);
1967 auto searchDividerColor = searchTheme->GetSearchDividerColor();
1968 auto dividerRenderProperty = dividerFrameNode->GetPaintProperty<DividerRenderProperty>();
1969 CHECK_NULL_VOID(dividerRenderProperty);
1970 dividerRenderProperty->UpdateDividerColor(searchDividerColor);
1971 dividerFrameNode->MarkModifyDone();
1972 dividerFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1973 }
1974
UpdateCancelButtonColorMode()1975 void SearchPattern::UpdateCancelButtonColorMode()
1976 {
1977 auto cancelButtonNode = cancelButtonNode_.Upgrade();
1978 CHECK_NULL_VOID(cancelButtonNode);
1979 auto searchTheme = GetTheme();
1980 CHECK_NULL_VOID(searchTheme);
1981 auto cancelButtonRenderContext = cancelButtonNode->GetRenderContext();
1982 CHECK_NULL_VOID(cancelButtonRenderContext);
1983 cancelButtonRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
1984 auto textFrameNode = AceType::DynamicCast<FrameNode>(cancelButtonNode->GetChildren().front());
1985 CHECK_NULL_VOID(textFrameNode);
1986 auto textLayoutProperty = textFrameNode->GetLayoutProperty<TextLayoutProperty>();
1987 CHECK_NULL_VOID(textLayoutProperty);
1988 auto buttonLayoutProperty = cancelButtonNode->GetLayoutProperty<ButtonLayoutProperty>();
1989 CHECK_NULL_VOID(buttonLayoutProperty);
1990 if (!buttonLayoutProperty->HasFontColor()) {
1991 textLayoutProperty->UpdateTextColor(searchTheme->GetSearchButtonTextColor());
1992 }
1993 cancelButtonNode->MarkModifyDone();
1994 cancelButtonNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1995 }
1996
OnColorConfigurationUpdate()1997 void SearchPattern::OnColorConfigurationUpdate()
1998 {
1999 auto host = GetHost();
2000 CHECK_NULL_VOID(host);
2001 host->SetNeedCallChildrenUpdate(false);
2002 auto pipeline = host->GetContext();
2003 CHECK_NULL_VOID(pipeline);
2004 auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>(host->GetThemeScopeId());
2005 CHECK_NULL_VOID(textFieldTheme);
2006 auto renderContext = host->GetRenderContext();
2007 CHECK_NULL_VOID(renderContext);
2008 auto searchTheme = GetTheme();
2009 CHECK_NULL_VOID(searchTheme);
2010 UpdateCancelButtonColorMode();
2011 if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE) ||
2012 !SystemProperties::IsNeedSymbol()) {
2013 UpdateImageIconNode(IMAGE_INDEX);
2014 UpdateImageIconNode(CANCEL_IMAGE_INDEX);
2015 }
2016 auto buttonNode = buttonNode_.Upgrade();
2017 if (buttonNode) {
2018 auto buttonRenderContext = buttonNode->GetRenderContext();
2019 CHECK_NULL_VOID(buttonRenderContext);
2020 buttonRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
2021 auto textFrameNode = AceType::DynamicCast<FrameNode>(buttonNode->GetChildren().front());
2022 CHECK_NULL_VOID(textFrameNode);
2023 auto textLayoutProperty = textFrameNode->GetLayoutProperty<TextLayoutProperty>();
2024 CHECK_NULL_VOID(textLayoutProperty);
2025 auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
2026 CHECK_NULL_VOID(buttonLayoutProperty);
2027 if (!buttonLayoutProperty->HasFontColor()) {
2028 textLayoutProperty->UpdateTextColor(searchTheme->GetSearchButtonTextColor());
2029 }
2030 buttonNode->MarkModifyDone();
2031 buttonNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2032 }
2033 auto textField = textField_.Upgrade();
2034 if (textField) {
2035 auto textFieldLayoutProperty = textField->GetLayoutProperty<TextFieldLayoutProperty>();
2036 CHECK_NULL_VOID(textFieldLayoutProperty);
2037 textFieldLayoutProperty->UpdateTextColor(searchTheme->GetTextColor());
2038 textFieldLayoutProperty->UpdatePlaceholderTextColor(searchTheme->GetPlaceholderColor());
2039 textField->MarkModifyDone();
2040 textField->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2041 }
2042 UpdateDividerColorMode();
2043 }
2044
OnThemeScopeUpdate(int32_t themeScopeId)2045 bool SearchPattern::OnThemeScopeUpdate(int32_t themeScopeId)
2046 {
2047 auto result = false;
2048 auto host = GetHost();
2049 CHECK_NULL_RETURN(host, result);
2050
2051 auto pipeline = host->GetContext();
2052 CHECK_NULL_RETURN(pipeline, result);
2053 // need to get theme according to theme scope id to update searchTheme_ and searchNormalColor_
2054 auto searchTheme = pipeline->GetTheme<SearchTheme>(themeScopeId);
2055 CHECK_NULL_RETURN(searchTheme, result);
2056 auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>(themeScopeId);
2057 CHECK_NULL_RETURN(textFieldTheme, result);
2058 searchTheme_ = searchTheme; // update searchTheme_
2059 searchNormalColor_ = textFieldTheme->GetBgColor(); // update searchNormalColor_
2060
2061 if (!ButtonNodeOnThemeScopeUpdate(searchTheme)) {
2062 return result;
2063 }
2064
2065 if (!IconNodeOnThemeScopeUpdate(searchTheme)) {
2066 return result;
2067 }
2068
2069 HandleBackgroundColor();
2070 UpdateDividerColorMode();
2071
2072 TextNodeOnThemeScopeUpdate(searchTheme, textFieldTheme);
2073
2074 return result;
2075 }
2076
ButtonNodeOnThemeScopeUpdate(const RefPtr<SearchTheme> & searchTheme)2077 bool SearchPattern::ButtonNodeOnThemeScopeUpdate(const RefPtr<SearchTheme>& searchTheme)
2078 {
2079 CHECK_NULL_RETURN(searchTheme, false);
2080 auto buttonNode = buttonNode_.Upgrade();
2081 if (buttonNode) {
2082 auto textFrameNode = AceType::DynamicCast<FrameNode>(buttonNode->GetChildren().front());
2083 CHECK_NULL_RETURN(textFrameNode, false);
2084 auto textLayoutProperty = textFrameNode->GetLayoutProperty<TextLayoutProperty>();
2085 CHECK_NULL_RETURN(textLayoutProperty, false);
2086 auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
2087 CHECK_NULL_RETURN(buttonLayoutProperty, false);
2088
2089 if (!buttonLayoutProperty->HasFontColor()) {
2090 textLayoutProperty->UpdateTextColor(searchTheme->GetSearchButtonTextColor());
2091 buttonNode->MarkModifyDone();
2092 buttonNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2093 }
2094 }
2095 return true;
2096 }
2097
IconNodeOnThemeScopeUpdate(const RefPtr<SearchTheme> & searchTheme)2098 bool SearchPattern::IconNodeOnThemeScopeUpdate(const RefPtr<SearchTheme>& searchTheme)
2099 {
2100 CHECK_NULL_RETURN(searchTheme, false);
2101 auto host = GetHost();
2102 CHECK_NULL_RETURN(host, false);
2103 auto iconFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildAtIndex(IMAGE_INDEX));
2104 CHECK_NULL_RETURN(iconFrameNode, false);
2105 auto cancelIconFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildAtIndex(CANCEL_IMAGE_INDEX));
2106 CHECK_NULL_RETURN(cancelIconFrameNode, false);
2107 auto searchLayoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
2108 CHECK_NULL_RETURN(searchLayoutProperty, false);
2109
2110 auto iconColor = Color(iconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG ?
2111 searchTheme->GetSymbolIconColor() : searchTheme->GetSearchIconColor());
2112 if (!searchLayoutProperty->HasSearchIconColor()) {
2113 SetSearchIconColor(iconColor);
2114 }
2115 auto cancelIconColor = Color(cancelIconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG ?
2116 searchTheme->GetSymbolIconColor() : searchTheme->GetSearchIconColor());
2117 if (!searchLayoutProperty->HasCancelIconColor()) {
2118 SetCancelIconColor(cancelIconColor);
2119 }
2120 return true;
2121 }
2122
TextNodeOnThemeScopeUpdate(const RefPtr<SearchTheme> & searchTheme,const RefPtr<TextFieldTheme> & textFieldTheme)2123 bool SearchPattern::TextNodeOnThemeScopeUpdate(const RefPtr<SearchTheme>& searchTheme,
2124 const RefPtr<TextFieldTheme>& textFieldTheme)
2125 {
2126 CHECK_NULL_RETURN(searchTheme, false);
2127 CHECK_NULL_RETURN(textFieldTheme, false);
2128 auto textField = textField_.Upgrade();
2129 if (textField) {
2130 auto needUpdateNode = false;
2131 auto textFieldLayoutProperty = textField->GetLayoutProperty<TextFieldLayoutProperty>();
2132 CHECK_NULL_RETURN(textFieldLayoutProperty, false);
2133 auto textPaintProperty = textField->GetPaintProperty<TextFieldPaintProperty>();
2134 CHECK_NULL_RETURN(textPaintProperty, false);
2135
2136 if (!textPaintProperty->HasTextColorFlagByUser()) {
2137 textFieldLayoutProperty->UpdateTextColor(searchTheme->GetTextColor());
2138 needUpdateNode = true;
2139 }
2140
2141 if (!textPaintProperty->HasPlaceholderColorFlagByUser()) {
2142 textFieldLayoutProperty->UpdatePlaceholderTextColor(searchTheme->GetPlaceholderColor());
2143 needUpdateNode = true;
2144 }
2145
2146 if (!textPaintProperty->HasCaretColorFlagByUser()) {
2147 textPaintProperty->UpdateCursorColor(textFieldTheme->GetCursorColor());
2148 textField->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
2149 }
2150
2151 if (needUpdateNode) {
2152 textField->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2153 }
2154 }
2155 return true;
2156 }
2157
GetMaxLength() const2158 uint32_t SearchPattern::GetMaxLength() const
2159 {
2160 auto host = GetHost();
2161 CHECK_NULL_RETURN(host, Infinity<uint32_t>());
2162 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
2163 CHECK_NULL_RETURN(textFieldFrameNode, Infinity<uint32_t>());
2164 auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
2165 CHECK_NULL_RETURN(textFieldLayoutProperty, Infinity<uint32_t>());
2166 return textFieldLayoutProperty->HasMaxLength() ? textFieldLayoutProperty->GetMaxLengthValue(Infinity<uint32_t>())
2167 : Infinity<uint32_t>();
2168 }
2169
ToJsonValueForCancelButtonStyle(std::unique_ptr<JsonValue> & cancelButtonJson,const CancelButtonStyle & cancelButtonStyle) const2170 void SearchPattern::ToJsonValueForCancelButtonStyle(
2171 std::unique_ptr<JsonValue>& cancelButtonJson, const CancelButtonStyle& cancelButtonStyle) const
2172 {
2173 if (cancelButtonStyle == CancelButtonStyle::CONSTANT) {
2174 cancelButtonJson->Put("style", "CancelButtonStyle.CONSTANT");
2175 } else if (cancelButtonStyle == CancelButtonStyle::INVISIBLE) {
2176 cancelButtonJson->Put("style", "CancelButtonStyle.INVISIBLE");
2177 } else {
2178 cancelButtonJson->Put("style", "CancelButtonStyle.INPUT");
2179 }
2180 }
2181
SymbolColorToString(std::vector<Color> & colors) const2182 std::string SearchPattern::SymbolColorToString(std::vector<Color>& colors) const
2183 {
2184 if (colors.size() <= 0) {
2185 return "";
2186 }
2187 auto colorStr = std::string("[");
2188 for (auto color : colors) {
2189 colorStr.append(color.ColorToString());
2190 colorStr.append(",");
2191 }
2192 colorStr.append("]");
2193 return colorStr;
2194 }
2195
InitIconColorSize()2196 void SearchPattern::InitIconColorSize()
2197 {
2198 InitSearchIconColorSize();
2199 InitCancelIconColorSize();
2200 }
2201
InitSearchIconColorSize()2202 void SearchPattern::InitSearchIconColorSize()
2203 {
2204 auto searchTheme = GetTheme();
2205 CHECK_NULL_VOID(searchTheme);
2206 GetSearchNode()->SetSearchSymbolIconColor(Color(searchTheme->GetSymbolIconColor()));
2207 GetSearchNode()->SetSearchSymbolIconSize(searchTheme->GetSymbolIconHeight());
2208 GetSearchNode()->SetSearchImageIconColor(Color(searchTheme->GetSearchIconColor()));
2209 GetSearchNode()->SetSearchImageIconSize(searchTheme->GetIconHeight());
2210 }
2211
InitCancelIconColorSize()2212 void SearchPattern::InitCancelIconColorSize()
2213 {
2214 auto searchTheme = GetTheme();
2215 CHECK_NULL_VOID(searchTheme);
2216 GetSearchNode()->SetCancelSymbolIconColor(Color(searchTheme->GetSymbolIconColor()));
2217 GetSearchNode()->SetCancelSymbolIconSize(SYMBOL_ICON_HEIGHT);
2218 GetSearchNode()->SetCancelImageIconColor(Color(searchTheme->GetSearchIconColor()));
2219 GetSearchNode()->SetCancelImageIconSize(searchTheme->GetIconHeight());
2220 }
2221
CreateSearchIcon(const std::string & src,bool forceUpdate)2222 void SearchPattern::CreateSearchIcon(const std::string& src, bool forceUpdate)
2223 {
2224 CHECK_NULL_VOID(GetSearchNode());
2225 if (GetSearchNode()->HasSearchIconNodeCreated() && !forceUpdate) {
2226 UpdateSearchSymbolIconColor();
2227 return;
2228 }
2229 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) &&
2230 src.empty() && SystemProperties::IsNeedSymbol()) {
2231 CreateOrUpdateSymbol(IMAGE_INDEX, !GetSearchNode()->HasSearchIconNodeCreated(), false);
2232 } else {
2233 GetSearchNode()->SetSearchImageIconOptions(IconOptions(src));
2234 CreateOrUpdateImage(IMAGE_INDEX, !GetSearchNode()->HasSearchIconNodeCreated());
2235 }
2236 GetSearchNode()->UpdateHasSearchIconNodeCreated(true);
2237 }
2238
UpdateSearchSymbolIconColor()2239 void SearchPattern::UpdateSearchSymbolIconColor()
2240 {
2241 if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2242 return;
2243 }
2244 auto host = GetHost();
2245 CHECK_NULL_VOID(host);
2246 CHECK_NULL_VOID(GetSearchNode());
2247 auto searchButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(IMAGE_INDEX));
2248 CHECK_NULL_VOID(searchButtonFrameNode);
2249 auto layoutProperty = searchButtonFrameNode->GetLayoutProperty<TextLayoutProperty>();
2250 CHECK_NULL_VOID(layoutProperty);
2251 layoutProperty->UpdateSymbolColorList({ GetSearchNode()->GetSearchSymbolIconColor() });
2252 auto searchTheme = GetTheme();
2253 CHECK_NULL_VOID(searchTheme);
2254 if (isFocusIconColorSet_ && GetDefaultIconColor(IMAGE_INDEX) == searchTheme->GetSymbolIconColor()) {
2255 SetSymbolSearchIconColor(searchTheme->GetFocusIconColor());
2256 }
2257 }
2258
CreateCancelIcon()2259 void SearchPattern::CreateCancelIcon()
2260 {
2261 CHECK_NULL_VOID(GetSearchNode());
2262 if (GetSearchNode()->HasCancelIconNodeCreated()) {
2263 UpdateCancelSymbolIconColor();
2264 return;
2265 }
2266 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) &&
2267 SystemProperties::IsNeedSymbol()) {
2268 CreateOrUpdateSymbol(CANCEL_IMAGE_INDEX, !GetSearchNode()->HasCancelIconNodeCreated(), false);
2269 } else {
2270 GetSearchNode()->SetCancelImageIconOptions(IconOptions());
2271 CreateOrUpdateImage(CANCEL_IMAGE_INDEX, !GetSearchNode()->HasCancelIconNodeCreated());
2272 }
2273 GetSearchNode()->UpdateHasCancelIconNodeCreated(true);
2274 }
2275
UpdateCancelSymbolIconColor()2276 void SearchPattern::UpdateCancelSymbolIconColor()
2277 {
2278 if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
2279 return;
2280 }
2281 auto host = GetHost();
2282 CHECK_NULL_VOID(host);
2283 CHECK_NULL_VOID(GetSearchNode());
2284 auto cancelButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(CANCEL_IMAGE_INDEX));
2285 auto layoutProperty = cancelButtonFrameNode->GetLayoutProperty<TextLayoutProperty>();
2286 CHECK_NULL_VOID(layoutProperty);
2287 layoutProperty->UpdateSymbolColorList({ GetSearchNode()->GetCancelSymbolIconColor() });
2288 }
2289
CreateOrUpdateSymbol(int32_t index,bool isCreateNode,bool isFromModifier)2290 void SearchPattern::CreateOrUpdateSymbol(int32_t index, bool isCreateNode, bool isFromModifier)
2291 {
2292 CHECK_NULL_VOID(GetSearchNode());
2293 imageClickListener_ = nullptr;
2294 auto host = GetHost();
2295 CHECK_NULL_VOID(host);
2296 auto pipeline = host->GetContext();
2297 CHECK_NULL_VOID(pipeline);
2298 auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
2299 auto searchTheme = GetTheme();
2300 CHECK_NULL_VOID(searchTheme);
2301 auto iconFrameNode = FrameNode::GetOrCreateFrameNode(
2302 V2::SYMBOL_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<TextPattern>(); });
2303 auto layoutProperty = iconFrameNode->GetLayoutProperty<TextLayoutProperty>();
2304 layoutProperty->UpdateSymbolSourceInfo(index == IMAGE_INDEX ? SymbolSourceInfo(searchTheme->GetSearchSymbolId())
2305 : SymbolSourceInfo(searchTheme->GetCancelSymbolId()));
2306 layoutProperty->UpdateFontSize(
2307 index == IMAGE_INDEX ? GetSearchNode()->GetSearchSymbolIconSize() : GetSearchNode()->GetCancelSymbolIconSize());
2308 layoutProperty->UpdateSymbolColorList({index == IMAGE_INDEX ? GetSearchNode()->GetSearchSymbolIconColor()
2309 : GetSearchNode()->GetCancelSymbolIconColor()});
2310 float maxFontScale = MAX_FONT_SCALE;
2311 if (layoutProperty->GetFontSize()->Unit() != DimensionUnit::VP) {
2312 maxFontScale = std::min(pipeline->GetMaxAppFontScale(), MAX_FONT_SCALE);
2313 }
2314 layoutProperty->UpdateMaxFontScale(maxFontScale);
2315 auto parentInspector = GetSearchNode()->GetInspectorIdValue("");
2316 iconFrameNode->UpdateInspectorId(INSPECTOR_PREFIX + SPECICALIZED_INSPECTOR_INDEXS[index] + parentInspector);
2317
2318 if (isFromModifier) {
2319 UpdateSymbolIconProperties(iconFrameNode, index);
2320 }
2321
2322 if (isCreateNode) {
2323 iconFrameNode->MountToParent(GetSearchNode());
2324 if (index == CANCEL_IMAGE_INDEX) {
2325 auto cancelButtonEvent = iconFrameNode->GetOrCreateEventHub<ButtonEventHub>();
2326 CHECK_NULL_VOID(cancelButtonEvent);
2327 cancelButtonEvent->SetEnabled(false);
2328 }
2329 iconFrameNode->MarkModifyDone();
2330 } else {
2331 auto oldFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(index));
2332 CHECK_NULL_VOID(oldFrameNode);
2333 GetSearchNode()->ReplaceChild(oldFrameNode, iconFrameNode);
2334 if (index == CANCEL_IMAGE_INDEX) {
2335 UpdateIconChangeEvent();
2336 }
2337 iconFrameNode->MarkModifyDone();
2338 iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2339 }
2340 }
2341
CreateOrUpdateImage(int32_t index,bool isCreateNode)2342 void SearchPattern::CreateOrUpdateImage(int32_t index, bool isCreateNode)
2343 {
2344 CHECK_NULL_VOID(GetSearchNode());
2345 imageClickListener_ = nullptr;
2346 auto host = GetHost();
2347 CHECK_NULL_VOID(host);
2348 auto pipeline = host->GetContext();
2349 CHECK_NULL_VOID(pipeline);
2350 auto iconFrameNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
2351 ElementRegister::GetInstance()->MakeUniqueId(),
2352 []() { return AceType::MakeRefPtr<ImagePattern>(); });
2353 UpdateImageIconProperties(iconFrameNode, index);
2354 if (isCreateNode) {
2355 iconFrameNode->MountToParent(GetSearchNode());
2356 if (index == CANCEL_IMAGE_INDEX) {
2357 auto cancelButtonEvent = iconFrameNode->GetOrCreateEventHub<ButtonEventHub>();
2358 CHECK_NULL_VOID(cancelButtonEvent);
2359 cancelButtonEvent->SetEnabled(false);
2360 }
2361 iconFrameNode->MarkModifyDone();
2362 } else {
2363 auto oldFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(index));
2364 CHECK_NULL_VOID(oldFrameNode);
2365 GetSearchNode()->ReplaceChild(oldFrameNode, iconFrameNode);
2366 if (index == CANCEL_IMAGE_INDEX) {
2367 UpdateIconChangeEvent();
2368 }
2369 iconFrameNode->MarkModifyDone();
2370 iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2371 }
2372 }
2373
SetSearchSrcPath(const std::string & src,const std::string & bundleName,const std::string & moduleName)2374 void SearchPattern::SetSearchSrcPath(
2375 const std::string& src, const std::string& bundleName, const std::string& moduleName)
2376 {
2377 CHECK_NULL_VOID(GetSearchNode());
2378 auto &imageIconOptions = GetSearchNode()->GetSearchImageIconOptions();
2379 imageIconOptions.UpdateSrc(std::string(src), std::string(bundleName), std::string(moduleName));
2380 UpdateImageIconNode(IMAGE_INDEX);
2381 }
2382
SetSearchIconSize(const Dimension & value)2383 void SearchPattern::SetSearchIconSize(const Dimension& value)
2384 {
2385 CHECK_NULL_VOID(GetSearchNode());
2386 auto& imageIconOptions = GetSearchNode()->GetSearchImageIconOptions();
2387 imageIconOptions.UpdateSize(Dimension(value));
2388 UpdateImageIconNode(IMAGE_INDEX);
2389 }
2390
SetSearchIconColor(const Color & color)2391 void SearchPattern::SetSearchIconColor(const Color& color)
2392 {
2393 CHECK_NULL_VOID(GetSearchNode());
2394 auto frameNode = GetHost();
2395 CHECK_NULL_VOID(frameNode);
2396 auto iconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(IMAGE_INDEX));
2397 CHECK_NULL_VOID(iconFrameNode);
2398 if (iconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
2399 GetSearchNode()->SetSearchSymbolIconColor(Color(color));
2400 auto symbolLayoutProperty = iconFrameNode->GetLayoutProperty<TextLayoutProperty>();
2401 CHECK_NULL_VOID(symbolLayoutProperty);
2402 symbolLayoutProperty->UpdateSymbolColorList({color});
2403 iconFrameNode->MarkModifyDone();
2404 iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2405 } else {
2406 auto &imageIconOptions = GetSearchNode()->GetSearchImageIconOptions();
2407 imageIconOptions.UpdateColor(Color(color));
2408 auto imageLayoutProperty = iconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
2409 CHECK_NULL_VOID(imageLayoutProperty);
2410 CHECK_NULL_VOID(imageLayoutProperty->GetImageSourceInfo());
2411 auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value();
2412 if (imageSourceInfo.IsSvg()) {
2413 imageSourceInfo.SetFillColor(color);
2414 imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
2415 auto imageRenderProperty = iconFrameNode->GetPaintProperty<ImageRenderProperty>();
2416 CHECK_NULL_VOID(imageRenderProperty);
2417 imageRenderProperty->UpdateSvgFillColor(color);
2418 iconFrameNode->MarkModifyDone();
2419 iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2420 }
2421 }
2422 }
2423
SetSymbolSearchIconColor(const Color & color)2424 void SearchPattern::SetSymbolSearchIconColor(const Color& color)
2425 {
2426 bool isCurSymbolNode = IsSymbolIcon(IMAGE_INDEX);
2427 if (isCurSymbolNode) {
2428 CHECK_NULL_VOID(GetSearchNode());
2429 GetSearchNode()->SetSearchSymbolIconColor(Color(color));
2430 UpdateSymbolIconNode(IMAGE_INDEX);
2431 }
2432 }
2433
SetSearchImageIcon(IconOptions & iconOptions)2434 void SearchPattern::SetSearchImageIcon(IconOptions& iconOptions)
2435 {
2436 CHECK_NULL_VOID(GetSearchNode());
2437 auto& imageIconOptions = GetSearchNode()->GetSearchImageIconOptions();
2438 if (iconOptions.GetColor().has_value()) {
2439 imageIconOptions.UpdateColor(iconOptions.GetColor().value());
2440 }
2441 if (iconOptions.GetSize().has_value()) {
2442 imageIconOptions.UpdateSize(ConvertImageIconSizeValue(iconOptions.GetSize().value()));
2443 }
2444 if (iconOptions.GetSrc().has_value()) {
2445 imageIconOptions.UpdateSrc(iconOptions.GetSrc().value_or(""),
2446 iconOptions.GetBundleName().value_or(""),
2447 iconOptions.GetModuleName().value_or(""));
2448 }
2449 UpdateImageIconNode(IMAGE_INDEX);
2450 }
2451
SetSearchSymbolIcon()2452 void SearchPattern::SetSearchSymbolIcon()
2453 {
2454 UpdateSymbolIconNode(IMAGE_INDEX);
2455 }
2456
SetCancelIconSize(const Dimension & value)2457 void SearchPattern::SetCancelIconSize(const Dimension& value)
2458 {
2459 CHECK_NULL_VOID(GetSearchNode());
2460 auto& imageIconOptions = GetSearchNode()->GetCancelImageIconOptions();
2461 imageIconOptions.UpdateSize(Dimension(value));
2462 UpdateImageIconNode(CANCEL_IMAGE_INDEX);
2463 }
2464
SetCancelIconColor(const Color & color)2465 void SearchPattern::SetCancelIconColor(const Color& color)
2466 {
2467 CHECK_NULL_VOID(GetSearchNode());
2468 auto frameNode = GetHost();
2469 CHECK_NULL_VOID(frameNode);
2470 auto cancelIconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(CANCEL_IMAGE_INDEX));
2471 CHECK_NULL_VOID(cancelIconFrameNode);
2472 if (cancelIconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
2473 GetSearchNode()->SetCancelSymbolIconColor(Color(color));
2474 auto symbolLayoutProperty = cancelIconFrameNode->GetLayoutProperty<TextLayoutProperty>();
2475 CHECK_NULL_VOID(symbolLayoutProperty);
2476 symbolLayoutProperty->UpdateSymbolColorList({color});
2477 cancelIconFrameNode->MarkModifyDone();
2478 cancelIconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2479 } else {
2480 auto &imageIconOptions = GetSearchNode()->GetCancelImageIconOptions();
2481 imageIconOptions.UpdateColor(Color(color));
2482 auto imageLayoutProperty = cancelIconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
2483 CHECK_NULL_VOID(imageLayoutProperty);
2484 auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value();
2485 if (imageSourceInfo.IsSvg()) {
2486 imageSourceInfo.SetFillColor(color);
2487 imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
2488 auto imageRenderProperty = cancelIconFrameNode->GetPaintProperty<ImageRenderProperty>();
2489 CHECK_NULL_VOID(imageRenderProperty);
2490 imageRenderProperty->UpdateSvgFillColor(color);
2491 cancelIconFrameNode->MarkModifyDone();
2492 cancelIconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2493 }
2494 }
2495 }
2496
SetRightIconSrcPath(const std::string & src)2497 void SearchPattern::SetRightIconSrcPath(const std::string& src)
2498 {
2499 CHECK_NULL_VOID(GetSearchNode());
2500 auto &imageIconOptions = GetSearchNode()->GetCancelImageIconOptions();
2501 imageIconOptions.UpdateSrc(std::string(src), "", "");
2502 UpdateImageIconNode(CANCEL_IMAGE_INDEX);
2503 }
2504
SetCancelButtonStyle(const CancelButtonStyle & style)2505 void SearchPattern::SetCancelButtonStyle(const CancelButtonStyle& style)
2506 {
2507 auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(TEXTFIELD_INDEX));
2508 CHECK_NULL_VOID(textFieldFrameNode);
2509 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
2510 CHECK_NULL_VOID(textFieldPattern);
2511 UpdateChangeEvent(textFieldPattern->GetTextUtf16Value(), static_cast<int16_t>(style));
2512 }
2513
GetDefaultIconColor(int32_t index)2514 Color SearchPattern::GetDefaultIconColor(int32_t index)
2515 {
2516 Color defaultIconColor;
2517 auto searchTheme = GetTheme();
2518 CHECK_NULL_RETURN(searchTheme, defaultIconColor);
2519 auto normalIconColor = searchTheme->GetSymbolIconColor();
2520 defaultIconColor = normalIconColor;
2521 CHECK_NULL_RETURN(GetSearchNode(), defaultIconColor);
2522 auto iconFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(index));
2523 CHECK_NULL_RETURN(iconFrameNode, defaultIconColor);
2524 if (iconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
2525 auto symbolLayoutProperty = iconFrameNode->GetLayoutProperty<TextLayoutProperty>();
2526 CHECK_NULL_RETURN(symbolLayoutProperty, defaultIconColor);
2527 std::vector<Color> symbolColorList = symbolLayoutProperty->GetSymbolColorListValue({ normalIconColor });
2528 if (symbolColorList.size() >= 1) {
2529 defaultIconColor = symbolColorList[0];
2530 }
2531 } else {
2532 auto imageLayoutProperty = iconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
2533 CHECK_NULL_RETURN(imageLayoutProperty, defaultIconColor);
2534 auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value();
2535 if (imageSourceInfo.IsSvg()) {
2536 auto imageRenderProperty = iconFrameNode->GetPaintProperty<ImageRenderProperty>();
2537 CHECK_NULL_RETURN(imageRenderProperty, defaultIconColor);
2538 defaultIconColor = imageRenderProperty->GetSvgFillColorValue(normalIconColor);
2539 }
2540 }
2541 return defaultIconColor;
2542 }
2543
SetCancelImageIcon(IconOptions & iconOptions)2544 void SearchPattern::SetCancelImageIcon(IconOptions& iconOptions)
2545 {
2546 CHECK_NULL_VOID(GetSearchNode());
2547 auto& imageIconOptions = GetSearchNode()->GetCancelImageIconOptions();
2548 if (iconOptions.GetColor().has_value()) {
2549 imageIconOptions.UpdateColor(iconOptions.GetColor().value());
2550 }
2551 if (iconOptions.GetSize().has_value()) {
2552 imageIconOptions.UpdateSize(ConvertImageIconSizeValue(iconOptions.GetSize().value()));
2553 }
2554 if (iconOptions.GetSrc().has_value()) {
2555 imageIconOptions.UpdateSrc(iconOptions.GetSrc().value(),
2556 iconOptions.GetBundleName().value_or(""),
2557 iconOptions.GetModuleName().value_or(""));
2558 }
2559 UpdateImageIconNode(CANCEL_IMAGE_INDEX);
2560 }
2561
SetCancelSymbolIcon()2562 void SearchPattern::SetCancelSymbolIcon()
2563 {
2564 UpdateSymbolIconNode(CANCEL_IMAGE_INDEX);
2565 }
2566
UpdateImageIconNode(int32_t index)2567 void SearchPattern::UpdateImageIconNode(int32_t index)
2568 {
2569 bool isCurSymbolNode = IsSymbolIcon(index);
2570 if (isCurSymbolNode) {
2571 CreateOrUpdateImage(index, false);
2572 } else {
2573 auto frameNode = GetHost();
2574 CHECK_NULL_VOID(frameNode);
2575 auto iconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(index));
2576 UpdateImageIconProperties(iconFrameNode, index);
2577 iconFrameNode->MarkModifyDone();
2578 iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2579 }
2580 }
2581
UpdateSymbolIconNode(int32_t index)2582 void SearchPattern::UpdateSymbolIconNode(int32_t index)
2583 {
2584 bool isCurSymbolNode = IsSymbolIcon(index);
2585 if (!isCurSymbolNode) {
2586 CreateOrUpdateSymbol(index, false, true);
2587 } else {
2588 auto frameNode = GetHost();
2589 CHECK_NULL_VOID(frameNode);
2590 auto iconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(index));
2591 UpdateSymbolIconProperties(iconFrameNode, index);
2592 iconFrameNode->MarkModifyDone();
2593 iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2594 }
2595 }
2596
UpdateImageIconProperties(RefPtr<FrameNode> & iconFrameNode,int32_t index)2597 void SearchPattern::UpdateImageIconProperties(RefPtr<FrameNode>& iconFrameNode, int32_t index)
2598 {
2599 CHECK_NULL_VOID(iconFrameNode);
2600 if (iconFrameNode->GetTag() == V2::IMAGE_ETS_TAG) {
2601 auto iconOptions = index == IMAGE_INDEX ? GetSearchNode()->GetSearchImageIconOptions()
2602 : GetSearchNode()->GetCancelImageIconOptions();
2603 auto imageLayoutProperty = iconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
2604 CHECK_NULL_VOID(imageLayoutProperty);
2605 ImageSourceInfo imageSourceInfo("");
2606 auto imageSourceInfoOp = imageLayoutProperty->GetImageSourceInfo();
2607 if (imageSourceInfoOp.has_value()) {
2608 imageSourceInfo = imageSourceInfoOp.value();
2609 }
2610 auto host = GetHost();
2611 CHECK_NULL_VOID(host);
2612 auto pipeline = host->GetContext();
2613 CHECK_NULL_VOID(pipeline);
2614 auto searchTheme = GetTheme();
2615 CHECK_NULL_VOID(searchTheme);
2616 auto iconTheme = pipeline->GetTheme<IconTheme>(host->GetThemeScopeId());
2617 CHECK_NULL_VOID(iconTheme);
2618 if (iconOptions.GetSrc().value_or("").empty()) {
2619 imageSourceInfo.SetResourceId(index == IMAGE_INDEX ? InternalResource::ResourceId::SEARCH_SVG
2620 : InternalResource::ResourceId::CLOSE_SVG);
2621 auto iconPath = iconTheme->GetIconPath(index == IMAGE_INDEX ? InternalResource::ResourceId::SEARCH_SVG
2622 : InternalResource::ResourceId::CLOSE_SVG);
2623 imageSourceInfo.SetSrc(iconPath, iconOptions.GetColor().value_or(searchTheme->GetSearchIconColor()));
2624 } else {
2625 imageSourceInfo.SetSrc(iconOptions.GetSrc().value());
2626 }
2627 imageSourceInfo.SetBundleName(iconOptions.GetBundleName().value_or(""));
2628 imageSourceInfo.SetModuleName(iconOptions.GetModuleName().value_or(""));
2629 imageSourceInfo.SetFillColor(iconOptions.GetColor().value_or(searchTheme->GetSearchIconColor()));
2630 imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
2631 CalcSize imageCalcSize(CalcLength(iconOptions.GetSize().value_or(searchTheme->GetIconHeight())),
2632 CalcLength(iconOptions.GetSize().value_or(searchTheme->GetIconHeight())));
2633
2634 imageLayoutProperty->UpdateUserDefinedIdealSize(imageCalcSize);
2635 auto parentInspector = GetSearchNode()->GetInspectorIdValue("");
2636 iconFrameNode->UpdateInspectorId(INSPECTOR_PREFIX + SPECICALIZED_INSPECTOR_INDEXS[index] + parentInspector);
2637 auto imageRenderProperty = iconFrameNode->GetPaintProperty<ImageRenderProperty>();
2638 CHECK_NULL_VOID(imageRenderProperty);
2639 imageSourceInfo.SetFillColor(iconOptions.GetColor().value_or(searchTheme->GetSearchIconColor()));
2640 imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
2641 imageRenderProperty->UpdateSvgFillColor(iconOptions.GetColor().value_or(searchTheme->GetSearchIconColor()));
2642 }
2643 }
2644
UpdateSymbolIconProperties(RefPtr<FrameNode> & iconFrameNode,int32_t index)2645 void SearchPattern::UpdateSymbolIconProperties(RefPtr<FrameNode>& iconFrameNode, int32_t index)
2646 {
2647 auto host = GetHost();
2648 CHECK_NULL_VOID(host);
2649 CHECK_NULL_VOID(iconFrameNode);
2650 auto searchTheme = GetTheme();
2651 CHECK_NULL_VOID(searchTheme);
2652 auto layoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
2653 CHECK_NULL_VOID(layoutProperty);
2654 auto symbolLayoutProperty = iconFrameNode->GetLayoutProperty<TextLayoutProperty>();
2655 CHECK_NULL_VOID(symbolLayoutProperty);
2656 symbolLayoutProperty->UpdateSymbolSourceInfo(index == IMAGE_INDEX
2657 ? SymbolSourceInfo(searchTheme->GetSearchSymbolId())
2658 : SymbolSourceInfo(searchTheme->GetCancelSymbolId()));
2659 auto defaultSymbolIconSize = (index == IMAGE_INDEX ? GetSearchNode()->GetSearchSymbolIconSize()
2660 : GetSearchNode()->GetCancelSymbolIconSize());
2661 symbolLayoutProperty->UpdateFontSize(defaultSymbolIconSize);
2662 symbolLayoutProperty->UpdateSymbolColorList({ index == IMAGE_INDEX ? GetSearchNode()->GetSearchSymbolIconColor()
2663 : GetSearchNode()->GetCancelSymbolIconColor() });
2664 auto parentInspector = GetSearchNode()->GetInspectorIdValue("");
2665 iconFrameNode->UpdateInspectorId(INSPECTOR_PREFIX + SPECICALIZED_INSPECTOR_INDEXS[index] + parentInspector);
2666 if (index == IMAGE_INDEX) {
2667 auto iconSymbol = layoutProperty->GetSearchIconSymbol();
2668 if (iconSymbol != nullptr) {
2669 iconSymbol(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconFrameNode)));
2670 symbolLayoutProperty->OnPropertyChangeMeasure();
2671 }
2672 } else {
2673 auto iconSymbol = layoutProperty->GetCancelIconSymbol();
2674 if (iconSymbol != nullptr) {
2675 iconSymbol(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconFrameNode)));
2676 symbolLayoutProperty->OnPropertyChangeMeasure();
2677 }
2678 }
2679 // reset symbol effect
2680 auto symbolEffectOptions = symbolLayoutProperty->GetSymbolEffectOptionsValue(SymbolEffectOptions());
2681 symbolEffectOptions.SetIsTxtActive(false);
2682 symbolLayoutProperty->UpdateSymbolEffectOptions(symbolEffectOptions);
2683 auto fontSize = symbolLayoutProperty->GetFontSize().value_or(defaultSymbolIconSize);
2684 if (GreatOrEqualCustomPrecision(fontSize.ConvertToPxDistribute(GetMinFontScale(), GetMaxFontScale()),
2685 ICON_MAX_SIZE.ConvertToPx())) {
2686 symbolLayoutProperty->UpdateFontSize(ICON_MAX_SIZE);
2687 }
2688 }
2689
IsSymbolIcon(int32_t index)2690 bool SearchPattern::IsSymbolIcon(int32_t index)
2691 {
2692 auto frameNode = GetHost();
2693 CHECK_NULL_RETURN(frameNode, false);
2694 auto iconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(index));
2695 CHECK_NULL_RETURN(iconFrameNode, false);
2696 return iconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG;
2697 }
2698
UpdateIconChangeEvent()2699 void SearchPattern::UpdateIconChangeEvent()
2700 {
2701 CHECK_NULL_VOID(GetSearchNode());
2702 auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(TEXTFIELD_INDEX));
2703 CHECK_NULL_VOID(textFieldFrameNode);
2704 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
2705 CHECK_NULL_VOID(textFieldPattern);
2706 UpdateChangeEvent(textFieldPattern->GetTextUtf16Value());
2707 }
2708
ConvertImageIconSizeValue(const Dimension & iconSizeValue)2709 const Dimension SearchPattern::ConvertImageIconSizeValue(const Dimension& iconSizeValue)
2710 {
2711 auto host = GetHost();
2712 CHECK_NULL_RETURN(host, iconSizeValue);
2713 auto maxFontScale = GetMaxFontScale();
2714 auto minFontScale = GetMinFontScale();
2715 if (GreatOrEqualCustomPrecision(iconSizeValue.ConvertToPxDistribute(minFontScale, maxFontScale),
2716 ICON_MAX_SIZE.ConvertToPx())) {
2717 return ICON_MAX_SIZE;
2718 }
2719 if (iconSizeValue.Unit() != DimensionUnit::VP) {
2720 return Dimension(iconSizeValue.ConvertToPxDistribute(minFontScale, maxFontScale));
2721 } else {
2722 return iconSizeValue;
2723 }
2724 }
2725
GetMaxFontScale()2726 float SearchPattern::GetMaxFontScale()
2727 {
2728 auto host = GetHost();
2729 CHECK_NULL_RETURN(host, MAX_FONT_SCALE);
2730 auto pipeline = host->GetContext();
2731 CHECK_NULL_RETURN(pipeline, MAX_FONT_SCALE);
2732 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
2733 CHECK_NULL_RETURN(textFieldFrameNode, MAX_FONT_SCALE);
2734 auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
2735 CHECK_NULL_RETURN(textFieldLayoutProperty, MAX_FONT_SCALE);
2736
2737 auto maxFontScale = MAX_FONT_SCALE;
2738 if (textFieldLayoutProperty->HasMaxFontScale()) {
2739 maxFontScale = std::min(textFieldLayoutProperty->GetMaxFontScale().value(), maxFontScale);
2740 } else if (pipeline->GetMaxAppFontScale()) {
2741 maxFontScale = std::min(pipeline->GetMaxAppFontScale(), maxFontScale);
2742 }
2743 return maxFontScale;
2744 }
2745
GetMinFontScale()2746 float SearchPattern::GetMinFontScale()
2747 {
2748 auto host = GetHost();
2749 CHECK_NULL_RETURN(host, 0.0f);
2750 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
2751 CHECK_NULL_RETURN(textFieldFrameNode, 0.0f);
2752 auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
2753 CHECK_NULL_RETURN(textFieldLayoutProperty, 0.0f);
2754 auto minFontScale = 0.0f;
2755 if (textFieldLayoutProperty->HasMinFontScale()) {
2756 minFontScale = textFieldLayoutProperty->GetMinFontScale().value();
2757 }
2758 return minFontScale;
2759 }
2760
SetKeyboardAppearanceConfig(const KeyboardAppearanceConfig & config)2761 void SearchPattern::SetKeyboardAppearanceConfig(const KeyboardAppearanceConfig& config)
2762 {
2763 auto host = GetHost();
2764 CHECK_NULL_VOID(host);
2765 auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
2766 CHECK_NULL_VOID(textFieldFrameNode);
2767 auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
2768 CHECK_NULL_VOID(textFieldPattern);
2769 textFieldPattern->SetKeyboardAppearanceConfig(config);
2770 }
2771
2772 #define DEFINE_PROP_HANDLER(KEY_TYPE, VALUE_TYPE, UPDATE_METHOD) \
2773 { \
2774 #KEY_TYPE, [](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) { \
2775 if (auto realValue = std::get_if<VALUE_TYPE>(&(value->GetValue()))) { \
2776 prop->UPDATE_METHOD(*realValue); \
2777 } \
2778 } \
2779 }
2780
UpdatePropertyImpl(const std::string & key,RefPtr<PropertyValueBase> value)2781 void SearchPattern::UpdatePropertyImpl(const std::string& key, RefPtr<PropertyValueBase> value)
2782 {
2783 auto frameNode = GetHost();
2784 CHECK_NULL_VOID(frameNode);
2785 auto layoutProperty = frameNode->GetLayoutPropertyPtr<SearchLayoutProperty>();
2786 CHECK_NULL_VOID(layoutProperty);
2787 CHECK_NULL_VOID(value);
2788
2789 using Handler = std::function<void(SearchLayoutProperty*, RefPtr<PropertyValueBase>)>;
2790 const std::unordered_map<std::string, Handler> handlers = {
2791
2792 {"placeholder", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2793 if (auto realValue = std::get_if<std::u16string>(&(value->GetValue()))) {
2794 auto pattern = wp.Upgrade();
2795 CHECK_NULL_VOID(pattern);
2796 pattern->UpdatePlaceholderResource(*realValue);
2797 }
2798 }
2799 },
2800
2801 {"text", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2802 if (auto realValue = std::get_if<std::u16string>(&(value->GetValue()))) {
2803 auto pattern = wp.Upgrade();
2804 CHECK_NULL_VOID(pattern);
2805 pattern->UpdateTextResource(*realValue);
2806 }
2807 }
2808 },
2809
2810 {"searchButtonValue", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2811 if (auto realValue = std::get_if<std::string>(&(value->GetValue()))) {
2812 auto pattern = wp.Upgrade();
2813 CHECK_NULL_VOID(pattern);
2814 pattern->UpdateSearchButtonValueResource(*realValue);
2815 }
2816 }
2817 },
2818
2819 {"searchButtonFontSize", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2820 if (auto realValue = std::get_if<CalcDimension>(&(value->GetValue()))) {
2821 auto pattern = wp.Upgrade();
2822 CHECK_NULL_VOID(pattern);
2823 pattern->UpdateSearchButtonFontSizeResource(*realValue);
2824 prop->UpdateSearchButtonFontSize(*realValue);
2825 }
2826 }
2827 },
2828
2829 {"searchButtonFontColor", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2830 if (auto realValue = std::get_if<Color>(&(value->GetValue()))) {
2831 auto pattern = wp.Upgrade();
2832 CHECK_NULL_VOID(pattern);
2833 pattern->UpdateSearchButtonFontColorResource(*realValue);
2834 }
2835 }
2836 },
2837
2838 {"searchIconSize", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2839 if (auto realValue = std::get_if<CalcDimension>(&(value->GetValue()))) {
2840 auto pattern = wp.Upgrade();
2841 CHECK_NULL_VOID(pattern);
2842 realValue->SetUnit(DimensionUnit::VP);
2843 pattern->SetSearchIconSize(*realValue);
2844 prop->UpdateSearchIconUDSize(*realValue);
2845 }
2846 }
2847 },
2848
2849 {"searchIconColor", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2850 if (auto realValue = std::get_if<Color>(&(value->GetValue()))) {
2851 auto pattern = wp.Upgrade();
2852 CHECK_NULL_VOID(pattern);
2853 pattern->GetSearchNode()->SetSearchImageIconColor(*realValue);
2854 pattern->SetSearchIconColor(*realValue);
2855 }
2856 }
2857 },
2858
2859 {"searchIconSrc", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2860 if (auto realValue = std::get_if<std::string>(&(value->GetValue()))) {
2861 auto pattern = wp.Upgrade();
2862 CHECK_NULL_VOID(pattern);
2863 pattern->SetSearchSrcPath(*realValue, "", "");
2864 }
2865 }
2866 },
2867
2868 {"cancelButtonIconSize", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2869 if (auto realValue = std::get_if<CalcDimension>(&(value->GetValue()))) {
2870 auto pattern = wp.Upgrade();
2871 CHECK_NULL_VOID(pattern);
2872 realValue->SetUnit(DimensionUnit::VP);
2873 pattern->SetCancelIconSize(*realValue);
2874 prop->UpdateCancelButtonUDSize(*realValue);
2875 }
2876 }
2877 },
2878
2879 {"cancelButtonIconColor", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2880 if (auto realValue = std::get_if<Color>(&(value->GetValue()))) {
2881 auto pattern = wp.Upgrade();
2882 CHECK_NULL_VOID(pattern);
2883 pattern->SetCancelIconColor(*realValue);
2884 }
2885 }
2886 },
2887
2888 {"scancelButtonIconSrc", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2889 if (auto realValue = std::get_if<std::string>(&(value->GetValue()))) {
2890 auto pattern = wp.Upgrade();
2891 pattern->SetRightIconSrcPath(*realValue);
2892 }
2893 }
2894 },
2895
2896 {"fontSize", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2897 if (auto realValue = std::get_if<CalcDimension>(&(value->GetValue()))) {
2898 auto pattern = wp.Upgrade();
2899 CHECK_NULL_VOID(pattern);
2900 pattern->UpdateFontSizeResource(*realValue);
2901 }
2902 }
2903 },
2904
2905 {"fontColor", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2906 if (auto realValue = std::get_if<Color>(&(value->GetValue()))) {
2907 auto pattern = wp.Upgrade();
2908 CHECK_NULL_VOID(pattern);
2909 pattern->UpdateFontColorResource(*realValue);
2910 }
2911 }
2912 },
2913
2914 {"caretColor", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2915 if (auto realValue = std::get_if<Color>(&(value->GetValue()))) {
2916 auto pattern = wp.Upgrade();
2917 CHECK_NULL_VOID(pattern);
2918 pattern->UpdateCaretColorResource(*realValue);
2919 }
2920 }
2921 },
2922
2923 {"caretWidth", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2924 if (auto realValue = std::get_if<CalcDimension>(&(value->GetValue()))) {
2925 auto pattern = wp.Upgrade();
2926 CHECK_NULL_VOID(pattern);
2927 pattern->UpdateCaretWidthResource(*realValue);
2928 }
2929 }
2930 },
2931
2932 {"placeholderColor", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2933 if (auto realValue = std::get_if<Color>(&(value->GetValue()))) {
2934 auto pattern = wp.Upgrade();
2935 CHECK_NULL_VOID(pattern);
2936 pattern->UpdatePlaceholderColorResource(*realValue);
2937 }
2938 }
2939 },
2940
2941 {"placeholderFontSize", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2942 if (auto realValue = std::get_if<CalcDimension>(&(value->GetValue()))) {
2943 auto pattern = wp.Upgrade();
2944 CHECK_NULL_VOID(pattern);
2945 pattern->UpdatePlaceholderFontSizeResource(*realValue);
2946 }
2947 }
2948 },
2949
2950 {"decorationColor", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2951 if (auto realValue = std::get_if<Color>(&(value->GetValue()))) {
2952 auto pattern = wp.Upgrade();
2953 CHECK_NULL_VOID(pattern);
2954 pattern->UpdateDecorationColorResource(*realValue);
2955 }
2956 }
2957 },
2958
2959 {"minFontSize", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2960 if (auto realValue = std::get_if<CalcDimension>(&(value->GetValue()))) {
2961 auto pattern = wp.Upgrade();
2962 CHECK_NULL_VOID(pattern);
2963 pattern->UpdateMinFontSizeResource(*realValue);
2964 }
2965 }
2966 },
2967
2968 {"maxFontSize", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2969 if (auto realValue = std::get_if<CalcDimension>(&(value->GetValue()))) {
2970 auto pattern = wp.Upgrade();
2971 CHECK_NULL_VOID(pattern);
2972 pattern->UpdateMaxFontSizeResource(*realValue);
2973 }
2974 }
2975 },
2976
2977 {"letterSpacing", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2978 if (auto realValue = std::get_if<CalcDimension>(&(value->GetValue()))) {
2979 auto pattern = wp.Upgrade();
2980 CHECK_NULL_VOID(pattern);
2981 pattern->UpdateLetterSpacingResource(*realValue);
2982 }
2983 }
2984 },
2985
2986 {"lineHeight", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2987 if (auto realValue = std::get_if<CalcDimension>(&(value->GetValue()))) {
2988 auto pattern = wp.Upgrade();
2989 CHECK_NULL_VOID(pattern);
2990 pattern->UpdateLineHeightResource(*realValue);
2991 }
2992 }
2993 },
2994
2995 {"minFontScale", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
2996 if (auto realValue = std::get_if<float>(&(value->GetValue()))) {
2997 auto pattern = wp.Upgrade();
2998 CHECK_NULL_VOID(pattern);
2999 pattern->UpdateMinFontScaleResource(*realValue);
3000 }
3001 }
3002 },
3003
3004 {"maxFontScale", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
3005 if (auto realValue = std::get_if<float>(&(value->GetValue()))) {
3006 auto pattern = wp.Upgrade();
3007 CHECK_NULL_VOID(pattern);
3008 pattern->UpdateMaxFontScaleResource(*realValue);
3009 }
3010 }
3011 },
3012
3013 {"selectedBackgroundColor", [wp = WeakClaim(this)]
3014 (SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
3015 if (auto realValue = std::get_if<Color>(&(value->GetValue()))) {
3016 if (realValue->GetAlpha() == 255) {
3017 *realValue = realValue->ChangeOpacity(0.2);
3018 }
3019 auto pattern = wp.Upgrade();
3020 CHECK_NULL_VOID(pattern);
3021 pattern->UpdateSelectedBackgroundColorResource(*realValue);
3022 }
3023 }
3024 },
3025
3026 {"inputFilter", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
3027 if (auto realValue = std::get_if<std::string>(&(value->GetValue()))) {
3028 auto pattern = wp.Upgrade();
3029 CHECK_NULL_VOID(pattern);
3030 pattern->UpdateInputFilterResource(*realValue);
3031 }
3032 }
3033 },
3034
3035 {"textIndent", [wp = WeakClaim(this)](SearchLayoutProperty* prop, RefPtr<PropertyValueBase> value) {
3036 if (auto realValue = std::get_if<CalcDimension>(&(value->GetValue()))) {
3037 auto pattern = wp.Upgrade();
3038 CHECK_NULL_VOID(pattern);
3039 pattern->UpdateTextIndentResource(*realValue);
3040 }
3041 }
3042 },
3043 };
3044
3045 auto it = handlers.find(key);
3046 if (it != handlers.end()) {
3047 it->second(layoutProperty, value);
3048 }
3049 if (frameNode->GetRerenderable()) {
3050 frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3051 }
3052 }
3053
UpdatePlaceholderResource(const std::u16string & value)3054 void SearchPattern::UpdatePlaceholderResource(const std::u16string& value)
3055 {
3056 auto frameNode = GetHost();
3057 CHECK_NULL_VOID(frameNode);
3058 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3059 CHECK_NULL_VOID(textFieldChild);
3060 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3061 CHECK_NULL_VOID(textFieldLayoutProperty);
3062 textFieldLayoutProperty->UpdatePlaceholder(value);
3063 textFieldLayoutProperty->UpdatePlaceholderMaxLines(1);
3064 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3065 }
3066
UpdateTextResource(const std::u16string & value)3067 void SearchPattern::UpdateTextResource(const std::u16string& value)
3068 {
3069 auto frameNode = GetHost();
3070 CHECK_NULL_VOID(frameNode);
3071 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3072 CHECK_NULL_VOID(textFieldChild);
3073 auto pattern = textFieldChild->GetPattern<TextFieldPattern>();
3074 auto textValue = pattern->GetTextUtf16Value();
3075 if (value != textValue) {
3076 auto changed = pattern->InitValueText(value);
3077 pattern->SetTextChangedAtCreation(changed);
3078 }
3079 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3080 }
3081
UpdateSearchButtonValueResource(const std::string text)3082 void SearchPattern::UpdateSearchButtonValueResource(const std::string text)
3083 {
3084 auto frameNode = GetHost();
3085 CHECK_NULL_VOID(frameNode);
3086 auto buttonFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(BUTTON_INDEX));
3087 CHECK_NULL_VOID(buttonFrameNode);
3088
3089 auto searchButtonRenderContext = buttonFrameNode->GetRenderContext();
3090 CHECK_NULL_VOID(searchButtonRenderContext);
3091
3092 auto searchButtonEvent = buttonFrameNode->GetEventHub<ButtonEventHub>();
3093 CHECK_NULL_VOID(searchButtonEvent);
3094
3095 if (!text.empty()) {
3096 searchButtonEvent->SetEnabled(true);
3097 searchButtonRenderContext->UpdateOpacity(1.0);
3098 ACE_UPDATE_NODE_LAYOUT_PROPERTY(SearchLayoutProperty, SearchButton, text, frameNode);
3099 } else {
3100 searchButtonEvent->SetEnabled(false);
3101 searchButtonRenderContext->UpdateOpacity(0.0);
3102 }
3103
3104 auto buttonLayoutProperty = buttonFrameNode->GetLayoutProperty<ButtonLayoutProperty>();
3105 CHECK_NULL_VOID(buttonLayoutProperty);
3106 buttonLayoutProperty->UpdateLabel(text);
3107
3108 buttonFrameNode->MarkModifyDone();
3109 buttonFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3110 }
3111
UpdateSearchButtonFontSizeResource(const Dimension & value)3112 void SearchPattern::UpdateSearchButtonFontSizeResource(const Dimension& value)
3113 {
3114 auto frameNode = GetHost();
3115 CHECK_NULL_VOID(frameNode);
3116 auto buttonFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(BUTTON_INDEX));
3117 CHECK_NULL_VOID(buttonFrameNode);
3118 auto buttonLayoutProperty = buttonFrameNode->GetLayoutProperty<ButtonLayoutProperty>();
3119 CHECK_NULL_VOID(buttonLayoutProperty);
3120
3121 buttonLayoutProperty->UpdateFontSize(value);
3122 buttonFrameNode->MarkModifyDone();
3123 buttonFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3124 }
3125
UpdateSearchButtonFontColorResource(const Color & value)3126 void SearchPattern::UpdateSearchButtonFontColorResource(const Color& value)
3127 {
3128 auto frameNode = GetHost();
3129 CHECK_NULL_VOID(frameNode);
3130 auto buttonFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(BUTTON_INDEX));
3131 CHECK_NULL_VOID(buttonFrameNode);
3132 auto buttonLayoutProperty = buttonFrameNode->GetLayoutProperty<ButtonLayoutProperty>();
3133 CHECK_NULL_VOID(buttonLayoutProperty);
3134
3135 buttonLayoutProperty->UpdateFontColor(value);
3136 buttonFrameNode->MarkModifyDone();
3137 buttonFrameNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
3138 }
3139
UpdateFontColorResource(const Color & color)3140 void SearchPattern::UpdateFontColorResource(const Color& color)
3141 {
3142 auto frameNode = GetHost();
3143 CHECK_NULL_VOID(frameNode);
3144 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3145 CHECK_NULL_VOID(textFieldChild);
3146 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3147 CHECK_NULL_VOID(textFieldLayoutProperty);
3148 auto textFieldPaintProperty = textFieldChild->GetPaintProperty<TextFieldPaintProperty>();
3149 CHECK_NULL_VOID(textFieldPaintProperty);
3150 textFieldLayoutProperty->UpdateTextColor(color);
3151 textFieldPaintProperty->UpdateTextColorFlagByUser(color);
3152 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
3153 }
3154
UpdateCaretColorResource(const Color & value)3155 void SearchPattern::UpdateCaretColorResource(const Color& value)
3156 {
3157 auto frameNode = GetHost();
3158 CHECK_NULL_VOID(frameNode);
3159 auto textFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(TEXTFIELD_INDEX));
3160 CHECK_NULL_VOID(textFrameNode);
3161 auto textPaintProperty = textFrameNode->GetPaintProperty<TextFieldPaintProperty>();
3162 CHECK_NULL_VOID(textPaintProperty);
3163 textPaintProperty->UpdateCursorColor(value);
3164 textPaintProperty->UpdateCaretColorFlagByUser(true);
3165 textFrameNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
3166 }
3167
UpdateCaretWidthResource(const Dimension & value)3168 void SearchPattern::UpdateCaretWidthResource(const Dimension& value)
3169 {
3170 auto frameNode = GetHost();
3171 CHECK_NULL_VOID(frameNode);
3172 auto textFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(TEXTFIELD_INDEX));
3173 CHECK_NULL_VOID(textFrameNode);
3174 auto textPaintProperty = textFrameNode->GetPaintProperty<TextFieldPaintProperty>();
3175 CHECK_NULL_VOID(textPaintProperty);
3176 textPaintProperty->UpdateCursorWidth(value);
3177 textFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3178 }
3179
UpdatePlaceholderColorResource(const Color & value)3180 void SearchPattern::UpdatePlaceholderColorResource(const Color& value)
3181 {
3182 auto frameNode = GetHost();
3183 CHECK_NULL_VOID(frameNode);
3184 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3185 CHECK_NULL_VOID(textFieldChild);
3186 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3187 CHECK_NULL_VOID(textFieldLayoutProperty);
3188 auto textFieldPaintProperty = textFieldChild->GetPaintProperty<TextFieldPaintProperty>();
3189 CHECK_NULL_VOID(textFieldPaintProperty);
3190 textFieldLayoutProperty->UpdatePlaceholderTextColor(value);
3191 textFieldPaintProperty->UpdatePlaceholderColorFlagByUser(true);
3192 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
3193 }
3194
UpdatePlaceholderFontSizeResource(const Dimension & value)3195 void SearchPattern::UpdatePlaceholderFontSizeResource(const Dimension& value)
3196 {
3197 auto frameNode = GetHost();
3198 CHECK_NULL_VOID(frameNode);
3199 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3200 CHECK_NULL_VOID(textFieldChild);
3201 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3202 CHECK_NULL_VOID(textFieldLayoutProperty);
3203 textFieldLayoutProperty->UpdatePlaceholderFontSize(value);
3204 textFieldLayoutProperty->UpdatePreferredPlaceholderLineHeightNeedToUpdate(true);
3205 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3206 }
3207
UpdateDecorationColorResource(const Color & value)3208 void SearchPattern::UpdateDecorationColorResource(const Color& value)
3209 {
3210 auto frameNode = GetHost();
3211 CHECK_NULL_VOID(frameNode);
3212 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3213 CHECK_NULL_VOID(textFieldChild);
3214 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3215 CHECK_NULL_VOID(textFieldLayoutProperty);
3216 textFieldLayoutProperty->UpdateTextDecorationColor(value);
3217 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3218 }
3219
UpdateMinFontSizeResource(const Dimension & value)3220 void SearchPattern::UpdateMinFontSizeResource(const Dimension& value)
3221 {
3222 auto frameNode = GetHost();
3223 CHECK_NULL_VOID(frameNode);
3224 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3225 CHECK_NULL_VOID(textFieldChild);
3226 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3227 CHECK_NULL_VOID(textFieldLayoutProperty);
3228 textFieldLayoutProperty->UpdateAdaptMinFontSize(value);
3229 textFieldLayoutProperty->UpdateHeightAdaptivePolicy(TextHeightAdaptivePolicy::LAYOUT_CONSTRAINT_FIRST);
3230 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3231 }
3232
UpdateMaxFontSizeResource(const Dimension & value)3233 void SearchPattern::UpdateMaxFontSizeResource(const Dimension& value)
3234 {
3235 auto frameNode = GetHost();
3236 CHECK_NULL_VOID(frameNode);
3237 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3238 CHECK_NULL_VOID(textFieldChild);
3239 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3240 CHECK_NULL_VOID(textFieldLayoutProperty);
3241 textFieldLayoutProperty->UpdateAdaptMaxFontSize(value);
3242 textFieldLayoutProperty->UpdateHeightAdaptivePolicy(TextHeightAdaptivePolicy::LAYOUT_CONSTRAINT_FIRST);
3243 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3244 }
3245
UpdateLetterSpacingResource(const Dimension & value)3246 void SearchPattern::UpdateLetterSpacingResource(const Dimension& value)
3247 {
3248 auto frameNode = GetHost();
3249 CHECK_NULL_VOID(frameNode);
3250 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3251 CHECK_NULL_VOID(textFieldChild);
3252 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3253 CHECK_NULL_VOID(textFieldLayoutProperty);
3254 textFieldLayoutProperty->UpdateLetterSpacing(value);
3255 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3256 }
3257
UpdateLineHeightResource(const Dimension & value)3258 void SearchPattern::UpdateLineHeightResource(const Dimension& value)
3259 {
3260 auto frameNode = GetHost();
3261 CHECK_NULL_VOID(frameNode);
3262 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3263 CHECK_NULL_VOID(textFieldChild);
3264 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3265 CHECK_NULL_VOID(textFieldLayoutProperty);
3266 textFieldLayoutProperty->UpdateLineHeight(value);
3267 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3268 }
3269
UpdateMinFontScaleResource(const float value)3270 void SearchPattern::UpdateMinFontScaleResource(const float value)
3271 {
3272 auto frameNode = GetHost();
3273 CHECK_NULL_VOID(frameNode);
3274 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3275 CHECK_NULL_VOID(textFieldChild);
3276 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3277 CHECK_NULL_VOID(textFieldLayoutProperty);
3278 auto tmpValue = LessOrEqual(value, 0.0f) ? 0.0f : value;
3279 tmpValue = GreatOrEqual(tmpValue, 1.0f) ? 1.0f : tmpValue;
3280 textFieldLayoutProperty->UpdateMinFontScale(tmpValue);
3281 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3282 }
3283
UpdateMaxFontScaleResource(const float value)3284 void SearchPattern::UpdateMaxFontScaleResource(const float value)
3285 {
3286 auto frameNode = GetHost();
3287 CHECK_NULL_VOID(frameNode);
3288 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3289 CHECK_NULL_VOID(textFieldChild);
3290 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3291 CHECK_NULL_VOID(textFieldLayoutProperty);
3292 auto tmpValue = LessOrEqual(value, 1.0f) ? 1.0f : value;
3293 textFieldLayoutProperty->UpdateMaxFontScale(std::min(tmpValue, MAX_FONT_SCALE));
3294 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3295 }
3296
UpdateSelectedBackgroundColorResource(const Color & value)3297 void SearchPattern::UpdateSelectedBackgroundColorResource(const Color& value)
3298 {
3299 auto frameNode = GetHost();
3300 CHECK_NULL_VOID(frameNode);
3301 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3302 CHECK_NULL_VOID(textFieldChild);
3303 auto textFieldPaintProperty = textFieldChild->GetPaintProperty<TextFieldPaintProperty>();
3304 CHECK_NULL_VOID(textFieldPaintProperty);
3305 textFieldPaintProperty->UpdateSelectedBackgroundColor(value);
3306 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
3307 }
3308
UpdateTextIndentResource(const Dimension & value)3309 void SearchPattern::UpdateTextIndentResource(const Dimension& value)
3310 {
3311 auto frameNode = GetHost();
3312 CHECK_NULL_VOID(frameNode);
3313 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3314 CHECK_NULL_VOID(textFieldChild);
3315 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3316 CHECK_NULL_VOID(textFieldLayoutProperty);
3317 Dimension tmpValue = value;
3318 tmpValue.SetUnit(DimensionUnit::VP);
3319 textFieldLayoutProperty->UpdateTextIndent(tmpValue);
3320 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3321 }
3322
UpdateInputFilterResource(const std::string & value)3323 void SearchPattern::UpdateInputFilterResource(const std::string& value)
3324 {
3325 auto frameNode = GetHost();
3326 CHECK_NULL_VOID(frameNode);
3327 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3328 CHECK_NULL_VOID(textFieldChild);
3329 auto textFieldPattern = textFieldChild->GetPattern<TextFieldPattern>();
3330 CHECK_NULL_VOID(textFieldPattern);
3331 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3332 CHECK_NULL_VOID(textFieldLayoutProperty);
3333 textFieldLayoutProperty->UpdateInputFilter(value);
3334 textFieldPattern->FilterInitializeText();
3335 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3336 }
3337
UpdateFontSizeResource(const Dimension & value)3338 void SearchPattern::UpdateFontSizeResource(const Dimension& value)
3339 {
3340 auto frameNode = GetHost();
3341 CHECK_NULL_VOID(frameNode);
3342 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3343 CHECK_NULL_VOID(textFieldChild);
3344 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3345 CHECK_NULL_VOID(textFieldLayoutProperty);
3346 textFieldLayoutProperty->UpdateFontSize(value);
3347 textFieldLayoutProperty->UpdatePreferredTextLineHeightNeedToUpdate(true);
3348 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3349 }
3350
UpdateBorderResource()3351 void SearchPattern::UpdateBorderResource()
3352 {
3353 auto frameNode = GetHost();
3354 CHECK_NULL_VOID(frameNode);
3355 auto renderContext = frameNode->GetRenderContext();
3356 CHECK_NULL_VOID(renderContext);
3357 auto textFieldChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
3358 CHECK_NULL_VOID(textFieldChild);
3359 auto textFieldLayoutProperty = textFieldChild->GetLayoutProperty<TextFieldLayoutProperty>();
3360 CHECK_NULL_VOID(textFieldLayoutProperty);
3361
3362 bool isRTL = textFieldLayoutProperty->GetNonAutoLayoutDirection() == TextDirection::RTL;
3363 auto borderRadiusProperty = renderContext->GetBorderRadius();
3364 CHECK_NULL_VOID(borderRadiusProperty);
3365 auto radius = borderRadiusProperty.value();
3366
3367 radius.radiusTopLeft = radius.radiusTopLeft.has_value() ? radius.radiusTopLeft :
3368 (isRTL ? radius.radiusTopEnd : radius.radiusTopStart);
3369 radius.radiusTopRight = radius.radiusTopRight.has_value() ? radius.radiusTopRight :
3370 (isRTL ? radius.radiusTopStart : radius.radiusTopEnd);
3371 radius.radiusBottomLeft = radius.radiusBottomLeft.has_value() ? radius.radiusBottomLeft :
3372 (isRTL ? radius.radiusBottomEnd : radius.radiusBottomStart);
3373 radius.radiusBottomRight = radius.radiusBottomRight.has_value() ? radius.radiusBottomRight :
3374 (isRTL ? radius.radiusBottomStart : radius.radiusBottomEnd);
3375
3376 auto textFieldPaintProperty = frameNode->GetPaintProperty<TextFieldPaintProperty>();
3377 CHECK_NULL_VOID(textFieldPaintProperty);
3378 textFieldPaintProperty->UpdateBorderRadiusFlagByUser(radius);
3379 textFieldChild->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
3380 }
3381
OnColorModeChange(uint32_t colorMode)3382 void SearchPattern::OnColorModeChange(uint32_t colorMode)
3383 {
3384 Pattern::OnColorModeChange(colorMode);
3385 auto frameNode = GetHost();
3386 CHECK_NULL_VOID(frameNode);
3387 frameNode->MarkModifyDone();
3388 }
3389
InitMargin(const RefPtr<SearchLayoutProperty> & property)3390 void SearchPattern::InitMargin(const RefPtr<SearchLayoutProperty>& property)
3391 {
3392 if (!property->GetMarginProperty()) {
3393 MarginProperty margin;
3394 margin.top = CalcLength(UP_AND_DOWN_PADDING.ConvertToPx());
3395 margin.bottom = CalcLength(UP_AND_DOWN_PADDING.ConvertToPx());
3396 property->UpdateMargin(margin);
3397 }
3398 if (property->HasUserMargin()) {
3399 return;
3400 }
3401 auto layoutPolicyProperty = property->GetLayoutPolicyProperty();
3402 CHECK_NULL_VOID(layoutPolicyProperty);
3403 MarginProperty margin;
3404 auto hasWidthPolicy = layoutPolicyProperty->widthLayoutPolicy_.has_value() &&
3405 layoutPolicyProperty->widthLayoutPolicy_.value() != LayoutCalPolicy::NO_MATCH;
3406 auto hasHeightPolicy = layoutPolicyProperty->heightLayoutPolicy_.has_value() &&
3407 layoutPolicyProperty->heightLayoutPolicy_.value() != LayoutCalPolicy::NO_MATCH;
3408 if (!hasWidthPolicy && !hasHeightPolicy) {
3409 margin.top = CalcLength(UP_AND_DOWN_PADDING.ConvertToPx());
3410 margin.bottom = CalcLength(UP_AND_DOWN_PADDING.ConvertToPx());
3411 }
3412 property->UpdateMargin(margin);
3413 }
3414
OnAttachToMainTree()3415 void SearchPattern::OnAttachToMainTree()
3416 {
3417 auto host = GetHost();
3418 // call OnAttachToMainTreeMultiThread() by multi thread Pattern::OnAttachToMainTree()
3419 THREAD_SAFE_NODE_CHECK(host, OnAttachToMainTree);
3420 }
3421 } // namespace OHOS::Ace::NG
3422