1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/search/search_pattern.h"
17 
18 #include <cstdint>
19 #include "base/geometry/dimension.h"
20 #include "core/components_ng/pattern/divider/divider_layout_property.h"
21 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
22 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
23 #endif
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_ng/base/inspector_filter.h"
30 #include "core/components_ng/base/view_stack_processor.h"
31 #include "core/components_ng/pattern/button/button_pattern.h"
32 #include "core/components_ng/pattern/divider/divider_render_property.h"
33 #include "core/components_ng/pattern/image/image_pattern.h"
34 #include "core/components_ng/pattern/search/search_model.h"
35 #include "core/components_ng/pattern/search/search_text_field.h"
36 #include "core/components_ng/pattern/text/text_layout_property.h"
37 #include "core/components_ng/pattern/text/text_pattern.h"
38 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
39 #include "core/event/touch_event.h"
40 
41 namespace OHOS::Ace::NG {
42 
43 namespace {
44 constexpr int32_t TEXTFIELD_INDEX = 0;
45 constexpr int32_t IMAGE_INDEX = 1;
46 constexpr int32_t CANCEL_IMAGE_INDEX = 2;
47 constexpr int32_t CANCEL_BUTTON_INDEX = 3;
48 constexpr int32_t BUTTON_INDEX = 4;
49 constexpr int32_t DIVIDER_INDEX = 5;
50 constexpr int32_t DOUBLE = 2;
51 constexpr int32_t ERROR = -1;
52 
53 // The focus state requires an 2vp inner stroke, which should be indented by 1vp when drawn.
54 constexpr Dimension FOCUS_OFFSET = 1.0_vp;
55 constexpr Dimension UP_AND_DOWN_PADDING = 8.0_vp;
56 constexpr Dimension SYMBOL_ICON_HEIGHT = 16.0_fp;
57 constexpr Dimension ICON_MAX_SIZE = 32.0_vp;
58 constexpr float HOVER_OPACITY = 0.05f;
59 constexpr float TOUCH_OPACITY = 0.1f;
60 constexpr float MAX_FONT_SCALE = 2.0f;
61 constexpr int32_t HOVER_TO_TOUCH_DURATION = 100;
62 constexpr int32_t HOVER_DURATION = 250;
63 constexpr int32_t TOUCH_DURATION = 250;
64 
65 const std::string INSPECTOR_PREFIX = "__SearchField__";
66 const std::vector<std::string> SPECICALIZED_INSPECTOR_INDEXS = { "", "Image__", "CancelImage__", "CancelButton__",
67     "Button__" };
68 } // namespace
69 
UpdateChangeEvent(const std::string & textValue,int16_t style)70 void SearchPattern::UpdateChangeEvent(const std::string& textValue, int16_t style)
71 {
72     auto frameNode = GetHost();
73     CHECK_NULL_VOID(frameNode);
74     auto buttonHost = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(CANCEL_BUTTON_INDEX));
75     CHECK_NULL_VOID(buttonHost);
76     auto imageHost = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(CANCEL_IMAGE_INDEX));
77     CHECK_NULL_VOID(imageHost);
78     if (style == ERROR) {
79         auto layoutProperty = frameNode->GetLayoutProperty<SearchLayoutProperty>();
80         CHECK_NULL_VOID(layoutProperty);
81         style = static_cast<int16_t>(layoutProperty->GetCancelButtonStyle().value_or(CancelButtonStyle::INPUT));
82     }
83     UpdateCancelButtonStatus(textValue, style);
84     buttonHost->MarkModifyDone();
85     imageHost->MarkModifyDone();
86     buttonHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
87     imageHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
88     if (imageHost->GetTag() == V2::SYMBOL_ETS_TAG) {
89         auto textLayoutProperty = imageHost->GetLayoutProperty<TextLayoutProperty>();
90         CHECK_NULL_VOID(textLayoutProperty);
91         auto layoutConstraint = textLayoutProperty->GetLayoutConstraint();
92         auto textLayoutWrapper = imageHost->CreateLayoutWrapper();
93         CHECK_NULL_VOID(textLayoutWrapper);
94         ScopedLayout scope(frameNode->GetContext());
95         textLayoutWrapper->Measure(layoutConstraint);
96     }
97 }
98 
UpdateCancelButtonStatus(const std::string & textValue,int16_t style)99 void SearchPattern::UpdateCancelButtonStatus(const std::string& textValue, int16_t style)
100 {
101     auto frameNode = GetHost();
102     CHECK_NULL_VOID(frameNode);
103     auto buttonHost = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(CANCEL_BUTTON_INDEX));
104     CHECK_NULL_VOID(buttonHost);
105     auto imageHost = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(CANCEL_IMAGE_INDEX));
106     CHECK_NULL_VOID(imageHost);
107     auto cancelButtonRenderContext = buttonHost->GetRenderContext();
108     CHECK_NULL_VOID(cancelButtonRenderContext);
109     auto cancelImageRenderContext = imageHost->GetRenderContext();
110     CHECK_NULL_VOID(cancelImageRenderContext);
111     auto cancelButtonEvent = buttonHost->GetEventHub<ButtonEventHub>();
112     CHECK_NULL_VOID(cancelButtonEvent);
113     auto buttonLayoutProperty = buttonHost->GetLayoutProperty<LayoutProperty>();
114     CHECK_NULL_VOID(buttonLayoutProperty);
115     auto imageLayoutProperty = imageHost->GetLayoutProperty<LayoutProperty>();
116     CHECK_NULL_VOID(imageLayoutProperty);
117     bool isEventEnabled = IsEventEnabled(textValue, style);
118     if (isEventEnabled) {
119         cancelButtonRenderContext->UpdateOpacity(1.0);
120         cancelImageRenderContext->UpdateOpacity(1.0);
121         cancelButtonEvent->SetEnabled(true);
122         buttonLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
123         imageLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
124     } else {
125         cancelButtonRenderContext->UpdateOpacity(0.0);
126         cancelImageRenderContext->UpdateOpacity(0.0);
127         cancelButtonEvent->SetEnabled(false);
128         buttonLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
129         imageLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
130     }
131     if (imageHost->GetTag() == V2::IMAGE_ETS_TAG) {
132         auto imageEvent = imageHost->GetEventHub<ImageEventHub>();
133         CHECK_NULL_VOID(imageEvent);
134         imageEvent->SetEnabled(isEventEnabled);
135     }
136 }
137 
IsEventEnabled(const std::string & textValue,int16_t style)138 bool SearchPattern::IsEventEnabled(const std::string& textValue, int16_t style)
139 {
140     return (style == static_cast<int16_t>(CancelButtonStyle::CONSTANT)) ||
141            ((style == static_cast<int16_t>(CancelButtonStyle::INPUT)) && !textValue.empty());
142 }
143 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig &)144 bool SearchPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& /*config*/)
145 {
146     auto geometryNode = dirty->GetGeometryNode();
147     CHECK_NULL_RETURN(geometryNode, true);
148     searchSize_ = geometryNode->GetContentSize();
149     searchOffset_ = geometryNode->GetContentOffset();
150 
151     auto textFieldLayoutWrapper = dirty->GetOrCreateChildByIndex(TEXTFIELD_INDEX);
152     CHECK_NULL_RETURN(textFieldLayoutWrapper, true);
153     auto textFieldGeometryNode = textFieldLayoutWrapper->GetGeometryNode();
154     CHECK_NULL_RETURN(textFieldGeometryNode, true);
155     textFieldOffset_ = textFieldGeometryNode->GetFrameOffset();
156     textFieldSize_ = textFieldGeometryNode->GetFrameSize();
157 
158     auto buttonLayoutWrapper = dirty->GetOrCreateChildByIndex(BUTTON_INDEX);
159     CHECK_NULL_RETURN(buttonLayoutWrapper, true);
160     auto buttonGeometryNode = buttonLayoutWrapper->GetGeometryNode();
161     CHECK_NULL_RETURN(buttonGeometryNode, true);
162     buttonOffset_ = buttonGeometryNode->GetFrameOffset();
163 
164     auto buttonNode = buttonLayoutWrapper->GetHostNode();
165     CHECK_NULL_RETURN(buttonNode, true);
166     auto searchButtonEvent = buttonNode->GetEventHub<ButtonEventHub>();
167     CHECK_NULL_RETURN(searchButtonEvent, true);
168 
169     if (!searchButtonEvent->IsEnabled()) {
170         buttonSize_.Reset();
171     } else {
172         buttonSize_ = buttonGeometryNode->GetFrameSize();
173     }
174 
175     auto cancelButtonLayoutWrapper = dirty->GetOrCreateChildByIndex(CANCEL_BUTTON_INDEX);
176     CHECK_NULL_RETURN(cancelButtonLayoutWrapper, true);
177     auto cancelButtonGeometryNode = cancelButtonLayoutWrapper->GetGeometryNode();
178     CHECK_NULL_RETURN(cancelButtonGeometryNode, true);
179 
180     auto cancelButtonNode = cancelButtonLayoutWrapper->GetHostNode();
181     CHECK_NULL_RETURN(cancelButtonNode, true);
182     auto cancelButtonEvent = cancelButtonNode->GetEventHub<ButtonEventHub>();
183     CHECK_NULL_RETURN(cancelButtonEvent, true);
184     cancelButtonOffset_ = cancelButtonGeometryNode->GetFrameOffset();
185     if (!cancelButtonEvent->IsEnabled()) {
186         cancelButtonSize_.Reset();
187     } else {
188         cancelButtonSize_ = cancelButtonGeometryNode->GetFrameSize();
189     }
190     SetAccessibilityClearAction();
191     return true;
192 }
193 
SetAccessibilityClearAction()194 void SearchPattern::SetAccessibilityClearAction()
195 {
196     auto host = GetHost();
197     CHECK_NULL_VOID(host);
198     auto cancelButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(CANCEL_BUTTON_INDEX));
199     CHECK_NULL_VOID(cancelButtonFrameNode);
200     auto textAccessibilityProperty = cancelButtonFrameNode->GetAccessibilityProperty<AccessibilityProperty>();
201     CHECK_NULL_VOID(textAccessibilityProperty);
202     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
203     CHECK_NULL_VOID(textFieldFrameNode);
204     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
205     CHECK_NULL_VOID(textFieldPattern);
206     auto layoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
207     CHECK_NULL_VOID(layoutProperty);
208     auto cleanNodeStyle = layoutProperty->GetCleanNodeStyleValue(CleanNodeStyle::INPUT);
209     auto hasContent = cleanNodeStyle == CleanNodeStyle::CONSTANT ||
210                         (cleanNodeStyle == CleanNodeStyle::INPUT && textFieldPattern->IsOperation());
211     textAccessibilityProperty->SetAccessibilityText(hasContent ? textFieldPattern->GetCancelButton() : "");
212 }
213 
OnModifyDone()214 void SearchPattern::OnModifyDone()
215 {
216     Pattern::OnModifyDone();
217     auto host = GetHost();
218     CHECK_NULL_VOID(host);
219     auto layoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
220     CHECK_NULL_VOID(layoutProperty);
221     if (!layoutProperty->GetMarginProperty()) {
222         MarginProperty margin;
223         margin.top = CalcLength(UP_AND_DOWN_PADDING.ConvertToPx());
224         margin.bottom = CalcLength(UP_AND_DOWN_PADDING.ConvertToPx());
225         layoutProperty->UpdateMargin(margin);
226     }
227 
228     HandleBackgroundColor();
229 
230     auto searchButton = layoutProperty->GetSearchButton();
231     searchButton_ = searchButton.has_value() ? searchButton->value() : "";
232     InitSearchController();
233     auto imageFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(IMAGE_INDEX));
234     CHECK_NULL_VOID(imageFrameNode);
235     imageFrameNode->MarkModifyDone();
236     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(BUTTON_INDEX));
237     CHECK_NULL_VOID(buttonFrameNode);
238     auto buttonLayoutProperty = buttonFrameNode->GetLayoutProperty<ButtonLayoutProperty>();
239     CHECK_NULL_VOID(buttonLayoutProperty);
240     buttonLayoutProperty->UpdateVisibility(searchButton.has_value() ? VisibleType::VISIBLE : VisibleType::GONE);
241     buttonLayoutProperty->UpdateLabel(searchButton_);
242     buttonLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
243     buttonFrameNode->MarkModifyDone();
244 
245     auto searchButtonEvent = buttonFrameNode->GetEventHub<ButtonEventHub>();
246     isSearchButtonEnabled_ = searchButtonEvent->IsEnabled();
247 
248     UpdateCancelButton();
249     UpdateDivider();
250     InitButtonAndImageClickEvent();
251     InitCancelButtonClickEvent();
252     InitTextFieldValueChangeEvent();
253     InitTextFieldDragEvent();
254     InitTextFieldClickEvent();
255     InitButtonMouseAndTouchEvent();
256     HandleTouchableAndHitTestMode();
257     auto focusHub = host->GetFocusHub();
258     CHECK_NULL_VOID(focusHub);
259     InitOnKeyEvent(focusHub);
260     InitFocusEvent(focusHub);
261     InitClickEvent();
262     HandleEnabled();
263     SetAccessibilityAction();
264 }
265 
UpdateCancelButton()266 void SearchPattern::UpdateCancelButton()
267 {
268     auto host = GetHost();
269     CHECK_NULL_VOID(host);
270     auto cancelButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(CANCEL_BUTTON_INDEX));
271     CHECK_NULL_VOID(cancelButtonFrameNode);
272     auto cancelButtonLayoutProperty = cancelButtonFrameNode->GetLayoutProperty<ButtonLayoutProperty>();
273     CHECK_NULL_VOID(cancelButtonLayoutProperty);
274     cancelButtonLayoutProperty->UpdateLabel("");
275     cancelButtonFrameNode->MarkModifyDone();
276 }
277 
UpdateDivider()278 void SearchPattern::UpdateDivider()
279 {
280     auto host = GetHost();
281     CHECK_NULL_VOID(host);
282     auto layoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
283     CHECK_NULL_VOID(layoutProperty);
284     auto dividerFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(DIVIDER_INDEX));
285     CHECK_NULL_VOID(dividerFrameNode);
286     auto dividerLayoutProperty = dividerFrameNode->GetLayoutProperty<DividerLayoutProperty>();
287     CHECK_NULL_VOID(dividerLayoutProperty);
288     auto searchButton = layoutProperty->GetSearchButton();
289     dividerLayoutProperty->UpdateVisibility(searchButton.has_value() ? VisibleType::VISIBLE : VisibleType::GONE);
290     dividerFrameNode->MarkModifyDone();
291 }
292 
SetAccessibilityAction()293 void SearchPattern::SetAccessibilityAction()
294 {
295     auto host = GetHost();
296     CHECK_NULL_VOID(host);
297     auto textAccessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
298     CHECK_NULL_VOID(textAccessibilityProperty);
299     textAccessibilityProperty->SetActionSetSelection(
300         [weak = WeakClaim(this)](int32_t start, int32_t end, bool isForward) {
301         auto pattern = weak.Upgrade();
302         CHECK_NULL_VOID(pattern);
303         auto host = pattern->GetHost();
304         CHECK_NULL_VOID(host);
305         auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
306         CHECK_NULL_VOID(textFieldFrameNode);
307         auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
308         CHECK_NULL_VOID(textFieldPattern);
309         textFieldPattern->SetSelectionFlag(start, end, std::nullopt, isForward);
310     });
311 
312     textAccessibilityProperty->SetActionSetIndex([weakPtr = WeakClaim(this)](int32_t index) {
313         const auto& pattern = weakPtr.Upgrade();
314         CHECK_NULL_VOID(pattern);
315         pattern->HandleCaretPosition(index);
316     });
317 
318     textAccessibilityProperty->SetActionGetIndex([weakPtr = WeakClaim(this)]() -> int32_t {
319         const auto& pattern = weakPtr.Upgrade();
320         CHECK_NULL_RETURN(pattern, -1);
321         auto index = pattern->HandleGetCaretIndex();
322         return index;
323     });
324     SetSearchFieldAccessibilityAction();
325     SetSearchButtonAccessibilityAction();
326 }
327 
SetSearchFieldAccessibilityAction()328 void SearchPattern::SetSearchFieldAccessibilityAction()
329 {
330     auto host = GetHost();
331     CHECK_NULL_VOID(host);
332     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
333     auto textFieldAccessibilityProperty = textFieldFrameNode->GetAccessibilityProperty<AccessibilityProperty>();
334     textFieldAccessibilityProperty->SetActionClick([weak = WeakClaim(this)]() {
335         auto pattern = weak.Upgrade();
336         CHECK_NULL_VOID(pattern);
337         auto host = pattern->GetHost();
338         CHECK_NULL_VOID(host);
339         auto gesture = host->GetOrCreateGestureEventHub();
340         CHECK_NULL_VOID(gesture);
341         auto actuator = gesture->GetUserClickEventActuator();
342         CHECK_NULL_VOID(actuator);
343         auto callBack = actuator->GetClickEvent();
344         CHECK_NULL_VOID(callBack);
345         GestureEvent gestureEvent;
346         callBack(gestureEvent);
347     });
348 
349     auto textAccessibilityProperty = host->GetAccessibilityProperty<AccessibilityProperty>();
350     textAccessibilityProperty->SetActionSetText([weak = WeakClaim(this)](const std::string& value) {
351         auto pattern = weak.Upgrade();
352         CHECK_NULL_VOID(pattern);
353         auto host = pattern->GetHost();
354         CHECK_NULL_VOID(host);
355         auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
356         CHECK_NULL_VOID(textFieldFrameNode);
357         auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
358         CHECK_NULL_VOID(textFieldPattern);
359         textFieldPattern->InsertValue(value);
360     });
361 }
362 
SetSearchButtonAccessibilityAction()363 void SearchPattern::SetSearchButtonAccessibilityAction()
364 {
365     auto host = GetHost();
366     CHECK_NULL_VOID(host);
367     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(BUTTON_INDEX));
368     CHECK_NULL_VOID(buttonFrameNode);
369     auto searchButtonAccessibilityProperty = buttonFrameNode->GetAccessibilityProperty<AccessibilityProperty>();
370     CHECK_NULL_VOID(searchButtonAccessibilityProperty);
371     searchButtonAccessibilityProperty->SetAccessibilityLevel("yes");
372     searchButtonAccessibilityProperty->SetAccessibilityGroup(true);
373 }
374 
HandleBackgroundColor()375 void SearchPattern::HandleBackgroundColor()
376 {
377     auto host = GetHost();
378     CHECK_NULL_VOID(host);
379     auto renderContext = host->GetRenderContext();
380     CHECK_NULL_VOID(renderContext);
381     auto pipeline = host->GetContext();
382     CHECK_NULL_VOID(pipeline);
383     auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>();
384     CHECK_NULL_VOID(textFieldTheme);
385     if (!renderContext->HasBackgroundColor()) {
386         renderContext->UpdateBackgroundColor(textFieldTheme->GetBgColor());
387     }
388 }
389 
HandleEnabled()390 void SearchPattern::HandleEnabled()
391 {
392     auto host = GetHost();
393     CHECK_NULL_VOID(host);
394     auto searchEventHub = host->GetEventHub<EventHub>();
395     CHECK_NULL_VOID(searchEventHub);
396     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
397     CHECK_NULL_VOID(textFieldFrameNode);
398     auto eventHub = textFieldFrameNode->GetEventHub<TextFieldEventHub>();
399     eventHub->SetEnabled(searchEventHub->IsEnabled() ? true : false);
400     auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
401     CHECK_NULL_VOID(textFieldLayoutProperty);
402     auto searchLayoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
403     CHECK_NULL_VOID(searchLayoutProperty);
404     textFieldLayoutProperty->UpdateLayoutDirection(searchLayoutProperty->GetLayoutDirection());
405     textFieldFrameNode->MarkModifyDone();
406 }
407 
HandleTouchableAndHitTestMode()408 void SearchPattern::HandleTouchableAndHitTestMode()
409 {
410     auto host = GetHost();
411     CHECK_NULL_VOID(host);
412     auto searchEventHub = host->GetEventHub<EventHub>();
413     CHECK_NULL_VOID(searchEventHub);
414     auto searchGestureHub = searchEventHub->GetGestureEventHub();
415     CHECK_NULL_VOID(searchGestureHub);
416     bool searchTouchable = true;
417     HitTestMode searchHitTestMode = HitTestMode::HTMDEFAULT;
418     if (searchGestureHub) {
419         searchTouchable = searchGestureHub->GetTouchable();
420         searchHitTestMode = searchGestureHub->GetHitTestMode();
421     }
422     for (int32_t childIndex = TEXTFIELD_INDEX; childIndex <= BUTTON_INDEX; childIndex++) {
423         auto childFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childIndex));
424         CHECK_NULL_VOID(childFrameNode);
425         auto childEventHub = childFrameNode->GetEventHub<EventHub>();
426         auto childGestureHub = childEventHub->GetGestureEventHub();
427         CHECK_NULL_VOID(childGestureHub);
428         childGestureHub->SetTouchable(searchTouchable);
429         childGestureHub->SetHitTestMode(searchHitTestMode);
430         childFrameNode->MarkModifyDone();
431     }
432 }
433 
InitButtonMouseAndTouchEvent()434 void SearchPattern::InitButtonMouseAndTouchEvent()
435 {
436     InitButtonMouseEvent(searchButtonMouseEvent_, BUTTON_INDEX);
437     InitButtonMouseEvent(cancelButtonMouseEvent_, CANCEL_BUTTON_INDEX);
438     InitButtonTouchEvent(searchButtonTouchListener_, BUTTON_INDEX);
439     InitButtonTouchEvent(cancelButtonTouchListener_, CANCEL_BUTTON_INDEX);
440 }
441 
InitTextFieldValueChangeEvent()442 void SearchPattern::InitTextFieldValueChangeEvent()
443 {
444     auto host = GetHost();
445     CHECK_NULL_VOID(host);
446     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
447     CHECK_NULL_VOID(textFieldFrameNode);
448     auto eventHub = textFieldFrameNode->GetEventHub<TextFieldEventHub>();
449     CHECK_NULL_VOID(eventHub);
450     if (!eventHub->GetOnChange()) {
451         auto searchChangeFunc = [weak = AceType::WeakClaim(this)](const std::string& value, PreviewText& previewText) {
452             auto searchPattern = weak.Upgrade();
453             searchPattern->UpdateChangeEvent(value);
454         };
455         eventHub->SetOnChange(std::move(searchChangeFunc));
456     }
457 }
458 
InitTextFieldDragEvent()459 void SearchPattern::InitTextFieldDragEvent()
460 {
461     auto host = GetHost();
462     CHECK_NULL_VOID(host);
463     auto searchEventHub = host->GetEventHub<EventHub>();
464     CHECK_NULL_VOID(searchEventHub);
465     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
466     CHECK_NULL_VOID(textFieldFrameNode);
467     auto textFieldEventHub = textFieldFrameNode->GetEventHub<EventHub>();
468     CHECK_NULL_VOID(textFieldEventHub);
469 
470     textFieldFrameNode->SetDragPreview(host->GetDragPreview());
471 
472     auto dragStart = searchEventHub->GetOnDragStart();
473     if (dragStart != nullptr) {
474         textFieldEventHub->SetOnDragStart(std::move(dragStart));
475     }
476 
477     auto customerDragEnter = searchEventHub->GetCustomerOnDragFunc(DragFuncType::DRAG_ENTER);
478     if (customerDragEnter != nullptr) {
479         textFieldEventHub->SetCustomerOnDragFunc(DragFuncType::DRAG_ENTER, std::move(customerDragEnter));
480     }
481 
482     auto customerDragLeave = searchEventHub->GetCustomerOnDragFunc(DragFuncType::DRAG_LEAVE);
483     if (customerDragLeave != nullptr) {
484         textFieldEventHub->SetCustomerOnDragFunc(DragFuncType::DRAG_LEAVE, std::move(customerDragLeave));
485     }
486 
487     auto customerDragMove = searchEventHub->GetCustomerOnDragFunc(DragFuncType::DRAG_MOVE);
488     if (customerDragMove != nullptr) {
489         textFieldEventHub->SetCustomerOnDragFunc(DragFuncType::DRAG_MOVE, std::move(customerDragMove));
490     }
491 
492     auto customerDragDrop = searchEventHub->GetCustomerOnDragFunc(DragFuncType::DRAG_DROP);
493     if (customerDragDrop != nullptr) {
494         textFieldEventHub->SetCustomerOnDragFunc(DragFuncType::DRAG_DROP, std::move(customerDragDrop));
495     }
496 
497     auto customerDragEnd = searchEventHub->GetCustomerOnDragEndFunc();
498     if (customerDragEnd != nullptr) {
499         textFieldEventHub->SetCustomerOnDragFunc(DragFuncType::DRAG_END, std::move(customerDragEnd));
500     }
501 
502     searchEventHub->ClearCustomerOnDragFunc();
503     RemoveDragFrameNodeFromManager();
504 }
505 
RemoveDragFrameNodeFromManager()506 void SearchPattern::RemoveDragFrameNodeFromManager()
507 {
508     auto frameNode = GetHost();
509     CHECK_NULL_VOID(frameNode);
510     auto context = frameNode->GetContext();
511     CHECK_NULL_VOID(context);
512     auto dragDropManager = context->GetDragDropManager();
513     CHECK_NULL_VOID(dragDropManager);
514     dragDropManager->RemoveDragFrameNode(frameNode->GetId());
515 }
516 
OnAfterModifyDone()517 void SearchPattern::OnAfterModifyDone()
518 {
519     auto host = GetHost();
520     CHECK_NULL_VOID(host);
521     auto inspectorId = host->GetInspectorId().value_or("");
522     if (!inspectorId.empty()) {
523         auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
524         CHECK_NULL_VOID(textFieldFrameNode);
525         auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
526         CHECK_NULL_VOID(textFieldPattern);
527         auto text = textFieldPattern->GetTextValue();
528         Recorder::NodeDataCache::Get().PutString(host, inspectorId, text);
529     }
530 }
531 
InitButtonAndImageClickEvent()532 void SearchPattern::InitButtonAndImageClickEvent()
533 {
534     // Image click event
535     if (imageClickListener_) {
536         return;
537     }
538     auto host = GetHost();
539     CHECK_NULL_VOID(host);
540     auto imageFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(IMAGE_INDEX));
541     CHECK_NULL_VOID(imageFrameNode);
542     CHECK_NULL_VOID(!imageClickListener_);
543     auto imageGesture = imageFrameNode->GetOrCreateGestureEventHub();
544     CHECK_NULL_VOID(imageGesture);
545     auto imageClickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
546         auto searchPattern = weak.Upgrade();
547         CHECK_NULL_VOID(searchPattern);
548         searchPattern->OnClickButtonAndImage();
549     };
550     imageClickListener_ = MakeRefPtr<ClickEvent>(std::move(imageClickCallback));
551     imageGesture->AddClickEvent(imageClickListener_);
552     // Button click event
553     if (buttonClickListener_) {
554         return;
555     }
556     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(BUTTON_INDEX));
557     CHECK_NULL_VOID(buttonFrameNode);
558     CHECK_NULL_VOID(!buttonClickListener_);
559     auto buttonGesture = buttonFrameNode->GetOrCreateGestureEventHub();
560     CHECK_NULL_VOID(buttonGesture);
561     auto buttonClickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
562         auto searchPattern = weak.Upgrade();
563         CHECK_NULL_VOID(searchPattern);
564         searchPattern->OnClickButtonAndImage();
565     };
566     buttonClickListener_ = MakeRefPtr<ClickEvent>(std::move(buttonClickCallback));
567     buttonGesture->AddClickEvent(buttonClickListener_);
568 }
569 
InitCancelButtonClickEvent()570 void SearchPattern::InitCancelButtonClickEvent()
571 {
572     // CancelButton click event
573     if (cancelButtonClickListener_) {
574         return;
575     }
576     auto host = GetHost();
577     CHECK_NULL_VOID(host);
578     auto cancelButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(CANCEL_BUTTON_INDEX));
579     CHECK_NULL_VOID(cancelButtonFrameNode);
580     auto cancelButtonGesture = cancelButtonFrameNode->GetOrCreateGestureEventHub();
581     CHECK_NULL_VOID(cancelButtonGesture);
582     auto cancelButtonClickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
583         auto searchPattern = weak.Upgrade();
584         CHECK_NULL_VOID(searchPattern);
585         searchPattern->OnClickCancelButton();
586     };
587     cancelButtonClickListener_ = MakeRefPtr<ClickEvent>(std::move(cancelButtonClickCallback));
588     cancelButtonGesture->AddClickEvent(cancelButtonClickListener_);
589 }
590 
InitTextFieldClickEvent()591 void SearchPattern::InitTextFieldClickEvent()
592 {
593     if (textFieldClickListener_) {
594         return;
595     }
596     auto host = GetHost();
597     CHECK_NULL_VOID(host);
598     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
599     CHECK_NULL_VOID(textFieldFrameNode);
600     auto textFieldGesture = textFieldFrameNode->GetOrCreateGestureEventHub();
601     CHECK_NULL_VOID(textFieldGesture);
602     auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
603         auto searchPattern = weak.Upgrade();
604         CHECK_NULL_VOID(searchPattern);
605         searchPattern->OnClickTextField();
606     };
607     textFieldClickListener_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
608     textFieldGesture->AddClickEvent(textFieldClickListener_);
609 }
610 
InitSearchController()611 void SearchPattern::InitSearchController()
612 {
613     searchController_->SetCaretPosition([weak = WeakClaim(this)](int32_t caretPosition) {
614         auto search = weak.Upgrade();
615         CHECK_NULL_VOID(search);
616         search->HandleCaretPosition(caretPosition);
617     });
618 
619     searchController_->SetGetTextContentRect([weak = WeakClaim(this)]() {
620         auto search = weak.Upgrade();
621         CHECK_NULL_RETURN(search, Rect(0, 0, 0, 0));
622         auto rect = search->searchController_->GetTextContentRect();
623         search->HandleTextContentRect(rect);
624         return rect;
625     });
626 
627     searchController_->SetGetTextContentLinesNum([weak = WeakClaim(this)]() {
628         auto search = weak.Upgrade();
629         CHECK_NULL_RETURN(search, 0);
630         return search->HandleTextContentLines();
631     });
632 
633     searchController_->SetGetCaretIndex([weak = WeakClaim(this)]() {
634         auto search = weak.Upgrade();
635         CHECK_NULL_RETURN(search, ERROR);
636         return search->HandleGetCaretIndex();
637     });
638 
639     searchController_->SetGetCaretPosition([weak = WeakClaim(this)]() {
640         auto search = weak.Upgrade();
641         CHECK_NULL_RETURN(search, NG::OffsetF(ERROR, ERROR));
642         return search->HandleGetCaretPosition();
643     });
644 
645     searchController_->SetStopEditing([weak = WeakClaim(this)]() {
646         auto search = weak.Upgrade();
647         CHECK_NULL_VOID(search);
648         search->StopEditing();
649     });
650 }
651 
HandleGetCaretIndex()652 int32_t SearchPattern::HandleGetCaretIndex()
653 {
654     auto host = GetHost();
655     CHECK_NULL_RETURN(host, ERROR);
656     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
657     CHECK_NULL_RETURN(textFieldFrameNode, ERROR);
658     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
659     CHECK_NULL_RETURN(textFieldPattern, ERROR);
660     return textFieldPattern->GetCaretIndex();
661 }
662 
HandleGetCaretPosition()663 NG::OffsetF SearchPattern::HandleGetCaretPosition()
664 {
665     auto host = GetHost();
666     CHECK_NULL_RETURN(host, NG::OffsetF(ERROR, ERROR));
667     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
668     CHECK_NULL_RETURN(textFieldFrameNode, NG::OffsetF(ERROR, ERROR));
669     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
670     CHECK_NULL_RETURN(textFieldPattern, NG::OffsetF(ERROR, ERROR));
671     return textFieldPattern->GetCaretOffset();
672 }
673 
HandleCaretPosition(int32_t caretPosition)674 void SearchPattern::HandleCaretPosition(int32_t caretPosition)
675 {
676     auto host = GetHost();
677     CHECK_NULL_VOID(host);
678     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
679     CHECK_NULL_VOID(textFieldFrameNode);
680     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
681     CHECK_NULL_VOID(textFieldPattern);
682     textFieldPattern->SetCaretPosition(caretPosition);
683 }
684 
HandleTextContentRect(Rect & rect)685 void SearchPattern::HandleTextContentRect(Rect& rect)
686 {
687     auto host = GetHost();
688     CHECK_NULL_VOID(host);
689     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
690     CHECK_NULL_VOID(textFieldFrameNode);
691     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
692     CHECK_NULL_VOID(textFieldPattern);
693     RectF frameRect = textFieldPattern->GetFrameRect();
694     rect.SetLeft(rect.Left() + frameRect.Left());
695     rect.SetTop(rect.Top() + frameRect.Top());
696 }
697 
HandleTextContentLines()698 int32_t SearchPattern::HandleTextContentLines()
699 {
700     int lines = 0;
701     auto host = GetHost();
702     CHECK_NULL_RETURN(host, lines);
703     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
704     CHECK_NULL_RETURN(textFieldFrameNode, lines);
705     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
706     CHECK_NULL_RETURN(textFieldPattern, lines);
707     if (!textFieldPattern->IsOperation()) {
708         return lines;
709     }
710     RectF textRect = textFieldPattern->GetTextRect();
711 
712     if ((int32_t)textFieldPattern->GetLineHeight() == 0) {
713         return lines;
714     }
715     lines = (int32_t)textRect.Height() / (int32_t)textFieldPattern->GetLineHeight();
716     return lines;
717 }
718 
StopEditing()719 void SearchPattern::StopEditing()
720 {
721     auto host = GetHost();
722     CHECK_NULL_VOID(host);
723     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
724     CHECK_NULL_VOID(textFieldFrameNode);
725     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
726     CHECK_NULL_VOID(textFieldPattern);
727     textFieldPattern->StopEditing();
728 }
729 
OnClickButtonAndImage()730 void SearchPattern::OnClickButtonAndImage()
731 {
732     auto host = GetHost();
733     CHECK_NULL_VOID(host);
734     auto searchEventHub = host->GetEventHub<SearchEventHub>();
735     CHECK_NULL_VOID(searchEventHub);
736     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
737     CHECK_NULL_VOID(textFieldFrameNode);
738     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
739     CHECK_NULL_VOID(textFieldPattern);
740     auto text = textFieldPattern->GetTextValue();
741     // Enter key type callback
742     TextFieldCommonEvent event;
743     searchEventHub->FireOnSubmit(text, event);
744     // If the developer doesn't want to keep editing, close keyboard and select background color
745     if (!event.IsKeepEditable()) {
746         textFieldPattern->StopEditing();
747     }
748 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
749     UiSessionManager::GetInstance().ReportComponentChangeEvent("event", "Search.onSubmit");
750 #endif
751 }
752 
OnClickCancelButton()753 void SearchPattern::OnClickCancelButton()
754 {
755     auto host = GetHost();
756     CHECK_NULL_VOID(host);
757     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(host->GetChildren().front());
758     CHECK_NULL_VOID(textFieldFrameNode);
759     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
760     CHECK_NULL_VOID(textFieldPattern);
761     CHECK_NULL_VOID(!textFieldPattern->IsDragging());
762     CHECK_NULL_VOID(!textFieldPattern->IsHandleDragging());
763     focusChoice_ = FocusChoice::SEARCH;
764     textFieldPattern->InitEditingValueText("");
765     textFieldPattern->SetTextChangedAtCreation(true);
766     auto textRect = textFieldPattern->GetTextRect();
767     textRect.SetLeft(0.0f);
768     textFieldPattern->SetTextRect(textRect);
769     auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
770     CHECK_NULL_VOID(textFieldLayoutProperty);
771     textFieldLayoutProperty->UpdateValue("");
772     auto eventHub = textFieldFrameNode->GetEventHub<TextFieldEventHub>();
773     PreviewText previewText {};
774     eventHub->FireOnChange("", previewText);
775     auto focusHub = host->GetOrCreateFocusHub();
776     CHECK_NULL_VOID(focusHub);
777     focusHub->RequestFocusImmediately();
778     textFieldPattern->HandleFocusEvent();
779     textFieldFrameNode->OnAccessibilityEvent(AccessibilityEventType::REQUEST_FOCUS);
780     host->MarkModifyDone();
781     textFieldFrameNode->MarkModifyDone();
782 }
783 
OnClickTextField()784 void SearchPattern::OnClickTextField()
785 {
786     focusChoice_ = FocusChoice::SEARCH;
787     auto host = GetHost();
788     CHECK_NULL_VOID(host);
789     RoundRect focusRect;
790     GetInnerFocusPaintRect(focusRect);
791     auto focusHub = host->GetFocusHub();
792     CHECK_NULL_VOID(focusHub);
793     focusHub->PaintInnerFocusState(focusRect);
794     host->MarkModifyDone();
795 }
796 
InitOnKeyEvent(const RefPtr<FocusHub> & focusHub)797 void SearchPattern::InitOnKeyEvent(const RefPtr<FocusHub>& focusHub)
798 {
799     auto onKeyEvent = [wp = WeakClaim(this)](const KeyEvent& event) -> bool {
800         auto pattern = wp.Upgrade();
801         CHECK_NULL_RETURN(pattern, false);
802         return pattern->OnKeyEvent(event);
803     };
804     focusHub->SetOnKeyEventInternal(std::move(onKeyEvent));
805 
806     auto getInnerPaintRectCallback = [wp = WeakClaim(this)](RoundRect& paintRect) {
807         auto pattern = wp.Upgrade();
808         if (pattern) {
809             pattern->GetInnerFocusPaintRect(paintRect);
810         }
811     };
812     focusHub->SetInnerFocusPaintRectCallback(getInnerPaintRectCallback);
813 }
814 
OnKeyEvent(const KeyEvent & event)815 bool SearchPattern::OnKeyEvent(const KeyEvent& event)
816 {
817     TAG_LOGI(AceLogTag::ACE_SEARCH, "KeyAction:%{public}d, KeyCode:%{public}d", static_cast<int>(event.action),
818         static_cast<int>(event.code));
819     auto host = GetHost();
820     CHECK_NULL_RETURN(host, false);
821     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
822     CHECK_NULL_RETURN(textFieldFrameNode, false);
823     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
824     CHECK_NULL_RETURN(textFieldPattern, false);
825 
826     bool isAllTextSelected = textFieldPattern->IsSelectAll();
827     bool isCaretVisible = textFieldPattern->GetCursorVisible();
828     bool isTextEmpty = textFieldPattern->GetTextValue().empty();
829     bool isOnlyTabPressed = event.pressedCodes.size() == 1 && event.code == KeyCode::KEY_TAB;
830 
831     auto parentHub = host->GetOrCreateFocusHub()->GetParentFocusHub();
832     auto getMaxFocusableCount = [](auto self, const RefPtr<FocusHub>& focusHub) -> size_t {
833         CHECK_NULL_RETURN(focusHub, 0);
834         auto parentHub = focusHub->GetParentFocusHub();
835         return std::max(focusHub->GetFocusableCount(), self(self, parentHub));
836     };
837     constexpr int ONE = 1; // Only one focusable component on scene
838     bool isOnlyOneFocusableComponent = getMaxFocusableCount(getMaxFocusableCount, parentHub) == ONE;
839     auto container = Container::Current();
840     if (container && container->IsUIExtensionWindow()) {
841         isOnlyOneFocusableComponent = false; // UI Extension Window
842     }
843 
844     if (event.action != KeyAction::DOWN) {
845         if (event.code == KeyCode::KEY_TAB && focusChoice_ == FocusChoice::SEARCH) {
846             textFieldPattern->OnKeyEvent(event);
847         }
848         return false;
849     }
850 
851     // If the focus is on the search, press Enter to request keyboard.
852     if (event.code == KeyCode::KEY_ENTER && focusChoice_ == FocusChoice::SEARCH && !IsSearchAttached()) {
853         RequestKeyboard();
854         return true;
855     }
856     // If the focus is on the search button, press Enter to submit the content.
857     if (event.code == KeyCode::KEY_ENTER && focusChoice_ == FocusChoice::SEARCH_BUTTON) {
858         OnClickButtonAndImage();
859         return true;
860     }
861     // If the focus is on the Delete button, press Enter to delete the content.
862     if (event.code == KeyCode::KEY_ENTER && focusChoice_ == FocusChoice::CANCEL_BUTTON) {
863         OnClickCancelButton();
864         PaintFocusState();
865         return true;
866     }
867     // When press '->' or '<-', focus delete button or search button according to whether there is text in the search.
868     if (event.code == KeyCode::KEY_DPAD_LEFT || event.IsShiftWith(KeyCode::KEY_TAB)) {
869         if (focusChoice_ == FocusChoice::CANCEL_BUTTON) {
870             focusChoice_ = FocusChoice::SEARCH;
871             PaintFocusState();
872             return true;
873         }
874         if (focusChoice_ == FocusChoice::SEARCH_BUTTON) {
875             if (NearZero(cancelButtonSize_.Height())) {
876                 focusChoice_ = FocusChoice::SEARCH;
877             } else {
878                 focusChoice_ = FocusChoice::CANCEL_BUTTON;
879             }
880             PaintFocusState();
881             return true;
882         }
883         if (focusChoice_ == FocusChoice::SEARCH && isOnlyOneFocusableComponent && event.IsShiftWith(KeyCode::KEY_TAB)) {
884             if (isSearchButtonEnabled_) {
885                 focusChoice_ = FocusChoice::SEARCH_BUTTON;
886             } else if (!isTextEmpty) {
887                 focusChoice_ = FocusChoice::CANCEL_BUTTON;
888             }
889             PaintFocusState();
890             return true;
891         }
892         if (focusChoice_ == FocusChoice::SEARCH && event.IsShiftWith(KeyCode::KEY_TAB)) {
893             textFieldPattern->CloseKeyboard(true);
894             return false;
895         }
896         if (focusChoice_ == FocusChoice::SEARCH && !isAllTextSelected && !isTextEmpty) {
897             return textFieldPattern->OnKeyEvent(event);
898         }
899         if (focusChoice_ == FocusChoice::SEARCH && isAllTextSelected && !isCaretVisible &&
900             event.code == KeyCode::KEY_DPAD_LEFT) {
901             return true; // no action
902         }
903     }
904     if (event.code == KeyCode::KEY_DPAD_RIGHT || (event.pressedCodes.size() == 1 && event.code == KeyCode::KEY_TAB)) {
905         if (focusChoice_ == FocusChoice::SEARCH && (isAllTextSelected || isTextEmpty || isOnlyTabPressed)) {
906             if (NearZero(cancelButtonSize_.Height()) && !isSearchButtonEnabled_ &&
907                 event.code == KeyCode::KEY_DPAD_RIGHT) {
908                 return true;
909             } else if (NearZero(cancelButtonSize_.Height()) && !isSearchButtonEnabled_) {
910                 textFieldPattern->CloseKeyboard(true);
911                 return false;
912             }
913             if (NearZero(cancelButtonSize_.Height())) {
914                 focusChoice_ = FocusChoice::SEARCH_BUTTON;
915             } else {
916                 focusChoice_ = FocusChoice::CANCEL_BUTTON;
917             }
918             PaintFocusState();
919             return true;
920         } else if (focusChoice_ == FocusChoice::SEARCH && event.code == KeyCode::KEY_DPAD_RIGHT) {
921             textFieldPattern->OnKeyEvent(event);
922             return true;
923         }
924         if (focusChoice_ == FocusChoice::CANCEL_BUTTON) {
925             if (!NearZero(cancelButtonSize_.Height()) && (!isSearchButtonEnabled_) &&
926                 (event.code == KeyCode::KEY_DPAD_RIGHT)) {
927                 return false; // Go out of Search
928             }
929             if (isOnlyOneFocusableComponent && isOnlyTabPressed && !isSearchButtonEnabled_) {
930                 focusChoice_ = FocusChoice::SEARCH;
931                 PaintFocusState();
932                 return true;
933             }
934             if (!isSearchButtonEnabled_) {
935                 return !isOnlyTabPressed; // go outside if Tab pressed, or no action if arrow pressed
936             }
937             focusChoice_ = FocusChoice::SEARCH_BUTTON;
938             PaintFocusState();
939             return true;
940         }
941         if (focusChoice_ == FocusChoice::SEARCH_BUTTON && isOnlyOneFocusableComponent && isOnlyTabPressed) {
942             focusChoice_ = FocusChoice::SEARCH;
943             PaintFocusState();
944             return true;
945         }
946         if (focusChoice_ == FocusChoice::SEARCH_BUTTON &&
947             (event.pressedCodes.size() == 1 && event.code == KeyCode::KEY_TAB)) {
948             textFieldPattern->CloseKeyboard(true);
949             return false;
950         }
951         if (focusChoice_ == FocusChoice::SEARCH_BUTTON && isSearchButtonEnabled_ &&
952             (event.code == KeyCode::KEY_DPAD_RIGHT)) {
953             return false; // Go out of Search
954         }
955     }
956 
957     if (focusChoice_ == FocusChoice::SEARCH) {
958         return textFieldPattern->OnKeyEvent(event);
959     } else {
960         return true;
961     }
962 }
963 
IsSearchAttached()964 bool SearchPattern::IsSearchAttached()
965 {
966     auto host = GetHost();
967     CHECK_NULL_RETURN(host, false);
968     auto context = host->GetContext();
969     CHECK_NULL_RETURN(context, false);
970     auto textFieldManager = DynamicCast<TextFieldManagerNG>(context->GetTextFieldManager());
971     CHECK_NULL_RETURN(textFieldManager, false);
972     return textFieldManager->GetIsImeAttached();
973 }
974 
PaintFocusState(bool recoverFlag)975 void SearchPattern::PaintFocusState(bool recoverFlag)
976 {
977     TAG_LOGI(AceLogTag::ACE_SEARCH, "Focus Choice = %{public}d", static_cast<int>(focusChoice_));
978     auto host = GetHost();
979     CHECK_NULL_VOID(host);
980     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
981     CHECK_NULL_VOID(textFieldFrameNode);
982     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
983     CHECK_NULL_VOID(textFieldPattern);
984     auto searchTextFieldPattern = DynamicCast<SearchTextFieldPattern>(textFieldPattern);
985     CHECK_NULL_VOID(searchTextFieldPattern);
986 
987     if (focusChoice_ == FocusChoice::SEARCH) {
988         if (!recoverFlag) {
989             if (!textFieldPattern->GetTextValue().empty()) {
990                 textFieldPattern->NeedRequestKeyboard();
991                 textFieldPattern->SearchRequestKeyboard();
992                 textFieldPattern->HandleOnSelectAll(false); // Select all text
993                 searchTextFieldPattern->ResetSearchRequestStopTwinkling(); // reset flag
994                 textFieldPattern->StopTwinkling(); // Hide caret
995             } else {
996                 textFieldPattern->HandleFocusEvent(); // Show caret
997                 searchTextFieldPattern->SearchRequestStartTwinkling();
998             }
999         } else {
1000             textFieldPattern->HandleFocusEvent();
1001             searchTextFieldPattern->SearchRequestStartTwinkling();
1002         }
1003     } else {
1004         textFieldPattern->CloseKeyboard(true);
1005         searchTextFieldPattern->SearchRequestStopTwinkling(); // Hide caret
1006     }
1007 
1008     auto context = host->GetContext();
1009     CHECK_NULL_VOID(context);
1010     RoundRect focusRect;
1011     GetInnerFocusPaintRect(focusRect);
1012     auto focusHub = host->GetFocusHub();
1013     CHECK_NULL_VOID(focusHub);
1014     focusHub->PaintInnerFocusState(focusRect, true);
1015     host->MarkModifyDone();
1016 }
1017 
GetInnerFocusPaintRect(RoundRect & paintRect)1018 void SearchPattern::GetInnerFocusPaintRect(RoundRect& paintRect)
1019 {
1020     float originX = 0.0f;
1021     float originY = 0.0f;
1022     float endX = 0.0f;
1023     float endY = 0.0f;
1024     float radiusTopLeft = 0.0f;
1025     float radiusTopRight = 0.0f;
1026     float radiusBottomLeft = 0.0f;
1027     float radiusBottomRight = 0.0f;
1028     float focusOffset = FOCUS_OFFSET.ConvertToPx();
1029     if (focusChoice_ == FocusChoice::SEARCH) {
1030         return;
1031     }
1032     if (focusChoice_ == FocusChoice::CANCEL_BUTTON) {
1033         originX = cancelButtonOffset_.GetX() + focusOffset;
1034         originY = cancelButtonOffset_.GetY() + focusOffset;
1035         endX = cancelButtonSize_.Width() + originX - DOUBLE * focusOffset;
1036         endY = cancelButtonSize_.Height() + originY - DOUBLE * focusOffset;
1037         radiusTopLeft = cancelButtonSize_.Height() / DOUBLE - focusOffset;
1038         radiusTopRight = cancelButtonSize_.Height() / DOUBLE - focusOffset;
1039         radiusBottomLeft = cancelButtonSize_.Height() / DOUBLE - focusOffset;
1040         radiusBottomRight = cancelButtonSize_.Height() / DOUBLE - focusOffset;
1041     }
1042     if (focusChoice_ == FocusChoice::SEARCH_BUTTON) {
1043         originX = buttonOffset_.GetX() + focusOffset;
1044         originY = buttonOffset_.GetY() + focusOffset;
1045         endX = buttonSize_.Width() + originX - DOUBLE * focusOffset;
1046         endY = buttonSize_.Height() + originY - DOUBLE * focusOffset;
1047         radiusTopLeft = buttonSize_.Height() / DOUBLE - focusOffset;
1048         radiusTopRight = buttonSize_.Height() / DOUBLE - focusOffset;
1049         radiusBottomLeft = buttonSize_.Height() / DOUBLE - focusOffset;
1050         radiusBottomRight = buttonSize_.Height() / DOUBLE - focusOffset;
1051     }
1052 
1053     paintRect.SetRect({ originX, originY, endX - originX, endY - originY });
1054     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS, radiusTopLeft, radiusTopLeft);
1055     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS, radiusTopRight, radiusTopRight);
1056     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS, radiusBottomLeft, radiusBottomLeft);
1057     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS, radiusBottomRight, radiusBottomRight);
1058 }
1059 
GetFocusPattern() const1060 FocusPattern SearchPattern::GetFocusPattern() const
1061 {
1062     FocusPattern focusPattern = { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION };
1063     focusPattern.SetIsFocusActiveWhenFocused(true);
1064     return focusPattern;
1065 }
1066 
RequestKeyboard()1067 void SearchPattern::RequestKeyboard()
1068 {
1069     auto host = GetHost();
1070     CHECK_NULL_VOID(host);
1071     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1072     CHECK_NULL_VOID(textFieldFrameNode);
1073     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1074     textFieldPattern->SearchRequestKeyboard();
1075 }
1076 
InitButtonTouchEvent(RefPtr<TouchEventImpl> & touchEvent,int32_t childId)1077 void SearchPattern::InitButtonTouchEvent(RefPtr<TouchEventImpl>& touchEvent, int32_t childId)
1078 {
1079     if (touchEvent) {
1080         return;
1081     }
1082     auto host = GetHost();
1083     CHECK_NULL_VOID(host);
1084     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1085     CHECK_NULL_VOID(buttonFrameNode);
1086     auto gesture = buttonFrameNode->GetOrCreateGestureEventHub();
1087     CHECK_NULL_VOID(gesture);
1088     auto eventHub = buttonFrameNode->GetEventHub<ButtonEventHub>();
1089     CHECK_NULL_VOID(eventHub);
1090     eventHub->SetStateEffect(false);
1091     auto touchTask = [weak = WeakClaim(this), childId](const TouchEventInfo& info) {
1092         auto pattern = weak.Upgrade();
1093         CHECK_NULL_VOID(pattern);
1094         auto touchType = info.GetTouches().front().GetTouchType();
1095         if (touchType == TouchType::DOWN) {
1096             pattern->OnButtonTouchDown(childId);
1097         }
1098         if (touchType == TouchType::UP || touchType == TouchType::CANCEL) {
1099             pattern->OnButtonTouchUp(childId);
1100         }
1101     };
1102     touchEvent = MakeRefPtr<TouchEventImpl>(std::move(touchTask));
1103     gesture->AddTouchEvent(touchEvent);
1104 }
1105 
InitButtonMouseEvent(RefPtr<InputEvent> & inputEvent,int32_t childId)1106 void SearchPattern::InitButtonMouseEvent(RefPtr<InputEvent>& inputEvent, int32_t childId)
1107 {
1108     if (inputEvent) {
1109         return;
1110     }
1111     auto host = GetHost();
1112     CHECK_NULL_VOID(host);
1113     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1114     CHECK_NULL_VOID(buttonFrameNode);
1115     auto eventHub = buttonFrameNode->GetEventHub<ButtonEventHub>();
1116     auto inputHub = eventHub->GetOrCreateInputEventHub();
1117     auto buttonPattern = buttonFrameNode->GetPattern<ButtonPattern>();
1118     CHECK_NULL_VOID(buttonPattern);
1119     auto buttonHoverListener = buttonPattern->GetHoverListener();
1120     inputHub->RemoveOnHoverEvent(buttonHoverListener);
1121     auto mouseTask = [weak = WeakClaim(this), childId](bool isHover) {
1122         auto pattern = weak.Upgrade();
1123         if (pattern) {
1124             pattern->HandleButtonMouseEvent(isHover, childId);
1125         }
1126     };
1127     inputEvent = MakeRefPtr<InputEvent>(std::move(mouseTask));
1128     inputHub->AddOnHoverEvent(inputEvent);
1129 }
1130 
OnButtonTouchDown(int32_t childId)1131 void SearchPattern::OnButtonTouchDown(int32_t childId)
1132 {
1133     auto host = GetHost();
1134     CHECK_NULL_VOID(host);
1135     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1136     CHECK_NULL_VOID(buttonFrameNode);
1137     auto renderContext = buttonFrameNode->GetRenderContext();
1138     CHECK_NULL_VOID(renderContext);
1139     if (childId == CANCEL_BUTTON_INDEX ? isCancelButtonHover_ : isSearchButtonHover_) {
1140         AnimateTouchAndHover(renderContext, HOVER_OPACITY, TOUCH_OPACITY, HOVER_TO_TOUCH_DURATION, Curves::SHARP);
1141     } else {
1142         AnimateTouchAndHover(renderContext, 0.0f, TOUCH_OPACITY, TOUCH_DURATION, Curves::FRICTION);
1143     }
1144 }
1145 
OnButtonTouchUp(int32_t childId)1146 void SearchPattern::OnButtonTouchUp(int32_t childId)
1147 {
1148     auto host = GetHost();
1149     CHECK_NULL_VOID(host);
1150     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1151     CHECK_NULL_VOID(buttonFrameNode);
1152     auto renderContext = buttonFrameNode->GetRenderContext();
1153     CHECK_NULL_VOID(renderContext);
1154     if (childId == CANCEL_BUTTON_INDEX ? isCancelButtonHover_ : isSearchButtonHover_) {
1155         AnimateTouchAndHover(renderContext, TOUCH_OPACITY, HOVER_OPACITY, HOVER_TO_TOUCH_DURATION, Curves::SHARP);
1156     } else {
1157         AnimateTouchAndHover(renderContext, TOUCH_OPACITY, 0.0f, TOUCH_DURATION, Curves::FRICTION);
1158     }
1159 }
1160 
SetMouseStyle(MouseFormat format)1161 void SearchPattern::SetMouseStyle(MouseFormat format)
1162 {
1163     auto host = GetHost();
1164     CHECK_NULL_VOID(host);
1165     auto pipeline = host->GetContext();
1166     CHECK_NULL_VOID(pipeline);
1167     auto windowId = pipeline->GetWindowId();
1168     auto mouseStyle = MouseStyle::CreateMouseStyle();
1169     CHECK_NULL_VOID(mouseStyle);
1170 
1171     int32_t currentPointerStyle = 0;
1172     mouseStyle->GetPointerStyle(windowId, currentPointerStyle);
1173     if (currentPointerStyle != static_cast<int32_t>(format)) {
1174         mouseStyle->SetPointerStyle(windowId, format);
1175     }
1176 }
1177 
HandleButtonMouseEvent(bool isHover,int32_t childId)1178 void SearchPattern::HandleButtonMouseEvent(bool isHover, int32_t childId)
1179 {
1180     if (childId == CANCEL_BUTTON_INDEX) {
1181         isCancelButtonHover_ = isHover;
1182     } else {
1183         isSearchButtonHover_ = isHover;
1184     }
1185     auto host = GetHost();
1186     CHECK_NULL_VOID(host);
1187     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1188     CHECK_NULL_VOID(buttonFrameNode);
1189     auto renderContext = buttonFrameNode->GetRenderContext();
1190     CHECK_NULL_VOID(renderContext);
1191     if (isHover) {
1192         AnimateTouchAndHover(renderContext, 0.0f, HOVER_OPACITY, HOVER_DURATION, Curves::FRICTION);
1193     } else {
1194         AnimateTouchAndHover(renderContext, HOVER_OPACITY, 0.0f, HOVER_DURATION, Curves::FRICTION);
1195     }
1196 }
1197 
AnimateTouchAndHover(RefPtr<RenderContext> & renderContext,float startOpacity,float endOpacity,int32_t duration,const RefPtr<Curve> & curve)1198 void SearchPattern::AnimateTouchAndHover(RefPtr<RenderContext>& renderContext, float startOpacity, float endOpacity,
1199     int32_t duration, const RefPtr<Curve>& curve)
1200 {
1201     auto colorMode = SystemProperties::GetColorMode();
1202     Color touchColorFrom = Color::FromRGBO(0, 0, 0, startOpacity);
1203     Color touchColorTo = Color::FromRGBO(0, 0, 0, endOpacity);
1204     if (colorMode == ColorMode::DARK) {
1205         touchColorFrom = Color::FromRGBO(255, 255, 255, startOpacity);
1206         touchColorTo = Color::FromRGBO(255, 255, 255, endOpacity);
1207     }
1208     Color highlightStart = renderContext->GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(touchColorFrom);
1209     Color highlightEnd = renderContext->GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(touchColorTo);
1210     renderContext->OnBackgroundColorUpdate(highlightStart);
1211     AnimationOption option = AnimationOption();
1212     option.SetDuration(duration);
1213     option.SetCurve(curve);
1214     AnimationUtils::Animate(
1215         option, [renderContext, highlightEnd]() { renderContext->OnBackgroundColorUpdate(highlightEnd); });
1216 }
1217 
ResetDragOption()1218 void SearchPattern::ResetDragOption()
1219 {
1220     ClearButtonStyle(BUTTON_INDEX);
1221     ClearButtonStyle(CANCEL_BUTTON_INDEX);
1222 }
1223 
ClearButtonStyle(int32_t childId)1224 void SearchPattern::ClearButtonStyle(int32_t childId)
1225 {
1226     auto host = GetHost();
1227     CHECK_NULL_VOID(host);
1228     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1229     CHECK_NULL_VOID(buttonFrameNode);
1230     auto renderContext = buttonFrameNode->GetRenderContext();
1231     CHECK_NULL_VOID(renderContext);
1232     AnimateTouchAndHover(renderContext, TOUCH_OPACITY, 0.0f, HOVER_TO_TOUCH_DURATION, Curves::SHARP);
1233 }
1234 
InitFocusEvent(const RefPtr<FocusHub> & focusHub)1235 void SearchPattern::InitFocusEvent(const RefPtr<FocusHub>& focusHub)
1236 {
1237     auto focusTask = [weak = WeakClaim(this)]() {
1238         auto pattern = weak.Upgrade();
1239         if (!pattern) {
1240             return;
1241         }
1242         bool backwardFocusMovement = false;
1243         bool forwardFocusMovement = false;
1244         auto host = pattern->GetHost();
1245         if (host) {
1246             auto rootHub = host->GetOrCreateFocusHub()->GetRootFocusHub();
1247             backwardFocusMovement = rootHub && rootHub->HasBackwardFocusMovementInChildren();
1248             forwardFocusMovement = rootHub && rootHub->HasForwardFocusMovementInChildren();
1249             if (rootHub) {
1250                 rootHub->ClearFocusMovementFlagsInChildren();
1251             }
1252         }
1253         pattern->HandleFocusEvent(forwardFocusMovement, backwardFocusMovement);
1254     };
1255     focusHub->SetOnFocusInternal(focusTask);
1256     auto blurTask = [weak = WeakClaim(this)]() {
1257         auto pattern = weak.Upgrade();
1258         CHECK_NULL_VOID(pattern);
1259         pattern->HandleBlurEvent();
1260     };
1261     focusHub->SetOnBlurInternal(blurTask);
1262 }
1263 
HandleFocusEvent(bool forwardFocusMovement,bool backwardFocusMovement)1264 void SearchPattern::HandleFocusEvent(bool forwardFocusMovement, bool backwardFocusMovement)
1265 {
1266     auto host = GetHost();
1267     CHECK_NULL_VOID(host);
1268     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1269     CHECK_NULL_VOID(textFieldFrameNode);
1270     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1271     CHECK_NULL_VOID(textFieldPattern);
1272 
1273     if (forwardFocusMovement || backwardFocusMovement) { // Don't update focus if no factical focus movement
1274         focusChoice_ = backwardFocusMovement ? FocusChoice::SEARCH_BUTTON : FocusChoice::SEARCH;
1275         if (focusChoice_ == FocusChoice::SEARCH_BUTTON && !isSearchButtonEnabled_) {
1276             bool isCancelHidden = NearZero(cancelButtonSize_.Height());
1277             focusChoice_ = isCancelHidden ? FocusChoice::SEARCH : FocusChoice::CANCEL_BUTTON;
1278         }
1279     }
1280     PaintFocusState(!(forwardFocusMovement || backwardFocusMovement));
1281 }
1282 
HandleBlurEvent()1283 void SearchPattern::HandleBlurEvent()
1284 {
1285     auto host = GetHost();
1286     CHECK_NULL_VOID(host);
1287     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1288     CHECK_NULL_VOID(textFieldFrameNode);
1289     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1290     CHECK_NULL_VOID(textFieldPattern);
1291     textFieldPattern->HandleBlurEvent();
1292 }
1293 
InitClickEvent()1294 void SearchPattern::InitClickEvent()
1295 {
1296     if (clickListener_) {
1297         return;
1298     }
1299     auto host = GetHost();
1300     CHECK_NULL_VOID(host);
1301     auto gesture = host->GetOrCreateGestureEventHub();
1302     CHECK_NULL_VOID(gesture);
1303     auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
1304         auto pattern = weak.Upgrade();
1305         CHECK_NULL_VOID(pattern);
1306         pattern->HandleClickEvent(info);
1307     };
1308     clickListener_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
1309     gesture->AddClickEvent(clickListener_);
1310 }
1311 
HandleClickEvent(GestureEvent & info)1312 void SearchPattern::HandleClickEvent(GestureEvent& info)
1313 {
1314     auto host = GetHost();
1315     CHECK_NULL_VOID(host);
1316     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1317     CHECK_NULL_VOID(textFieldFrameNode);
1318     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1319     CHECK_NULL_VOID(textFieldPattern);
1320     textFieldPattern->HandleClickEvent(info);
1321 }
1322 
HandleInputChildOnFocus() const1323 bool SearchPattern::HandleInputChildOnFocus() const
1324 {
1325 #if !defined(PREVIEW)
1326     return false;
1327 #endif
1328     auto focusHub = GetHost()->GetOrCreateFocusHub();
1329     focusHub->RequestFocusImmediately();
1330     return true;
1331 }
1332 
ToJsonValueForTextField(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1333 void SearchPattern::ToJsonValueForTextField(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1334 {
1335     /* no fixed attr below, just return */
1336     if (filter.IsFastFilter()) {
1337         return;
1338     }
1339     auto host = GetHost();
1340     CHECK_NULL_VOID(host);
1341     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1342     CHECK_NULL_VOID(textFieldFrameNode);
1343     auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
1344     CHECK_NULL_VOID(textFieldLayoutProperty);
1345     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1346     CHECK_NULL_VOID(textFieldPattern);
1347 
1348     json->PutExtAttr("value", textFieldPattern->GetTextValue().c_str(), filter);
1349     json->PutExtAttr("placeholder", textFieldPattern->GetPlaceHolder().c_str(), filter);
1350     json->PutExtAttr("placeholderColor", textFieldPattern->GetPlaceholderColor().c_str(), filter);
1351     json->PutExtAttr("placeholderFont", textFieldPattern->GetPlaceholderFont().c_str(), filter);
1352     json->PutExtAttr("textAlign", V2::ConvertWrapTextAlignToString(textFieldPattern->GetTextAlign()).c_str(), filter);
1353     auto textColor = textFieldLayoutProperty->GetTextColor().value_or(Color());
1354     json->PutExtAttr("fontColor", textColor.ColorToString().c_str(), filter);
1355     auto textFontJson = JsonUtil::Create(true);
1356     textFontJson->Put("fontSize", textFieldPattern->GetFontSize().c_str());
1357     textFontJson->Put("fontStyle",
1358         textFieldPattern->GetItalicFontStyle() == Ace::FontStyle::NORMAL ? "FontStyle.Normal" : "FontStyle.Italic");
1359     textFontJson->Put("fontWeight", V2::ConvertWrapFontWeightToStirng(textFieldPattern->GetFontWeight()).c_str());
1360     textFontJson->Put("fontFamily", textFieldPattern->GetFontFamily().c_str());
1361     json->PutExtAttr("textFont", textFontJson->ToString().c_str(), filter);
1362     json->PutExtAttr("copyOption",
1363         ConvertCopyOptionsToString(textFieldLayoutProperty->GetCopyOptionsValue(CopyOptions::None)).c_str(), filter);
1364     auto maxLength = GetMaxLength();
1365     json->PutExtAttr(
1366         "maxLength", GreatOrEqual(maxLength, Infinity<uint32_t>()) ? "INF" : std::to_string(maxLength).c_str(), filter);
1367     json->PutExtAttr("type", SearchTypeToString().c_str(), filter);
1368     textFieldLayoutProperty->HasCopyOptions();
1369     json->PutExtAttr(
1370         "letterSpacing", textFieldLayoutProperty->GetLetterSpacing().value_or(Dimension()).ToString().c_str(), filter);
1371     json->PutExtAttr(
1372         "lineHeight", textFieldLayoutProperty->GetLineHeight().value_or(0.0_vp).ToString().c_str(), filter);
1373     auto jsonDecoration = JsonUtil::Create(true);
1374     std::string type = V2::ConvertWrapTextDecorationToStirng(
1375         textFieldLayoutProperty->GetTextDecoration().value_or(TextDecoration::NONE));
1376     jsonDecoration->Put("type", type.c_str());
1377     jsonDecoration->Put(
1378         "color", textFieldLayoutProperty->GetTextDecorationColor().value_or(Color::BLACK).ColorToString().c_str());
1379     std::string style = V2::ConvertWrapTextDecorationStyleToString(
1380         textFieldLayoutProperty->GetTextDecorationStyle().value_or(TextDecorationStyle::SOLID));
1381     jsonDecoration->Put("style", style.c_str());
1382     json->PutExtAttr("decoration", jsonDecoration->ToString().c_str(), filter);
1383     json->PutExtAttr(
1384         "minFontSize", textFieldLayoutProperty->GetAdaptMinFontSize().value_or(Dimension()).ToString().c_str(), filter);
1385     json->PutExtAttr(
1386         "maxFontSize", textFieldLayoutProperty->GetAdaptMaxFontSize().value_or(Dimension()).ToString().c_str(), filter);
1387     json->PutExtAttr("inputFilter", textFieldLayoutProperty->GetInputFilterValue("").c_str(), filter);
1388     json->PutExtAttr(
1389         "textIndent", textFieldLayoutProperty->GetTextIndent().value_or(0.0_vp).ToString().c_str(), filter);
1390     json->PutExtAttr("enablePreviewText", textFieldPattern->GetSupportPreviewText(), filter);
1391     textFieldPattern->ToJsonValueSelectOverlay(json, filter);
1392 }
1393 
SearchTypeToString() const1394 std::string SearchPattern::SearchTypeToString() const
1395 {
1396     auto host = GetHost();
1397     CHECK_NULL_RETURN(host, "");
1398     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1399     CHECK_NULL_RETURN(textFieldFrameNode, "");
1400     auto layoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
1401     CHECK_NULL_RETURN(layoutProperty, "");
1402     switch (layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED)) {
1403         case TextInputType::NUMBER:
1404             return "SearchType.NUMBER";
1405         case TextInputType::EMAIL_ADDRESS:
1406             return "SearchType.EMAIL";
1407         case TextInputType::PHONE:
1408             return "SearchType.PHONE_NUMBER";
1409         case TextInputType::URL:
1410             return "SearchType.URL";
1411         default:
1412             return "SearchType.NORMAL";
1413     }
1414 }
1415 
ToJsonValueForSearchIcon(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1416 void SearchPattern::ToJsonValueForSearchIcon(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1417 {
1418     /* no fixed attr below, just return */
1419     if (filter.IsFastFilter()) {
1420         return;
1421     }
1422     auto host = GetHost();
1423     CHECK_NULL_VOID(host);
1424     auto searchIconFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(IMAGE_INDEX));
1425     CHECK_NULL_VOID(searchIconFrameNode);
1426     auto searchIconJson = JsonUtil::Create(true);
1427 
1428     // icon size
1429     auto searchIconGeometryNode = searchIconFrameNode->GetGeometryNode();
1430     CHECK_NULL_VOID(searchIconGeometryNode);
1431     auto searchIconFrameSize = searchIconGeometryNode->GetFrameSize().Width();
1432     auto searchLayoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
1433     CHECK_NULL_VOID(searchLayoutProperty);
1434     auto searchIconSize = searchLayoutProperty->GetSearchIconUDSizeValue(Dimension(searchIconFrameSize)).ConvertToPx();
1435     searchIconJson->Put("size", Dimension(searchIconSize, DimensionUnit::PX).ToString().c_str());
1436 
1437     if (searchIconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
1438         auto symbolLayoutProperty = searchIconFrameNode->GetLayoutProperty<TextLayoutProperty>();
1439         CHECK_NULL_VOID(symbolLayoutProperty);
1440         // icon color
1441         auto searchIconColor = symbolLayoutProperty->GetSymbolColorList();
1442         if (searchIconColor.has_value()) {
1443             searchIconJson->Put("color", SymbolColorToString(searchIconColor.value()).c_str());
1444         } else {
1445             searchIconJson->Put("color", std::string("").c_str());
1446         }
1447 
1448         // icon path
1449         auto symbolSourceInfo = symbolLayoutProperty->GetSymbolSourceInfo().value_or(SymbolSourceInfo());
1450         searchIconJson->Put("src", static_cast<int64_t>(symbolSourceInfo.GetUnicode()));
1451         json->PutExtAttr("icon", static_cast<int64_t>(symbolSourceInfo.GetUnicode()), filter);
1452         json->PutExtAttr("searchIcon", searchIconJson, filter);
1453     } else {
1454         auto imageLayoutProperty = searchIconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
1455         CHECK_NULL_VOID(imageLayoutProperty);
1456         // icon color
1457         auto searchIconColor = imageLayoutProperty->GetImageSourceInfo()->GetFillColor().value_or(Color());
1458         searchIconJson->Put("color", searchIconColor.ColorToString().c_str());
1459 
1460         // icon path
1461         auto searchIconPath = imageLayoutProperty->GetImageSourceInfo()->GetSrc();
1462         searchIconJson->Put("src", searchIconPath.c_str());
1463         json->PutExtAttr("icon", searchIconPath.c_str(), filter);
1464         json->PutExtAttr("searchIcon", searchIconJson, filter);
1465     }
1466 }
1467 
ToJsonValueForCancelButton(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1468 void SearchPattern::ToJsonValueForCancelButton(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1469 {
1470     /* no fixed attr below, just return */
1471     if (filter.IsFastFilter()) {
1472         return;
1473     }
1474     auto host = GetHost();
1475     CHECK_NULL_VOID(host);
1476     auto layoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
1477     CHECK_NULL_VOID(layoutProperty);
1478     auto cancelImageFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(CANCEL_IMAGE_INDEX));
1479     CHECK_NULL_VOID(cancelImageFrameNode);
1480     auto cancelButtonJson = JsonUtil::Create(true);
1481     ToJsonValueForCancelButtonStyle(
1482         cancelButtonJson, layoutProperty->GetCancelButtonStyle().value_or(CancelButtonStyle::INPUT));
1483     auto cancelIconJson = JsonUtil::Create(true);
1484     // icon size
1485     auto cancelIconGeometryNode = cancelImageFrameNode->GetGeometryNode();
1486     CHECK_NULL_VOID(cancelIconGeometryNode);
1487     auto cancelIconFrameSize = cancelIconGeometryNode->GetFrameSize().Width();
1488     auto searchLayoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
1489     CHECK_NULL_VOID(searchLayoutProperty);
1490     auto cancelIconSize =
1491         searchLayoutProperty->GetCancelButtonUDSizeValue(Dimension(cancelIconFrameSize)).ConvertToPx();
1492     cancelIconJson->Put("size", Dimension(cancelIconSize, DimensionUnit::PX).ToString().c_str());
1493     if (cancelImageFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
1494         auto symbolLayoutProperty = cancelImageFrameNode->GetLayoutProperty<TextLayoutProperty>();
1495         CHECK_NULL_VOID(symbolLayoutProperty);
1496         // icon color & right icon src path
1497         auto searchIconColor = symbolLayoutProperty->GetSymbolColorList();
1498         if (searchIconColor.has_value()) {
1499             cancelIconJson->Put("color", SymbolColorToString(searchIconColor.value()).c_str());
1500         } else {
1501             cancelIconJson->Put("color", std::string("").c_str());
1502         }
1503         auto symbolSourceInfo = symbolLayoutProperty->GetSymbolSourceInfo().value_or(SymbolSourceInfo());
1504         cancelIconJson->Put("src", static_cast<int64_t>(symbolSourceInfo.GetUnicode()));
1505         cancelButtonJson->Put("icon", cancelIconJson);
1506         json->PutExtAttr("cancelButton", cancelButtonJson, filter);
1507     } else {
1508         auto cancelImageLayoutProperty = cancelImageFrameNode->GetLayoutProperty<ImageLayoutProperty>();
1509         CHECK_NULL_VOID(cancelImageLayoutProperty);
1510         // icon color
1511         auto cancelImageRenderProperty = cancelImageFrameNode->GetPaintProperty<ImageRenderProperty>();
1512         CHECK_NULL_VOID(cancelImageRenderProperty);
1513         auto cancelIconColor = cancelImageRenderProperty->GetSvgFillColor().value_or(Color());
1514         cancelIconJson->Put("color", cancelIconColor.ColorToString().c_str());
1515         // right icon src path
1516         auto cancelImageSrc = cancelImageLayoutProperty->GetImageSourceInfo()->GetSrc();
1517         cancelIconJson->Put("src", cancelImageSrc.c_str());
1518         cancelButtonJson->Put("icon", cancelIconJson);
1519         json->PutExtAttr("cancelButton", cancelButtonJson, filter);
1520     }
1521 }
1522 
ToJsonValueForSearchButtonOption(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1523 void SearchPattern::ToJsonValueForSearchButtonOption(
1524     std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1525 {
1526     /* no fixed attr below, just return */
1527     if (filter.IsFastFilter()) {
1528         return;
1529     }
1530     auto host = GetHost();
1531     CHECK_NULL_VOID(host);
1532     auto searchButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(BUTTON_INDEX));
1533     CHECK_NULL_VOID(searchButtonFrameNode);
1534     auto searchButtonLayoutProperty = searchButtonFrameNode->GetLayoutProperty<ButtonLayoutProperty>();
1535     CHECK_NULL_VOID(searchButtonLayoutProperty);
1536     auto searchButtonJson = JsonUtil::Create(true);
1537 
1538     // font size
1539     auto searchButtonFontSize = searchButtonLayoutProperty->GetFontSize().value_or(Dimension(0, DimensionUnit::VP));
1540     searchButtonJson->Put("fontSize", searchButtonFontSize.ToString().c_str());
1541 
1542     // font color
1543     auto searchButtonFontColor = searchButtonLayoutProperty->GetFontColor().value_or(Color());
1544     searchButtonJson->Put("fontColor", searchButtonFontColor.ColorToString().c_str());
1545     json->PutExtAttr("searchButtonOption", searchButtonJson, filter);
1546 }
1547 
ToJsonValueForCursor(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1548 void SearchPattern::ToJsonValueForCursor(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1549 {
1550     /* no fixed attr below, just return */
1551     if (filter.IsFastFilter()) {
1552         return;
1553     }
1554     auto host = GetHost();
1555     CHECK_NULL_VOID(host);
1556     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1557     CHECK_NULL_VOID(textFieldFrameNode);
1558     auto textFieldPaintProperty = textFieldFrameNode->GetPaintProperty<TextFieldPaintProperty>();
1559     CHECK_NULL_VOID(textFieldPaintProperty);
1560     auto cursorJson = JsonUtil::Create(true);
1561 
1562     // color
1563     auto caretColor = textFieldPaintProperty->GetCursorColor().value_or(Color());
1564     cursorJson->Put("color", caretColor.ColorToString().c_str());
1565     auto caretWidth = textFieldPaintProperty->GetCursorWidth().value_or(Dimension(0, DimensionUnit::VP));
1566     cursorJson->Put("width", caretWidth.ToString().c_str());
1567     json->PutExtAttr("caretStyle", cursorJson, filter);
1568     auto selectedBackgroundColor = textFieldPaintProperty->GetSelectedBackgroundColor().value_or(Color());
1569     json->PutExtAttr("selectedBackgroundColor", selectedBackgroundColor.ColorToString().c_str(), filter);
1570 }
1571 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1572 void SearchPattern::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1573 {
1574     Pattern::ToJsonValue(json, filter);
1575 
1576     ToJsonValueForTextField(json, filter);
1577     ToJsonValueForSearchIcon(json, filter);
1578     ToJsonValueForCancelButton(json, filter);
1579     ToJsonValueForCursor(json, filter);
1580     ToJsonValueForSearchButtonOption(json, filter);
1581 }
1582 
UpdateDividerColorMode()1583 void SearchPattern::UpdateDividerColorMode()
1584 {
1585     auto host = GetHost();
1586     CHECK_NULL_VOID(host);
1587     auto dividerFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(DIVIDER_INDEX));
1588     CHECK_NULL_VOID(dividerFrameNode);
1589     auto pipeline = dividerFrameNode->GetContext();
1590     CHECK_NULL_VOID(pipeline);
1591     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1592     CHECK_NULL_VOID(searchTheme);
1593     auto searchDividerColor = searchTheme->GetSearchDividerColor();
1594     auto dividerRenderProperty = dividerFrameNode->GetPaintProperty<DividerRenderProperty>();
1595     CHECK_NULL_VOID(dividerRenderProperty);
1596     dividerRenderProperty->UpdateDividerColor(searchDividerColor);
1597     dividerFrameNode->MarkModifyDone();
1598     dividerFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1599 }
1600 
UpdateCancelButtonColorMode()1601 void SearchPattern::UpdateCancelButtonColorMode()
1602 {
1603     auto cancelButtonNode = cancelButtonNode_.Upgrade();
1604     CHECK_NULL_VOID(cancelButtonNode);
1605     auto pipeline = cancelButtonNode->GetContext();
1606     CHECK_NULL_VOID(pipeline);
1607     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1608     CHECK_NULL_VOID(searchTheme);
1609     auto cancelButtonRenderContext = cancelButtonNode->GetRenderContext();
1610     CHECK_NULL_VOID(cancelButtonRenderContext);
1611     cancelButtonRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
1612     auto textFrameNode = AceType::DynamicCast<FrameNode>(cancelButtonNode->GetChildren().front());
1613     CHECK_NULL_VOID(textFrameNode);
1614     auto textLayoutProperty = textFrameNode->GetLayoutProperty<TextLayoutProperty>();
1615     CHECK_NULL_VOID(textLayoutProperty);
1616     textLayoutProperty->UpdateTextColor(searchTheme->GetSearchButtonTextColor());
1617     cancelButtonNode->MarkModifyDone();
1618     cancelButtonNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1619 }
1620 
OnColorConfigurationUpdate()1621 void SearchPattern::OnColorConfigurationUpdate()
1622 {
1623     auto host = GetHost();
1624     CHECK_NULL_VOID(host);
1625     host->SetNeedCallChildrenUpdate(false);
1626     auto pipeline = host->GetContext();
1627     CHECK_NULL_VOID(pipeline);
1628     auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>();
1629     CHECK_NULL_VOID(textFieldTheme);
1630     auto renderContext = host->GetRenderContext();
1631     CHECK_NULL_VOID(renderContext);
1632     renderContext->UpdateBackgroundColor(textFieldTheme->GetBgColor());
1633     CHECK_NULL_VOID(pipeline);
1634     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1635     CHECK_NULL_VOID(searchTheme);
1636     UpdateCancelButtonColorMode();
1637     auto buttonNode = buttonNode_.Upgrade();
1638     if (buttonNode) {
1639         auto buttonRenderContext = buttonNode->GetRenderContext();
1640         CHECK_NULL_VOID(buttonRenderContext);
1641         buttonRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
1642         auto textFrameNode = AceType::DynamicCast<FrameNode>(buttonNode->GetChildren().front());
1643         CHECK_NULL_VOID(textFrameNode);
1644         auto textLayoutProperty = textFrameNode->GetLayoutProperty<TextLayoutProperty>();
1645         CHECK_NULL_VOID(textLayoutProperty);
1646         textLayoutProperty->UpdateTextColor(searchTheme->GetSearchButtonTextColor());
1647         buttonNode->MarkModifyDone();
1648         buttonNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1649     }
1650     auto textField = textField_.Upgrade();
1651     if (textField) {
1652         auto textFieldLayoutProperty = textField->GetLayoutProperty<TextFieldLayoutProperty>();
1653         CHECK_NULL_VOID(textFieldLayoutProperty);
1654         textFieldLayoutProperty->UpdateTextColor(searchTheme->GetTextColor());
1655         textFieldLayoutProperty->UpdatePlaceholderTextColor(searchTheme->GetPlaceholderColor());
1656         textField->MarkModifyDone();
1657         textField->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1658     }
1659     UpdateDividerColorMode();
1660 }
1661 
GetMaxLength() const1662 uint32_t SearchPattern::GetMaxLength() const
1663 {
1664     auto host = GetHost();
1665     CHECK_NULL_RETURN(host, Infinity<uint32_t>());
1666     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1667     CHECK_NULL_RETURN(textFieldFrameNode, Infinity<uint32_t>());
1668     auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
1669     CHECK_NULL_RETURN(textFieldLayoutProperty, Infinity<uint32_t>());
1670     return textFieldLayoutProperty->HasMaxLength() ? textFieldLayoutProperty->GetMaxLengthValue(Infinity<uint32_t>())
1671                                                    : Infinity<uint32_t>();
1672 }
1673 
ToJsonValueForCancelButtonStyle(std::unique_ptr<JsonValue> & cancelButtonJson,const CancelButtonStyle & cancelButtonStyle) const1674 void SearchPattern::ToJsonValueForCancelButtonStyle(
1675     std::unique_ptr<JsonValue>& cancelButtonJson, const CancelButtonStyle& cancelButtonStyle) const
1676 {
1677     if (cancelButtonStyle == CancelButtonStyle::CONSTANT) {
1678         cancelButtonJson->Put("style", "CancelButtonStyle.CONSTANT");
1679     } else if (cancelButtonStyle == CancelButtonStyle::INVISIBLE) {
1680         cancelButtonJson->Put("style", "CancelButtonStyle.INVISIBLE");
1681     } else {
1682         cancelButtonJson->Put("style", "CancelButtonStyle.INPUT");
1683     }
1684 }
1685 
SymbolColorToString(std::vector<Color> & colors) const1686 std::string SearchPattern::SymbolColorToString(std::vector<Color>& colors) const
1687 {
1688     if (colors.size() <= 0) {
1689         return "";
1690     }
1691     auto colorStr = std::string("[");
1692     for (auto color : colors) {
1693         colorStr.append(color.ColorToString());
1694         colorStr.append(",");
1695     }
1696     colorStr.append("]");
1697     return colorStr;
1698 }
1699 
InitIconColorSize()1700 void SearchPattern::InitIconColorSize()
1701 {
1702     InitSearchIconColorSize();
1703     InitCancelIconColorSize();
1704 }
1705 
InitSearchIconColorSize()1706 void SearchPattern::InitSearchIconColorSize()
1707 {
1708     auto host = GetHost();
1709     CHECK_NULL_VOID(host);
1710     auto pipeline = host->GetContext();
1711     CHECK_NULL_VOID(pipeline);
1712     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1713     CHECK_NULL_VOID(searchTheme);
1714     GetSearchNode()->SetSearchSymbolIconColor(Color(searchTheme->GetSymbolIconColor()));
1715     GetSearchNode()->SetSearchSymbolIconSize(SYMBOL_ICON_HEIGHT);
1716     GetSearchNode()->SetSearchImageIconColor(Color(searchTheme->GetSearchIconColor()));
1717     GetSearchNode()->SetSearchImageIconSize(searchTheme->GetIconHeight());
1718 }
1719 
InitCancelIconColorSize()1720 void SearchPattern::InitCancelIconColorSize()
1721 {
1722     auto host = GetHost();
1723     CHECK_NULL_VOID(host);
1724     auto pipeline = host->GetContext();
1725     CHECK_NULL_VOID(pipeline);
1726     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1727     CHECK_NULL_VOID(searchTheme);
1728     GetSearchNode()->SetCancelSymbolIconColor(Color(searchTheme->GetSymbolIconColor()));
1729     GetSearchNode()->SetCancelSymbolIconSize(SYMBOL_ICON_HEIGHT);
1730     GetSearchNode()->SetCancelImageIconColor(Color(searchTheme->GetSearchIconColor()));
1731     GetSearchNode()->SetCancelImageIconSize(searchTheme->GetIconHeight());
1732 }
1733 
CreateSearchIcon(const std::string & src)1734 void SearchPattern::CreateSearchIcon(const std::string& src)
1735 {
1736     CHECK_NULL_VOID(GetSearchNode());
1737     if (GetSearchNode()->HasSearchIconNodeCreated()) {
1738         UpdateSearchSymbolIconColor();
1739         return;
1740     }
1741     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) &&
1742         src.empty()) {
1743         CreateOrUpdateSymbol(IMAGE_INDEX, !GetSearchNode()->HasSearchIconNodeCreated(), false);
1744     } else {
1745         GetSearchNode()->SetSearchImageIconOptions(IconOptions(src));
1746         CreateOrUpdateImage(IMAGE_INDEX, !GetSearchNode()->HasSearchIconNodeCreated());
1747     }
1748     GetSearchNode()->UpdateHasSearchIconNodeCreated(true);
1749 }
1750 
UpdateSearchSymbolIconColor()1751 void SearchPattern::UpdateSearchSymbolIconColor()
1752 {
1753     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1754         return;
1755     }
1756     auto host = GetHost();
1757     CHECK_NULL_VOID(host);
1758     CHECK_NULL_VOID(GetSearchNode());
1759     auto cancelButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(IMAGE_INDEX));
1760     auto layoutProperty = cancelButtonFrameNode->GetLayoutProperty<TextLayoutProperty>();
1761     CHECK_NULL_VOID(layoutProperty);
1762     layoutProperty->UpdateSymbolColorList({ GetSearchNode()->GetSearchSymbolIconColor() });
1763 }
1764 
CreateCancelIcon()1765 void SearchPattern::CreateCancelIcon()
1766 {
1767     CHECK_NULL_VOID(GetSearchNode());
1768     if (GetSearchNode()->HasCancelIconNodeCreated()) {
1769         UpdateCancelSymbolIconColor();
1770         return;
1771     }
1772     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1773         CreateOrUpdateSymbol(CANCEL_IMAGE_INDEX, !GetSearchNode()->HasCancelIconNodeCreated(), false);
1774     } else {
1775         GetSearchNode()->SetCancelImageIconOptions(IconOptions());
1776         CreateOrUpdateImage(CANCEL_IMAGE_INDEX, !GetSearchNode()->HasCancelIconNodeCreated());
1777     }
1778     GetSearchNode()->UpdateHasCancelIconNodeCreated(true);
1779 }
1780 
UpdateCancelSymbolIconColor()1781 void SearchPattern::UpdateCancelSymbolIconColor()
1782 {
1783     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1784         return;
1785     }
1786     auto host = GetHost();
1787     CHECK_NULL_VOID(host);
1788     CHECK_NULL_VOID(GetSearchNode());
1789     auto cancelButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(CANCEL_IMAGE_INDEX));
1790     auto layoutProperty = cancelButtonFrameNode->GetLayoutProperty<TextLayoutProperty>();
1791     CHECK_NULL_VOID(layoutProperty);
1792     layoutProperty->UpdateSymbolColorList({ GetSearchNode()->GetCancelSymbolIconColor() });
1793 }
1794 
CreateOrUpdateSymbol(int32_t index,bool isCreateNode,bool isFromModifier)1795 void SearchPattern::CreateOrUpdateSymbol(int32_t index, bool isCreateNode, bool isFromModifier)
1796 {
1797     CHECK_NULL_VOID(GetSearchNode());
1798     imageClickListener_ = nullptr;
1799     auto host = GetHost();
1800     CHECK_NULL_VOID(host);
1801     auto pipeline = host->GetContext();
1802     CHECK_NULL_VOID(pipeline);
1803     auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
1804     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1805     CHECK_NULL_VOID(searchTheme);
1806     auto iconFrameNode = FrameNode::GetOrCreateFrameNode(
1807         V2::SYMBOL_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<TextPattern>(); });
1808     auto layoutProperty = iconFrameNode->GetLayoutProperty<TextLayoutProperty>();
1809     layoutProperty->UpdateSymbolSourceInfo(index == IMAGE_INDEX ? SymbolSourceInfo(searchTheme->GetSearchSymbolId())
1810                                                                 : SymbolSourceInfo(searchTheme->GetCancelSymbolId()));
1811     layoutProperty->UpdateFontSize(
1812         index == IMAGE_INDEX ? GetSearchNode()->GetSearchSymbolIconSize() : GetSearchNode()->GetCancelSymbolIconSize());
1813     layoutProperty->UpdateSymbolColorList({index == IMAGE_INDEX ? GetSearchNode()->GetSearchSymbolIconColor()
1814                                                                 : GetSearchNode()->GetCancelSymbolIconColor()});
1815     float maxFontScale = MAX_FONT_SCALE;
1816     if (layoutProperty->GetFontSize()->Unit() != DimensionUnit::VP) {
1817         maxFontScale = std::min(pipeline->GetMaxAppFontScale(), MAX_FONT_SCALE);
1818     }
1819     layoutProperty->UpdateMaxFontScale(maxFontScale);
1820     auto parentInspector = GetSearchNode()->GetInspectorIdValue("");
1821     iconFrameNode->UpdateInspectorId(INSPECTOR_PREFIX + SPECICALIZED_INSPECTOR_INDEXS[index] + parentInspector);
1822 
1823     if (isFromModifier) {
1824         UpdateSymbolIconProperties(iconFrameNode, index);
1825     }
1826 
1827     if (isCreateNode) {
1828         iconFrameNode->MountToParent(GetSearchNode());
1829         if (index == CANCEL_IMAGE_INDEX) {
1830             auto cancelButtonEvent = iconFrameNode->GetEventHub<ButtonEventHub>();
1831             CHECK_NULL_VOID(cancelButtonEvent);
1832             cancelButtonEvent->SetEnabled(false);
1833         }
1834         iconFrameNode->MarkModifyDone();
1835     } else {
1836         auto oldFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(index));
1837         CHECK_NULL_VOID(oldFrameNode);
1838         GetSearchNode()->ReplaceChild(oldFrameNode, iconFrameNode);
1839         if (index == CANCEL_IMAGE_INDEX) {
1840             UpdateIconChangeEvent();
1841         }
1842         iconFrameNode->MarkModifyDone();
1843         iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1844     }
1845 }
1846 
CreateOrUpdateImage(int32_t index,bool isCreateNode)1847 void SearchPattern::CreateOrUpdateImage(int32_t index, bool isCreateNode)
1848 {
1849     CHECK_NULL_VOID(GetSearchNode());
1850     imageClickListener_ = nullptr;
1851     auto host = GetHost();
1852     CHECK_NULL_VOID(host);
1853     auto pipeline = host->GetContext();
1854     CHECK_NULL_VOID(pipeline);
1855     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1856     CHECK_NULL_VOID(searchTheme);
1857     auto iconFrameNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
1858         ElementRegister::GetInstance()->MakeUniqueId(),
1859         []() { return AceType::MakeRefPtr<ImagePattern>(); });
1860     UpdateImageIconProperties(iconFrameNode, index);
1861     if (isCreateNode) {
1862         iconFrameNode->MountToParent(GetSearchNode());
1863         if (index == CANCEL_IMAGE_INDEX) {
1864             auto cancelButtonEvent = iconFrameNode->GetEventHub<ButtonEventHub>();
1865             CHECK_NULL_VOID(cancelButtonEvent);
1866             cancelButtonEvent->SetEnabled(false);
1867         }
1868         iconFrameNode->MarkModifyDone();
1869     } else {
1870         auto oldFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(index));
1871         CHECK_NULL_VOID(oldFrameNode);
1872         GetSearchNode()->ReplaceChild(oldFrameNode, iconFrameNode);
1873         if (index == CANCEL_IMAGE_INDEX) {
1874             UpdateIconChangeEvent();
1875         }
1876         iconFrameNode->MarkModifyDone();
1877         iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1878     }
1879 }
1880 
SetSearchSrcPath(const std::string & src,const std::string & bundleName,const std::string & moduleName)1881 void SearchPattern::SetSearchSrcPath(
1882     const std::string& src, const std::string& bundleName, const std::string& moduleName)
1883 {
1884     CHECK_NULL_VOID(GetSearchNode());
1885     auto &imageIconOptions = GetSearchNode()->GetSearchImageIconOptions();
1886     imageIconOptions.UpdateSrc(std::string(src), std::string(bundleName), std::string(moduleName));
1887     UpdateImageIconNode(IMAGE_INDEX);
1888 }
1889 
SetSearchIconSize(const Dimension & value)1890 void SearchPattern::SetSearchIconSize(const Dimension& value)
1891 {
1892     CHECK_NULL_VOID(GetSearchNode());
1893     auto& imageIconOptions = GetSearchNode()->GetSearchImageIconOptions();
1894     imageIconOptions.UpdateSize(Dimension(value));
1895     UpdateImageIconNode(IMAGE_INDEX);
1896 }
1897 
SetSearchIconColor(const Color & color)1898 void SearchPattern::SetSearchIconColor(const Color& color)
1899 {
1900     CHECK_NULL_VOID(GetSearchNode());
1901     auto frameNode = GetHost();
1902     CHECK_NULL_VOID(frameNode);
1903     auto iconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(IMAGE_INDEX));
1904     CHECK_NULL_VOID(iconFrameNode);
1905     if (iconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
1906         GetSearchNode()->SetSearchSymbolIconColor(Color(color));
1907         auto symbolLayoutProperty = iconFrameNode->GetLayoutProperty<TextLayoutProperty>();
1908         CHECK_NULL_VOID(symbolLayoutProperty);
1909         symbolLayoutProperty->UpdateSymbolColorList({color});
1910         iconFrameNode->MarkModifyDone();
1911         iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1912     } else {
1913         auto &imageIconOptions = GetSearchNode()->GetSearchImageIconOptions();
1914         imageIconOptions.UpdateColor(Color(color));
1915         auto imageLayoutProperty = iconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
1916         CHECK_NULL_VOID(imageLayoutProperty);
1917         auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value();
1918         if (imageSourceInfo.IsSvg()) {
1919             imageSourceInfo.SetFillColor(color);
1920             imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
1921             auto imageRenderProperty = iconFrameNode->GetPaintProperty<ImageRenderProperty>();
1922             CHECK_NULL_VOID(imageRenderProperty);
1923             imageRenderProperty->UpdateSvgFillColor(color);
1924             iconFrameNode->MarkModifyDone();
1925             iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1926         }
1927     }
1928 }
1929 
SetSearchImageIcon(IconOptions & iconOptions)1930 void SearchPattern::SetSearchImageIcon(IconOptions& iconOptions)
1931 {
1932     CHECK_NULL_VOID(GetSearchNode());
1933     auto& imageIconOptions = GetSearchNode()->GetSearchImageIconOptions();
1934     if (iconOptions.GetColor().has_value()) {
1935         imageIconOptions.UpdateColor(iconOptions.GetColor().value());
1936     }
1937     if (iconOptions.GetSize().has_value()) {
1938         imageIconOptions.UpdateSize(ConvertImageIconSizeValue(iconOptions.GetSize().value()));
1939     }
1940     if (iconOptions.GetSrc().has_value()) {
1941         imageIconOptions.UpdateSrc(iconOptions.GetSrc().value_or(""),
1942             iconOptions.GetBundleName().value_or(""),
1943             iconOptions.GetModuleName().value_or(""));
1944     }
1945     UpdateImageIconNode(IMAGE_INDEX);
1946 }
1947 
SetSearchSymbolIcon()1948 void SearchPattern::SetSearchSymbolIcon()
1949 {
1950     UpdateSymbolIconNode(IMAGE_INDEX);
1951 }
1952 
SetCancelIconSize(const Dimension & value)1953 void SearchPattern::SetCancelIconSize(const Dimension& value)
1954 {
1955     CHECK_NULL_VOID(GetSearchNode());
1956     auto& imageIconOptions = GetSearchNode()->GetCancelImageIconOptions();
1957     imageIconOptions.UpdateSize(Dimension(value));
1958     UpdateImageIconNode(CANCEL_IMAGE_INDEX);
1959 }
1960 
SetCancelIconColor(const Color & color)1961 void SearchPattern::SetCancelIconColor(const Color& color)
1962 {
1963     CHECK_NULL_VOID(GetSearchNode());
1964     auto frameNode = GetHost();
1965     CHECK_NULL_VOID(frameNode);
1966     auto cancelIconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(CANCEL_IMAGE_INDEX));
1967     CHECK_NULL_VOID(cancelIconFrameNode);
1968     if (cancelIconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
1969         GetSearchNode()->SetCancelSymbolIconColor(Color(color));
1970         auto symbolLayoutProperty = cancelIconFrameNode->GetLayoutProperty<TextLayoutProperty>();
1971         CHECK_NULL_VOID(symbolLayoutProperty);
1972         symbolLayoutProperty->UpdateSymbolColorList({color});
1973         cancelIconFrameNode->MarkModifyDone();
1974         cancelIconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1975     } else {
1976         auto &imageIconOptions = GetSearchNode()->GetCancelImageIconOptions();
1977         imageIconOptions.UpdateColor(Color(color));
1978         auto imageLayoutProperty = cancelIconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
1979         CHECK_NULL_VOID(imageLayoutProperty);
1980         auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value();
1981         if (imageSourceInfo.IsSvg()) {
1982             imageSourceInfo.SetFillColor(color);
1983             imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
1984             auto imageRenderProperty = cancelIconFrameNode->GetPaintProperty<ImageRenderProperty>();
1985             CHECK_NULL_VOID(imageRenderProperty);
1986             imageRenderProperty->UpdateSvgFillColor(color);
1987             cancelIconFrameNode->MarkModifyDone();
1988             cancelIconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1989         }
1990     }
1991 }
1992 
SetRightIconSrcPath(const std::string & src)1993 void SearchPattern::SetRightIconSrcPath(const std::string& src)
1994 {
1995     CHECK_NULL_VOID(GetSearchNode());
1996     auto &imageIconOptions = GetSearchNode()->GetCancelImageIconOptions();
1997     imageIconOptions.UpdateSrc(std::string(src), "", "");
1998     UpdateImageIconNode(CANCEL_IMAGE_INDEX);
1999 }
2000 
SetCancelButtonStyle(const CancelButtonStyle & style)2001 void SearchPattern::SetCancelButtonStyle(const CancelButtonStyle& style)
2002 {
2003     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(TEXTFIELD_INDEX));
2004     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
2005     UpdateChangeEvent(textFieldPattern->GetTextValue(), static_cast<int16_t>(style));
2006 }
2007 
SetCancelImageIcon(IconOptions & iconOptions)2008 void SearchPattern::SetCancelImageIcon(IconOptions& iconOptions)
2009 {
2010     CHECK_NULL_VOID(GetSearchNode());
2011     auto &imageIconOptions = GetSearchNode()->GetCancelImageIconOptions();
2012     if (iconOptions.GetColor().has_value()) {
2013         imageIconOptions.UpdateColor(iconOptions.GetColor().value());
2014     }
2015     if (iconOptions.GetSize().has_value()) {
2016         imageIconOptions.UpdateSize(ConvertImageIconSizeValue(iconOptions.GetSize().value()));
2017     }
2018     if (iconOptions.GetSrc().has_value()) {
2019         imageIconOptions.UpdateSrc(iconOptions.GetSrc().value(),
2020             iconOptions.GetBundleName().value_or(""),
2021             iconOptions.GetModuleName().value_or(""));
2022     }
2023     UpdateImageIconNode(CANCEL_IMAGE_INDEX);
2024 }
2025 
SetCancelSymbolIcon()2026 void SearchPattern::SetCancelSymbolIcon()
2027 {
2028     UpdateSymbolIconNode(CANCEL_IMAGE_INDEX);
2029 }
2030 
UpdateImageIconNode(int32_t index)2031 void SearchPattern::UpdateImageIconNode(int32_t index)
2032 {
2033     bool isCurSymbolNode = IsSymbolIcon(index);
2034     if (isCurSymbolNode) {
2035         CreateOrUpdateImage(index, false);
2036     } else {
2037         auto frameNode = GetHost();
2038         CHECK_NULL_VOID(frameNode);
2039         auto iconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(index));
2040         UpdateImageIconProperties(iconFrameNode, index);
2041         iconFrameNode->MarkModifyDone();
2042         iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2043     }
2044 }
2045 
UpdateSymbolIconNode(int32_t index)2046 void SearchPattern::UpdateSymbolIconNode(int32_t index)
2047 {
2048     bool isCurSymbolNode = IsSymbolIcon(index);
2049     if (!isCurSymbolNode) {
2050         CreateOrUpdateSymbol(index, false, true);
2051     } else {
2052         auto frameNode = GetHost();
2053         CHECK_NULL_VOID(frameNode);
2054         auto iconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(index));
2055         UpdateSymbolIconProperties(iconFrameNode, index);
2056         iconFrameNode->MarkModifyDone();
2057         iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2058     }
2059 }
2060 
UpdateImageIconProperties(RefPtr<FrameNode> & iconFrameNode,int32_t index)2061 void SearchPattern::UpdateImageIconProperties(RefPtr<FrameNode>& iconFrameNode, int32_t index)
2062 {
2063     CHECK_NULL_VOID(iconFrameNode);
2064     if (iconFrameNode->GetTag() == V2::IMAGE_ETS_TAG) {
2065         auto iconOptions = index == IMAGE_INDEX ? GetSearchNode()->GetSearchImageIconOptions()
2066                                                 : GetSearchNode()->GetCancelImageIconOptions();
2067         auto imageLayoutProperty = iconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
2068         CHECK_NULL_VOID(imageLayoutProperty);
2069         ImageSourceInfo imageSourceInfo("");
2070         auto imageSourceInfoOp = imageLayoutProperty->GetImageSourceInfo();
2071         if (imageSourceInfoOp.has_value()) {
2072             imageSourceInfo = imageSourceInfoOp.value();
2073         }
2074         auto host = GetHost();
2075         CHECK_NULL_VOID(host);
2076         auto pipeline = host->GetContext();
2077         CHECK_NULL_VOID(pipeline);
2078         auto searchTheme = pipeline->GetTheme<SearchTheme>();
2079         CHECK_NULL_VOID(searchTheme);
2080         auto iconTheme = pipeline->GetTheme<IconTheme>();
2081         CHECK_NULL_VOID(iconTheme);
2082         if (iconOptions.GetSrc().value_or("").empty()) {
2083             imageSourceInfo.SetResourceId(index == IMAGE_INDEX ? InternalResource::ResourceId::SEARCH_SVG
2084                                                                : InternalResource::ResourceId::CLOSE_SVG);
2085             auto iconPath = iconTheme->GetIconPath(index == IMAGE_INDEX ? InternalResource::ResourceId::SEARCH_SVG
2086                                                                         : InternalResource::ResourceId::CLOSE_SVG);
2087             imageSourceInfo.SetSrc(iconPath, iconOptions.GetColor().value_or(searchTheme->GetSearchIconColor()));
2088         } else {
2089             imageSourceInfo.SetSrc(iconOptions.GetSrc().value());
2090         }
2091         imageSourceInfo.SetBundleName(iconOptions.GetBundleName().value_or(""));
2092         imageSourceInfo.SetModuleName(iconOptions.GetModuleName().value_or(""));
2093         imageSourceInfo.SetFillColor(iconOptions.GetColor().value_or(searchTheme->GetSearchIconColor()));
2094         imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
2095         CalcSize imageCalcSize(CalcLength(iconOptions.GetSize().value_or(searchTheme->GetIconHeight())),
2096             CalcLength(iconOptions.GetSize().value_or(searchTheme->GetIconHeight())));
2097 
2098         imageLayoutProperty->UpdateUserDefinedIdealSize(imageCalcSize);
2099         auto parentInspector = GetSearchNode()->GetInspectorIdValue("");
2100         iconFrameNode->UpdateInspectorId(INSPECTOR_PREFIX + SPECICALIZED_INSPECTOR_INDEXS[index] + parentInspector);
2101         auto imageRenderProperty = iconFrameNode->GetPaintProperty<ImageRenderProperty>();
2102         CHECK_NULL_VOID(imageRenderProperty);
2103         imageSourceInfo.SetFillColor(iconOptions.GetColor().value_or(searchTheme->GetSearchIconColor()));
2104         imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
2105         imageRenderProperty->UpdateSvgFillColor(iconOptions.GetColor().value_or(searchTheme->GetSearchIconColor()));
2106     }
2107 }
2108 
UpdateSymbolIconProperties(RefPtr<FrameNode> & iconFrameNode,int32_t index)2109 void SearchPattern::UpdateSymbolIconProperties(RefPtr<FrameNode>& iconFrameNode, int32_t index)
2110 {
2111     auto host = GetHost();
2112     CHECK_NULL_VOID(host);
2113     CHECK_NULL_VOID(iconFrameNode);
2114     auto pipeline = host->GetContext();
2115     CHECK_NULL_VOID(pipeline);
2116     auto searchTheme = pipeline->GetTheme<SearchTheme>();
2117     CHECK_NULL_VOID(searchTheme);
2118     auto layoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
2119     CHECK_NULL_VOID(layoutProperty);
2120     auto symbolLayoutProperty = iconFrameNode->GetLayoutProperty<TextLayoutProperty>();
2121     symbolLayoutProperty->UpdateSymbolSourceInfo(index == IMAGE_INDEX
2122                                                      ? SymbolSourceInfo(searchTheme->GetSearchSymbolId())
2123                                                      : SymbolSourceInfo(searchTheme->GetCancelSymbolId()));
2124     auto defaultSymbolIconSize = (index == IMAGE_INDEX ? GetSearchNode()->GetSearchSymbolIconSize()
2125                                                        : GetSearchNode()->GetCancelSymbolIconSize());
2126     symbolLayoutProperty->UpdateFontSize(defaultSymbolIconSize);
2127     symbolLayoutProperty->UpdateSymbolColorList({ index == IMAGE_INDEX ? GetSearchNode()->GetSearchSymbolIconColor()
2128                                                                        : GetSearchNode()->GetCancelSymbolIconColor() });
2129     auto parentInspector = GetSearchNode()->GetInspectorIdValue("");
2130     iconFrameNode->UpdateInspectorId(INSPECTOR_PREFIX + SPECICALIZED_INSPECTOR_INDEXS[index] + parentInspector);
2131     if (index == IMAGE_INDEX) {
2132         auto iconSymbol = layoutProperty->GetSearchIconSymbol();
2133         if (iconSymbol != nullptr) {
2134             iconSymbol(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconFrameNode)));
2135         }
2136     } else {
2137         auto iconSymbol = layoutProperty->GetCancelIconSymbol();
2138         if (iconSymbol != nullptr) {
2139             iconSymbol(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconFrameNode)));
2140         }
2141     }
2142     // reset symbol effect
2143     auto symbolEffectOptions = symbolLayoutProperty->GetSymbolEffectOptionsValue(SymbolEffectOptions());
2144     symbolEffectOptions.SetIsTxtActive(false);
2145     symbolLayoutProperty->UpdateSymbolEffectOptions(symbolEffectOptions);
2146     auto fontSize = symbolLayoutProperty->GetFontSize().value_or(defaultSymbolIconSize);
2147     if (GreatOrEqualCustomPrecision(fontSize.ConvertToPx(), ICON_MAX_SIZE.ConvertToPx())) {
2148         symbolLayoutProperty->UpdateFontSize(ICON_MAX_SIZE);
2149     }
2150 }
2151 
IsSymbolIcon(int32_t index)2152 bool SearchPattern::IsSymbolIcon(int32_t index)
2153 {
2154     auto frameNode = GetHost();
2155     CHECK_NULL_RETURN(frameNode, false);
2156     auto iconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(index));
2157     CHECK_NULL_RETURN(iconFrameNode, false);
2158     return iconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG;
2159 }
2160 
UpdateIconChangeEvent()2161 void SearchPattern::UpdateIconChangeEvent()
2162 {
2163     CHECK_NULL_VOID(GetSearchNode());
2164     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(TEXTFIELD_INDEX));
2165     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
2166     UpdateChangeEvent(textFieldPattern->GetTextValue());
2167 }
2168 
ConvertImageIconSizeValue(const Dimension & iconSizeValue)2169 const Dimension SearchPattern::ConvertImageIconSizeValue(const Dimension& iconSizeValue)
2170 {
2171     if (GreatOrEqualCustomPrecision(iconSizeValue.ConvertToPx(), ICON_MAX_SIZE.ConvertToPx())) {
2172         return ICON_MAX_SIZE;
2173     }
2174     return ConvertImageIconScaleLimit(iconSizeValue);
2175 }
2176 
ConvertImageIconScaleLimit(const Dimension & iconSizeValue)2177 const Dimension SearchPattern::ConvertImageIconScaleLimit(const Dimension& iconSizeValue)
2178 {
2179     auto host = GetHost();
2180     CHECK_NULL_RETURN(host, iconSizeValue);
2181     auto pipeline = host->GetContext();
2182     CHECK_NULL_RETURN(pipeline, iconSizeValue);
2183 
2184     float fontScale = pipeline->GetFontScale();
2185     if (fontScale == 0) {
2186         return iconSizeValue;
2187     }
2188 
2189     if (iconSizeValue.Unit() != DimensionUnit::VP) {
2190         float maxFontScale = std::min(pipeline->GetMaxAppFontScale(), MAX_FONT_SCALE);
2191         fontScale = std::clamp(fontScale, 0.0f, maxFontScale);
2192         return iconSizeValue * fontScale;
2193     }
2194     return iconSizeValue;
2195 }
2196 
2197 } // namespace OHOS::Ace::NG
2198