• 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/common/event_manager.h"
17 
18 #include "base/geometry/ng/point_t.h"
19 #include "base/log/ace_trace.h"
20 #include "base/memory/ace_type.h"
21 #include "base/utils/utils.h"
22 #include "core/common/container.h"
23 #include "core/components_ng/base/frame_node.h"
24 #include "core/event/ace_events.h"
25 #include "core/event/key_event.h"
26 #include "core/event/touch_event.h"
27 #include "core/gestures/gesture_referee.h"
28 #include "core/pipeline/base/element.h"
29 #include "core/pipeline/base/render_node.h"
30 
31 namespace OHOS::Ace {
32 
TouchTest(const TouchEvent & touchPoint,const RefPtr<RenderNode> & renderNode,const TouchRestrict & touchRestrict,const Offset & offset,float viewScale,bool needAppend)33 void EventManager::TouchTest(const TouchEvent& touchPoint, const RefPtr<RenderNode>& renderNode,
34     const TouchRestrict& touchRestrict, const Offset& offset, float viewScale, bool needAppend)
35 {
36     ContainerScope scope(instanceId_);
37 
38     ACE_FUNCTION_TRACE();
39     CHECK_NULL_VOID(renderNode);
40     // first clean.
41     referee_->CleanGestureScope(touchPoint.id);
42     // collect
43     TouchTestResult hitTestResult;
44     const Point point { touchPoint.x, touchPoint.y, touchPoint.sourceType };
45     // For root node, the parent local point is the same as global point.
46     renderNode->TouchTest(point, point, touchRestrict, hitTestResult);
47     if (needAppend) {
48 #ifdef OHOS_STANDARD_SYSTEM
49         for (auto entry = hitTestResult.begin(); entry != hitTestResult.end(); ++entry) {
50             if ((*entry)) {
51                 (*entry)->SetSubPipelineGlobalOffset(offset, viewScale);
52             }
53         }
54 #endif
55         TouchTestResult prevHitTestResult = touchTestResults_[touchPoint.id];
56         hitTestResult.splice(hitTestResult.end(), prevHitTestResult);
57     }
58     touchTestResults_[touchPoint.id] = std::move(hitTestResult);
59 }
60 
TouchTest(const TouchEvent & touchPoint,const RefPtr<NG::FrameNode> & frameNode,const TouchRestrict & touchRestrict,const Offset & offset,float viewScale,bool needAppend)61 void EventManager::TouchTest(const TouchEvent& touchPoint, const RefPtr<NG::FrameNode>& frameNode,
62     const TouchRestrict& touchRestrict, const Offset& offset, float viewScale, bool needAppend)
63 {
64     ContainerScope scope(instanceId_);
65 
66     ACE_FUNCTION_TRACE();
67     CHECK_NULL_VOID(frameNode);
68     // collect
69     TouchTestResult hitTestResult;
70     const NG::PointF point { touchPoint.x, touchPoint.y };
71     if (refereeNG_->QueryAllDone(touchPoint.id)) {
72         refereeNG_->CleanGestureScope(touchPoint.id);
73     }
74     // For root node, the parent local point is the same as global point.
75     frameNode->TouchTest(point, point, touchRestrict, hitTestResult, touchPoint.id);
76     if (needAppend) {
77 #ifdef OHOS_STANDARD_SYSTEM
78         for (const auto& entry : hitTestResult) {
79             if (entry) {
80                 entry->SetSubPipelineGlobalOffset(offset, viewScale);
81             }
82         }
83 #endif
84         TouchTestResult prevHitTestResult = touchTestResults_[touchPoint.id];
85         hitTestResult.splice(hitTestResult.end(), prevHitTestResult);
86     }
87     touchTestResults_[touchPoint.id] = std::move(hitTestResult);
88 }
89 
TouchTest(const AxisEvent & event,const RefPtr<NG::FrameNode> & frameNode,const TouchRestrict & touchRestrict)90 void EventManager::TouchTest(
91     const AxisEvent& event, const RefPtr<NG::FrameNode>& frameNode, const TouchRestrict& touchRestrict)
92 {
93     ContainerScope scope(instanceId_);
94 
95     ACE_FUNCTION_TRACE();
96     CHECK_NULL_VOID(frameNode);
97     // collect
98     const NG::PointF point { event.x, event.y };
99     // For root node, the parent local point is the same as global point.
100     frameNode->TouchTest(point, point, touchRestrict, axisTouchTestResult_, event.id);
101 }
102 
HandleGlobalEvent(const TouchEvent & touchPoint,const RefPtr<TextOverlayManager> & textOverlayManager)103 void EventManager::HandleGlobalEvent(const TouchEvent& touchPoint, const RefPtr<TextOverlayManager>& textOverlayManager)
104 {
105     if (touchPoint.type != TouchType::DOWN) {
106         return;
107     }
108     auto coordinateOffset = textOverlayManager->GetCoordinateOffset();
109     const Point point { touchPoint.x - coordinateOffset.GetX(), touchPoint.y - coordinateOffset.GetY(),
110         touchPoint.sourceType };
111     CHECK_NULL_VOID_NOLOG(textOverlayManager);
112     auto textOverlayBase = textOverlayManager->GetTextOverlayBase();
113     CHECK_NULL_VOID_NOLOG(textOverlayBase);
114     auto targetNode = textOverlayManager->GetTargetNode();
115     CHECK_NULL_VOID_NOLOG(targetNode);
116     for (auto& rect : textOverlayManager->GetTextOverlayRect()) {
117         if (rect.IsInRegion(point)) {
118             inSelectedRect_ = true;
119         }
120     }
121     for (auto& rect : textOverlayBase->GetSelectedRect()) {
122         if (rect.IsInRegion(point)) {
123             inSelectedRect_ = true;
124         }
125     }
126     if (!inSelectedRect_) {
127         textOverlayManager->PopTextOverlay();
128         textOverlayBase->ChangeSelection(0, 0);
129         textOverlayBase->MarkIsOverlayShowed(false);
130         targetNode->MarkNeedRender();
131     }
132     inSelectedRect_ = false;
133 }
134 
HandleOutOfRectCallback(const Point & point,std::vector<RectCallback> & rectCallbackList)135 void EventManager::HandleOutOfRectCallback(const Point& point, std::vector<RectCallback>& rectCallbackList)
136 {
137     for (auto iter = rectCallbackList.begin(); iter != rectCallbackList.end();) {
138         auto rectCallback = *iter;
139         auto rectGetCallback = rectCallback.rectGetCallback;
140         if (!rectGetCallback) {
141             ++iter;
142             continue;
143         }
144         std::vector<Rect> rectList;
145         rectGetCallback(rectList);
146         if (std::any_of(
147                 rectList.begin(), rectList.end(), [point](const Rect& rect) { return rect.IsInRegion(point); })) {
148             ++iter;
149             continue;
150         }
151         for (const auto& rect : rectList) {
152             LOGI("Point(%{public}f, %{public}f) out of Rect-[%{public}f, %{public}f, %{public}f, %{public}f]",
153                 point.GetX(), point.GetY(), rect.Left(), rect.Right(), rect.Top(), rect.Bottom());
154         }
155         if (point.GetSourceType() == SourceType::TOUCH) {
156             if (!rectCallback.touchCallback) {
157                 ++iter;
158                 continue;
159             }
160             rectCallback.touchCallback();
161         } else if (point.GetSourceType() == SourceType::MOUSE) {
162             if (!rectCallback.mouseCallback) {
163                 ++iter;
164                 continue;
165             }
166             rectCallback.mouseCallback();
167         }
168         iter = rectCallbackList.erase(iter);
169     }
170 }
171 
TouchTest(const AxisEvent & event,const RefPtr<RenderNode> & renderNode,const TouchRestrict & touchRestrict)172 void EventManager::TouchTest(
173     const AxisEvent& event, const RefPtr<RenderNode>& renderNode, const TouchRestrict& touchRestrict)
174 {
175     ContainerScope scope(instanceId_);
176 
177     ACE_FUNCTION_TRACE();
178     CHECK_NULL_VOID(renderNode);
179     // collect
180     const Point point { event.x, event.y, event.sourceType };
181     // For root node, the parent local point is the same as global point.
182     renderNode->TouchTest(point, point, touchRestrict, axisTouchTestResult_);
183 }
184 
FlushTouchEventsBegin(const std::list<TouchEvent> & touchEvents)185 void EventManager::FlushTouchEventsBegin(const std::list<TouchEvent>& touchEvents)
186 {
187     for (auto iter = touchEvents.begin(); iter != touchEvents.end(); ++iter) {
188         const auto result = touchTestResults_.find((*iter).id);
189         if (result != touchTestResults_.end()) {
190             for (auto entry = result->second.rbegin(); entry != result->second.rend(); ++entry) {
191                 (*entry)->OnFlushTouchEventsBegin();
192             }
193         }
194     }
195 }
196 
FlushTouchEventsEnd(const std::list<TouchEvent> & touchEvents)197 void EventManager::FlushTouchEventsEnd(const std::list<TouchEvent>& touchEvents)
198 {
199     for (auto iter = touchEvents.begin(); iter != touchEvents.end(); ++iter) {
200         const auto result = touchTestResults_.find((*iter).id);
201         if (result != touchTestResults_.end()) {
202             for (auto entry = result->second.rbegin(); entry != result->second.rend(); ++entry) {
203                 (*entry)->OnFlushTouchEventsEnd();
204             }
205         }
206     }
207 }
208 
DispatchTouchEvent(const TouchEvent & point)209 bool EventManager::DispatchTouchEvent(const TouchEvent& point)
210 {
211     ContainerScope scope(instanceId_);
212 
213     ACE_FUNCTION_TRACE();
214     const auto iter = touchTestResults_.find(point.id);
215     if (iter == touchTestResults_.end()) {
216         LOGI("the %{public}d touch test result does not exist!", point.id);
217         return false;
218     }
219 
220     if (point.type == TouchType::DOWN) {
221         // first collect gesture into gesture referee.
222         if (Container::IsCurrentUseNewPipeline()) {
223             refereeNG_->AddGestureToScope(point.id, iter->second);
224         }
225     }
226 
227     bool dispatchSuccess = true;
228     for (auto entry = iter->second.rbegin(); entry != iter->second.rend(); ++entry) {
229         if (!(*entry)->DispatchMultiContainerEvent(point)) {
230             dispatchSuccess = false;
231             break;
232         }
233     }
234     // If one gesture recognizer has already been won, other gesture recognizers will still be affected by
235     // the event, each recognizer needs to filter the extra events by itself.
236     if (dispatchSuccess) {
237         if (Container::IsCurrentUseNewPipeline()) {
238             // Need update here: onTouch/Recognizer need update
239             bool isStopTouchEvent = false;
240             for (const auto& entry : iter->second) {
241                 auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(entry);
242                 if (recognizer) {
243                     entry->HandleMultiContainerEvent(point);
244                 }
245                 if (!recognizer && !isStopTouchEvent) {
246                     isStopTouchEvent = !entry->HandleMultiContainerEvent(point);
247                 }
248             }
249         } else {
250             for (const auto& entry : iter->second) {
251                 if (!entry->HandleMultiContainerEvent(point)) {
252                     break;
253                 }
254             }
255         }
256     }
257 
258     if (point.type == TouchType::UP || point.type == TouchType::CANCEL) {
259         refereeNG_->CleanGestureScope(point.id);
260         referee_->CleanGestureScope(point.id);
261         touchTestResults_.erase(point.id);
262     }
263 
264     return true;
265 }
266 
DispatchTouchEvent(const AxisEvent & event)267 bool EventManager::DispatchTouchEvent(const AxisEvent& event)
268 {
269     ContainerScope scope(instanceId_);
270 
271     if (event.action == AxisAction::BEGIN) {
272         // first collect gesture into gesture referee.
273         if (Container::IsCurrentUseNewPipeline()) {
274             if (refereeNG_) {
275                 refereeNG_->AddGestureToScope(event.id, axisTouchTestResult_);
276             }
277         }
278     }
279 
280     ACE_FUNCTION_TRACE();
281     for (const auto& entry : axisTouchTestResult_) {
282         if (!entry->HandleEvent(event)) {
283             break;
284         }
285     }
286     if (event.action == AxisAction::END || event.action == AxisAction::NONE || event.action == AxisAction::CANCEL) {
287         if (Container::IsCurrentUseNewPipeline()) {
288             if (refereeNG_) {
289                 refereeNG_->CleanGestureScope(event.id);
290             }
291         }
292         axisTouchTestResult_.clear();
293     }
294     return true;
295 }
296 
DispatchTabIndexEvent(const KeyEvent & event,const RefPtr<FocusNode> & focusNode,const RefPtr<FocusGroup> & mainNode)297 bool EventManager::DispatchTabIndexEvent(
298     const KeyEvent& event, const RefPtr<FocusNode>& focusNode, const RefPtr<FocusGroup>& mainNode)
299 {
300     LOGD("The key code is %{public}d, the key action is %{public}d, the repeat time is %{public}d.", event.code,
301         event.action, event.repeatTime);
302     CHECK_NULL_RETURN(focusNode, false);
303     CHECK_NULL_RETURN(mainNode, false);
304     if (focusNode->HandleFocusByTabIndex(event, mainNode)) {
305         LOGI("Tab index focus system handled this event");
306         return true;
307     }
308     return false;
309 }
310 
DispatchKeyEvent(const KeyEvent & event,const RefPtr<FocusNode> & focusNode)311 bool EventManager::DispatchKeyEvent(const KeyEvent& event, const RefPtr<FocusNode>& focusNode)
312 {
313     CHECK_NULL_RETURN(focusNode, false);
314     LOGD("The key code is %{public}d, the key action is %{public}d, the repeat time is %{public}d.", event.code,
315         event.action, event.repeatTime);
316     if (focusNode->HandleKeyEvent(event)) {
317         LOGI("Default focus system handled this event");
318         return true;
319     }
320     LOGI("Use platform to handle this event");
321     return false;
322 }
323 
DispatchTabIndexEventNG(const KeyEvent & event,const RefPtr<NG::FrameNode> & focusNode,const RefPtr<NG::FrameNode> & mainNode)324 bool EventManager::DispatchTabIndexEventNG(
325     const KeyEvent& event, const RefPtr<NG::FrameNode>& focusNode, const RefPtr<NG::FrameNode>& mainNode)
326 {
327     LOGD("The key code is %{public}d, the key action is %{public}d, the repeat time is %{public}d.", event.code,
328         event.action, event.repeatTime);
329     CHECK_NULL_RETURN(focusNode, false);
330     CHECK_NULL_RETURN(mainNode, false);
331     auto focusNodeHub = focusNode->GetFocusHub();
332     CHECK_NULL_RETURN(focusNodeHub, false);
333     auto mainNodeHub = mainNode->GetFocusHub();
334     CHECK_NULL_RETURN(mainNodeHub, false);
335     if (focusNodeHub->HandleFocusByTabIndex(event, mainNodeHub)) {
336         LOGI("Tab index focus system handled this event");
337         return true;
338     }
339     return false;
340 }
341 
DispatchKeyEventNG(const KeyEvent & event,const RefPtr<NG::FrameNode> & focusNode)342 bool EventManager::DispatchKeyEventNG(const KeyEvent& event, const RefPtr<NG::FrameNode>& focusNode)
343 {
344     CHECK_NULL_RETURN(focusNode, false);
345     LOGD("The key code is %{public}d, the key action is %{public}d, the repeat time is %{public}d.", event.code,
346         event.action, event.repeatTime);
347     auto focusNodeHub = focusNode->GetFocusHub();
348     CHECK_NULL_RETURN(focusNodeHub, false);
349     if (focusNodeHub->HandleKeyEvent(event)) {
350         LOGI("Default focus system handled this event");
351         return true;
352     }
353     LOGI("Use platform to handle this event");
354     return false;
355 }
356 
MouseTest(const MouseEvent & event,const RefPtr<RenderNode> & renderNode)357 void EventManager::MouseTest(const MouseEvent& event, const RefPtr<RenderNode>& renderNode)
358 {
359     CHECK_NULL_VOID(renderNode);
360     const Point point { event.x, event.y };
361     MouseHoverTestList hitTestResult;
362     WeakPtr<RenderNode> hoverNode = nullptr;
363     renderNode->MouseDetect(point, point, hitTestResult, hoverNode);
364     if (hitTestResult.empty()) {
365         LOGD("mouse hover test result is empty");
366     }
367     if (event.action == MouseAction::WINDOW_LEAVE) {
368         mouseHoverTestResultsPre_ = std::move(mouseHoverTestResults_);
369         mouseHoverTestResults_.clear();
370     } else if (event.action == MouseAction::WINDOW_ENTER) {
371         mouseHoverTestResultsPre_.clear();
372         mouseHoverTestResults_ = std::move(hitTestResult);
373     } else {
374         mouseHoverTestResultsPre_ = std::move(mouseHoverTestResults_);
375         mouseHoverTestResults_ = std::move(hitTestResult);
376     }
377     mouseHoverNodePre_ = mouseHoverNode_;
378     mouseHoverNode_ = hoverNode;
379     LOGI("MouseDetect hit test last/new result size = %{public}zu/%{public}zu", mouseHoverTestResultsPre_.size(),
380         mouseHoverTestResults_.size());
381 }
382 
DispatchMouseEvent(const MouseEvent & event)383 bool EventManager::DispatchMouseEvent(const MouseEvent& event)
384 {
385     if (event.action == MouseAction::PRESS || event.action == MouseAction::RELEASE ||
386         event.action == MouseAction::MOVE) {
387         LOGD("RenderBox::HandleMouseEvent, button is %{public}d, action is %{public}d", event.button, event.action);
388         for (const auto& wp : mouseHoverTestResults_) {
389             auto hoverNode = wp.Upgrade();
390             if (hoverNode) {
391                 if (hoverNode->HandleMouseEvent(event)) {
392                     LOGI("Do HandleMouseEvent. Dispatch node: %{public}s", AceType::TypeName(hoverNode));
393                     break;
394                 }
395             }
396         }
397         return true;
398     }
399     return false;
400 }
401 
DispatchMouseHoverAnimation(const MouseEvent & event)402 void EventManager::DispatchMouseHoverAnimation(const MouseEvent& event)
403 {
404     auto hoverNodeCur = mouseHoverNode_.Upgrade();
405     auto hoverNodePre = mouseHoverNodePre_.Upgrade();
406     if (event.action == MouseAction::PRESS) {
407         if (hoverNodeCur) {
408             hoverNodeCur->AnimateMouseHoverExit();
409         }
410     } else if (event.action == MouseAction::RELEASE) {
411         if (hoverNodeCur) {
412             hoverNodeCur->AnimateMouseHoverEnter();
413         }
414     } else if (event.button == MouseButton::NONE_BUTTON && event.action == MouseAction::MOVE) {
415         if (hoverNodeCur != hoverNodePre) {
416             if (hoverNodeCur) {
417                 hoverNodeCur->AnimateMouseHoverEnter();
418             }
419             if (hoverNodePre) {
420                 hoverNodePre->AnimateMouseHoverExit();
421             }
422         }
423     } else if (event.action == MouseAction::WINDOW_ENTER) {
424         if (hoverNodeCur) {
425             hoverNodeCur->AnimateMouseHoverEnter();
426         }
427     } else if (event.action == MouseAction::WINDOW_LEAVE) {
428         if (hoverNodeCur) {
429             hoverNodeCur->AnimateMouseHoverExit();
430         }
431     }
432 }
433 
DispatchMouseHoverEvent(const MouseEvent & event)434 bool EventManager::DispatchMouseHoverEvent(const MouseEvent& event)
435 {
436     for (const auto& wp : mouseHoverTestResultsPre_) {
437         // get all previous hover nodes while it's not in current hover nodes. Those nodes exit hover
438         auto it = std::find(mouseHoverTestResults_.begin(), mouseHoverTestResults_.end(), wp);
439         if (it == mouseHoverTestResults_.end()) {
440             auto hoverNode = wp.Upgrade();
441             if (hoverNode) {
442                 hoverNode->HandleMouseHoverEvent(MouseState::NONE);
443             }
444         }
445     }
446     for (const auto& wp : mouseHoverTestResults_) {
447         // get all current hover nodes while it's not in previous hover nodes. Those nodes are new hover
448         auto it = std::find(mouseHoverTestResultsPre_.begin(), mouseHoverTestResultsPre_.end(), wp);
449         if (it == mouseHoverTestResultsPre_.end()) {
450             auto hoverNode = wp.Upgrade();
451             if (hoverNode) {
452                 hoverNode->HandleMouseHoverEvent(MouseState::HOVER);
453             }
454         }
455     }
456     return true;
457 }
458 
LogPrintMouseTest()459 void EventManager::LogPrintMouseTest()
460 {
461     if (!SystemProperties::GetDebugEnabled()) {
462         return;
463     }
464     if (currMouseTestResults_.empty()) {
465         LOGD("Mouse test onMouse result is empty.");
466     } else {
467         for (const auto& result : currMouseTestResults_) {
468             LOGD("Mouse test onMouse result: %{public}s/%{public}d.", result->GetNodeName().c_str(),
469                 result->GetNodeId());
470         }
471     }
472     if (lastHoverTestResults_.empty()) {
473         LOGD("Mouse test onHover last result is empty.");
474     } else {
475         for (const auto& result : lastHoverTestResults_) {
476             LOGD("Mouse test onHover last result: %{public}s/%{public}d.", result->GetNodeName().c_str(),
477                 result->GetNodeId());
478         }
479     }
480     if (currHoverTestResults_.empty()) {
481         LOGD("Mouse test onHover current result is empty.");
482     } else {
483         for (const auto& result : currHoverTestResults_) {
484             LOGD("Mouse test onHover current result: %{public}s/%{public}d.", result->GetNodeName().c_str(),
485                 result->GetNodeId());
486         }
487     }
488     auto lastNode = lastHoverNode_.Upgrade();
489     auto currNode = currHoverNode_.Upgrade();
490     LOGD("Mouse test last/current hoverEffect node: %{public}s/%{public}d / %{public}s/%{public}d",
491         lastNode ? lastNode->GetTag().c_str() : "NULL", lastNode ? lastNode->GetId() : -1,
492         currNode ? currNode->GetTag().c_str() : "NULL", currNode ? currNode->GetId() : -1);
493 }
494 
MouseTest(const MouseEvent & event,const RefPtr<NG::FrameNode> & frameNode,const TouchRestrict & touchRestrict)495 void EventManager::MouseTest(
496     const MouseEvent& event, const RefPtr<NG::FrameNode>& frameNode, const TouchRestrict& touchRestrict)
497 {
498     LOGD("Mouse test start. Mouse event is (%{public}f,%{public}f), button: %{public}d, action: %{public}d", event.x,
499         event.y, event.button, event.action);
500     CHECK_NULL_VOID(frameNode);
501     const NG::PointF point { event.x, event.y };
502     TouchTestResult testResult;
503     frameNode->TouchTest(point, point, touchRestrict, testResult, event.GetId());
504     if (testResult.empty()) {
505         LOGD("mouse hover test result is empty");
506     }
507     currMouseTestResults_.clear();
508     HoverTestResult hoverTestResult;
509     WeakPtr<NG::FrameNode> hoverNode = nullptr;
510     for (const auto& result : testResult) {
511         auto mouseResult = AceType::DynamicCast<MouseEventTarget>(result);
512         if (mouseResult) {
513             currMouseTestResults_.emplace_back(mouseResult);
514         }
515         auto hoverResult = AceType::DynamicCast<HoverEventTarget>(result);
516         if (hoverResult) {
517             hoverTestResult.emplace_back(hoverResult);
518         }
519         if (!hoverNode.Upgrade()) {
520             auto hoverEffectResult = AceType::DynamicCast<HoverEffectTarget>(result);
521             if (hoverEffectResult) {
522                 hoverNode = hoverEffectResult->GetHoverNode();
523             }
524         }
525     }
526     if (event.action == MouseAction::WINDOW_LEAVE) {
527         lastHoverTestResults_ = std::move(currHoverTestResults_);
528         currHoverTestResults_.clear();
529     } else if (event.action == MouseAction::WINDOW_ENTER) {
530         lastHoverTestResults_.clear();
531         currHoverTestResults_ = std::move(hoverTestResult);
532     } else {
533         lastHoverTestResults_ = std::move(currHoverTestResults_);
534         currHoverTestResults_ = std::move(hoverTestResult);
535     }
536     lastHoverNode_ = currHoverNode_;
537     currHoverNode_ = hoverNode;
538     LogPrintMouseTest();
539     LOGD("Mouse test end.");
540 }
541 
DispatchMouseEventNG(const MouseEvent & event)542 bool EventManager::DispatchMouseEventNG(const MouseEvent& event)
543 {
544     LOGD("DispatchMouseEventNG: button is %{public}d, action is %{public}d.", event.button, event.action);
545     if (event.action == MouseAction::PRESS || event.action == MouseAction::RELEASE ||
546         event.action == MouseAction::MOVE) {
547         for (const auto& mouseTarget : currMouseTestResults_) {
548             if (mouseTarget) {
549                 if (mouseTarget->HandleMouseEvent(event)) {
550                     return true;
551                 }
552             }
553         }
554     }
555     return false;
556 }
557 
DispatchMouseHoverAnimationNG(const MouseEvent & event)558 void EventManager::DispatchMouseHoverAnimationNG(const MouseEvent& event)
559 {
560     LOGD("DispatchMouseHoverAnimationNG: button is %{public}d, action is %{public}d.", event.button, event.action);
561     auto hoverNodeCur = currHoverNode_.Upgrade();
562     auto hoverNodePre = lastHoverNode_.Upgrade();
563     if (event.action == MouseAction::PRESS) {
564         if (hoverNodeCur) {
565             hoverNodeCur->AnimateHoverEffect(false);
566         }
567     } else if (event.action == MouseAction::RELEASE) {
568         if (hoverNodeCur) {
569             hoverNodeCur->AnimateHoverEffect(true);
570         }
571     } else if (event.button == MouseButton::NONE_BUTTON && event.action == MouseAction::MOVE) {
572         if (hoverNodeCur != hoverNodePre) {
573             if (hoverNodeCur) {
574                 hoverNodeCur->AnimateHoverEffect(true);
575             }
576             if (hoverNodePre) {
577                 hoverNodePre->AnimateHoverEffect(false);
578             }
579         }
580     } else if (event.action == MouseAction::WINDOW_ENTER) {
581         if (hoverNodeCur) {
582             hoverNodeCur->AnimateHoverEffect(true);
583         }
584     } else if (event.action == MouseAction::WINDOW_LEAVE) {
585         if (hoverNodeCur) {
586             hoverNodeCur->AnimateHoverEffect(false);
587         }
588     }
589 }
590 
DispatchMouseHoverEventNG(const MouseEvent & event)591 bool EventManager::DispatchMouseHoverEventNG(const MouseEvent& event)
592 {
593     LOGD("DispatchMouseHoverEventNG: button is %{public}d, action is %{public}d.", event.button, event.action);
594     for (const auto& hoverResult : lastHoverTestResults_) {
595         // get all previous hover nodes while it's not in current hover nodes. Those nodes exit hover
596         auto it = std::find(currHoverTestResults_.begin(), currHoverTestResults_.end(), hoverResult);
597         if (it == currHoverTestResults_.end()) {
598             hoverResult->HandleHoverEvent(false);
599         }
600     }
601     for (const auto& hoverResult : currHoverTestResults_) {
602         // get all current hover nodes while it's not in previous hover nodes. Those nodes are new hover
603         auto it = std::find(lastHoverTestResults_.begin(), lastHoverTestResults_.end(), hoverResult);
604         if (it == lastHoverTestResults_.end()) {
605             hoverResult->HandleHoverEvent(true);
606         }
607     }
608     return true;
609 }
610 
AxisTest(const AxisEvent & event,const RefPtr<RenderNode> & renderNode)611 void EventManager::AxisTest(const AxisEvent& event, const RefPtr<RenderNode>& renderNode)
612 {
613     CHECK_NULL_VOID(renderNode);
614     const Point point { event.x, event.y };
615     WeakPtr<RenderNode> axisNode = nullptr;
616     renderNode->AxisDetect(point, point, axisNode, event.GetDirection());
617     axisNode_ = axisNode;
618     LOGI("Current axis node is %{public}s", AceType::TypeName(axisNode_.Upgrade()));
619 }
620 
DispatchAxisEvent(const AxisEvent & event)621 bool EventManager::DispatchAxisEvent(const AxisEvent& event)
622 {
623     auto responseNode = axisNode_.Upgrade();
624     if (responseNode) {
625         responseNode->HandleAxisEvent(event);
626     }
627     return true;
628 }
629 
AxisTest(const AxisEvent & event,const RefPtr<NG::FrameNode> & frameNode)630 void EventManager::AxisTest(const AxisEvent& event, const RefPtr<NG::FrameNode>& frameNode)
631 {
632     CHECK_NULL_VOID(frameNode);
633     const NG::PointF point { event.x, event.y };
634     frameNode->AxisTest(point, point, axisTestResults_);
635 }
636 
DispatchAxisEventNG(const AxisEvent & event)637 bool EventManager::DispatchAxisEventNG(const AxisEvent& event)
638 {
639     if (event.horizontalAxis == 0 && event.verticalAxis == 0 && event.pinchAxisScale == 0) {
640         return false;
641     }
642     LOGD("DispatchAxisEventNG, action is %{public}d, axis is %{public}f / %{public}f / %{public}f", event.action,
643         event.horizontalAxis, event.verticalAxis, event.pinchAxisScale);
644     for (const auto& axisTarget : axisTestResults_) {
645         if (axisTarget && axisTarget->HandleAxisEvent(event)) {
646             return true;
647         }
648     }
649     return true;
650 }
651 
DispatchRotationEvent(const RotationEvent & event,const RefPtr<RenderNode> & renderNode,const RefPtr<RenderNode> & requestFocusNode)652 bool EventManager::DispatchRotationEvent(
653     const RotationEvent& event, const RefPtr<RenderNode>& renderNode, const RefPtr<RenderNode>& requestFocusNode)
654 {
655     CHECK_NULL_RETURN(renderNode, false);
656     if (requestFocusNode && renderNode->RotationMatchTest(requestFocusNode)) {
657         LOGD("RotationMatchTest: dispatch rotation to request node.");
658         return requestFocusNode->RotationTestForward(event);
659     } else {
660         LOGD("RotationMatchTest: dispatch rotation to stack render node.");
661         return renderNode->RotationTest(event);
662     }
663 }
664 
ClearResults()665 void EventManager::ClearResults()
666 {
667     touchTestResults_.clear();
668     mouseTestResults_.clear();
669 }
670 
EventManager()671 EventManager::EventManager()
672 {
673     LOGD("EventManger Constructor.");
674     refereeNG_ = AceType::MakeRefPtr<NG::GestureReferee>();
675     referee_ = AceType::MakeRefPtr<GestureReferee>();
676 
677     auto callback = [weak = WeakClaim(this)](size_t touchId) -> bool {
678         auto eventManager = weak.Upgrade();
679         CHECK_NULL_RETURN(eventManager, false);
680         auto refereeNG = eventManager->refereeNG_;
681         CHECK_NULL_RETURN(refereeNG, false);
682         return refereeNG->HasGestureAccepted(touchId);
683     };
684     referee_->SetQueryStateFunc(std::move(callback));
685 
686     auto cleanReferee = [weak = WeakClaim(this)](size_t touchId) -> void {
687         auto eventManager = weak.Upgrade();
688         CHECK_NULL_VOID(eventManager);
689         auto referee = eventManager->referee_;
690         CHECK_NULL_VOID(referee);
691         auto gestureScope = referee->GetGestureScope();
692         const auto iter = gestureScope.find(touchId);
693         if (iter == gestureScope.end()) {
694             return;
695         }
696 
697         auto highRecognizers = iter->second.GetHighRecognizers();
698         auto lowRecognizers = iter->second.GetLowRecognizers();
699         auto parallelRecognizers = iter->second.GetParallelRecognizers();
700 
701         for (const auto& weak : highRecognizers) {
702             auto gesture = weak.Upgrade();
703             if (gesture) {
704                 gesture->OnRejected(touchId);
705             }
706         }
707 
708         for (const auto& weak : lowRecognizers) {
709             auto gesture = weak.Upgrade();
710             if (gesture) {
711                 gesture->OnRejected(touchId);
712             }
713         }
714 
715         for (const auto& weak : parallelRecognizers) {
716             auto gesture = weak.Upgrade();
717             if (gesture) {
718                 gesture->OnRejected(touchId);
719             }
720         }
721     };
722     refereeNG_->SetQueryStateFunc(std::move(cleanReferee));
723 }
724 
725 } // namespace OHOS::Ace
726