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