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