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