• 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 "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     LOGD("render touch listener: on touch test hit!");
91     auto context = context_.Upgrade();
92     if (context && context->GetIsDeclarative()) {
93         coordinateOffset_ = coordinateOffset;
94         result.emplace_back(Claim(this));
95         return;
96     }
97     rawRecognizer_->SetCoordinateOffset(coordinateOffset);
98     result.emplace_back(rawRecognizer_);
99     if (swipeRecognizer_) {
100         result.emplace_back(swipeRecognizer_);
101     }
102 }
103 
GetVisible() const104 bool RenderTouchListener::GetVisible() const
105 {
106     return RenderNode::GetVisible() && isVisible_;
107 }
108 
DispatchEvent(const TouchEvent & point)109 bool RenderTouchListener::DispatchEvent(const TouchEvent& point)
110 {
111     return true;
112 }
113 
HandleEvent(const TouchEvent & point)114 bool RenderTouchListener::HandleEvent(const TouchEvent& point)
115 {
116     bool isPropagation = true;
117     auto context = context_.Upgrade();
118     if (context && context->GetIsDeclarative()) {
119         if (point.type == TouchType::DOWN) {
120             touchPointMap_[point.id] = point;
121             isPropagation = TriggerTouchCallBack(point);
122         } else if (point.type == TouchType::UP) {
123             isPropagation = TriggerTouchCallBack(point);
124             touchPointMap_.erase(point.id);
125         } else {
126             for (const auto& pointPair : touchPointMap_) {
127                 if (pointPair.first == point.id && (pointPair.second.x != point.x || pointPair.second.y != point.y)) {
128                     touchPointMap_[point.id] = point;
129                     isPropagation = TriggerTouchCallBack(point);
130                     break;
131                 }
132             }
133         }
134     }
135     return isPropagation;
136 }
137 
TriggerTouchCallBack(const TouchEvent & changedPoint)138 bool RenderTouchListener::TriggerTouchCallBack(const TouchEvent& changedPoint)
139 {
140     LOGI("Trigger touch callback");
141     if (!onTouchEventCallback_ && !onTouchFocusEventCallback_) {
142         return true;
143     }
144     auto event = std::make_shared<TouchEventInfo>("touchEvent");
145     event->SetTimeStamp(changedPoint.time);
146     TouchLocationInfo changedInfo("onTouch", changedPoint.id);
147     float localX = changedPoint.x - coordinateOffset_.GetX();
148     float localY = changedPoint.y - coordinateOffset_.GetY();
149     changedInfo.SetLocalLocation(Offset(localX, localY));
150     changedInfo.SetGlobalLocation(Offset(changedPoint.x, changedPoint.y));
151     changedInfo.SetScreenLocation(Offset(changedPoint.screenX, changedPoint.screenY));
152     changedInfo.SetTouchType(changedPoint.type);
153     changedInfo.SetForce(changedPoint.force);
154     if (changedPoint.tiltX.has_value()) {
155         changedInfo.SetTiltX(changedPoint.tiltX.value());
156     }
157     if (changedPoint.tiltY.has_value()) {
158         changedInfo.SetTiltY(changedPoint.tiltY.value());
159     }
160     changedInfo.SetSourceTool(changedPoint.sourceTool);
161     event->AddChangedTouchLocationInfo(std::move(changedInfo));
162 
163     // all fingers collection
164     for (const auto& pointPair : touchPointMap_) {
165         float globalX = pointPair.second.x;
166         float globalY = pointPair.second.y;
167         float screenX = pointPair.second.screenX;
168         float screenY = pointPair.second.screenY;
169         float localX = pointPair.second.x - coordinateOffset_.GetX();
170         float localY = pointPair.second.y - coordinateOffset_.GetY();
171         TouchLocationInfo info("onTouch", pointPair.second.id);
172         info.SetGlobalLocation(Offset(globalX, globalY));
173         info.SetLocalLocation(Offset(localX, localY));
174         info.SetScreenLocation(Offset(screenX, screenY));
175         info.SetTouchType(pointPair.second.type);
176         info.SetForce(pointPair.second.force);
177         if (pointPair.second.tiltX.has_value()) {
178             info.SetTiltX(pointPair.second.tiltX.value());
179         }
180         if (pointPair.second.tiltY.has_value()) {
181             info.SetTiltY(pointPair.second.tiltY.value());
182         }
183         info.SetSourceTool(pointPair.second.sourceTool);
184         event->AddTouchLocationInfo(std::move(info));
185     }
186     event->SetSourceDevice(changedPoint.sourceType);
187     event->SetForce(changedPoint.force);
188     if (changedPoint.tiltX.has_value()) {
189         event->SetTiltX(changedPoint.tiltX.value());
190     }
191     if (changedPoint.tiltY.has_value()) {
192         event->SetTiltY(changedPoint.tiltY.value());
193     }
194     event->SetSourceTool(changedPoint.sourceTool);
195     if (onTouchEventCallback_) {
196         onTouchEventCallback_(event);
197     }
198     if (onTouchFocusEventCallback_ && changedPoint.type == TouchType::DOWN) {
199         onTouchFocusEventCallback_();
200     }
201     LOGD("IsStopPropagation = %{public}d", event->IsStopPropagation());
202     return event->IsStopPropagation() ? false : true;
203 }
204 
205 } // namespace OHOS::Ace