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