• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ChangeValueInfo& info) {
452             auto searchPattern = weak.Upgrade();
453             searchPattern->UpdateChangeEvent(info.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->ClearTextContent();
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     auto focusHub = host->GetOrCreateFocusHub();
772     CHECK_NULL_VOID(focusHub);
773     focusHub->RequestFocusImmediately();
774     textFieldPattern->HandleFocusEvent();
775     textFieldFrameNode->OnAccessibilityEvent(AccessibilityEventType::REQUEST_FOCUS);
776     host->MarkModifyDone();
777     textFieldFrameNode->MarkModifyDone();
778 }
779 
OnClickTextField()780 void SearchPattern::OnClickTextField()
781 {
782     focusChoice_ = FocusChoice::SEARCH;
783     auto host = GetHost();
784     CHECK_NULL_VOID(host);
785     RoundRect focusRect;
786     GetInnerFocusPaintRect(focusRect);
787     auto focusHub = host->GetFocusHub();
788     CHECK_NULL_VOID(focusHub);
789     focusHub->PaintInnerFocusState(focusRect);
790     host->MarkModifyDone();
791 }
792 
InitOnKeyEvent(const RefPtr<FocusHub> & focusHub)793 void SearchPattern::InitOnKeyEvent(const RefPtr<FocusHub>& focusHub)
794 {
795     auto onKeyEvent = [wp = WeakClaim(this)](const KeyEvent& event) -> bool {
796         auto pattern = wp.Upgrade();
797         CHECK_NULL_RETURN(pattern, false);
798         return pattern->OnKeyEvent(event);
799     };
800     focusHub->SetOnKeyEventInternal(std::move(onKeyEvent));
801 
802     auto getInnerPaintRectCallback = [wp = WeakClaim(this)](RoundRect& paintRect) {
803         auto pattern = wp.Upgrade();
804         if (pattern) {
805             pattern->GetInnerFocusPaintRect(paintRect);
806         }
807     };
808     focusHub->SetInnerFocusPaintRectCallback(getInnerPaintRectCallback);
809 }
810 
OnKeyEvent(const KeyEvent & event)811 bool SearchPattern::OnKeyEvent(const KeyEvent& event)
812 {
813     TAG_LOGI(AceLogTag::ACE_SEARCH, "KeyAction:%{public}d, KeyCode:%{public}d", static_cast<int>(event.action),
814         static_cast<int>(event.code));
815     auto host = GetHost();
816     CHECK_NULL_RETURN(host, false);
817     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
818     CHECK_NULL_RETURN(textFieldFrameNode, false);
819     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
820     CHECK_NULL_RETURN(textFieldPattern, false);
821 
822     bool isAllTextSelected = textFieldPattern->IsSelectAll();
823     bool isCaretVisible = textFieldPattern->GetCursorVisible();
824     bool isTextEmpty = textFieldPattern->GetTextValue().empty();
825     bool isOnlyTabPressed = event.pressedCodes.size() == 1 && event.code == KeyCode::KEY_TAB;
826 
827     auto parentHub = host->GetOrCreateFocusHub()->GetParentFocusHub();
828     auto getMaxFocusableCount = [](auto self, const RefPtr<FocusHub>& focusHub) -> size_t {
829         CHECK_NULL_RETURN(focusHub, 0);
830         auto parentHub = focusHub->GetParentFocusHub();
831         return std::max(focusHub->GetFocusableCount(), self(self, parentHub));
832     };
833     constexpr int ONE = 1; // Only one focusable component on scene
834     bool isOnlyOneFocusableComponent = getMaxFocusableCount(getMaxFocusableCount, parentHub) == ONE;
835     auto container = Container::Current();
836     if (container && container->IsUIExtensionWindow()) {
837         isOnlyOneFocusableComponent = false; // UI Extension Window
838     }
839 
840     if (event.action != KeyAction::DOWN) {
841         if ((event.code == KeyCode::KEY_TAB ||
842             event.code == KeyCode::KEY_SHIFT_LEFT ||
843             event.code == KeyCode::KEY_SHIFT_RIGHT) &&
844             focusChoice_ == FocusChoice::SEARCH) {
845             textFieldPattern->OnKeyEvent(event);
846         }
847         return false;
848     }
849 
850     if (focusChoice_ == FocusChoice::SEARCH &&
851         (event.IsShiftWith(KeyCode::KEY_DPAD_LEFT) ||
852         event.IsShiftWith(KeyCode::KEY_DPAD_RIGHT))) {
853         return textFieldPattern->OnKeyEvent(event);
854     }
855 
856     // If the focus is on the search, press Enter to request keyboard.
857     if (event.code == KeyCode::KEY_ENTER && focusChoice_ == FocusChoice::SEARCH && !IsSearchAttached()) {
858         RequestKeyboard();
859         return true;
860     }
861     // If the focus is on the search button, press Enter to submit the content.
862     if (event.code == KeyCode::KEY_ENTER && focusChoice_ == FocusChoice::SEARCH_BUTTON) {
863         OnClickButtonAndImage();
864         return true;
865     }
866     // If the focus is on the Delete button, press Enter to delete the content.
867     if (event.code == KeyCode::KEY_ENTER && focusChoice_ == FocusChoice::CANCEL_BUTTON) {
868         OnClickCancelButton();
869         PaintFocusState();
870         return true;
871     }
872     // When press '->' or '<-', focus delete button or search button according to whether there is text in the search.
873     if (event.code == KeyCode::KEY_DPAD_LEFT || event.IsShiftWith(KeyCode::KEY_TAB)) {
874         if (focusChoice_ == FocusChoice::CANCEL_BUTTON) {
875             focusChoice_ = FocusChoice::SEARCH;
876             PaintFocusState();
877             return true;
878         }
879         if (focusChoice_ == FocusChoice::SEARCH_BUTTON) {
880             if (NearZero(cancelButtonSize_.Height())) {
881                 focusChoice_ = FocusChoice::SEARCH;
882             } else {
883                 focusChoice_ = FocusChoice::CANCEL_BUTTON;
884             }
885             PaintFocusState();
886             return true;
887         }
888         if (focusChoice_ == FocusChoice::SEARCH && isOnlyOneFocusableComponent && event.IsShiftWith(KeyCode::KEY_TAB)) {
889             if (isSearchButtonEnabled_) {
890                 focusChoice_ = FocusChoice::SEARCH_BUTTON;
891             } else if (!isTextEmpty) {
892                 focusChoice_ = FocusChoice::CANCEL_BUTTON;
893             }
894             PaintFocusState();
895             return true;
896         }
897         if (focusChoice_ == FocusChoice::SEARCH && event.IsShiftWith(KeyCode::KEY_TAB)) {
898             textFieldPattern->CloseKeyboard(true);
899             return false;
900         }
901         if (focusChoice_ == FocusChoice::SEARCH && !isAllTextSelected && !isTextEmpty) {
902             return textFieldPattern->OnKeyEvent(event);
903         }
904         if (focusChoice_ == FocusChoice::SEARCH && isAllTextSelected && !isCaretVisible &&
905             event.code == KeyCode::KEY_DPAD_LEFT) {
906             return true; // no action
907         }
908     }
909     if (event.code == KeyCode::KEY_DPAD_RIGHT || (event.pressedCodes.size() == 1 && event.code == KeyCode::KEY_TAB)) {
910         if (focusChoice_ == FocusChoice::SEARCH && (isAllTextSelected || isTextEmpty || isOnlyTabPressed)) {
911             if (NearZero(cancelButtonSize_.Height()) && !isSearchButtonEnabled_ &&
912                 event.code == KeyCode::KEY_DPAD_RIGHT) {
913                 return true;
914             } else if (NearZero(cancelButtonSize_.Height()) && !isSearchButtonEnabled_) {
915                 textFieldPattern->CloseKeyboard(true);
916                 return false;
917             }
918             if (NearZero(cancelButtonSize_.Height())) {
919                 focusChoice_ = FocusChoice::SEARCH_BUTTON;
920             } else {
921                 focusChoice_ = FocusChoice::CANCEL_BUTTON;
922             }
923             PaintFocusState();
924             return true;
925         } else if (focusChoice_ == FocusChoice::SEARCH && event.code == KeyCode::KEY_DPAD_RIGHT) {
926             textFieldPattern->OnKeyEvent(event);
927             return true;
928         }
929         if (focusChoice_ == FocusChoice::CANCEL_BUTTON) {
930             if (!NearZero(cancelButtonSize_.Height()) && (!isSearchButtonEnabled_) &&
931                 (event.code == KeyCode::KEY_DPAD_RIGHT)) {
932                 return false; // Go out of Search
933             }
934             if (isOnlyOneFocusableComponent && isOnlyTabPressed && !isSearchButtonEnabled_) {
935                 focusChoice_ = FocusChoice::SEARCH;
936                 PaintFocusState();
937                 return true;
938             }
939             if (!isSearchButtonEnabled_) {
940                 return !isOnlyTabPressed; // go outside if Tab pressed, or no action if arrow pressed
941             }
942             focusChoice_ = FocusChoice::SEARCH_BUTTON;
943             PaintFocusState();
944             return true;
945         }
946         if (focusChoice_ == FocusChoice::SEARCH_BUTTON && isOnlyOneFocusableComponent && isOnlyTabPressed) {
947             focusChoice_ = FocusChoice::SEARCH;
948             PaintFocusState();
949             return true;
950         }
951         if (focusChoice_ == FocusChoice::SEARCH_BUTTON &&
952             (event.pressedCodes.size() == 1 && event.code == KeyCode::KEY_TAB)) {
953             textFieldPattern->CloseKeyboard(true);
954             return false;
955         }
956         if (focusChoice_ == FocusChoice::SEARCH_BUTTON && isSearchButtonEnabled_ &&
957             (event.code == KeyCode::KEY_DPAD_RIGHT)) {
958             return false; // Go out of Search
959         }
960     }
961 
962     if (focusChoice_ == FocusChoice::SEARCH) {
963         return textFieldPattern->OnKeyEvent(event);
964     } else {
965         return true;
966     }
967 }
968 
IsSearchAttached()969 bool SearchPattern::IsSearchAttached()
970 {
971     auto host = GetHost();
972     CHECK_NULL_RETURN(host, false);
973     auto context = host->GetContext();
974     CHECK_NULL_RETURN(context, false);
975     auto textFieldManager = DynamicCast<TextFieldManagerNG>(context->GetTextFieldManager());
976     CHECK_NULL_RETURN(textFieldManager, false);
977     return textFieldManager->GetIsImeAttached();
978 }
979 
PaintFocusState(bool recoverFlag)980 void SearchPattern::PaintFocusState(bool recoverFlag)
981 {
982     TAG_LOGI(AceLogTag::ACE_SEARCH, "Focus Choice = %{public}d", static_cast<int>(focusChoice_));
983     auto host = GetHost();
984     CHECK_NULL_VOID(host);
985     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
986     CHECK_NULL_VOID(textFieldFrameNode);
987     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
988     CHECK_NULL_VOID(textFieldPattern);
989     auto searchTextFieldPattern = DynamicCast<SearchTextFieldPattern>(textFieldPattern);
990     CHECK_NULL_VOID(searchTextFieldPattern);
991 
992     if (focusChoice_ == FocusChoice::SEARCH) {
993         if (!recoverFlag) {
994             if (!textFieldPattern->GetTextValue().empty()) {
995                 textFieldPattern->NeedRequestKeyboard();
996                 textFieldPattern->SearchRequestKeyboard();
997                 textFieldPattern->HandleOnSelectAll(false); // Select all text
998                 searchTextFieldPattern->ResetSearchRequestStopTwinkling(); // reset flag
999                 textFieldPattern->StopTwinkling(); // Hide caret
1000             } else {
1001                 textFieldPattern->HandleFocusEvent(); // Show caret
1002                 searchTextFieldPattern->SearchRequestStartTwinkling();
1003             }
1004         } else {
1005             textFieldPattern->HandleFocusEvent();
1006             searchTextFieldPattern->SearchRequestStartTwinkling();
1007         }
1008     } else {
1009         textFieldPattern->CloseKeyboard(true);
1010         searchTextFieldPattern->SearchRequestStopTwinkling(); // Hide caret
1011     }
1012 
1013     auto context = host->GetContext();
1014     CHECK_NULL_VOID(context);
1015     RoundRect focusRect;
1016     GetInnerFocusPaintRect(focusRect);
1017     auto focusHub = host->GetFocusHub();
1018     CHECK_NULL_VOID(focusHub);
1019     focusHub->PaintInnerFocusState(focusRect, true);
1020     host->MarkModifyDone();
1021 }
1022 
GetInnerFocusPaintRect(RoundRect & paintRect)1023 void SearchPattern::GetInnerFocusPaintRect(RoundRect& paintRect)
1024 {
1025     float originX = 0.0f;
1026     float originY = 0.0f;
1027     float endX = 0.0f;
1028     float endY = 0.0f;
1029     float radiusTopLeft = 0.0f;
1030     float radiusTopRight = 0.0f;
1031     float radiusBottomLeft = 0.0f;
1032     float radiusBottomRight = 0.0f;
1033     float focusOffset = FOCUS_OFFSET.ConvertToPx();
1034     if (focusChoice_ == FocusChoice::SEARCH) {
1035         return;
1036     }
1037     if (focusChoice_ == FocusChoice::CANCEL_BUTTON) {
1038         originX = cancelButtonOffset_.GetX() + focusOffset;
1039         originY = cancelButtonOffset_.GetY() + focusOffset;
1040         endX = cancelButtonSize_.Width() + originX - DOUBLE * focusOffset;
1041         endY = cancelButtonSize_.Height() + originY - DOUBLE * focusOffset;
1042         radiusTopLeft = cancelButtonSize_.Height() / DOUBLE - focusOffset;
1043         radiusTopRight = cancelButtonSize_.Height() / DOUBLE - focusOffset;
1044         radiusBottomLeft = cancelButtonSize_.Height() / DOUBLE - focusOffset;
1045         radiusBottomRight = cancelButtonSize_.Height() / DOUBLE - focusOffset;
1046     }
1047     if (focusChoice_ == FocusChoice::SEARCH_BUTTON) {
1048         originX = buttonOffset_.GetX() + focusOffset;
1049         originY = buttonOffset_.GetY() + focusOffset;
1050         endX = buttonSize_.Width() + originX - DOUBLE * focusOffset;
1051         endY = buttonSize_.Height() + originY - DOUBLE * focusOffset;
1052         radiusTopLeft = buttonSize_.Height() / DOUBLE - focusOffset;
1053         radiusTopRight = buttonSize_.Height() / DOUBLE - focusOffset;
1054         radiusBottomLeft = buttonSize_.Height() / DOUBLE - focusOffset;
1055         radiusBottomRight = buttonSize_.Height() / DOUBLE - focusOffset;
1056     }
1057 
1058     paintRect.SetRect({ originX, originY, endX - originX, endY - originY });
1059     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS, radiusTopLeft, radiusTopLeft);
1060     paintRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS, radiusTopRight, radiusTopRight);
1061     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS, radiusBottomLeft, radiusBottomLeft);
1062     paintRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS, radiusBottomRight, radiusBottomRight);
1063 }
1064 
GetFocusPattern() const1065 FocusPattern SearchPattern::GetFocusPattern() const
1066 {
1067     FocusPattern focusPattern = { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION };
1068     focusPattern.SetIsFocusActiveWhenFocused(true);
1069     return focusPattern;
1070 }
1071 
RequestKeyboard()1072 void SearchPattern::RequestKeyboard()
1073 {
1074     auto host = GetHost();
1075     CHECK_NULL_VOID(host);
1076     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1077     CHECK_NULL_VOID(textFieldFrameNode);
1078     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1079     textFieldPattern->SearchRequestKeyboard();
1080 }
1081 
InitButtonTouchEvent(RefPtr<TouchEventImpl> & touchEvent,int32_t childId)1082 void SearchPattern::InitButtonTouchEvent(RefPtr<TouchEventImpl>& touchEvent, int32_t childId)
1083 {
1084     if (touchEvent) {
1085         return;
1086     }
1087     auto host = GetHost();
1088     CHECK_NULL_VOID(host);
1089     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1090     CHECK_NULL_VOID(buttonFrameNode);
1091     auto gesture = buttonFrameNode->GetOrCreateGestureEventHub();
1092     CHECK_NULL_VOID(gesture);
1093     auto eventHub = buttonFrameNode->GetEventHub<ButtonEventHub>();
1094     CHECK_NULL_VOID(eventHub);
1095     eventHub->SetStateEffect(false);
1096     auto touchTask = [weak = WeakClaim(this), childId](const TouchEventInfo& info) {
1097         auto pattern = weak.Upgrade();
1098         CHECK_NULL_VOID(pattern);
1099         auto touchType = info.GetTouches().front().GetTouchType();
1100         if (touchType == TouchType::DOWN) {
1101             pattern->OnButtonTouchDown(childId);
1102         }
1103         if (touchType == TouchType::UP || touchType == TouchType::CANCEL) {
1104             pattern->OnButtonTouchUp(childId);
1105         }
1106     };
1107     touchEvent = MakeRefPtr<TouchEventImpl>(std::move(touchTask));
1108     gesture->AddTouchEvent(touchEvent);
1109 }
1110 
InitButtonMouseEvent(RefPtr<InputEvent> & inputEvent,int32_t childId)1111 void SearchPattern::InitButtonMouseEvent(RefPtr<InputEvent>& inputEvent, int32_t childId)
1112 {
1113     if (inputEvent) {
1114         return;
1115     }
1116     auto host = GetHost();
1117     CHECK_NULL_VOID(host);
1118     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1119     CHECK_NULL_VOID(buttonFrameNode);
1120     auto eventHub = buttonFrameNode->GetEventHub<ButtonEventHub>();
1121     auto inputHub = eventHub->GetOrCreateInputEventHub();
1122     auto buttonPattern = buttonFrameNode->GetPattern<ButtonPattern>();
1123     CHECK_NULL_VOID(buttonPattern);
1124     auto buttonHoverListener = buttonPattern->GetHoverListener();
1125     inputHub->RemoveOnHoverEvent(buttonHoverListener);
1126     auto mouseTask = [weak = WeakClaim(this), childId](bool isHover) {
1127         auto pattern = weak.Upgrade();
1128         if (pattern) {
1129             pattern->HandleButtonMouseEvent(isHover, childId);
1130         }
1131     };
1132     inputEvent = MakeRefPtr<InputEvent>(std::move(mouseTask));
1133     inputHub->AddOnHoverEvent(inputEvent);
1134 }
1135 
OnButtonTouchDown(int32_t childId)1136 void SearchPattern::OnButtonTouchDown(int32_t childId)
1137 {
1138     auto host = GetHost();
1139     CHECK_NULL_VOID(host);
1140     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1141     CHECK_NULL_VOID(buttonFrameNode);
1142     auto renderContext = buttonFrameNode->GetRenderContext();
1143     CHECK_NULL_VOID(renderContext);
1144     if (childId == CANCEL_BUTTON_INDEX ? isCancelButtonHover_ : isSearchButtonHover_) {
1145         AnimateTouchAndHover(renderContext, HOVER_OPACITY, TOUCH_OPACITY, HOVER_TO_TOUCH_DURATION, Curves::SHARP);
1146     } else {
1147         AnimateTouchAndHover(renderContext, 0.0f, TOUCH_OPACITY, TOUCH_DURATION, Curves::FRICTION);
1148     }
1149 }
1150 
OnButtonTouchUp(int32_t childId)1151 void SearchPattern::OnButtonTouchUp(int32_t childId)
1152 {
1153     auto host = GetHost();
1154     CHECK_NULL_VOID(host);
1155     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1156     CHECK_NULL_VOID(buttonFrameNode);
1157     auto renderContext = buttonFrameNode->GetRenderContext();
1158     CHECK_NULL_VOID(renderContext);
1159     if (childId == CANCEL_BUTTON_INDEX ? isCancelButtonHover_ : isSearchButtonHover_) {
1160         AnimateTouchAndHover(renderContext, TOUCH_OPACITY, HOVER_OPACITY, HOVER_TO_TOUCH_DURATION, Curves::SHARP);
1161     } else {
1162         AnimateTouchAndHover(renderContext, TOUCH_OPACITY, 0.0f, TOUCH_DURATION, Curves::FRICTION);
1163     }
1164 }
1165 
SetMouseStyle(MouseFormat format)1166 void SearchPattern::SetMouseStyle(MouseFormat format)
1167 {
1168     auto host = GetHost();
1169     CHECK_NULL_VOID(host);
1170     auto pipeline = host->GetContext();
1171     CHECK_NULL_VOID(pipeline);
1172     auto windowId = pipeline->GetWindowId();
1173     auto mouseStyle = MouseStyle::CreateMouseStyle();
1174     CHECK_NULL_VOID(mouseStyle);
1175 
1176     int32_t currentPointerStyle = 0;
1177     mouseStyle->GetPointerStyle(windowId, currentPointerStyle);
1178     if (currentPointerStyle != static_cast<int32_t>(format)) {
1179         mouseStyle->SetPointerStyle(windowId, format);
1180     }
1181 }
1182 
HandleButtonMouseEvent(bool isHover,int32_t childId)1183 void SearchPattern::HandleButtonMouseEvent(bool isHover, int32_t childId)
1184 {
1185     if (childId == CANCEL_BUTTON_INDEX) {
1186         isCancelButtonHover_ = isHover;
1187     } else {
1188         isSearchButtonHover_ = isHover;
1189     }
1190     auto host = GetHost();
1191     CHECK_NULL_VOID(host);
1192     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1193     CHECK_NULL_VOID(buttonFrameNode);
1194     auto renderContext = buttonFrameNode->GetRenderContext();
1195     CHECK_NULL_VOID(renderContext);
1196     if (isHover) {
1197         AnimateTouchAndHover(renderContext, 0.0f, HOVER_OPACITY, HOVER_DURATION, Curves::FRICTION);
1198     } else {
1199         AnimateTouchAndHover(renderContext, HOVER_OPACITY, 0.0f, HOVER_DURATION, Curves::FRICTION);
1200     }
1201 }
1202 
AnimateTouchAndHover(RefPtr<RenderContext> & renderContext,float startOpacity,float endOpacity,int32_t duration,const RefPtr<Curve> & curve)1203 void SearchPattern::AnimateTouchAndHover(RefPtr<RenderContext>& renderContext, float startOpacity, float endOpacity,
1204     int32_t duration, const RefPtr<Curve>& curve)
1205 {
1206     auto colorMode = SystemProperties::GetColorMode();
1207     Color touchColorFrom = Color::FromRGBO(0, 0, 0, startOpacity);
1208     Color touchColorTo = Color::FromRGBO(0, 0, 0, endOpacity);
1209     if (colorMode == ColorMode::DARK) {
1210         touchColorFrom = Color::FromRGBO(255, 255, 255, startOpacity);
1211         touchColorTo = Color::FromRGBO(255, 255, 255, endOpacity);
1212     }
1213     Color highlightStart = renderContext->GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(touchColorFrom);
1214     Color highlightEnd = renderContext->GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(touchColorTo);
1215     renderContext->OnBackgroundColorUpdate(highlightStart);
1216     AnimationOption option = AnimationOption();
1217     option.SetDuration(duration);
1218     option.SetCurve(curve);
1219     AnimationUtils::Animate(
1220         option, [renderContext, highlightEnd]() { renderContext->OnBackgroundColorUpdate(highlightEnd); });
1221 }
1222 
ResetDragOption()1223 void SearchPattern::ResetDragOption()
1224 {
1225     ClearButtonStyle(BUTTON_INDEX);
1226     ClearButtonStyle(CANCEL_BUTTON_INDEX);
1227 }
1228 
ClearButtonStyle(int32_t childId)1229 void SearchPattern::ClearButtonStyle(int32_t childId)
1230 {
1231     auto host = GetHost();
1232     CHECK_NULL_VOID(host);
1233     auto buttonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(childId));
1234     CHECK_NULL_VOID(buttonFrameNode);
1235     auto renderContext = buttonFrameNode->GetRenderContext();
1236     CHECK_NULL_VOID(renderContext);
1237     AnimateTouchAndHover(renderContext, TOUCH_OPACITY, 0.0f, HOVER_TO_TOUCH_DURATION, Curves::SHARP);
1238 }
1239 
InitFocusEvent(const RefPtr<FocusHub> & focusHub)1240 void SearchPattern::InitFocusEvent(const RefPtr<FocusHub>& focusHub)
1241 {
1242     auto focusTask = [weak = WeakClaim(this)]() {
1243         auto pattern = weak.Upgrade();
1244         if (!pattern) {
1245             return;
1246         }
1247         bool backwardFocusMovement = false;
1248         bool forwardFocusMovement = false;
1249         auto host = pattern->GetHost();
1250         if (host) {
1251             auto rootHub = host->GetOrCreateFocusHub()->GetRootFocusHub();
1252             backwardFocusMovement = rootHub && rootHub->HasBackwardFocusMovementInChildren();
1253             forwardFocusMovement = rootHub && rootHub->HasForwardFocusMovementInChildren();
1254             if (rootHub) {
1255                 rootHub->ClearFocusMovementFlagsInChildren();
1256             }
1257         }
1258         pattern->HandleFocusEvent(forwardFocusMovement, backwardFocusMovement);
1259     };
1260     focusHub->SetOnFocusInternal(focusTask);
1261     auto blurTask = [weak = WeakClaim(this)]() {
1262         auto pattern = weak.Upgrade();
1263         CHECK_NULL_VOID(pattern);
1264         pattern->HandleBlurEvent();
1265     };
1266     focusHub->SetOnBlurInternal(blurTask);
1267 }
1268 
HandleFocusEvent(bool forwardFocusMovement,bool backwardFocusMovement)1269 void SearchPattern::HandleFocusEvent(bool forwardFocusMovement, bool backwardFocusMovement)
1270 {
1271     auto host = GetHost();
1272     CHECK_NULL_VOID(host);
1273     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1274     CHECK_NULL_VOID(textFieldFrameNode);
1275     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1276     CHECK_NULL_VOID(textFieldPattern);
1277 
1278     if (forwardFocusMovement || backwardFocusMovement) { // Don't update focus if no factical focus movement
1279         focusChoice_ = backwardFocusMovement ? FocusChoice::SEARCH_BUTTON : FocusChoice::SEARCH;
1280         if (focusChoice_ == FocusChoice::SEARCH_BUTTON && !isSearchButtonEnabled_) {
1281             bool isCancelHidden = NearZero(cancelButtonSize_.Height());
1282             focusChoice_ = isCancelHidden ? FocusChoice::SEARCH : FocusChoice::CANCEL_BUTTON;
1283         }
1284     }
1285     PaintFocusState(!(forwardFocusMovement || backwardFocusMovement));
1286 }
1287 
HandleBlurEvent()1288 void SearchPattern::HandleBlurEvent()
1289 {
1290     auto host = GetHost();
1291     CHECK_NULL_VOID(host);
1292     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1293     CHECK_NULL_VOID(textFieldFrameNode);
1294     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1295     CHECK_NULL_VOID(textFieldPattern);
1296     textFieldPattern->HandleBlurEvent();
1297 }
1298 
InitClickEvent()1299 void SearchPattern::InitClickEvent()
1300 {
1301     if (clickListener_) {
1302         return;
1303     }
1304     auto host = GetHost();
1305     CHECK_NULL_VOID(host);
1306     auto gesture = host->GetOrCreateGestureEventHub();
1307     CHECK_NULL_VOID(gesture);
1308     auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
1309         auto pattern = weak.Upgrade();
1310         CHECK_NULL_VOID(pattern);
1311         pattern->HandleClickEvent(info);
1312     };
1313     clickListener_ = MakeRefPtr<ClickEvent>(std::move(clickCallback));
1314     gesture->AddClickEvent(clickListener_);
1315 }
1316 
HandleClickEvent(GestureEvent & info)1317 void SearchPattern::HandleClickEvent(GestureEvent& info)
1318 {
1319     auto host = GetHost();
1320     CHECK_NULL_VOID(host);
1321     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1322     CHECK_NULL_VOID(textFieldFrameNode);
1323     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1324     CHECK_NULL_VOID(textFieldPattern);
1325     textFieldPattern->HandleClickEvent(info);
1326 }
1327 
HandleInputChildOnFocus() const1328 bool SearchPattern::HandleInputChildOnFocus() const
1329 {
1330 #if !defined(PREVIEW)
1331     return false;
1332 #endif
1333     auto focusHub = GetHost()->GetOrCreateFocusHub();
1334     focusHub->RequestFocusImmediately();
1335     return true;
1336 }
1337 
ToJsonValueForTextField(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1338 void SearchPattern::ToJsonValueForTextField(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1339 {
1340     /* no fixed attr below, just return */
1341     if (filter.IsFastFilter()) {
1342         return;
1343     }
1344     auto host = GetHost();
1345     CHECK_NULL_VOID(host);
1346     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1347     CHECK_NULL_VOID(textFieldFrameNode);
1348     auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
1349     CHECK_NULL_VOID(textFieldLayoutProperty);
1350     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
1351     CHECK_NULL_VOID(textFieldPattern);
1352 
1353     json->PutExtAttr("value", textFieldPattern->GetTextValue().c_str(), filter);
1354     json->PutExtAttr("placeholder", textFieldPattern->GetPlaceHolder().c_str(), filter);
1355     json->PutExtAttr("placeholderColor", textFieldPattern->GetPlaceholderColor().c_str(), filter);
1356     json->PutExtAttr("placeholderFont", textFieldPattern->GetPlaceholderFont().c_str(), filter);
1357     json->PutExtAttr("textAlign", V2::ConvertWrapTextAlignToString(textFieldPattern->GetTextAlign()).c_str(), filter);
1358     auto textColor = textFieldLayoutProperty->GetTextColor().value_or(Color());
1359     json->PutExtAttr("fontColor", textColor.ColorToString().c_str(), filter);
1360     auto textFontJson = JsonUtil::Create(true);
1361     textFontJson->Put("fontSize", textFieldPattern->GetFontSize().c_str());
1362     textFontJson->Put("fontStyle",
1363         textFieldPattern->GetItalicFontStyle() == Ace::FontStyle::NORMAL ? "FontStyle.Normal" : "FontStyle.Italic");
1364     textFontJson->Put("fontWeight", V2::ConvertWrapFontWeightToStirng(textFieldPattern->GetFontWeight()).c_str());
1365     textFontJson->Put("fontFamily", textFieldPattern->GetFontFamily().c_str());
1366     json->PutExtAttr("textFont", textFontJson->ToString().c_str(), filter);
1367     json->PutExtAttr("copyOption",
1368         ConvertCopyOptionsToString(textFieldLayoutProperty->GetCopyOptionsValue(CopyOptions::None)).c_str(), filter);
1369     auto maxLength = GetMaxLength();
1370     json->PutExtAttr(
1371         "maxLength", GreatOrEqual(maxLength, Infinity<uint32_t>()) ? "INF" : std::to_string(maxLength).c_str(), filter);
1372     json->PutExtAttr("type", SearchTypeToString().c_str(), filter);
1373     textFieldLayoutProperty->HasCopyOptions();
1374     json->PutExtAttr(
1375         "letterSpacing", textFieldLayoutProperty->GetLetterSpacing().value_or(Dimension()).ToString().c_str(), filter);
1376     json->PutExtAttr(
1377         "lineHeight", textFieldLayoutProperty->GetLineHeight().value_or(0.0_vp).ToString().c_str(), filter);
1378     auto jsonDecoration = JsonUtil::Create(true);
1379     std::string type = V2::ConvertWrapTextDecorationToStirng(
1380         textFieldLayoutProperty->GetTextDecoration().value_or(TextDecoration::NONE));
1381     jsonDecoration->Put("type", type.c_str());
1382     jsonDecoration->Put(
1383         "color", textFieldLayoutProperty->GetTextDecorationColor().value_or(Color::BLACK).ColorToString().c_str());
1384     std::string style = V2::ConvertWrapTextDecorationStyleToString(
1385         textFieldLayoutProperty->GetTextDecorationStyle().value_or(TextDecorationStyle::SOLID));
1386     jsonDecoration->Put("style", style.c_str());
1387     json->PutExtAttr("decoration", jsonDecoration->ToString().c_str(), filter);
1388     json->PutExtAttr(
1389         "minFontSize", textFieldLayoutProperty->GetAdaptMinFontSize().value_or(Dimension()).ToString().c_str(), filter);
1390     json->PutExtAttr(
1391         "maxFontSize", textFieldLayoutProperty->GetAdaptMaxFontSize().value_or(Dimension()).ToString().c_str(), filter);
1392     json->PutExtAttr("inputFilter", textFieldLayoutProperty->GetInputFilterValue("").c_str(), filter);
1393     json->PutExtAttr(
1394         "textIndent", textFieldLayoutProperty->GetTextIndent().value_or(0.0_vp).ToString().c_str(), filter);
1395     json->PutExtAttr("enablePreviewText", textFieldPattern->GetSupportPreviewText(), filter);
1396     textFieldPattern->ToJsonValueSelectOverlay(json, filter);
1397     json->PutExtAttr("stopBackPress", textFieldLayoutProperty->GetStopBackPressValue(true), filter);
1398     json->PutExtAttr("keyboardAppearance", static_cast<int32_t>(textFieldPattern->GetKeyboardAppearance()), filter);
1399 }
1400 
SearchTypeToString() const1401 std::string SearchPattern::SearchTypeToString() const
1402 {
1403     auto host = GetHost();
1404     CHECK_NULL_RETURN(host, "");
1405     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1406     CHECK_NULL_RETURN(textFieldFrameNode, "");
1407     auto layoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
1408     CHECK_NULL_RETURN(layoutProperty, "");
1409     switch (layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED)) {
1410         case TextInputType::NUMBER:
1411             return "SearchType.NUMBER";
1412         case TextInputType::EMAIL_ADDRESS:
1413             return "SearchType.EMAIL";
1414         case TextInputType::PHONE:
1415             return "SearchType.PHONE_NUMBER";
1416         case TextInputType::URL:
1417             return "SearchType.URL";
1418         default:
1419             return "SearchType.NORMAL";
1420     }
1421 }
1422 
ToJsonValueForSearchIcon(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1423 void SearchPattern::ToJsonValueForSearchIcon(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1424 {
1425     /* no fixed attr below, just return */
1426     if (filter.IsFastFilter()) {
1427         return;
1428     }
1429     auto host = GetHost();
1430     CHECK_NULL_VOID(host);
1431     auto searchIconFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(IMAGE_INDEX));
1432     CHECK_NULL_VOID(searchIconFrameNode);
1433     auto searchIconJson = JsonUtil::Create(true);
1434 
1435     // icon size
1436     auto searchIconGeometryNode = searchIconFrameNode->GetGeometryNode();
1437     CHECK_NULL_VOID(searchIconGeometryNode);
1438     auto searchIconFrameSize = searchIconGeometryNode->GetFrameSize().Width();
1439     auto searchLayoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
1440     CHECK_NULL_VOID(searchLayoutProperty);
1441     auto searchIconSize = searchLayoutProperty->GetSearchIconUDSizeValue(Dimension(searchIconFrameSize)).ConvertToPx();
1442     searchIconJson->Put("size", Dimension(searchIconSize, DimensionUnit::PX).ToString().c_str());
1443 
1444     if (searchIconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
1445         auto symbolLayoutProperty = searchIconFrameNode->GetLayoutProperty<TextLayoutProperty>();
1446         CHECK_NULL_VOID(symbolLayoutProperty);
1447         // icon color
1448         auto searchIconColor = symbolLayoutProperty->GetSymbolColorList();
1449         if (searchIconColor.has_value()) {
1450             searchIconJson->Put("color", SymbolColorToString(searchIconColor.value()).c_str());
1451         } else {
1452             searchIconJson->Put("color", std::string("").c_str());
1453         }
1454 
1455         // icon path
1456         auto symbolSourceInfo = symbolLayoutProperty->GetSymbolSourceInfo().value_or(SymbolSourceInfo());
1457         searchIconJson->Put("src", static_cast<int64_t>(symbolSourceInfo.GetUnicode()));
1458         json->PutExtAttr("icon", static_cast<int64_t>(symbolSourceInfo.GetUnicode()), filter);
1459         json->PutExtAttr("searchIcon", searchIconJson, filter);
1460     } else {
1461         auto imageLayoutProperty = searchIconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
1462         CHECK_NULL_VOID(imageLayoutProperty);
1463         // icon color
1464         auto searchIconColor = imageLayoutProperty->GetImageSourceInfo()->GetFillColor().value_or(Color());
1465         searchIconJson->Put("color", searchIconColor.ColorToString().c_str());
1466 
1467         // icon path
1468         auto searchIconPath = imageLayoutProperty->GetImageSourceInfo()->GetSrc();
1469         searchIconJson->Put("src", searchIconPath.c_str());
1470         json->PutExtAttr("icon", searchIconPath.c_str(), filter);
1471         json->PutExtAttr("searchIcon", searchIconJson, filter);
1472     }
1473 }
1474 
ToJsonValueForCancelButton(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1475 void SearchPattern::ToJsonValueForCancelButton(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1476 {
1477     /* no fixed attr below, just return */
1478     if (filter.IsFastFilter()) {
1479         return;
1480     }
1481     auto host = GetHost();
1482     CHECK_NULL_VOID(host);
1483     auto layoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
1484     CHECK_NULL_VOID(layoutProperty);
1485     auto cancelImageFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(CANCEL_IMAGE_INDEX));
1486     CHECK_NULL_VOID(cancelImageFrameNode);
1487     auto cancelButtonJson = JsonUtil::Create(true);
1488     ToJsonValueForCancelButtonStyle(
1489         cancelButtonJson, layoutProperty->GetCancelButtonStyle().value_or(CancelButtonStyle::INPUT));
1490     auto cancelIconJson = JsonUtil::Create(true);
1491     // icon size
1492     auto cancelIconGeometryNode = cancelImageFrameNode->GetGeometryNode();
1493     CHECK_NULL_VOID(cancelIconGeometryNode);
1494     auto cancelIconFrameSize = cancelIconGeometryNode->GetFrameSize().Width();
1495     auto searchLayoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
1496     CHECK_NULL_VOID(searchLayoutProperty);
1497     auto cancelIconSize =
1498         searchLayoutProperty->GetCancelButtonUDSizeValue(Dimension(cancelIconFrameSize)).ConvertToPx();
1499     cancelIconJson->Put("size", Dimension(cancelIconSize, DimensionUnit::PX).ToString().c_str());
1500     if (cancelImageFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
1501         auto symbolLayoutProperty = cancelImageFrameNode->GetLayoutProperty<TextLayoutProperty>();
1502         CHECK_NULL_VOID(symbolLayoutProperty);
1503         // icon color & right icon src path
1504         auto searchIconColor = symbolLayoutProperty->GetSymbolColorList();
1505         if (searchIconColor.has_value()) {
1506             cancelIconJson->Put("color", SymbolColorToString(searchIconColor.value()).c_str());
1507         } else {
1508             cancelIconJson->Put("color", std::string("").c_str());
1509         }
1510         auto symbolSourceInfo = symbolLayoutProperty->GetSymbolSourceInfo().value_or(SymbolSourceInfo());
1511         cancelIconJson->Put("src", static_cast<int64_t>(symbolSourceInfo.GetUnicode()));
1512         cancelButtonJson->Put("icon", cancelIconJson);
1513         json->PutExtAttr("cancelButton", cancelButtonJson, filter);
1514     } else {
1515         auto cancelImageLayoutProperty = cancelImageFrameNode->GetLayoutProperty<ImageLayoutProperty>();
1516         CHECK_NULL_VOID(cancelImageLayoutProperty);
1517         // icon color
1518         auto cancelImageRenderProperty = cancelImageFrameNode->GetPaintProperty<ImageRenderProperty>();
1519         CHECK_NULL_VOID(cancelImageRenderProperty);
1520         auto cancelIconColor = cancelImageRenderProperty->GetSvgFillColor().value_or(Color());
1521         cancelIconJson->Put("color", cancelIconColor.ColorToString().c_str());
1522         // right icon src path
1523         auto cancelImageSrc = cancelImageLayoutProperty->GetImageSourceInfo()->GetSrc();
1524         cancelIconJson->Put("src", cancelImageSrc.c_str());
1525         cancelButtonJson->Put("icon", cancelIconJson);
1526         json->PutExtAttr("cancelButton", cancelButtonJson, filter);
1527     }
1528 }
1529 
ToJsonValueForSearchButtonOption(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1530 void SearchPattern::ToJsonValueForSearchButtonOption(
1531     std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1532 {
1533     /* no fixed attr below, just return */
1534     if (filter.IsFastFilter()) {
1535         return;
1536     }
1537     auto host = GetHost();
1538     CHECK_NULL_VOID(host);
1539     auto searchButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(BUTTON_INDEX));
1540     CHECK_NULL_VOID(searchButtonFrameNode);
1541     auto searchButtonLayoutProperty = searchButtonFrameNode->GetLayoutProperty<ButtonLayoutProperty>();
1542     CHECK_NULL_VOID(searchButtonLayoutProperty);
1543     auto searchButtonJson = JsonUtil::Create(true);
1544 
1545     // font size
1546     auto searchButtonFontSize = searchButtonLayoutProperty->GetFontSize().value_or(Dimension(0, DimensionUnit::VP));
1547     searchButtonJson->Put("fontSize", searchButtonFontSize.ToString().c_str());
1548 
1549     // font color
1550     auto searchButtonFontColor = searchButtonLayoutProperty->GetFontColor().value_or(Color());
1551     searchButtonJson->Put("fontColor", searchButtonFontColor.ColorToString().c_str());
1552     json->PutExtAttr("searchButtonOption", searchButtonJson, filter);
1553 }
1554 
ToJsonValueForCursor(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1555 void SearchPattern::ToJsonValueForCursor(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1556 {
1557     /* no fixed attr below, just return */
1558     if (filter.IsFastFilter()) {
1559         return;
1560     }
1561     auto host = GetHost();
1562     CHECK_NULL_VOID(host);
1563     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1564     CHECK_NULL_VOID(textFieldFrameNode);
1565     auto textFieldPaintProperty = textFieldFrameNode->GetPaintProperty<TextFieldPaintProperty>();
1566     CHECK_NULL_VOID(textFieldPaintProperty);
1567     auto cursorJson = JsonUtil::Create(true);
1568 
1569     // color
1570     auto caretColor = textFieldPaintProperty->GetCursorColor().value_or(Color());
1571     cursorJson->Put("color", caretColor.ColorToString().c_str());
1572     auto caretWidth = textFieldPaintProperty->GetCursorWidth().value_or(Dimension(0, DimensionUnit::VP));
1573     cursorJson->Put("width", caretWidth.ToString().c_str());
1574     json->PutExtAttr("caretStyle", cursorJson, filter);
1575     auto selectedBackgroundColor = textFieldPaintProperty->GetSelectedBackgroundColor().value_or(Color());
1576     json->PutExtAttr("selectedBackgroundColor", selectedBackgroundColor.ColorToString().c_str(), filter);
1577 }
1578 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1579 void SearchPattern::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1580 {
1581     Pattern::ToJsonValue(json, filter);
1582 
1583     ToJsonValueForTextField(json, filter);
1584     ToJsonValueForSearchIcon(json, filter);
1585     ToJsonValueForCancelButton(json, filter);
1586     ToJsonValueForCursor(json, filter);
1587     ToJsonValueForSearchButtonOption(json, filter);
1588 }
1589 
UpdateDividerColorMode()1590 void SearchPattern::UpdateDividerColorMode()
1591 {
1592     auto host = GetHost();
1593     CHECK_NULL_VOID(host);
1594     auto dividerFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(DIVIDER_INDEX));
1595     CHECK_NULL_VOID(dividerFrameNode);
1596     auto pipeline = dividerFrameNode->GetContext();
1597     CHECK_NULL_VOID(pipeline);
1598     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1599     CHECK_NULL_VOID(searchTheme);
1600     auto searchDividerColor = searchTheme->GetSearchDividerColor();
1601     auto dividerRenderProperty = dividerFrameNode->GetPaintProperty<DividerRenderProperty>();
1602     CHECK_NULL_VOID(dividerRenderProperty);
1603     dividerRenderProperty->UpdateDividerColor(searchDividerColor);
1604     dividerFrameNode->MarkModifyDone();
1605     dividerFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1606 }
1607 
UpdateCancelButtonColorMode()1608 void SearchPattern::UpdateCancelButtonColorMode()
1609 {
1610     auto cancelButtonNode = cancelButtonNode_.Upgrade();
1611     CHECK_NULL_VOID(cancelButtonNode);
1612     auto pipeline = cancelButtonNode->GetContext();
1613     CHECK_NULL_VOID(pipeline);
1614     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1615     CHECK_NULL_VOID(searchTheme);
1616     auto cancelButtonRenderContext = cancelButtonNode->GetRenderContext();
1617     CHECK_NULL_VOID(cancelButtonRenderContext);
1618     cancelButtonRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
1619     auto textFrameNode = AceType::DynamicCast<FrameNode>(cancelButtonNode->GetChildren().front());
1620     CHECK_NULL_VOID(textFrameNode);
1621     auto textLayoutProperty = textFrameNode->GetLayoutProperty<TextLayoutProperty>();
1622     CHECK_NULL_VOID(textLayoutProperty);
1623     textLayoutProperty->UpdateTextColor(searchTheme->GetSearchButtonTextColor());
1624     cancelButtonNode->MarkModifyDone();
1625     cancelButtonNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1626 }
1627 
OnColorConfigurationUpdate()1628 void SearchPattern::OnColorConfigurationUpdate()
1629 {
1630     auto host = GetHost();
1631     CHECK_NULL_VOID(host);
1632     host->SetNeedCallChildrenUpdate(false);
1633     auto pipeline = host->GetContext();
1634     CHECK_NULL_VOID(pipeline);
1635     auto textFieldTheme = pipeline->GetTheme<TextFieldTheme>();
1636     CHECK_NULL_VOID(textFieldTheme);
1637     auto renderContext = host->GetRenderContext();
1638     CHECK_NULL_VOID(renderContext);
1639     renderContext->UpdateBackgroundColor(textFieldTheme->GetBgColor());
1640     CHECK_NULL_VOID(pipeline);
1641     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1642     CHECK_NULL_VOID(searchTheme);
1643     UpdateCancelButtonColorMode();
1644     auto buttonNode = buttonNode_.Upgrade();
1645     if (buttonNode) {
1646         auto buttonRenderContext = buttonNode->GetRenderContext();
1647         CHECK_NULL_VOID(buttonRenderContext);
1648         buttonRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
1649         auto textFrameNode = AceType::DynamicCast<FrameNode>(buttonNode->GetChildren().front());
1650         CHECK_NULL_VOID(textFrameNode);
1651         auto textLayoutProperty = textFrameNode->GetLayoutProperty<TextLayoutProperty>();
1652         CHECK_NULL_VOID(textLayoutProperty);
1653         textLayoutProperty->UpdateTextColor(searchTheme->GetSearchButtonTextColor());
1654         buttonNode->MarkModifyDone();
1655         buttonNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1656     }
1657     auto textField = textField_.Upgrade();
1658     if (textField) {
1659         auto textFieldLayoutProperty = textField->GetLayoutProperty<TextFieldLayoutProperty>();
1660         CHECK_NULL_VOID(textFieldLayoutProperty);
1661         textFieldLayoutProperty->UpdateTextColor(searchTheme->GetTextColor());
1662         textFieldLayoutProperty->UpdatePlaceholderTextColor(searchTheme->GetPlaceholderColor());
1663         textField->MarkModifyDone();
1664         textField->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1665     }
1666     UpdateDividerColorMode();
1667 }
1668 
GetMaxLength() const1669 uint32_t SearchPattern::GetMaxLength() const
1670 {
1671     auto host = GetHost();
1672     CHECK_NULL_RETURN(host, Infinity<uint32_t>());
1673     auto textFieldFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(TEXTFIELD_INDEX));
1674     CHECK_NULL_RETURN(textFieldFrameNode, Infinity<uint32_t>());
1675     auto textFieldLayoutProperty = textFieldFrameNode->GetLayoutProperty<TextFieldLayoutProperty>();
1676     CHECK_NULL_RETURN(textFieldLayoutProperty, Infinity<uint32_t>());
1677     return textFieldLayoutProperty->HasMaxLength() ? textFieldLayoutProperty->GetMaxLengthValue(Infinity<uint32_t>())
1678                                                    : Infinity<uint32_t>();
1679 }
1680 
ToJsonValueForCancelButtonStyle(std::unique_ptr<JsonValue> & cancelButtonJson,const CancelButtonStyle & cancelButtonStyle) const1681 void SearchPattern::ToJsonValueForCancelButtonStyle(
1682     std::unique_ptr<JsonValue>& cancelButtonJson, const CancelButtonStyle& cancelButtonStyle) const
1683 {
1684     if (cancelButtonStyle == CancelButtonStyle::CONSTANT) {
1685         cancelButtonJson->Put("style", "CancelButtonStyle.CONSTANT");
1686     } else if (cancelButtonStyle == CancelButtonStyle::INVISIBLE) {
1687         cancelButtonJson->Put("style", "CancelButtonStyle.INVISIBLE");
1688     } else {
1689         cancelButtonJson->Put("style", "CancelButtonStyle.INPUT");
1690     }
1691 }
1692 
SymbolColorToString(std::vector<Color> & colors) const1693 std::string SearchPattern::SymbolColorToString(std::vector<Color>& colors) const
1694 {
1695     if (colors.size() <= 0) {
1696         return "";
1697     }
1698     auto colorStr = std::string("[");
1699     for (auto color : colors) {
1700         colorStr.append(color.ColorToString());
1701         colorStr.append(",");
1702     }
1703     colorStr.append("]");
1704     return colorStr;
1705 }
1706 
InitIconColorSize()1707 void SearchPattern::InitIconColorSize()
1708 {
1709     InitSearchIconColorSize();
1710     InitCancelIconColorSize();
1711 }
1712 
InitSearchIconColorSize()1713 void SearchPattern::InitSearchIconColorSize()
1714 {
1715     auto host = GetHost();
1716     CHECK_NULL_VOID(host);
1717     auto pipeline = host->GetContext();
1718     CHECK_NULL_VOID(pipeline);
1719     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1720     CHECK_NULL_VOID(searchTheme);
1721     GetSearchNode()->SetSearchSymbolIconColor(Color(searchTheme->GetSymbolIconColor()));
1722     GetSearchNode()->SetSearchSymbolIconSize(SYMBOL_ICON_HEIGHT);
1723     GetSearchNode()->SetSearchImageIconColor(Color(searchTheme->GetSearchIconColor()));
1724     GetSearchNode()->SetSearchImageIconSize(searchTheme->GetIconHeight());
1725 }
1726 
InitCancelIconColorSize()1727 void SearchPattern::InitCancelIconColorSize()
1728 {
1729     auto host = GetHost();
1730     CHECK_NULL_VOID(host);
1731     auto pipeline = host->GetContext();
1732     CHECK_NULL_VOID(pipeline);
1733     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1734     CHECK_NULL_VOID(searchTheme);
1735     GetSearchNode()->SetCancelSymbolIconColor(Color(searchTheme->GetSymbolIconColor()));
1736     GetSearchNode()->SetCancelSymbolIconSize(SYMBOL_ICON_HEIGHT);
1737     GetSearchNode()->SetCancelImageIconColor(Color(searchTheme->GetSearchIconColor()));
1738     GetSearchNode()->SetCancelImageIconSize(searchTheme->GetIconHeight());
1739 }
1740 
CreateSearchIcon(const std::string & src)1741 void SearchPattern::CreateSearchIcon(const std::string& src)
1742 {
1743     CHECK_NULL_VOID(GetSearchNode());
1744     if (GetSearchNode()->HasSearchIconNodeCreated()) {
1745         UpdateSearchSymbolIconColor();
1746         return;
1747     }
1748     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) &&
1749         src.empty() && SystemProperties::IsNeedSymbol()) {
1750         CreateOrUpdateSymbol(IMAGE_INDEX, !GetSearchNode()->HasSearchIconNodeCreated(), false);
1751     } else {
1752         GetSearchNode()->SetSearchImageIconOptions(IconOptions(src));
1753         CreateOrUpdateImage(IMAGE_INDEX, !GetSearchNode()->HasSearchIconNodeCreated());
1754     }
1755     GetSearchNode()->UpdateHasSearchIconNodeCreated(true);
1756 }
1757 
UpdateSearchSymbolIconColor()1758 void SearchPattern::UpdateSearchSymbolIconColor()
1759 {
1760     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1761         return;
1762     }
1763     auto host = GetHost();
1764     CHECK_NULL_VOID(host);
1765     CHECK_NULL_VOID(GetSearchNode());
1766     auto cancelButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(IMAGE_INDEX));
1767     auto layoutProperty = cancelButtonFrameNode->GetLayoutProperty<TextLayoutProperty>();
1768     CHECK_NULL_VOID(layoutProperty);
1769     layoutProperty->UpdateSymbolColorList({ GetSearchNode()->GetSearchSymbolIconColor() });
1770 }
1771 
CreateCancelIcon()1772 void SearchPattern::CreateCancelIcon()
1773 {
1774     CHECK_NULL_VOID(GetSearchNode());
1775     if (GetSearchNode()->HasCancelIconNodeCreated()) {
1776         UpdateCancelSymbolIconColor();
1777         return;
1778     }
1779     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) &&
1780         SystemProperties::IsNeedSymbol()) {
1781         CreateOrUpdateSymbol(CANCEL_IMAGE_INDEX, !GetSearchNode()->HasCancelIconNodeCreated(), false);
1782     } else {
1783         GetSearchNode()->SetCancelImageIconOptions(IconOptions());
1784         CreateOrUpdateImage(CANCEL_IMAGE_INDEX, !GetSearchNode()->HasCancelIconNodeCreated());
1785     }
1786     GetSearchNode()->UpdateHasCancelIconNodeCreated(true);
1787 }
1788 
UpdateCancelSymbolIconColor()1789 void SearchPattern::UpdateCancelSymbolIconColor()
1790 {
1791     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1792         return;
1793     }
1794     auto host = GetHost();
1795     CHECK_NULL_VOID(host);
1796     CHECK_NULL_VOID(GetSearchNode());
1797     auto cancelButtonFrameNode = DynamicCast<FrameNode>(host->GetChildAtIndex(CANCEL_IMAGE_INDEX));
1798     auto layoutProperty = cancelButtonFrameNode->GetLayoutProperty<TextLayoutProperty>();
1799     CHECK_NULL_VOID(layoutProperty);
1800     layoutProperty->UpdateSymbolColorList({ GetSearchNode()->GetCancelSymbolIconColor() });
1801 }
1802 
CreateOrUpdateSymbol(int32_t index,bool isCreateNode,bool isFromModifier)1803 void SearchPattern::CreateOrUpdateSymbol(int32_t index, bool isCreateNode, bool isFromModifier)
1804 {
1805     CHECK_NULL_VOID(GetSearchNode());
1806     imageClickListener_ = nullptr;
1807     auto host = GetHost();
1808     CHECK_NULL_VOID(host);
1809     auto pipeline = host->GetContext();
1810     CHECK_NULL_VOID(pipeline);
1811     auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
1812     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1813     CHECK_NULL_VOID(searchTheme);
1814     auto iconFrameNode = FrameNode::GetOrCreateFrameNode(
1815         V2::SYMBOL_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<TextPattern>(); });
1816     auto layoutProperty = iconFrameNode->GetLayoutProperty<TextLayoutProperty>();
1817     layoutProperty->UpdateSymbolSourceInfo(index == IMAGE_INDEX ? SymbolSourceInfo(searchTheme->GetSearchSymbolId())
1818                                                                 : SymbolSourceInfo(searchTheme->GetCancelSymbolId()));
1819     layoutProperty->UpdateFontSize(
1820         index == IMAGE_INDEX ? GetSearchNode()->GetSearchSymbolIconSize() : GetSearchNode()->GetCancelSymbolIconSize());
1821     layoutProperty->UpdateSymbolColorList({index == IMAGE_INDEX ? GetSearchNode()->GetSearchSymbolIconColor()
1822                                                                 : GetSearchNode()->GetCancelSymbolIconColor()});
1823     float maxFontScale = MAX_FONT_SCALE;
1824     if (layoutProperty->GetFontSize()->Unit() != DimensionUnit::VP) {
1825         maxFontScale = std::min(pipeline->GetMaxAppFontScale(), MAX_FONT_SCALE);
1826     }
1827     layoutProperty->UpdateMaxFontScale(maxFontScale);
1828     auto parentInspector = GetSearchNode()->GetInspectorIdValue("");
1829     iconFrameNode->UpdateInspectorId(INSPECTOR_PREFIX + SPECICALIZED_INSPECTOR_INDEXS[index] + parentInspector);
1830 
1831     if (isFromModifier) {
1832         UpdateSymbolIconProperties(iconFrameNode, index);
1833     }
1834 
1835     if (isCreateNode) {
1836         iconFrameNode->MountToParent(GetSearchNode());
1837         if (index == CANCEL_IMAGE_INDEX) {
1838             auto cancelButtonEvent = iconFrameNode->GetEventHub<ButtonEventHub>();
1839             CHECK_NULL_VOID(cancelButtonEvent);
1840             cancelButtonEvent->SetEnabled(false);
1841         }
1842         iconFrameNode->MarkModifyDone();
1843     } else {
1844         auto oldFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(index));
1845         CHECK_NULL_VOID(oldFrameNode);
1846         GetSearchNode()->ReplaceChild(oldFrameNode, iconFrameNode);
1847         if (index == CANCEL_IMAGE_INDEX) {
1848             UpdateIconChangeEvent();
1849         }
1850         iconFrameNode->MarkModifyDone();
1851         iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1852     }
1853 }
1854 
CreateOrUpdateImage(int32_t index,bool isCreateNode)1855 void SearchPattern::CreateOrUpdateImage(int32_t index, bool isCreateNode)
1856 {
1857     CHECK_NULL_VOID(GetSearchNode());
1858     imageClickListener_ = nullptr;
1859     auto host = GetHost();
1860     CHECK_NULL_VOID(host);
1861     auto pipeline = host->GetContext();
1862     CHECK_NULL_VOID(pipeline);
1863     auto searchTheme = pipeline->GetTheme<SearchTheme>();
1864     CHECK_NULL_VOID(searchTheme);
1865     auto iconFrameNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
1866         ElementRegister::GetInstance()->MakeUniqueId(),
1867         []() { return AceType::MakeRefPtr<ImagePattern>(); });
1868     UpdateImageIconProperties(iconFrameNode, index);
1869     if (isCreateNode) {
1870         iconFrameNode->MountToParent(GetSearchNode());
1871         if (index == CANCEL_IMAGE_INDEX) {
1872             auto cancelButtonEvent = iconFrameNode->GetEventHub<ButtonEventHub>();
1873             CHECK_NULL_VOID(cancelButtonEvent);
1874             cancelButtonEvent->SetEnabled(false);
1875         }
1876         iconFrameNode->MarkModifyDone();
1877     } else {
1878         auto oldFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(index));
1879         CHECK_NULL_VOID(oldFrameNode);
1880         GetSearchNode()->ReplaceChild(oldFrameNode, iconFrameNode);
1881         if (index == CANCEL_IMAGE_INDEX) {
1882             UpdateIconChangeEvent();
1883         }
1884         iconFrameNode->MarkModifyDone();
1885         iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1886     }
1887 }
1888 
SetSearchSrcPath(const std::string & src,const std::string & bundleName,const std::string & moduleName)1889 void SearchPattern::SetSearchSrcPath(
1890     const std::string& src, const std::string& bundleName, const std::string& moduleName)
1891 {
1892     CHECK_NULL_VOID(GetSearchNode());
1893     auto &imageIconOptions = GetSearchNode()->GetSearchImageIconOptions();
1894     imageIconOptions.UpdateSrc(std::string(src), std::string(bundleName), std::string(moduleName));
1895     UpdateImageIconNode(IMAGE_INDEX);
1896 }
1897 
SetSearchIconSize(const Dimension & value)1898 void SearchPattern::SetSearchIconSize(const Dimension& value)
1899 {
1900     CHECK_NULL_VOID(GetSearchNode());
1901     auto& imageIconOptions = GetSearchNode()->GetSearchImageIconOptions();
1902     imageIconOptions.UpdateSize(Dimension(value));
1903     UpdateImageIconNode(IMAGE_INDEX);
1904 }
1905 
SetSearchIconColor(const Color & color)1906 void SearchPattern::SetSearchIconColor(const Color& color)
1907 {
1908     CHECK_NULL_VOID(GetSearchNode());
1909     auto frameNode = GetHost();
1910     CHECK_NULL_VOID(frameNode);
1911     auto iconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(IMAGE_INDEX));
1912     CHECK_NULL_VOID(iconFrameNode);
1913     if (iconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
1914         GetSearchNode()->SetSearchSymbolIconColor(Color(color));
1915         auto symbolLayoutProperty = iconFrameNode->GetLayoutProperty<TextLayoutProperty>();
1916         CHECK_NULL_VOID(symbolLayoutProperty);
1917         symbolLayoutProperty->UpdateSymbolColorList({color});
1918         iconFrameNode->MarkModifyDone();
1919         iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1920     } else {
1921         auto &imageIconOptions = GetSearchNode()->GetSearchImageIconOptions();
1922         imageIconOptions.UpdateColor(Color(color));
1923         auto imageLayoutProperty = iconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
1924         CHECK_NULL_VOID(imageLayoutProperty);
1925         auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value();
1926         if (imageSourceInfo.IsSvg()) {
1927             imageSourceInfo.SetFillColor(color);
1928             imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
1929             auto imageRenderProperty = iconFrameNode->GetPaintProperty<ImageRenderProperty>();
1930             CHECK_NULL_VOID(imageRenderProperty);
1931             imageRenderProperty->UpdateSvgFillColor(color);
1932             iconFrameNode->MarkModifyDone();
1933             iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1934         }
1935     }
1936 }
1937 
SetSearchImageIcon(IconOptions & iconOptions)1938 void SearchPattern::SetSearchImageIcon(IconOptions& iconOptions)
1939 {
1940     CHECK_NULL_VOID(GetSearchNode());
1941     auto& imageIconOptions = GetSearchNode()->GetSearchImageIconOptions();
1942     if (iconOptions.GetColor().has_value()) {
1943         imageIconOptions.UpdateColor(iconOptions.GetColor().value());
1944     }
1945     if (iconOptions.GetSize().has_value()) {
1946         imageIconOptions.UpdateSize(ConvertImageIconSizeValue(iconOptions.GetSize().value()));
1947     }
1948     if (iconOptions.GetSrc().has_value()) {
1949         imageIconOptions.UpdateSrc(iconOptions.GetSrc().value_or(""),
1950             iconOptions.GetBundleName().value_or(""),
1951             iconOptions.GetModuleName().value_or(""));
1952     }
1953     UpdateImageIconNode(IMAGE_INDEX);
1954 }
1955 
SetSearchSymbolIcon()1956 void SearchPattern::SetSearchSymbolIcon()
1957 {
1958     UpdateSymbolIconNode(IMAGE_INDEX);
1959 }
1960 
SetCancelIconSize(const Dimension & value)1961 void SearchPattern::SetCancelIconSize(const Dimension& value)
1962 {
1963     CHECK_NULL_VOID(GetSearchNode());
1964     auto& imageIconOptions = GetSearchNode()->GetCancelImageIconOptions();
1965     imageIconOptions.UpdateSize(Dimension(value));
1966     UpdateImageIconNode(CANCEL_IMAGE_INDEX);
1967 }
1968 
SetCancelIconColor(const Color & color)1969 void SearchPattern::SetCancelIconColor(const Color& color)
1970 {
1971     CHECK_NULL_VOID(GetSearchNode());
1972     auto frameNode = GetHost();
1973     CHECK_NULL_VOID(frameNode);
1974     auto cancelIconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(CANCEL_IMAGE_INDEX));
1975     CHECK_NULL_VOID(cancelIconFrameNode);
1976     if (cancelIconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG) {
1977         GetSearchNode()->SetCancelSymbolIconColor(Color(color));
1978         auto symbolLayoutProperty = cancelIconFrameNode->GetLayoutProperty<TextLayoutProperty>();
1979         CHECK_NULL_VOID(symbolLayoutProperty);
1980         symbolLayoutProperty->UpdateSymbolColorList({color});
1981         cancelIconFrameNode->MarkModifyDone();
1982         cancelIconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1983     } else {
1984         auto &imageIconOptions = GetSearchNode()->GetCancelImageIconOptions();
1985         imageIconOptions.UpdateColor(Color(color));
1986         auto imageLayoutProperty = cancelIconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
1987         CHECK_NULL_VOID(imageLayoutProperty);
1988         auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value();
1989         if (imageSourceInfo.IsSvg()) {
1990             imageSourceInfo.SetFillColor(color);
1991             imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
1992             auto imageRenderProperty = cancelIconFrameNode->GetPaintProperty<ImageRenderProperty>();
1993             CHECK_NULL_VOID(imageRenderProperty);
1994             imageRenderProperty->UpdateSvgFillColor(color);
1995             cancelIconFrameNode->MarkModifyDone();
1996             cancelIconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1997         }
1998     }
1999 }
2000 
SetRightIconSrcPath(const std::string & src)2001 void SearchPattern::SetRightIconSrcPath(const std::string& src)
2002 {
2003     CHECK_NULL_VOID(GetSearchNode());
2004     auto &imageIconOptions = GetSearchNode()->GetCancelImageIconOptions();
2005     imageIconOptions.UpdateSrc(std::string(src), "", "");
2006     UpdateImageIconNode(CANCEL_IMAGE_INDEX);
2007 }
2008 
SetCancelButtonStyle(const CancelButtonStyle & style)2009 void SearchPattern::SetCancelButtonStyle(const CancelButtonStyle& style)
2010 {
2011     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(TEXTFIELD_INDEX));
2012     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
2013     UpdateChangeEvent(textFieldPattern->GetTextValue(), static_cast<int16_t>(style));
2014 }
2015 
SetCancelImageIcon(IconOptions & iconOptions)2016 void SearchPattern::SetCancelImageIcon(IconOptions& iconOptions)
2017 {
2018     CHECK_NULL_VOID(GetSearchNode());
2019     auto &imageIconOptions = GetSearchNode()->GetCancelImageIconOptions();
2020     if (iconOptions.GetColor().has_value()) {
2021         imageIconOptions.UpdateColor(iconOptions.GetColor().value());
2022     }
2023     if (iconOptions.GetSize().has_value()) {
2024         imageIconOptions.UpdateSize(ConvertImageIconSizeValue(iconOptions.GetSize().value()));
2025     }
2026     if (iconOptions.GetSrc().has_value()) {
2027         imageIconOptions.UpdateSrc(iconOptions.GetSrc().value(),
2028             iconOptions.GetBundleName().value_or(""),
2029             iconOptions.GetModuleName().value_or(""));
2030     }
2031     UpdateImageIconNode(CANCEL_IMAGE_INDEX);
2032 }
2033 
SetCancelSymbolIcon()2034 void SearchPattern::SetCancelSymbolIcon()
2035 {
2036     UpdateSymbolIconNode(CANCEL_IMAGE_INDEX);
2037 }
2038 
UpdateImageIconNode(int32_t index)2039 void SearchPattern::UpdateImageIconNode(int32_t index)
2040 {
2041     bool isCurSymbolNode = IsSymbolIcon(index);
2042     if (isCurSymbolNode) {
2043         CreateOrUpdateImage(index, false);
2044     } else {
2045         auto frameNode = GetHost();
2046         CHECK_NULL_VOID(frameNode);
2047         auto iconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(index));
2048         UpdateImageIconProperties(iconFrameNode, index);
2049         iconFrameNode->MarkModifyDone();
2050         iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2051     }
2052 }
2053 
UpdateSymbolIconNode(int32_t index)2054 void SearchPattern::UpdateSymbolIconNode(int32_t index)
2055 {
2056     bool isCurSymbolNode = IsSymbolIcon(index);
2057     if (!isCurSymbolNode) {
2058         CreateOrUpdateSymbol(index, false, true);
2059     } else {
2060         auto frameNode = GetHost();
2061         CHECK_NULL_VOID(frameNode);
2062         auto iconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(index));
2063         UpdateSymbolIconProperties(iconFrameNode, index);
2064         iconFrameNode->MarkModifyDone();
2065         iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
2066     }
2067 }
2068 
UpdateImageIconProperties(RefPtr<FrameNode> & iconFrameNode,int32_t index)2069 void SearchPattern::UpdateImageIconProperties(RefPtr<FrameNode>& iconFrameNode, int32_t index)
2070 {
2071     CHECK_NULL_VOID(iconFrameNode);
2072     if (iconFrameNode->GetTag() == V2::IMAGE_ETS_TAG) {
2073         auto iconOptions = index == IMAGE_INDEX ? GetSearchNode()->GetSearchImageIconOptions()
2074                                                 : GetSearchNode()->GetCancelImageIconOptions();
2075         auto imageLayoutProperty = iconFrameNode->GetLayoutProperty<ImageLayoutProperty>();
2076         CHECK_NULL_VOID(imageLayoutProperty);
2077         ImageSourceInfo imageSourceInfo("");
2078         auto imageSourceInfoOp = imageLayoutProperty->GetImageSourceInfo();
2079         if (imageSourceInfoOp.has_value()) {
2080             imageSourceInfo = imageSourceInfoOp.value();
2081         }
2082         auto host = GetHost();
2083         CHECK_NULL_VOID(host);
2084         auto pipeline = host->GetContext();
2085         CHECK_NULL_VOID(pipeline);
2086         auto searchTheme = pipeline->GetTheme<SearchTheme>();
2087         CHECK_NULL_VOID(searchTheme);
2088         auto iconTheme = pipeline->GetTheme<IconTheme>();
2089         CHECK_NULL_VOID(iconTheme);
2090         if (iconOptions.GetSrc().value_or("").empty()) {
2091             imageSourceInfo.SetResourceId(index == IMAGE_INDEX ? InternalResource::ResourceId::SEARCH_SVG
2092                                                                : InternalResource::ResourceId::CLOSE_SVG);
2093             auto iconPath = iconTheme->GetIconPath(index == IMAGE_INDEX ? InternalResource::ResourceId::SEARCH_SVG
2094                                                                         : InternalResource::ResourceId::CLOSE_SVG);
2095             imageSourceInfo.SetSrc(iconPath, iconOptions.GetColor().value_or(searchTheme->GetSearchIconColor()));
2096         } else {
2097             imageSourceInfo.SetSrc(iconOptions.GetSrc().value());
2098         }
2099         imageSourceInfo.SetBundleName(iconOptions.GetBundleName().value_or(""));
2100         imageSourceInfo.SetModuleName(iconOptions.GetModuleName().value_or(""));
2101         imageSourceInfo.SetFillColor(iconOptions.GetColor().value_or(searchTheme->GetSearchIconColor()));
2102         imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
2103         CalcSize imageCalcSize(CalcLength(iconOptions.GetSize().value_or(searchTheme->GetIconHeight())),
2104             CalcLength(iconOptions.GetSize().value_or(searchTheme->GetIconHeight())));
2105 
2106         imageLayoutProperty->UpdateUserDefinedIdealSize(imageCalcSize);
2107         auto parentInspector = GetSearchNode()->GetInspectorIdValue("");
2108         iconFrameNode->UpdateInspectorId(INSPECTOR_PREFIX + SPECICALIZED_INSPECTOR_INDEXS[index] + parentInspector);
2109         auto imageRenderProperty = iconFrameNode->GetPaintProperty<ImageRenderProperty>();
2110         CHECK_NULL_VOID(imageRenderProperty);
2111         imageSourceInfo.SetFillColor(iconOptions.GetColor().value_or(searchTheme->GetSearchIconColor()));
2112         imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
2113         imageRenderProperty->UpdateSvgFillColor(iconOptions.GetColor().value_or(searchTheme->GetSearchIconColor()));
2114     }
2115 }
2116 
UpdateSymbolIconProperties(RefPtr<FrameNode> & iconFrameNode,int32_t index)2117 void SearchPattern::UpdateSymbolIconProperties(RefPtr<FrameNode>& iconFrameNode, int32_t index)
2118 {
2119     auto host = GetHost();
2120     CHECK_NULL_VOID(host);
2121     CHECK_NULL_VOID(iconFrameNode);
2122     auto pipeline = host->GetContext();
2123     CHECK_NULL_VOID(pipeline);
2124     auto searchTheme = pipeline->GetTheme<SearchTheme>();
2125     CHECK_NULL_VOID(searchTheme);
2126     auto layoutProperty = host->GetLayoutProperty<SearchLayoutProperty>();
2127     CHECK_NULL_VOID(layoutProperty);
2128     auto symbolLayoutProperty = iconFrameNode->GetLayoutProperty<TextLayoutProperty>();
2129     symbolLayoutProperty->UpdateSymbolSourceInfo(index == IMAGE_INDEX
2130                                                      ? SymbolSourceInfo(searchTheme->GetSearchSymbolId())
2131                                                      : SymbolSourceInfo(searchTheme->GetCancelSymbolId()));
2132     auto defaultSymbolIconSize = (index == IMAGE_INDEX ? GetSearchNode()->GetSearchSymbolIconSize()
2133                                                        : GetSearchNode()->GetCancelSymbolIconSize());
2134     symbolLayoutProperty->UpdateFontSize(defaultSymbolIconSize);
2135     symbolLayoutProperty->UpdateSymbolColorList({ index == IMAGE_INDEX ? GetSearchNode()->GetSearchSymbolIconColor()
2136                                                                        : GetSearchNode()->GetCancelSymbolIconColor() });
2137     auto parentInspector = GetSearchNode()->GetInspectorIdValue("");
2138     iconFrameNode->UpdateInspectorId(INSPECTOR_PREFIX + SPECICALIZED_INSPECTOR_INDEXS[index] + parentInspector);
2139     if (index == IMAGE_INDEX) {
2140         auto iconSymbol = layoutProperty->GetSearchIconSymbol();
2141         if (iconSymbol != nullptr) {
2142             iconSymbol(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconFrameNode)));
2143         }
2144     } else {
2145         auto iconSymbol = layoutProperty->GetCancelIconSymbol();
2146         if (iconSymbol != nullptr) {
2147             iconSymbol(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(iconFrameNode)));
2148         }
2149     }
2150     // reset symbol effect
2151     auto symbolEffectOptions = symbolLayoutProperty->GetSymbolEffectOptionsValue(SymbolEffectOptions());
2152     symbolEffectOptions.SetIsTxtActive(false);
2153     symbolLayoutProperty->UpdateSymbolEffectOptions(symbolEffectOptions);
2154     auto fontSize = symbolLayoutProperty->GetFontSize().value_or(defaultSymbolIconSize);
2155     if (GreatOrEqualCustomPrecision(fontSize.ConvertToPx(), ICON_MAX_SIZE.ConvertToPx())) {
2156         symbolLayoutProperty->UpdateFontSize(ICON_MAX_SIZE);
2157     }
2158 }
2159 
IsSymbolIcon(int32_t index)2160 bool SearchPattern::IsSymbolIcon(int32_t index)
2161 {
2162     auto frameNode = GetHost();
2163     CHECK_NULL_RETURN(frameNode, false);
2164     auto iconFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildAtIndex(index));
2165     CHECK_NULL_RETURN(iconFrameNode, false);
2166     return iconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG;
2167 }
2168 
UpdateIconChangeEvent()2169 void SearchPattern::UpdateIconChangeEvent()
2170 {
2171     CHECK_NULL_VOID(GetSearchNode());
2172     auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(GetSearchNode()->GetChildAtIndex(TEXTFIELD_INDEX));
2173     auto textFieldPattern = textFieldFrameNode->GetPattern<TextFieldPattern>();
2174     UpdateChangeEvent(textFieldPattern->GetTextValue());
2175 }
2176 
ConvertImageIconSizeValue(const Dimension & iconSizeValue)2177 const Dimension SearchPattern::ConvertImageIconSizeValue(const Dimension& iconSizeValue)
2178 {
2179     if (GreatOrEqualCustomPrecision(iconSizeValue.ConvertToPx(), ICON_MAX_SIZE.ConvertToPx())) {
2180         return ICON_MAX_SIZE;
2181     }
2182     return ConvertImageIconScaleLimit(iconSizeValue);
2183 }
2184 
ConvertImageIconScaleLimit(const Dimension & iconSizeValue)2185 const Dimension SearchPattern::ConvertImageIconScaleLimit(const Dimension& iconSizeValue)
2186 {
2187     auto host = GetHost();
2188     CHECK_NULL_RETURN(host, iconSizeValue);
2189     auto pipeline = host->GetContext();
2190     CHECK_NULL_RETURN(pipeline, iconSizeValue);
2191 
2192     float fontScale = pipeline->GetFontScale();
2193     if (fontScale == 0) {
2194         return iconSizeValue;
2195     }
2196 
2197     if (iconSizeValue.Unit() != DimensionUnit::VP) {
2198         float maxFontScale = std::min(pipeline->GetMaxAppFontScale(), MAX_FONT_SCALE);
2199         fontScale = std::clamp(fontScale, 0.0f, maxFontScale);
2200         return iconSizeValue * fontScale;
2201     }
2202     return iconSizeValue;
2203 }
2204 
2205 } // namespace OHOS::Ace::NG
2206