• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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/log/dump_log.h"
19 #include "base/thread/frame_trace_adapter.h"
20 #include "core/common/container.h"
21 #include "core/common/xcollie/xcollieInterface.h"
22 #include "core/components_ng/manager/select_overlay/select_overlay_manager.h"
23 #include "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
24 
25 namespace OHOS::Ace {
26 
PenHoverTest(const TouchEvent & event,const RefPtr<NG::FrameNode> & frameNode,TouchRestrict & touchRestrict)27 void EventManager::PenHoverTest(
28     const TouchEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict)
29 {
30     CHECK_NULL_VOID(frameNode);
31     const NG::PointF point { event.x, event.y };
32     TouchTestResult testResult;
33     ResponseLinkResult responseLinkResult;
34     frameNode->TouchTest(
35         point, point, point, touchRestrict, testResult, event.id, responseLinkResult);
36     SetResponseLinkRecognizers(testResult, responseLinkResult);
37     UpdatePenHoverNode(event, testResult);
38     UpdatePenHoverMoveNode(event, testResult);
39 }
40 
UpdatePenHoverNode(const TouchEvent & event,const TouchTestResult & testResult)41 void EventManager::UpdatePenHoverNode(const TouchEvent& event, const TouchTestResult& testResult)
42 {
43     HoverTestResult penHoverTestResult;
44     for (const auto& result : testResult) {
45         auto penHoverResult = AceType::DynamicCast<HoverEventTarget>(result);
46         if (penHoverResult && penHoverResult->IsPenHoverTarget()) {
47             penHoverTestResult.emplace_back(penHoverResult);
48         }
49     }
50 
51     int32_t eventIdentity = event.GetEventIdentity();
52     if (event.type == TouchType::PROXIMITY_IN) {
53         TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "pen proximity in hover event.");
54         lastPenHoverResultsMap_[eventIdentity].clear();
55         curPenHoverResultsMap_[eventIdentity] = std::move(penHoverTestResult);
56     } else if (event.type == TouchType::PROXIMITY_OUT) {
57         TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "pen proximity out hover event.");
58         lastPenHoverResultsMap_[eventIdentity] = std::move(curPenHoverResultsMap_[eventIdentity]);
59         curPenHoverResultsMap_[eventIdentity].clear();
60     } else {
61         lastPenHoverResultsMap_[eventIdentity] = std::move(curPenHoverResultsMap_[eventIdentity]);
62         curPenHoverResultsMap_[eventIdentity] = std::move(penHoverTestResult);
63     }
64 }
65 
UpdatePenHoverMoveNode(const TouchEvent & event,const TouchTestResult & testResult)66 void EventManager::UpdatePenHoverMoveNode(const TouchEvent& event, const TouchTestResult& testResult)
67 {
68     HoverTestResult penHoverTestResult;
69     for (const auto& result : testResult) {
70         auto penHoverResult = AceType::DynamicCast<HoverEventTarget>(result);
71         if (penHoverResult && penHoverResult->IsPenHoverMoveTarget()) {
72             penHoverTestResult.emplace_back(penHoverResult);
73         }
74     }
75     curPenHoverMoveResultsMap_[event.id] = std::move(penHoverTestResult);
76 }
77 
DispatchPenHoverEventNG(const TouchEvent & event)78 void EventManager::DispatchPenHoverEventNG(const TouchEvent& event)
79 {
80     HoverTestResult lastPenHoverResults;
81     if (auto it = lastPenHoverResultsMap_.find(event.GetEventIdentity()); it != lastPenHoverResultsMap_.end()) {
82         lastPenHoverResults = it->second;
83     }
84 
85     HoverTestResult curPenHoverResults;
86     if (auto it = curPenHoverResultsMap_.find(event.GetEventIdentity()); it != curPenHoverResultsMap_.end()) {
87         curPenHoverResults = it->second;
88     }
89     auto lastHoverEndNode = lastPenHoverResults.begin();
90     auto currHoverEndNode = curPenHoverResults.begin();
91     RefPtr<HoverEventTarget> lastHoverEndNodeTarget;
92     uint32_t iterCountLast = 0;
93     uint32_t iterCountCurr = 0;
94     for (const auto& hoverResult : lastPenHoverResults) {
95         // get valid part of previous hover nodes while it's not in current hover nodes. Those nodes exit hover
96         // there may have some nodes in curPenHoverResults but intercepted
97         iterCountLast++;
98         if (lastHoverEndNode != curPenHoverResults.end()) {
99             lastHoverEndNode++;
100         }
101         if (std::find(curPenHoverResults.begin(), curPenHoverResults.end(), hoverResult) ==
102             curPenHoverResults.end()) {
103             hoverResult->HandlePenHoverEvent(false, event);
104         }
105         if ((iterCountLast >= lastPenHoverDispatchLength_) && (lastPenHoverDispatchLength_ != 0)) {
106             lastHoverEndNodeTarget = hoverResult;
107             break;
108         }
109     }
110     lastPenHoverDispatchLength_ = 0;
111     for (const auto& hoverResult : curPenHoverResults) {
112         // get valid part of current hover nodes while it's not in previous hover nodes. Those nodes are new hover
113         // the valid part stops at first interception
114         iterCountCurr++;
115         if (currHoverEndNode != curPenHoverResults.end()) {
116             currHoverEndNode++;
117         }
118         if (std::find(lastPenHoverResults.begin(), lastHoverEndNode, hoverResult) == lastHoverEndNode) {
119             if (!hoverResult->HandlePenHoverEvent(true, event)) {
120                 lastPenHoverDispatchLength_ = iterCountCurr;
121                 break;
122             }
123         }
124         if (hoverResult == lastHoverEndNodeTarget) {
125             lastPenHoverDispatchLength_ = iterCountCurr;
126             break;
127         }
128     }
129     for (auto hoverResultIt = lastPenHoverResults.begin(); hoverResultIt != lastHoverEndNode; ++hoverResultIt) {
130         // there may have previous hover nodes in the invalid part of current hover nodes. Those nodes exit hover also
131         if (std::find(currHoverEndNode, curPenHoverResults.end(), *hoverResultIt) != curPenHoverResults.end()) {
132             (*hoverResultIt)->HandlePenHoverEvent(false, event);
133         }
134     }
135 }
136 
DispatchPenHoverMoveEventNG(const TouchEvent & event)137 void EventManager::DispatchPenHoverMoveEventNG(const TouchEvent& event)
138 {
139     auto item = curPenHoverMoveResultsMap_.find(event.id);
140     if (item == curPenHoverMoveResultsMap_.end()) {
141         return ;
142     }
143     for (const auto& hoverMoveResult : item->second) {
144         if (!hoverMoveResult->HandlePenHoverMoveEvent(event)) {
145             break;
146         }
147     }
148 }
149 } // namespace OHOS::Ace
150