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