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