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