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