• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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