1 /*
2  * Copyright (c) 2021-2022 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/search/render_search.h"
17 
18 namespace OHOS::Ace {
19 namespace {
20 
21 constexpr Dimension SEARCH_SPACING = 2.0_vp;
22 constexpr Dimension DIVIDER_WIDTH = 1.0_px;
23 constexpr Dimension TEXT_PADDING = 14.0_vp;
24 constexpr Dimension SEARCH_TEXT_HEIGHT = 36.0_vp;
25 constexpr Dimension SEARCH_BUTTON_TEXT_FONT_SIZE = 14.0_fp;
26 const Color SEARCH_BUTTON_TEXT_COLOR = Color(0xFF254FF7);
27 
28 } // namespace
29 
Update(const RefPtr<Component> & component)30 void RenderSearch::Update(const RefPtr<Component>& component)
31 {
32     searchComponent_ = AceType::DynamicCast<SearchComponent>(component);
33     if (!searchComponent_) {
34         LOGW("component is null");
35         return;
36     }
37     needReverse_ = (searchComponent_->GetTextDirection() == TextDirection::RTL);
38     closeIconSize_ = searchComponent_->GetCloseIconSize();
39     placeHoldStyle_ = searchComponent_->GetPlaceHoldStyle();
40     editingStyle_ = searchComponent_->GetEditingStyle();
41     closeIconHotZoneHorizontal_ = searchComponent_->GetCloseIconHotZoneHorizontal();
42 
43     decoration_ = searchComponent_->GetDecoration();
44     if (searchComponent_->GetTextEditController() && textEditController_ != searchComponent_->GetTextEditController()) {
45         if (textEditController_) {
46             textEditController_->RemoveObserver(WeakClaim(this));
47         }
48         textEditController_ = searchComponent_->GetTextEditController();
49         textEditController_->AddObserver(WeakClaim(this));
50     }
51 
52     hoverColor_ = searchComponent_->GetHoverColor();
53     pressColor_ = searchComponent_->GetPressColor();
54     CreateRenderImage(searchComponent_);
55     CreateRenderButton(searchComponent_);
56 
57     auto context = context_.Upgrade();
58     if (context && context->GetIsDeclarative()) {
59         if (searchComponent_->GetOnChange()) {
60             changeEvent_ = *searchComponent_->GetOnChange();
61         } else {
62             changeEvent_ = nullptr;
63         }
64 
65         if (searchComponent_->GetOnSubmit()) {
66             submitEvent_ = *searchComponent_->GetOnSubmit();
67         } else {
68             submitEvent_ = nullptr;
69         }
70     } else {
71         changeEvent_ = AceAsyncEvent<void(const std::string)>::Create(searchComponent_->GetChangeEventId(), context_);
72         submitEvent_ = AceAsyncEvent<void(const std::string)>::Create(searchComponent_->GetSubmitEventId(), context_);
73     }
74 
75     MarkNeedLayout();
76 }
77 
FireSubmitEvent(const std::string & searchKey)78 void RenderSearch::FireSubmitEvent(const std::string& searchKey)
79 {
80     if (submitEvent_) {
81         auto context = context_.Upgrade();
82         if (context && context->GetIsDeclarative()) {
83             submitEvent_(searchKey);
84         } else {
85             auto submitResult = JsonUtil::Create(true);
86             submitResult->Put("text", searchKey.c_str());
87             submitEvent_(std::string(R"("submit",)").append(submitResult->ToString()));
88         }
89     }
90 }
91 
PerformLayout()92 void RenderSearch::PerformLayout()
93 {
94     const auto& renderTextField = AceType::DynamicCast<RenderTextField>(GetChildren().front());
95     if (!renderTextField) {
96         return;
97     }
98     renderTextField->Layout(GetLayoutParam());
99     SetLayoutSize(renderTextField->GetLayoutSize());
100     renderTextField->SetSubmitEvent([weak = WeakClaim(this)](const std::string& searchKey) {
101         auto renderSearch = weak.Upgrade();
102         if (renderSearch) {
103             renderSearch->FireSubmitEvent(searchKey);
104         }
105     });
106 
107     auto context = context_.Upgrade();
108     if (context && context->GetIsDeclarative()) {
109         renderTextField->SetOnValueChangeEvent(changeEvent_);
110     } else {
111         renderTextField->SetOnTextChangeEvent(changeEvent_);
112     }
113 
114     Size deflateSize = Size(NormalizeToPx(SEARCH_SPACING), NormalizeToPx(SEARCH_SPACING)) * 2.0;
115     if (context && decoration_) {
116         deflateSize += decoration_->GetBorder().GetLayoutSize(context->GetDipScale());
117     }
118     LayoutParam layoutParam = LayoutParam(GetLayoutSize() - deflateSize, Size());
119     if (renderCloseIcon_) {
120         renderCloseIcon_->Layout(layoutParam);
121     }
122     if (renderSearchBox_) {
123         renderSearchBox_->Layout(layoutParam);
124     }
125 
126     InitRect(renderTextField);
127 }
128 
InitRect(const RefPtr<RenderTextField> & renderTextField)129 void RenderSearch::InitRect(const RefPtr<RenderTextField>& renderTextField)
130 {
131     auto pipelineContext = context_.Upgrade();
132     if (!pipelineContext) {
133         return;
134     }
135     Border border;
136     if (decoration_) {
137         border = decoration_->GetBorder();
138     }
139     double leftBorderWidth = NormalizeToPx(border.Left().GetWidth());
140     double topBorderWidth = NormalizeToPx(border.Top().GetWidth());
141     double rightBorderWidth = NormalizeToPx(border.Right().GetWidth());
142     double bottomBorderWidth = NormalizeToPx(border.Bottom().GetWidth());
143 
144     double searchHeight = GetLayoutSize().Height();
145     double searchInnerHeight = searchHeight - topBorderWidth - bottomBorderWidth;
146 
147     // Compute rect of search text.
148     double searchBoxSpacing = NormalizeToPx(SEARCH_SPACING) * 2.0 + NormalizeToPx(DIVIDER_WIDTH);
149     if (renderSearchBox_) {
150         double searchBoxVerticalOffset =
151             topBorderWidth + (searchInnerHeight - renderSearchBox_->GetLayoutSize().Height()) / 2.0;
152         double searchBoxWidth = renderSearchBox_->GetLayoutSize().Width();
153         Offset searchTextOffset = Offset(
154             GetLayoutSize().Width() - rightBorderWidth - searchBoxWidth - searchBoxSpacing, searchBoxVerticalOffset);
155         Offset searchReactOffset =
156             Offset(GetLayoutSize().Width() - rightBorderWidth - searchBoxWidth - searchBoxSpacing, topBorderWidth);
157         if (needReverse_) {
158             searchTextOffset = Offset(leftBorderWidth, searchBoxVerticalOffset);
159             searchReactOffset = Offset(leftBorderWidth, topBorderWidth);
160         }
161         Size searchBoxSize(renderSearchBox_->GetLayoutSize().Width() + searchBoxSpacing, GetLayoutSize().Height());
162         searchReactRect_ = Rect(searchReactOffset, searchBoxSize);
163         searchTextRect_ = Rect(searchTextOffset, renderSearchBox_->GetLayoutSize() + Size(searchBoxSpacing, 0.0));
164     } else {
165         searchTextRect_ = Rect();
166         searchReactRect_ = Rect();
167     }
168 
169     auto context = context_.Upgrade();
170     if (context && context->GetIsDeclarative()) {
171         double padding = searchTextRect_.Width() + rightBorderWidth + NormalizeToPx(closeIconHotZoneHorizontal_) -
172                          (NormalizeToPx(closeIconSize_) / 2.0);
173         renderTextField->SetPaddingHorizonForSearch(padding);
174     } else {
175         renderTextField->SetPaddingHorizonForSearch(searchTextRect_.Width());
176     }
177 
178     renderTextField->MarkNeedLayout();
179 
180     // Compute rect of close icon.
181     if (renderCloseIcon_) {
182         double iconVerticalOffset =
183             topBorderWidth + (searchInnerHeight - renderCloseIcon_->GetLayoutSize().Height()) / 2.0;
184         double iconHotzonOffset = (NormalizeToPx(closeIconHotZoneHorizontal_) - NormalizeToPx(closeIconSize_)) / 2.0;
185         Offset closeIconOffset = Offset(GetLayoutSize().Width() - rightBorderWidth - searchTextRect_.Width() -
186                                             renderCloseIcon_->GetLayoutSize().Width() - iconHotzonOffset,
187             iconVerticalOffset);
188         if (needReverse_) {
189             closeIconOffset = Offset(leftBorderWidth + searchTextRect_.Width() + iconHotzonOffset, iconVerticalOffset);
190         }
191         closeIconRect_ = Rect(closeIconOffset, renderCloseIcon_->GetLayoutSize());
192 
193         // Compute rect of hot zone of close icon.
194         double searchSpacing = NormalizeToPx(SEARCH_SPACING);
195         double horizonSpacing = iconHotzonOffset - searchSpacing;
196         double verticalSpacing =
197             std::min(iconHotzonOffset, (searchInnerHeight - renderCloseIcon_->GetLayoutSize().Height()) / 2.0) -
198             searchSpacing;
199         closeIconHotZoneRect_ =
200             closeIconRect_ - Offset(horizonSpacing, verticalSpacing) + Size(horizonSpacing, verticalSpacing) * 2.0;
201     } else {
202         closeIconRect_ = Rect();
203         closeIconHotZoneRect_ = Rect();
204     }
205 }
206 
OnValueChanged(bool needFireChangeEvent,bool needFireSelectChangeEvent)207 void RenderSearch::OnValueChanged(bool needFireChangeEvent, bool needFireSelectChangeEvent)
208 {
209     if (textEditController_) {
210         const auto& currentText = textEditController_->GetValue().text;
211         showCloseIcon_ = !currentText.empty();
212         auto context = context_.Upgrade();
213         if (context && context->GetIsDeclarative()) {
214             auto renderTextField = AceType::DynamicCast<RenderTextField>(GetChildren().front());
215             if (showCloseIcon_) {
216                 renderTextField->SetTextStyle(editingStyle_);
217             } else {
218                 renderTextField->SetTextStyle(placeHoldStyle_);
219             }
220         }
221     }
222 }
223 
CreateRenderImage(const RefPtr<SearchComponent> & searchComponent)224 void RenderSearch::CreateRenderImage(const RefPtr<SearchComponent>& searchComponent)
225 {
226     if (!searchComponent) {
227         return;
228     }
229     if (!renderCloseIcon_ && (SystemProperties::GetDeviceType() != DeviceType::TV)) {
230         const auto& closeIconSrc = searchComponent->GetCloseIconSrc();
231         RefPtr<ImageComponent> imageComponent;
232         if (closeIconSrc.empty()) {
233             imageComponent = AceType::MakeRefPtr<ImageComponent>(InternalResource::ResourceId::CLOSE_SVG);
234         } else {
235             imageComponent = AceType::MakeRefPtr<ImageComponent>(closeIconSrc);
236         }
237         imageComponent->SetWidth(searchComponent->GetCloseIconSize());
238         imageComponent->SetHeight(searchComponent->GetCloseIconSize());
239 
240         renderCloseIcon_ = AceType::DynamicCast<RenderImage>(imageComponent->CreateRenderNode());
241         if (!renderCloseIcon_) {
242             return;
243         }
244         renderCloseIcon_->Attach(GetContext());
245         renderCloseIcon_->Update(imageComponent);
246     }
247 }
248 
CreateRenderButton(const RefPtr<SearchComponent> & searchComponent)249 void RenderSearch::CreateRenderButton(const RefPtr<SearchComponent>& searchComponent)
250 {
251     if (!searchComponent) {
252         return;
253     }
254     if (searchComponent->GetSearchText().empty()) {
255         searchText_ = "";
256         renderSearchBox_.Reset();
257         return;
258     }
259     if (searchText_ != searchComponent->GetSearchText()) {
260         searchText_ = searchComponent->GetSearchText();
261         renderSearchBox_.Reset();
262     }
263     if (!renderSearchBox_ && (SystemProperties::GetDeviceType() != DeviceType::TV)) {
264         const auto& searchText = searchComponent->GetSearchText();
265         const auto& textComponent = AceType::MakeRefPtr<TextComponent>(searchText);
266         TextStyle textStyle;
267         textStyle.SetMaxLines(1);
268         textStyle.SetTextColor(SEARCH_BUTTON_TEXT_COLOR);
269         textStyle.SetFontSize(SEARCH_BUTTON_TEXT_FONT_SIZE);
270         textStyle.SetFontWeight(FontWeight::W500);
271         textComponent->SetTextStyle(textStyle);
272         auto renderText = AceType::DynamicCast<RenderText>(textComponent->CreateRenderNode());
273         if (!renderText) {
274             return;
275         }
276         renderText->Attach(GetContext());
277         renderText->Update(textComponent);
278 
279         auto boxComponent = AceType::MakeRefPtr<BoxComponent>();
280         Edge edge = Edge(TEXT_PADDING, 0.0_vp, TEXT_PADDING, 0.0_vp);
281         boxComponent->SetPadding(edge);
282         boxComponent->SetHeight(SEARCH_TEXT_HEIGHT.Value(), SEARCH_TEXT_HEIGHT.Unit());
283         renderSearchBox_ = AceType::DynamicCast<RenderBox>(boxComponent->CreateRenderNode());
284         if (!renderSearchBox_) {
285             return;
286         }
287         renderSearchBox_->Attach(GetContext());
288         renderSearchBox_->Update(boxComponent);
289         renderSearchBox_->AddChild(renderText);
290         renderSearchBox_->SyncRSNode(nullptr);
291         renderText->SyncRSNode(nullptr);
292     }
293 }
294 
HandleEnterEvent()295 bool RenderSearch::HandleEnterEvent()
296 {
297     auto renderTextField = AceType::DynamicCast<RenderTextField>(GetChildren().front());
298     if (!renderTextField || !textEditController_) {
299         return false;
300     }
301 
302     if (focusRender_ == SearchNodeType::IMAGE) {
303         renderTextField->SetNeedNotifyChangeEvent(true);
304         textEditController_->Clear();
305         focusRender_ = SearchNodeType::NONE;
306         MarkNeedRender();
307         return true;
308     }
309     if (focusRender_ == SearchNodeType::BUTTON) {
310         std::string searchKey = textEditController_->GetText();
311         FireSubmitEvent(searchKey);
312         focusRender_ = SearchNodeType::NONE;
313         MarkNeedRender();
314         return true;
315     }
316     return false;
317 }
318 
HandleFocusEvent(bool vertical,bool reverse)319 bool RenderSearch::HandleFocusEvent(bool vertical, bool reverse)
320 {
321     if (vertical) {
322         focusRender_ = SearchNodeType::NONE;
323         return false;
324     }
325     if (!(showCloseIcon_ && renderCloseIcon_) && !renderSearchBox_) {
326         focusRender_ = SearchNodeType::NONE;
327         return false;
328     }
329 
330     auto renderTextField = AceType::DynamicCast<RenderTextField>(GetChildren().front());
331     if (!renderTextField) {
332         focusRender_ = SearchNodeType::NONE;
333         return false;
334     }
335     bool result = false;
336     if ((showCloseIcon_ && renderCloseIcon_) && renderSearchBox_) {
337         if (focusRender_ == SearchNodeType::NONE) {
338             if (!reverse) {
339                 focusRender_ = SearchNodeType::IMAGE;
340                 result = true;
341             }
342         } else if (focusRender_ == SearchNodeType::IMAGE) {
343             if (!reverse) {
344                 focusRender_ = SearchNodeType::BUTTON;
345                 result = true;
346             } else {
347                 focusRender_ = SearchNodeType::NONE;
348                 renderTextField->UpdateFocusAnimation();
349                 result = true;
350             }
351         } else if (focusRender_ == SearchNodeType::BUTTON) {
352             if (reverse) {
353                 focusRender_ = SearchNodeType::IMAGE;
354                 result = true;
355             }
356         }
357     } else {
358         if (focusRender_ == SearchNodeType::NONE) {
359             if (!reverse) {
360                 focusRender_ = renderSearchBox_ ? SearchNodeType::BUTTON : SearchNodeType::IMAGE;
361                 result = true;
362             }
363         } else {
364             if (reverse) {
365                 focusRender_ = SearchNodeType::NONE;
366                 renderTextField->UpdateFocusAnimation();
367                 result = true;
368             }
369         }
370     }
371     if (result) {
372         MarkNeedRender();
373     }
374     return result;
375 }
376 
TouchTest(const Point & globalPoint,const Point & parentLocalPoint,const TouchRestrict & touchRestrict,TouchTestResult & result)377 bool RenderSearch::TouchTest(const Point& globalPoint, const Point& parentLocalPoint,
378     const TouchRestrict& touchRestrict, TouchTestResult& result)
379 {
380     auto pointWithoutMargin = parentLocalPoint - GetPosition();
381     if (GetDisableTouchEvent() || disabled_) {
382         return false;
383     }
384     if (showCloseIcon_ && closeIconHotZoneRect_.IsInRegion(pointWithoutMargin)) {
385         hoverOrPressRender_ = SearchNodeType::IMAGE;
386     } else if (searchReactRect_.IsInRegion(pointWithoutMargin)) {
387         hoverOrPressRender_ = SearchNodeType::BUTTON;
388     } else {
389         hoverOrPressRender_ = SearchNodeType::NONE;
390     }
391     // Since the paintRect is relative to parent, use parent local point to perform touch test.
392     if (closeIconHotZoneRect_.IsInRegion(pointWithoutMargin) || searchReactRect_.IsInRegion(pointWithoutMargin)) {
393         // Calculates the coordinate offset in this node.
394         const auto localPoint = pointWithoutMargin - GetPaintRect().GetOffset();
395         const auto coordinateOffset = globalPoint - localPoint;
396         globalPoint_ = globalPoint;
397         OnTouchTestHit(coordinateOffset, touchRestrict, result);
398         return true;
399     }
400     if (GetPaintRect().IsInRegion(parentLocalPoint)) {
401         // Calculates the local point location in this node.
402         const auto localPoint = parentLocalPoint - GetPaintRect().GetOffset();
403         bool dispatchSuccess = false;
404         for (auto iter = GetChildren().rbegin(); iter != GetChildren().rend(); ++iter) {
405             auto& child = *iter;
406             if (child->TouchTest(globalPoint, localPoint, touchRestrict, result)) {
407                 dispatchSuccess = true;
408                 break;
409             }
410             if (child->InterceptTouchEvent()) {
411                 break;
412             }
413         }
414         return dispatchSuccess;
415     }
416     return false;
417 }
418 
OnTouchTestHit(const Offset & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & result)419 void RenderSearch::OnTouchTestHit(
420     const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result)
421 {
422     if (!rawRecognizer_) {
423         rawRecognizer_ = AceType::MakeRefPtr<RawRecognizer>();
424         auto weak = WeakClaim(this);
425         rawRecognizer_->SetOnTouchDown([weak = WeakClaim(this)](const TouchEventInfo& info) {
426             auto search = weak.Upgrade();
427             if (search) {
428                 search->overlayColor_ = search->pressColor_;
429                 search->MarkNeedRender();
430             }
431         });
432 
433         rawRecognizer_->SetOnTouchUp([weak = WeakClaim(this)](const TouchEventInfo& info) {
434             auto search = weak.Upgrade();
435             if (search) {
436                 search->overlayColor_ = Color::TRANSPARENT;
437                 search->MarkNeedRender();
438             }
439         });
440 
441         rawRecognizer_->SetOnTouchCancel([weak = WeakClaim(this)](const TouchEventInfo& info) {
442             auto search = weak.Upgrade();
443             if (search) {
444                 search->overlayColor_ = Color::TRANSPARENT;
445                 search->MarkNeedRender();
446             }
447         });
448     }
449     rawRecognizer_->SetTouchRestrict(touchRestrict);
450     rawRecognizer_->SetCoordinateOffset(coordinateOffset);
451     result.emplace_back(rawRecognizer_);
452 
453     if (!clickRecognizer_) {
454         clickRecognizer_ = AceType::MakeRefPtr<ClickRecognizer>();
455         clickRecognizer_->SetOnClick([weak = WeakClaim(this)](const ClickInfo& info) {
456             auto search = weak.Upgrade();
457             if (search) {
458                 search->HandleClick();
459             }
460         });
461     }
462     clickRecognizer_->SetTouchRestrict(touchRestrict);
463     clickRecognizer_->SetCoordinateOffset(coordinateOffset);
464     result.emplace_back(clickRecognizer_);
465 }
466 
HandleClick()467 void RenderSearch::HandleClick()
468 {
469     auto renderTextField = AceType::DynamicCast<RenderTextField>(GetChildren().front());
470     if (!renderTextField || !textEditController_) {
471         return;
472     }
473     std::string accessibilityEventType = "click";
474     SendAccessibilityEvent(accessibilityEventType);
475     if (hoverOrPressRender_ == SearchNodeType::IMAGE) {
476         renderTextField->SetNeedNotifyChangeEvent(true);
477         textEditController_->Clear();
478         auto onValueChange = renderTextField->GetOnValueChange();
479         if (onValueChange) {
480             onValueChange();
481         }
482     } else if (hoverOrPressRender_ == SearchNodeType::BUTTON) {
483         std::string searchKey = textEditController_->GetText();
484         renderTextField->CloseKeyboard(true);
485         FireSubmitEvent(searchKey);
486     }
487 }
488 
MouseHoverTest(const Point & parentLocalPoint)489 bool RenderSearch::MouseHoverTest(const Point& parentLocalPoint)
490 {
491     auto context = context_.Upgrade();
492     if (!context) {
493         hoverOrPressRender_ = SearchNodeType::NONE;
494         return false;
495     }
496     if (!InTouchRectList(parentLocalPoint, GetTouchRectList())) {
497         if (mouseState_ == MouseState::HOVER) {
498             mouseState_ = MouseState::NONE;
499             hoverOrPressRender_ = SearchNodeType::NONE;
500         }
501         CancelTextFieldHover();
502         return false;
503     }
504     context->AddToHoverList(AceType::WeakClaim(this).Upgrade());
505 
506     if (showCloseIcon_ && closeIconHotZoneRect_.IsInRegion(parentLocalPoint)) {
507         if (mouseState_ == MouseState::NONE || hoverOrPressRender_ == SearchNodeType::BUTTON) {
508             mouseState_ = MouseState::HOVER;
509             hoverOrPressRender_ = SearchNodeType::IMAGE;
510             CancelTextFieldHover();
511             return true;
512         }
513     }
514 
515     if (searchTextRect_.IsInRegion(parentLocalPoint)) {
516         if (mouseState_ == MouseState::NONE || hoverOrPressRender_ == SearchNodeType::IMAGE) {
517             mouseState_ = MouseState::HOVER;
518             hoverOrPressRender_ = SearchNodeType::BUTTON;
519             CancelTextFieldHover();
520             return true;
521         }
522     }
523 
524     bool hoverInSearch = !searchTextRect_.IsInRegion(parentLocalPoint);
525     if (showCloseIcon_ && hoverInSearch) {
526         hoverInSearch = !closeIconHotZoneRect_.IsInRegion(parentLocalPoint);
527     }
528     if (hoverInSearch) {
529         hoverOrPressRender_ = SearchNodeType::NONE;
530         mouseState_ = MouseState::NONE;
531 
532         // Change textfield to hover.
533         auto renderTextField = AceType::DynamicCast<RenderTextField>(GetChildren().front());
534         if (renderTextField) {
535             renderTextField->SetOverlayColor(hoverColor_);
536             renderTextField->MarkNeedRender();
537         }
538     }
539     return true;
540 }
541 
CancelTextFieldHover()542 void RenderSearch::CancelTextFieldHover()
543 {
544     auto renderTextField = AceType::DynamicCast<RenderTextField>(GetChildren().front());
545     if (renderTextField) {
546         renderTextField->SetOverlayColor(Color::TRANSPARENT);
547         renderTextField->MarkNeedRender();
548     }
549 }
550 
HandleMouseEvent(const MouseEvent & event)551 bool RenderSearch::HandleMouseEvent(const MouseEvent& event)
552 {
553     MouseInfo info;
554     info.SetButton(event.button);
555     info.SetAction(event.action);
556     info.SetGlobalLocation(event.GetOffset());
557     info.SetLocalLocation(event.GetOffset() - Offset(GetCoordinatePoint().GetX(), GetCoordinatePoint().GetY()));
558     info.SetScreenLocation(event.GetScreenOffset());
559     info.SetTimeStamp(event.time);
560     auto lowBound = searchReactRect_.GetOffset().GetX();
561     auto upBound = searchReactRect_.GetOffset().GetX() + searchReactRect_.GetSize().Width();
562     RefPtr mouseStyle = MouseStyle::CreateMouseStyle();
563     auto context = GetContext().Upgrade();
564     auto windowId = context->GetWindowId();
565     int32_t curPointerStyle = 0;
566 
567     if (info.GetLocalLocation().GetX() >= lowBound && info.GetLocalLocation().GetX() <= upBound) {
568         isInSearchButton_ = true;
569     } else {
570         isInSearchButton_ = false;
571     }
572     if (preIsInSearchButton_ != isInSearchButton_) {
573         preIsInSearchButton_ = isInSearchButton_;
574         if (isInSearchButton_) {
575             MouseFormat defaultStyle = MouseFormat::DEFAULT;
576             mouseStyle->SetPointerStyle(windowId, defaultStyle);
577         } else {
578             MouseFormat textCursorStyle = MouseFormat::TEXT_CURSOR;
579             mouseStyle->SetPointerStyle(windowId, textCursorStyle);
580         }
581     }
582     MouseFormat hopenPointStyle = isInSearchButton_ ? MouseFormat::DEFAULT : MouseFormat::TEXT_CURSOR;
583     if (mouseStyle->GetPointerStyle(windowId, curPointerStyle) != -1 && (int32_t)hopenPointStyle != curPointerStyle) {
584         mouseStyle->SetPointerStyle(windowId, hopenPointStyle);
585         isInSearchButton_ = hopenPointStyle == MouseFormat::DEFAULT ? true : false;
586     }
587     return true;
588 }
589 
HandleMouseHoverEvent(MouseState mouseState)590 void RenderSearch::HandleMouseHoverEvent(MouseState mouseState) {}
591 
592 } // namespace OHOS::Ace
593