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 "render_touch_listener.h"
17
18 #include "core/components/touch_listener/touch_listener_component.h"
19 #include "core/event/ace_event_helper.h"
20
21 namespace OHOS::Ace {
22
RenderTouchListener()23 RenderTouchListener::RenderTouchListener() : rawRecognizer_(AceType::MakeRefPtr<RawRecognizer>()) {}
24
Create()25 RefPtr<RenderNode> RenderTouchListener::Create()
26 {
27 return AceType::MakeRefPtr<RenderTouchListener>();
28 }
29
Update(const RefPtr<Component> & component)30 void RenderTouchListener::Update(const RefPtr<Component>& component)
31 {
32 auto touchComponent = AceType::DynamicCast<TouchListenerComponent>(component);
33 ACE_DCHECK(touchComponent);
34 responseRegion_ = touchComponent->GetResponseRegion();
35 isResponseRegion_ = touchComponent->IsResponseRegion();
36 auto context = context_.Upgrade();
37 if (context && context->GetIsDeclarative()) {
38 onTouchEventCallback_ = AceSyncEvent<void(const std::shared_ptr<TouchEventInfo>&)>::Create(
39 touchComponent->GetOnTouchId(), context_);
40 return;
41 }
42
43 for (uint32_t eventStage = 0; eventStage < EventStage::SIZE; eventStage++) {
44 for (uint32_t touchEventType = 0; touchEventType < EventType::SIZE; touchEventType++) {
45 auto& onEventId = touchComponent->GetEvent(EventAction::ON, eventStage, touchEventType);
46 if (!onEventId.IsEmpty()) {
47 rawRecognizer_->SetOnEventCallback(
48 AceAsyncEvent<void(const TouchEventInfo&)>::Create(onEventId, context_), eventStage,
49 touchEventType);
50 }
51 auto& catchEventId = touchComponent->GetEvent(EventAction::CATCH, eventStage, touchEventType);
52 if (!catchEventId.IsEmpty()) {
53 rawRecognizer_->SetCatchEventCallback(
54 AceAsyncEvent<void()>::Create(catchEventId, context_), eventStage, touchEventType);
55 }
56 }
57
58 auto& onEventId = touchComponent->GetSwipeEvent(EventAction::ON, eventStage);
59 if (!onEventId.IsEmpty()) {
60 if (!swipeRecognizer_) {
61 swipeRecognizer_ = AceType::MakeRefPtr<SwipeRecognizer>();
62 }
63 swipeRecognizer_->SetSwipeCallback(
64 AceAsyncEvent<void(const SwipeEventInfo&)>::Create(onEventId, context_), eventStage);
65 }
66 auto& catchEventId = touchComponent->GetSwipeEvent(EventAction::CATCH, eventStage);
67 if (!catchEventId.IsEmpty()) {
68 if (!swipeRecognizer_) {
69 swipeRecognizer_ = AceType::MakeRefPtr<SwipeRecognizer>();
70 }
71 swipeRecognizer_->SetCatchEventCallback(
72 AceAsyncEvent<void(const SwipeEventInfo&)>::Create(catchEventId, context_), eventStage);
73 }
74 }
75 touchable_ = touchComponent->IsTouchable();
76 isVisible_ = touchComponent->IsVisible();
77 interceptTouchEvent_ = !touchable_;
78
79 if (!touchComponent->GetEvent(EventAction::CATCH, EventStage::CAPTURE, EventType::TOUCH_DOWN).IsEmpty()) {
80 EventMarker eventMarker("catchEvent");
81 auto event = AceAsyncEvent<void()>::Create(eventMarker, context_);
82 rawRecognizer_->SetCatchEventCallback(event, EventStage::CAPTURE, EventType::TOUCH_UP);
83 rawRecognizer_->SetCatchEventCallback(event, EventStage::CAPTURE, EventType::TOUCH_MOVE);
84 }
85 }
86
OnTouchTestHit(const Offset & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & result)87 void RenderTouchListener::OnTouchTestHit(
88 const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result)
89 {
90 auto context = context_.Upgrade();
91 if (context && context->GetIsDeclarative()) {
92 coordinateOffset_ = coordinateOffset;
93 result.emplace_back(Claim(this));
94 return;
95 }
96 rawRecognizer_->SetCoordinateOffset(coordinateOffset);
97 result.emplace_back(rawRecognizer_);
98 if (swipeRecognizer_) {
99 result.emplace_back(swipeRecognizer_);
100 }
101 }
102
GetVisible() const103 bool RenderTouchListener::GetVisible() const
104 {
105 return RenderNode::GetVisible() && isVisible_;
106 }
107
DispatchEvent(const TouchEvent & point)108 bool RenderTouchListener::DispatchEvent(const TouchEvent& point)
109 {
110 return true;
111 }
112
HandleEvent(const TouchEvent & point)113 bool RenderTouchListener::HandleEvent(const TouchEvent& point)
114 {
115 bool isPropagation = true;
116 auto context = context_.Upgrade();
117 if (context && context->GetIsDeclarative()) {
118 if (point.type == TouchType::DOWN) {
119 touchPointMap_[point.id] = point;
120 isPropagation = TriggerTouchCallBack(point);
121 } else if (point.type == TouchType::UP) {
122 isPropagation = TriggerTouchCallBack(point);
123 touchPointMap_.erase(point.id);
124 } else {
125 for (const auto& pointPair : touchPointMap_) {
126 if (pointPair.first == point.id && (pointPair.second.x != point.x || pointPair.second.y != point.y)) {
127 touchPointMap_[point.id] = point;
128 isPropagation = TriggerTouchCallBack(point);
129 break;
130 }
131 }
132 }
133 }
134 return isPropagation;
135 }
136
TriggerTouchCallBack(const TouchEvent & changedPoint)137 bool RenderTouchListener::TriggerTouchCallBack(const TouchEvent& changedPoint)
138 {
139 LOGI("Trigger touch callback");
140 if (!onTouchEventCallback_ && !onTouchFocusEventCallback_) {
141 return true;
142 }
143 auto event = std::make_shared<TouchEventInfo>("touchEvent");
144 event->SetTimeStamp(changedPoint.time);
145 TouchLocationInfo changedInfo("onTouch", changedPoint.id);
146 float localX = changedPoint.x - coordinateOffset_.GetX();
147 float localY = changedPoint.y - coordinateOffset_.GetY();
148 changedInfo.SetLocalLocation(Offset(localX, localY));
149 changedInfo.SetGlobalLocation(Offset(changedPoint.x, changedPoint.y));
150 changedInfo.SetScreenLocation(Offset(changedPoint.screenX, changedPoint.screenY));
151 changedInfo.SetTouchType(changedPoint.type);
152 changedInfo.SetForce(changedPoint.force);
153 if (changedPoint.tiltX.has_value()) {
154 changedInfo.SetTiltX(changedPoint.tiltX.value());
155 }
156 if (changedPoint.tiltY.has_value()) {
157 changedInfo.SetTiltY(changedPoint.tiltY.value());
158 }
159 changedInfo.SetSourceTool(changedPoint.sourceTool);
160 event->AddChangedTouchLocationInfo(std::move(changedInfo));
161
162 // all fingers collection
163 for (const auto& pointPair : touchPointMap_) {
164 float globalX = pointPair.second.x;
165 float globalY = pointPair.second.y;
166 float screenX = pointPair.second.screenX;
167 float screenY = pointPair.second.screenY;
168 float localX = pointPair.second.x - coordinateOffset_.GetX();
169 float localY = pointPair.second.y - coordinateOffset_.GetY();
170 TouchLocationInfo info("onTouch", pointPair.second.id);
171 info.SetGlobalLocation(Offset(globalX, globalY));
172 info.SetLocalLocation(Offset(localX, localY));
173 info.SetScreenLocation(Offset(screenX, screenY));
174 info.SetTouchType(pointPair.second.type);
175 info.SetForce(pointPair.second.force);
176 if (pointPair.second.tiltX.has_value()) {
177 info.SetTiltX(pointPair.second.tiltX.value());
178 }
179 if (pointPair.second.tiltY.has_value()) {
180 info.SetTiltY(pointPair.second.tiltY.value());
181 }
182 info.SetSourceTool(pointPair.second.sourceTool);
183 event->AddTouchLocationInfo(std::move(info));
184 }
185 event->SetSourceDevice(changedPoint.sourceType);
186 event->SetForce(changedPoint.force);
187 if (changedPoint.tiltX.has_value()) {
188 event->SetTiltX(changedPoint.tiltX.value());
189 }
190 if (changedPoint.tiltY.has_value()) {
191 event->SetTiltY(changedPoint.tiltY.value());
192 }
193 event->SetSourceTool(changedPoint.sourceTool);
194 if (onTouchEventCallback_) {
195 onTouchEventCallback_(event);
196 }
197 if (onTouchFocusEventCallback_ && changedPoint.type == TouchType::DOWN) {
198 onTouchFocusEventCallback_();
199 }
200 return event->IsStopPropagation() ? false : true;
201 }
202
203 } // namespace OHOS::Ace