1 /*
2 * Copyright (c) 2022-2023 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_ng/event/gesture_event_hub.h"
17
18 #include <cstdint>
19 #include <list>
20
21 #include "base/memory/ace_type.h"
22 #include "base/utils/time_util.h"
23 #include "core/common/container.h"
24 #include "core/components_ng/base/frame_node.h"
25 #include "core/components_ng/event/click_event.h"
26 #include "core/components_ng/event/event_hub.h"
27 #include "core/components_ng/gestures/recognizers/click_recognizer.h"
28 #include "core/components_ng/gestures/recognizers/exclusive_recognizer.h"
29 #include "core/components_ng/gestures/recognizers/long_press_recognizer.h"
30 #include "core/components_ng/gestures/recognizers/pan_recognizer.h"
31 #include "core/components_ng/gestures/recognizers/parallel_recognizer.h"
32 #include "core/components_ng/gestures/recognizers/pinch_recognizer.h"
33 #include "core/components_ng/gestures/recognizers/rotation_recognizer.h"
34 #include "core/components_ng/gestures/recognizers/swipe_recognizer.h"
35 #include "core/gestures/gesture_info.h"
36 #include "core/pipeline_ng/pipeline_context.h"
37
38 #ifdef ENABLE_DRAG_FRAMEWORK
39 #include "image_source.h"
40
41 #include "base/msdp/device_status/interfaces/innerkits/interaction/include/interaction_manager.h"
42 #include "core/common/udmf/udmf_client.h"
43 #include "core/components_ng/pattern/text_drag/text_drag_base.h"
44 #include "core/components_ng/render/adapter/component_snapshot.h"
45 #endif // ENABLE_DRAG_FRAMEWORK
46 namespace OHOS::Ace::NG {
47 #ifdef ENABLE_DRAG_FRAMEWORK
48 RefPtr<PixelMap> g_pixelMap;
49 bool g_getPixelMapSucc = false;
50 constexpr int32_t CREATE_PIXELMAP_TIME = 80;
51 using namespace Msdp::DeviceStatus;
52 const std::string DEFAULT_MOUSE_DRAG_IMAGE { "/system/etc/device_status/drag_icon/Copy_Drag.svg" };
53 #endif // ENABLE_DRAG_FRAMEWORK
54 constexpr const char* HIT_TEST_MODE[] = {
55 "HitTestMode.Default",
56 "HitTestMode.Block",
57 "HitTestMode.Transparent",
58 "HitTestMode.None",
59 };
60
GestureEventHub(const WeakPtr<EventHub> & eventHub)61 GestureEventHub::GestureEventHub(const WeakPtr<EventHub>& eventHub) : eventHub_(eventHub) {}
62
GetFrameNode() const63 RefPtr<FrameNode> GestureEventHub::GetFrameNode() const
64 {
65 auto eventHub = eventHub_.Upgrade();
66 return eventHub ? eventHub->GetFrameNode() : nullptr;
67 }
68
ProcessTouchTestHit(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & innerTargets,TouchTestResult & finalResult,int32_t touchId,const PointF & localPoint)69 bool GestureEventHub::ProcessTouchTestHit(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
70 TouchTestResult& innerTargets, TouchTestResult& finalResult, int32_t touchId, const PointF& localPoint)
71 {
72 size_t idx = innerTargets.size();
73 size_t newIdx = 0;
74 auto host = GetFrameNode();
75 auto eventHub = eventHub_.Upgrade();
76 auto getEventTargetImpl = eventHub ? eventHub->CreateGetEventTargetImpl() : nullptr;
77 if (scrollableActuator_) {
78 scrollableActuator_->CollectTouchTarget(
79 coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets, localPoint);
80 }
81 if (touchEventActuator_) {
82 touchEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets);
83 }
84 if (clickEventActuator_) {
85 clickEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets);
86 }
87 if (panEventActuator_) {
88 panEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets);
89 }
90
91 TouchTestResult dragTargets;
92 if (longPressEventActuator_) {
93 longPressEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, dragTargets);
94 }
95 if (dragEventActuator_) {
96 dragEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, dragTargets);
97 }
98
99 std::list<RefPtr<NGGestureRecognizer>> longPressRecognizers;
100 for (const auto& item : dragTargets) {
101 auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(item);
102 if (recognizer) {
103 recognizer->BeginReferee(touchId);
104 }
105 longPressRecognizers.emplace_back(AceType::DynamicCast<NGGestureRecognizer>(item));
106 }
107 if (!longPressRecognizers.empty()) {
108 // this node has long press and drag event, combine into parallelRecognizer.
109 if (!nodeParallelRecognizer_) {
110 nodeParallelRecognizer_ = MakeRefPtr<ParallelRecognizer>(std::move(longPressRecognizers));
111 } else {
112 nodeParallelRecognizer_->AddChildren(longPressRecognizers);
113 }
114 innerTargets.emplace_back(nodeParallelRecognizer_);
115 } else {
116 nodeParallelRecognizer_.Reset();
117 }
118
119 std::list<RefPtr<NGGestureRecognizer>> innerRecognizers;
120 for (auto const& eventTarget : innerTargets) {
121 auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(eventTarget);
122 if (recognizer) {
123 auto recognizerGroup = AceType::DynamicCast<RecognizerGroup>(recognizer);
124 if (!recognizerGroup && newIdx >= idx) {
125 recognizer->SetTransInfo(host->GetId());
126 }
127 recognizer->BeginReferee(touchId);
128 innerRecognizers.push_back(std::move(recognizer));
129 } else {
130 finalResult.push_back(eventTarget);
131 }
132 newIdx++; // not process previous recognizers
133 }
134
135 ProcessTouchTestHierarchy(coordinateOffset, touchRestrict, innerRecognizers, finalResult, touchId);
136
137 return false;
138 }
139
OnModifyDone()140 void GestureEventHub::OnModifyDone()
141 {
142 if (recreateGesture_) {
143 UpdateGestureHierarchy();
144 recreateGesture_ = false;
145 }
146 }
147
ProcessTouchTestHierarchy(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,std::list<RefPtr<NGGestureRecognizer>> & innerRecognizers,TouchTestResult & finalResult,int32_t touchId)148 void GestureEventHub::ProcessTouchTestHierarchy(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
149 std::list<RefPtr<NGGestureRecognizer>>& innerRecognizers, TouchTestResult& finalResult, int32_t touchId)
150 {
151 auto host = GetFrameNode();
152 if (!host) {
153 LOGE("the host is nullptr");
154 for (auto&& recognizer : innerRecognizers) {
155 finalResult.emplace_back(std::move(recognizer));
156 }
157 return;
158 }
159
160 auto offset = Offset(coordinateOffset.GetX(), coordinateOffset.GetY());
161 RefPtr<NGGestureRecognizer> current;
162
163 // Pack inner recognizer include self inner recognizer and children.
164 if (innerRecognizers.size() == 1) {
165 current = *innerRecognizers.begin();
166 } else if (innerRecognizers.size() > 1) {
167 if (!innerExclusiveRecognizer_) {
168 innerExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(innerRecognizers));
169 } else {
170 innerExclusiveRecognizer_->AddChildren(innerRecognizers);
171 }
172 innerExclusiveRecognizer_->SetCoordinateOffset(offset);
173 innerExclusiveRecognizer_->BeginReferee(touchId);
174 current = innerExclusiveRecognizer_;
175 }
176
177 auto geometryNode = host->GetGeometryNode();
178 auto size = geometryNode->GetFrameSize();
179 auto context = host->GetContext();
180 int32_t parallelIndex = 0;
181 int32_t exclusiveIndex = 0;
182 for (auto const& recognizer : gestureHierarchy_) {
183 if (!recognizer) {
184 continue;
185 }
186 auto recognizerGroup = AceType::DynamicCast<RecognizerGroup>(recognizer);
187 if (recognizerGroup) {
188 auto groupRecognizers = recognizerGroup->GetGroupRecognizer();
189 for (const auto& groupRecognizer : groupRecognizers) {
190 if (groupRecognizer) {
191 groupRecognizer->SetCoordinateOffset(offset);
192 }
193 groupRecognizer->SetTransInfo(host->GetId());
194 }
195 } else {
196 recognizer->SetTransInfo(host->GetId());
197 }
198 recognizer->SetSize(size.Height(), size.Width());
199 recognizer->SetCoordinateOffset(offset);
200 recognizer->BeginReferee(touchId, true);
201 auto gestureMask = recognizer->GetPriorityMask();
202 if (gestureMask == GestureMask::IgnoreInternal) {
203 // In ignore case, dropped the self inner recognizer and children recognizer.
204 current = recognizer;
205 continue;
206 }
207 auto priority = recognizer->GetPriority();
208 std::list<RefPtr<NGGestureRecognizer>> recognizers { 1, recognizer };
209 if (priority == GesturePriority::Parallel) {
210 if (current) {
211 recognizers.push_front(current);
212 }
213 if (recognizers.size() > 1) {
214 if ((static_cast<int32_t>(externalParallelRecognizer_.size()) <= parallelIndex)) {
215 externalParallelRecognizer_.emplace_back(
216 AceType::MakeRefPtr<ParallelRecognizer>(std::move(recognizers)));
217 } else {
218 externalParallelRecognizer_[parallelIndex]->AddChildren(recognizers);
219 }
220 externalParallelRecognizer_[parallelIndex]->SetCoordinateOffset(offset);
221 externalParallelRecognizer_[parallelIndex]->BeginReferee(touchId);
222 current = externalParallelRecognizer_[parallelIndex];
223 parallelIndex++;
224 } else if (recognizers.size() == 1) {
225 current = *recognizers.begin();
226 }
227 } else {
228 if (current) {
229 if (priority == GesturePriority::Low) {
230 recognizers.push_front(current);
231 } else {
232 recognizers.push_back(current);
233 }
234 }
235
236 if (recognizers.size() > 1) {
237 if ((static_cast<int32_t>(externalExclusiveRecognizer_.size()) <= exclusiveIndex)) {
238 externalExclusiveRecognizer_.emplace_back(
239 AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers)));
240 } else {
241 externalExclusiveRecognizer_[exclusiveIndex]->AddChildren(recognizers);
242 }
243 externalExclusiveRecognizer_[exclusiveIndex]->SetCoordinateOffset(offset);
244 externalExclusiveRecognizer_[exclusiveIndex]->BeginReferee(touchId);
245 current = externalExclusiveRecognizer_[exclusiveIndex];
246 exclusiveIndex++;
247 } else if (recognizers.size() == 1) {
248 current = *recognizers.begin();
249 }
250 }
251 }
252
253 if (exclusiveIndex != static_cast<int32_t>(externalExclusiveRecognizer_.size())) {
254 LOGI("externalExclusiveRecognizer size changed, %{public}d resize to %{public}d",
255 static_cast<int32_t>(externalExclusiveRecognizer_.size()), exclusiveIndex);
256 externalExclusiveRecognizer_.resize(exclusiveIndex);
257 }
258
259 if (parallelIndex != static_cast<int32_t>(externalParallelRecognizer_.size())) {
260 LOGI("externalParallelRecognizer size changed, %{public}d resize to %{public}d",
261 static_cast<int32_t>(externalParallelRecognizer_.size()), parallelIndex);
262 externalParallelRecognizer_.resize(parallelIndex);
263 }
264
265 if (current) {
266 finalResult.emplace_back(std::move(current));
267 }
268 }
269
UpdateGestureHierarchy()270 void GestureEventHub::UpdateGestureHierarchy()
271 {
272 auto host = GetFrameNode();
273 CHECK_NULL_VOID(host);
274 bool success = gestures_.size() == gestureHierarchy_.size();
275 if (success) {
276 auto iter = gestures_.begin();
277 auto recognizerIter = gestureHierarchy_.begin();
278 for (; iter != gestures_.end(); iter++, recognizerIter++) {
279 auto newRecognizer = (*iter)->CreateRecognizer();
280 success = success && (*recognizerIter)->ReconcileFrom(newRecognizer);
281 if (!success) {
282 break;
283 }
284 }
285 }
286
287 if (success) {
288 gestures_.clear();
289 return;
290 }
291
292 gestureHierarchy_.clear();
293 for (auto const& gesture : gestures_) {
294 if (!gesture) {
295 continue;
296 }
297 auto recognizer = gesture->CreateRecognizer();
298
299 auto clickRecognizer = AceType::DynamicCast<ClickRecognizer>(recognizer);
300 if (clickRecognizer) {
301 clickRecognizer->SetOnAccessibility(GetOnAccessibilityEventFunc());
302 }
303
304 auto longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(recognizer);
305 if (longPressRecognizer) {
306 longPressRecognizer->SetOnAccessibility(GetOnAccessibilityEventFunc());
307 }
308
309 if (!recognizer) {
310 continue;
311 }
312 auto priority = gesture->GetPriority();
313 auto gestureMask = gesture->GetGestureMask();
314 recognizer->SetPriority(priority);
315 recognizer->SetPriorityMask(gestureMask);
316 gestureHierarchy_.emplace_back(recognizer);
317 }
318 gestures_.clear();
319 }
320
CombineIntoExclusiveRecognizer(const PointF & globalPoint,const PointF & localPoint,TouchTestResult & result,int32_t touchId)321 void GestureEventHub::CombineIntoExclusiveRecognizer(
322 const PointF& globalPoint, const PointF& localPoint, TouchTestResult& result, int32_t touchId)
323 {
324 TouchTestResult finalResult;
325 std::list<RefPtr<NGGestureRecognizer>> recognizers;
326 const auto coordinateOffset = globalPoint - localPoint;
327 auto offset = Offset(coordinateOffset.GetX(), coordinateOffset.GetY());
328 for (auto const& eventTarget : result) {
329 auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(eventTarget);
330 if (recognizer) {
331 recognizers.push_back(std::move(recognizer));
332 } else {
333 finalResult.push_back(eventTarget);
334 }
335 }
336
337 RefPtr<NGGestureRecognizer> current;
338 if (recognizers.size() == 1) {
339 current = *recognizers.begin();
340 } else if (recognizers.size() > 1) {
341 if (!nodeExclusiveRecognizer_) {
342 nodeExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers));
343 } else {
344 nodeExclusiveRecognizer_->AddChildren(recognizers);
345 }
346 nodeExclusiveRecognizer_->SetCoordinateOffset(offset);
347 nodeExclusiveRecognizer_->BeginReferee(touchId);
348 current = nodeExclusiveRecognizer_;
349 }
350
351 if (current) {
352 finalResult.emplace_back(std::move(current));
353 }
354 result.swap(finalResult);
355 }
356
InitDragDropEvent()357 void GestureEventHub::InitDragDropEvent()
358 {
359 auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& info) {
360 auto gestureEventHub = weak.Upgrade();
361 CHECK_NULL_VOID_NOLOG(gestureEventHub);
362 gestureEventHub->HandleOnDragStart(info);
363 };
364
365 auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
366 auto gestureEventHub = weak.Upgrade();
367 CHECK_NULL_VOID_NOLOG(gestureEventHub);
368 gestureEventHub->HandleOnDragUpdate(info);
369 };
370
371 auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
372 auto gestureEventHub = weak.Upgrade();
373 CHECK_NULL_VOID_NOLOG(gestureEventHub);
374 gestureEventHub->HandleOnDragEnd(info);
375 };
376
377 auto actionCancelTask = [weak = WeakClaim(this)]() {
378 auto gestureEventHub = weak.Upgrade();
379 CHECK_NULL_VOID_NOLOG(gestureEventHub);
380 gestureEventHub->HandleOnDragCancel();
381 };
382
383 auto dragEvent = MakeRefPtr<DragEvent>(
384 std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
385 SetDragEvent(dragEvent, { PanDirection::ALL }, DEFAULT_PAN_FINGER, DEFAULT_PAN_DISTANCE);
386 }
387
IsAllowedDrag(RefPtr<EventHub> eventHub)388 bool GestureEventHub::IsAllowedDrag(RefPtr<EventHub> eventHub)
389 {
390 auto frameNode = GetFrameNode();
391 CHECK_NULL_RETURN(frameNode, false);
392 auto pattern = frameNode->GetPattern();
393 CHECK_NULL_RETURN(pattern, false);
394
395 if (frameNode->IsDraggable()) {
396 if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
397 LOGE("Default support for drag and drop, but there is no onDragStart function.");
398 return false;
399 }
400 } else {
401 if (frameNode->IsUserSet()) {
402 LOGE("User settings cannot be dragged");
403 return false;
404 }
405 if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
406 LOGE("The default does not support drag and drop, and there is no onDragStart function.");
407 return false;
408 }
409 }
410 return true;
411 }
412
StartLongPressActionForWeb()413 void GestureEventHub::StartLongPressActionForWeb()
414 {
415 auto pipeline = PipelineContext::GetCurrentContext();
416 CHECK_NULL_VOID(pipeline);
417 auto taskScheduler = pipeline->GetTaskExecutor();
418 CHECK_NULL_VOID(taskScheduler);
419
420 taskScheduler->PostTask(
421 [weak = WeakClaim(this)]() {
422 auto gestureHub = weak.Upgrade();
423 CHECK_NULL_VOID_NOLOG(gestureHub);
424 auto dragEventActuator = gestureHub->dragEventActuator_;
425 CHECK_NULL_VOID_NOLOG(dragEventActuator);
426 dragEventActuator->StartLongPressActionForWeb();
427 },
428 TaskExecutor::TaskType::UI);
429 }
430
CancelDragForWeb()431 void GestureEventHub::CancelDragForWeb()
432 {
433 auto pipeline = PipelineContext::GetCurrentContext();
434 CHECK_NULL_VOID(pipeline);
435 auto taskScheduler = pipeline->GetTaskExecutor();
436 CHECK_NULL_VOID(taskScheduler);
437
438 taskScheduler->PostTask(
439 [weak = WeakClaim(this)]() {
440 LOGI("web long press action start");
441 auto gestureHub = weak.Upgrade();
442 CHECK_NULL_VOID_NOLOG(gestureHub);
443 auto dragEventActuator = gestureHub->dragEventActuator_;
444 CHECK_NULL_VOID_NOLOG(dragEventActuator);
445 dragEventActuator->CancelDragForWeb();
446 },
447 TaskExecutor::TaskType::UI);
448 }
449
ResetDragActionForWeb()450 void GestureEventHub::ResetDragActionForWeb()
451 {
452 isReceivedDragGestureInfo_ = false;
453 CHECK_NULL_VOID_NOLOG(dragEventActuator_);
454 dragEventActuator_->ResetDragActionForWeb();
455 }
456
StartDragTaskForWeb()457 void GestureEventHub::StartDragTaskForWeb()
458 {
459 if (!isReceivedDragGestureInfo_) {
460 LOGI("not received drag info, wait ark drag start");
461 return;
462 }
463
464 isReceivedDragGestureInfo_ = false;
465 auto pipeline = PipelineContext::GetCurrentContext();
466 CHECK_NULL_VOID(pipeline);
467 auto taskScheduler = pipeline->GetTaskExecutor();
468 CHECK_NULL_VOID(taskScheduler);
469
470 taskScheduler->PostTask(
471 [weak = WeakClaim(this)]() {
472 LOGI("web drag task start");
473 auto gestureHub = weak.Upgrade();
474 CHECK_NULL_VOID_NOLOG(gestureHub);
475 auto dragEventActuator = gestureHub->dragEventActuator_;
476 CHECK_NULL_VOID_NOLOG(dragEventActuator);
477 dragEventActuator->StartDragTaskForWeb(gestureHub->gestureInfoForWeb_);
478 },
479 TaskExecutor::TaskType::UI);
480 }
481
482 #ifdef ENABLE_DRAG_FRAMEWORK
CreatePixelMapFromString(const std::string & filePath)483 std::shared_ptr<Media::PixelMap> CreatePixelMapFromString(const std::string& filePath)
484 {
485 Media::SourceOptions opts;
486 opts.formatHint = "image/svg+xml";
487 uint32_t errCode = 0;
488 auto imageSource = Media::ImageSource::CreateImageSource(filePath, opts, errCode);
489 CHECK_NULL_RETURN(imageSource, nullptr);
490 Media::DecodeOptions decodeOpts;
491 std::shared_ptr<Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, errCode);
492 return pixelMap;
493 }
494
GetPixelMapOffset(const GestureEvent & info,const SizeF & size,const float scale) const495 OffsetF GestureEventHub::GetPixelMapOffset(const GestureEvent& info, const SizeF& size, const float scale) const
496 {
497 OffsetF result = OffsetF(size.Width() * PIXELMAP_WIDTH_RATE, size.Height() * PIXELMAP_HEIGHT_RATE);
498 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
499 return result;
500 }
501 auto frameNode = GetFrameNode();
502 CHECK_NULL_RETURN(frameNode, result);
503 auto frameTag = frameNode->GetTag();
504 if (frameTag == V2::WEB_ETS_TAG) {
505 result.SetX(size.Width() * PIXELMAP_WIDTH_RATE);
506 result.SetY(size.Height() * PIXELMAP_HEIGHT_RATE);
507 } else if (!NearEqual(scale, 1.0f)) {
508 result.SetX(size.Width() * PIXELMAP_WIDTH_RATE);
509 result.SetY(PIXELMAP_DRAG_DEFAULT_HEIGHT);
510 } else if (frameTag == V2::RICH_EDITOR_ETS_TAG || frameTag == V2::TEXT_ETS_TAG ||
511 frameTag == V2::TEXTINPUT_ETS_TAG) {
512 auto hostPattern = frameNode->GetPattern<TextDragBase>();
513 if (hostPattern) {
514 auto frameNodeOffset = hostPattern->GetDragUpperLeftCoordinates();
515 auto coordinateX = frameNodeOffset.GetX();
516 auto coordinateY = frameNodeOffset.GetY();
517 result.SetX(scale * (coordinateX - info.GetGlobalLocation().GetX()));
518 result.SetY(scale * (coordinateY - info.GetGlobalLocation().GetY()));
519 }
520 } else {
521 auto coordinateX = frameNodeOffset_.GetX() > SystemProperties::GetDeviceWidth()
522 ? frameNodeOffset_.GetX() - SystemProperties::GetDeviceWidth()
523 : frameNodeOffset_.GetX();
524 auto coordinateY = frameNodeOffset_.GetY();
525 result.SetX(scale * (coordinateX - info.GetGlobalLocation().GetX()));
526 result.SetY(scale * (coordinateY - info.GetGlobalLocation().GetY()));
527 }
528 if (result.GetX() >= 0.0f || result.GetX() + size.Width() < 0.0f || result.GetY() >= 0.0f ||
529 result.GetY() + size.Height() < 0.0f) {
530 result.SetX(size.Width() * PIXELMAP_WIDTH_RATE);
531 result.SetY(size.Height() * PIXELMAP_HEIGHT_RATE);
532 }
533 if (SystemProperties::GetDebugEnabled()) {
534 LOGI("Get pixelMap offset is %{public}f and %{public}f.",
535 result.GetX(), result.GetY());
536 }
537 return result;
538 }
539
GetPixelMapScale(const int32_t height,const int32_t width) const540 float GestureEventHub::GetPixelMapScale(const int32_t height, const int32_t width) const
541 {
542 float scale = 1.0f;
543 int32_t deviceWidth = SystemProperties::GetDeviceWidth();
544 int32_t deviceHeight = SystemProperties::GetDeviceHeight();
545 int32_t maxDeviceLength = std::max(deviceHeight, deviceWidth);
546 int32_t minDeviceLength = std::min(deviceHeight, deviceWidth);
547 if (maxDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE > minDeviceLength) {
548 if (height > minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) {
549 scale = static_cast<float>(minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) / height;
550 }
551 } else {
552 if (GetTextDraggable() && height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
553 width > minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) {
554 scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
555 static_cast<float>(minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) / width);
556 } else if (height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
557 width > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) {
558 scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
559 static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / width);
560 }
561 }
562 return scale;
563 }
564 #endif
565
HandleNotallowDrag(const GestureEvent & info)566 void GestureEventHub::HandleNotallowDrag(const GestureEvent& info)
567 {
568 auto frameNode = GetFrameNode();
569 CHECK_NULL_VOID(frameNode);
570 if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
571 LOGI("web component receive drag start, need to let web kernel start drag action");
572 gestureInfoForWeb_ = info;
573 isReceivedDragGestureInfo_ = true;
574 }
575 }
576
HandleOnDragStart(const GestureEvent & info)577 void GestureEventHub::HandleOnDragStart(const GestureEvent& info)
578 {
579 if (SystemProperties::GetDebugEnabled()) {
580 LOGI("Start handle onDragStart.");
581 }
582 auto eventHub = eventHub_.Upgrade();
583 CHECK_NULL_VOID(eventHub);
584 if (!IsAllowedDrag(eventHub)) {
585 if (SystemProperties::GetDebugEnabled()) {
586 LOGW("FrameNode is not allow drag.");
587 }
588 HandleNotallowDrag(info);
589 return;
590 }
591 auto pipeline = PipelineContext::GetCurrentContext();
592 CHECK_NULL_VOID(pipeline);
593 auto frameNode = GetFrameNode();
594 CHECK_NULL_VOID(frameNode);
595 RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
596 if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
597 LOGI("web on drag start");
598 event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
599 event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
600 } else {
601 event->SetX(info.GetGlobalPoint().GetX());
602 event->SetY(info.GetGlobalPoint().GetY());
603 }
604 event->SetScreenX(info.GetScreenLocation().GetX());
605 event->SetScreenY(info.GetScreenLocation().GetY());
606
607 /*
608 * Users may remove frameNode in the js callback function "onDragStart "triggered below,
609 * so save the offset of the framenode relative to the window in advance
610 */
611 frameNodeOffset_ = frameNode->GetOffsetRelativeToWindow();
612 auto extraParams = eventHub->GetDragExtraParams(std::string(), info.GetGlobalPoint(), DragEventType::START);
613 auto dragDropInfo = (eventHub->GetOnDragStart())(event, extraParams);
614 #if defined(ENABLE_DRAG_FRAMEWORK) && defined(ENABLE_ROSEN_BACKEND) && defined(PIXEL_MAP_SUPPORTED)
615 if (dragDropInfo.customNode) {
616 g_getPixelMapSucc = false;
617 auto callback = [pipeline, info, gestureEventHubPtr = AceType::Claim(this), frameNode, dragDropInfo,
618 event](std::shared_ptr<Media::PixelMap> pixelMap, int32_t arg) {
619 if (pixelMap == nullptr) {
620 LOGW("%{public}s: failed to get pixelmap, return nullptr", __func__);
621 g_getPixelMapSucc = false;
622 } else {
623 g_pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
624 g_getPixelMapSucc = true;
625 }
626 auto taskScheduler = pipeline->GetTaskExecutor();
627 CHECK_NULL_VOID(taskScheduler);
628 taskScheduler->PostTask(
629 [pipeline, info, gestureEventHubPtr, frameNode, dragDropInfo, event]() {
630 CHECK_NULL_VOID_NOLOG(gestureEventHubPtr);
631 CHECK_NULL_VOID(frameNode);
632 gestureEventHubPtr->OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
633 },
634 TaskExecutor::TaskType::UI);
635 };
636 auto customNode = AceType::DynamicCast<FrameNode>(dragDropInfo.customNode);
637 NG::ComponentSnapshot::Create(customNode, std::move(callback), CREATE_PIXELMAP_TIME);
638 return;
639 }
640 #endif
641 OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
642 }
643
OnDragStart(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> frameNode,const DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)644 void GestureEventHub::OnDragStart(const GestureEvent& info, const RefPtr<PipelineBase>& context,
645 const RefPtr<FrameNode> frameNode, const DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
646 {
647 auto eventHub = eventHub_.Upgrade();
648 CHECK_NULL_VOID(eventHub);
649 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
650 CHECK_NULL_VOID(pipeline);
651
652 auto dragDropManager = pipeline->GetDragDropManager();
653 CHECK_NULL_VOID(dragDropManager);
654 if (dragDropProxy_) {
655 dragDropProxy_ = nullptr;
656 }
657 #ifdef ENABLE_DRAG_FRAMEWORK
658 CHECK_NULL_VOID(dragEvent);
659 auto eventRet = dragEvent->GetResult();
660 if (eventRet == DragRet::DRAG_FAIL || eventRet == DragRet::DRAG_CANCEL) {
661 LOGI("HandleOnDragStart: User Set DRAG_FAIL or DRAG_CANCEL");
662 return;
663 }
664 std::string udKey;
665 int32_t recordsSize = 1;
666 auto unifiedData = dragEvent->GetData();
667 CHECK_NULL_VOID(frameNode);
668 auto pattern = frameNode->GetPattern();
669 CHECK_NULL_VOID(pattern);
670 if (pattern->GetDragRecordSize() >= 0) {
671 recordsSize = pattern->GetDragRecordSize();
672 } else if (unifiedData) {
673 auto recordSize = unifiedData->GetSize();
674 recordsSize = recordSize > 1 ? recordSize : 1;
675 }
676 SetDragData(unifiedData, udKey);
677 if (SystemProperties::GetDebugEnabled()) {
678 LOGI("HandleOnDragStart: setDragData finish, udKey is %{public}s", udKey.c_str());
679 }
680
681 std::map<std::string, int64_t> summary;
682 int32_t ret = UdmfClient::GetInstance()->GetSummary(udKey, summary);
683 if (ret != 0) {
684 LOGW("HandleOnDragStart: UDMF GetSummary failed, ret %{public}d", ret);
685 }
686 dragDropManager->SetSummaryMap(summary);
687 std::shared_ptr<Media::PixelMap> pixelMap;
688 if (g_getPixelMapSucc) {
689 pixelMap = g_pixelMap->GetPixelMapSharedPtr();
690 } else if (dragDropInfo.pixelMap) {
691 pixelMap = dragDropInfo.pixelMap->GetPixelMapSharedPtr();
692 } else if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
693 dragDropManager->SetIsMouseDrag(true);
694 pixelMap = CreatePixelMapFromString(DEFAULT_MOUSE_DRAG_IMAGE);
695 CHECK_NULL_VOID(pixelMap);
696 if (HasThumbnailCallback()) {
697 auto taskExecutor = SingleTaskExecutor::Make(pipeline->GetTaskExecutor(), TaskExecutor::TaskType::UI);
698 CancelableCallback<void()> task;
699 task.Reset(callback_);
700 taskExecutor.PostTask(task);
701 }
702 } else {
703 CHECK_NULL_VOID(pixelMap_);
704 if (pixelMap == nullptr) {
705 pixelMap = pixelMap_->GetPixelMapSharedPtr();
706 }
707 }
708 float scale = GetPixelMapScale(pixelMap->GetHeight(), pixelMap->GetWidth());
709 pixelMap->scale(scale, scale);
710 auto overlayManager = pipeline->GetOverlayManager();
711 CHECK_NULL_VOID(overlayManager);
712 if (!overlayManager->GetIsOnAnimation()) {
713 dragEventActuator_->SetIsNotInPreviewState(true);
714 }
715 uint32_t width = pixelMap->GetWidth();
716 uint32_t height = pixelMap->GetHeight();
717 auto pixelMapOffset = GetPixelMapOffset(info, SizeF(width, height), scale);
718 Msdp::DeviceStatus::ShadowInfo shadowInfo { pixelMap, pixelMapOffset.GetX(), pixelMapOffset.GetY() };
719 DragData dragData { shadowInfo, {}, udKey, static_cast<int32_t>(info.GetSourceDevice()), recordsSize,
720 info.GetPointerId(), info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY(),
721 info.GetTargetDisplayId(), true };
722 ret = Msdp::DeviceStatus::InteractionManager::GetInstance()->StartDrag(
723 dragData, GetDragCallback(pipeline, eventHub));
724 if (ret != 0) {
725 LOGE("InteractionManager: drag start error");
726 return;
727 }
728 auto eventManager = pipeline->GetEventManager();
729 CHECK_NULL_VOID(eventManager);
730 eventManager->DoMouseActionRelease();
731 eventManager->SetIsDragging(true);
732 if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && dragEventActuator_->GetIsNotInPreviewState()) {
733 if (SystemProperties::GetDebugEnabled()) {
734 LOGI("Drag window start for not in previewState, set DragWindowVisible true.");
735 }
736 Msdp::DeviceStatus::InteractionManager::GetInstance()->SetDragWindowVisible(true);
737 } else if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON &&
738 (dragDropInfo.pixelMap || dragDropInfo.customNode)) {
739 if (SystemProperties::GetDebugEnabled()) {
740 LOGI("Drag window start for Mouse with custom pixelMap, set DragWindowVisible true.");
741 }
742 Msdp::DeviceStatus::InteractionManager::GetInstance()->SetDragWindowVisible(true);
743 dragDropManager->SetIsDragWindowShow(true);
744 }
745 dragDropProxy_ = dragDropManager->CreateFrameworkDragDropProxy();
746 if (!dragDropProxy_) {
747 LOGE("HandleOnDragStart: drag start error");
748 return;
749 }
750 CHECK_NULL_VOID(dragDropProxy_);
751 dragDropProxy_->OnDragStart(info, dragDropInfo.extraInfo, GetFrameNode());
752 #else
753 if (dragDropInfo.customNode) {
754 dragDropProxy_ = dragDropManager->CreateAndShowDragWindow(dragDropInfo.customNode, info);
755 } else if (dragDropInfo.pixelMap) {
756 dragDropProxy_ = dragDropManager->CreateAndShowDragWindow(dragDropInfo.pixelMap, info);
757 } else {
758 dragDropProxy_ = dragDropManager->CreateAndShowDragWindow(pixelMap_, info);
759 }
760 if (!dragDropProxy_) {
761 LOGE("HandleOnDragStart: drag start error");
762 return;
763 }
764
765 CHECK_NULL_VOID(dragDropProxy_);
766 dragDropProxy_->OnDragStart(info, dragDropInfo.extraInfo, GetFrameNode());
767 #endif // ENABLE_DRAG_FRAMEWORK
768 }
769
HandleOnDragUpdate(const GestureEvent & info)770 void GestureEventHub::HandleOnDragUpdate(const GestureEvent& info)
771 {
772 if (SystemProperties::GetDebugEnabled()) {
773 LOGI("Start handle onDragUpdate.");
774 }
775 gestureInfoForWeb_ = info;
776 CHECK_NULL_VOID(dragDropProxy_);
777 #ifndef ENABLE_DRAG_FRAMEWORK
778 auto pipeline = PipelineContext::GetCurrentContext();
779 CHECK_NULL_VOID(pipeline);
780 auto dragDropManager = pipeline->GetDragDropManager();
781 if (dragDropManager->IsDragged()) {
782 dragDropProxy_->OnDragMove(info);
783 }
784 #endif // ENABLE_DRAG_FRAMEWORK
785 }
786
HandleOnDragEnd(const GestureEvent & info)787 void GestureEventHub::HandleOnDragEnd(const GestureEvent& info)
788 {
789 if (SystemProperties::GetDebugEnabled()) {
790 LOGI("Start handle onDragEnd.");
791 }
792 auto pipeline = NG::PipelineContext::GetCurrentContext();
793 const static int32_t PLATFORM_VERSION_TEN = 10;
794 if (pipeline && (pipeline->GetMinPlatformVersion() < PLATFORM_VERSION_TEN)) {
795 auto eventHub = eventHub_.Upgrade();
796 CHECK_NULL_VOID(eventHub);
797
798 auto frameNode = GetFrameNode();
799 CHECK_NULL_VOID(frameNode);
800
801 // Only the onDrop callback of dragged frame node is triggered.
802 // The onDrop callback of target frame node is triggered in PipelineContext::OnDragEvent.
803 if (eventHub->HasOnDrop()) {
804 RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
805 if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
806 LOGI("web on drag end");
807 event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
808 event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
809 } else {
810 event->SetX(info.GetGlobalPoint().GetX());
811 event->SetY(info.GetGlobalPoint().GetY());
812 }
813 event->SetScreenX(info.GetScreenLocation().GetX());
814 event->SetScreenY(info.GetScreenLocation().GetY());
815 eventHub->FireOnDrop(event, "");
816 }
817 }
818
819 dragEventActuator_->ResetTextReceivedLongPress();
820 CHECK_NULL_VOID(dragDropProxy_);
821 dragDropProxy_->DestroyDragWindow();
822 dragDropProxy_ = nullptr;
823 }
824
HandleOnDragCancel()825 void GestureEventHub::HandleOnDragCancel()
826 {
827 CHECK_NULL_VOID(dragDropProxy_);
828 #ifndef ENABLE_DRAG_FRAMEWORK
829 dragDropProxy_->onDragCancel();
830 #endif // ENABLE_DRAG_FRAMEWORK
831 dragDropProxy_->DestroyDragWindow();
832 dragDropProxy_ = nullptr;
833 }
834
SetFocusClickEvent(GestureEventFunc && clickEvent)835 void GestureEventHub::SetFocusClickEvent(GestureEventFunc&& clickEvent)
836 {
837 auto eventHub = eventHub_.Upgrade();
838 CHECK_NULL_VOID(eventHub);
839 auto focusHub = eventHub->GetFocusHub();
840 CHECK_NULL_VOID_NOLOG(focusHub);
841 focusHub->SetOnClickCallback(std::move(clickEvent));
842 }
843
844 // helper function to ensure clickActuator is initialized
CheckClickActuator()845 void GestureEventHub::CheckClickActuator()
846 {
847 if (!clickEventActuator_) {
848 clickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
849 clickEventActuator_->SetOnAccessibility(GetOnAccessibilityEventFunc());
850 }
851 }
852
SetUserOnClick(GestureEventFunc && clickEvent)853 void GestureEventHub::SetUserOnClick(GestureEventFunc&& clickEvent)
854 {
855 CheckClickActuator();
856 clickEventActuator_->SetUserCallback(std::move(clickEvent));
857
858 SetFocusClickEvent(clickEventActuator_->GetClickEvent());
859 }
860
AddClickEvent(const RefPtr<ClickEvent> & clickEvent)861 void GestureEventHub::AddClickEvent(const RefPtr<ClickEvent>& clickEvent)
862 {
863 CheckClickActuator();
864 clickEventActuator_->AddClickEvent(clickEvent);
865
866 SetFocusClickEvent(clickEventActuator_->GetClickEvent());
867 }
868
869 // replace last showMenu callback
BindMenu(GestureEventFunc && showMenu)870 void GestureEventHub::BindMenu(GestureEventFunc&& showMenu)
871 {
872 if (showMenu_) {
873 RemoveClickEvent(showMenu_);
874 }
875 showMenu_ = MakeRefPtr<ClickEvent>(std::move(showMenu));
876 AddClickEvent(showMenu_);
877 }
878
GetOnAccessibilityEventFunc()879 OnAccessibilityEventFunc GestureEventHub::GetOnAccessibilityEventFunc()
880 {
881 auto callback = [weak = WeakClaim(this)](AccessibilityEventType eventType) {
882 auto gestureHub = weak.Upgrade();
883 CHECK_NULL_VOID_NOLOG(gestureHub);
884 auto node = gestureHub->GetFrameNode();
885 CHECK_NULL_VOID_NOLOG(node);
886 node->OnAccessibilityEvent(eventType);
887 };
888 return callback;
889 }
890
ActClick()891 bool GestureEventHub::ActClick()
892 {
893 auto host = GetFrameNode();
894 CHECK_NULL_RETURN(host, false);
895 GestureEventFunc click;
896 GestureEvent info;
897 std::chrono::microseconds microseconds(GetMicroTickCount());
898 TimeStamp time(microseconds);
899 info.SetTimeStamp(time);
900 EventTarget clickEventTarget;
901 clickEventTarget.id = host->GetId();
902 clickEventTarget.type = host->GetTag();
903 auto geometryNode = host->GetGeometryNode();
904 CHECK_NULL_RETURN(geometryNode, false);
905 auto offset = geometryNode->GetFrameOffset();
906 auto size = geometryNode->GetFrameSize();
907 clickEventTarget.area.SetOffset(DimensionOffset(offset));
908 clickEventTarget.area.SetHeight(Dimension(size.Height()));
909 clickEventTarget.area.SetWidth(Dimension(size.Width()));
910 clickEventTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
911 info.SetTarget(clickEventTarget);
912 Offset globalOffset(offset.GetX(), offset.GetY());
913 info.SetGlobalLocation(globalOffset);
914 if (clickEventActuator_) {
915 click = clickEventActuator_->GetClickEvent();
916 CHECK_NULL_RETURN_NOLOG(click, true);
917 click(info);
918 return true;
919 }
920 RefPtr<ClickRecognizer> clickRecognizer;
921 for (auto gestureRecognizer : gestureHierarchy_) {
922 clickRecognizer = AceType::DynamicCast<ClickRecognizer>(gestureRecognizer);
923 if (clickRecognizer && clickRecognizer->GetFingers() == 1 && clickRecognizer->GetCount() == 1) {
924 click = clickRecognizer->GetTapActionFunc();
925 click(info);
926 host->OnAccessibilityEvent(AccessibilityEventType::CLICK);
927 return true;
928 }
929 }
930 return false;
931 }
932
ActLongClick()933 bool GestureEventHub::ActLongClick()
934 {
935 auto host = GetFrameNode();
936 CHECK_NULL_RETURN(host, false);
937 GestureEventFunc click;
938 GestureEvent info;
939 std::chrono::microseconds microseconds(GetMicroTickCount());
940 TimeStamp time(microseconds);
941 info.SetTimeStamp(time);
942 EventTarget longPressTarget;
943 longPressTarget.id = host->GetId();
944 longPressTarget.type = host->GetTag();
945 auto geometryNode = host->GetGeometryNode();
946 CHECK_NULL_RETURN(geometryNode, false);
947 auto offset = geometryNode->GetFrameOffset();
948 auto size = geometryNode->GetFrameSize();
949 longPressTarget.area.SetOffset(DimensionOffset(offset));
950 longPressTarget.area.SetHeight(Dimension(size.Height()));
951 longPressTarget.area.SetWidth(Dimension(size.Width()));
952 longPressTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
953 info.SetTarget(longPressTarget);
954 Offset globalOffset(offset.GetX(), offset.GetY());
955 info.SetGlobalLocation(globalOffset);
956 if (longPressEventActuator_) {
957 click = longPressEventActuator_->GetGestureEventFunc();
958 CHECK_NULL_RETURN_NOLOG(click, true);
959 click(info);
960 return true;
961 }
962 RefPtr<LongPressRecognizer> longPressRecognizer;
963 for (auto gestureRecognizer : gestureHierarchy_) {
964 longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(gestureRecognizer);
965 if (longPressRecognizer && longPressRecognizer->GetFingers() == 1) {
966 click = longPressRecognizer->GetLongPressActionFunc();
967 click(info);
968 host->OnAccessibilityEvent(AccessibilityEventType::LONG_PRESS);
969 return true;
970 }
971 }
972 return false;
973 }
974
GetHitTestModeStr() const975 std::string GestureEventHub::GetHitTestModeStr() const
976 {
977 auto mode = static_cast<int32_t>(hitTestMode_);
978 if (mode < 0 || mode >= static_cast<int32_t>(std::size(HIT_TEST_MODE))) {
979 return HIT_TEST_MODE[0];
980 }
981 return HIT_TEST_MODE[mode];
982 }
983
KeyBoardShortCutClick(const KeyEvent & event,const WeakPtr<NG::FrameNode> & node)984 bool GestureEventHub::KeyBoardShortCutClick(const KeyEvent& event, const WeakPtr<NG::FrameNode>& node)
985 {
986 auto host = node.Upgrade();
987 CHECK_NULL_RETURN(host, false);
988 CHECK_NULL_RETURN(clickEventActuator_, false);
989 auto click = clickEventActuator_->GetClickEvent();
990 CHECK_NULL_RETURN(click, false);
991 GestureEvent info;
992 info.SetSourceDevice(event.sourceType);
993 info.SetTimeStamp(event.timeStamp);
994 EventTarget target;
995 target.id = host->GetId();
996 target.type = host->GetTag();
997 auto geometryNode = host->GetGeometryNode();
998 CHECK_NULL_RETURN(geometryNode, false);
999 auto offset = geometryNode->GetFrameOffset();
1000 auto size = geometryNode->GetFrameSize();
1001 target.area.SetOffset(DimensionOffset(offset));
1002 target.area.SetHeight(Dimension(size.Height()));
1003 target.area.SetWidth(Dimension(size.Width()));
1004 target.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1005 info.SetTarget(target);
1006 click(info);
1007 return true;
1008 }
1009
1010 #ifdef ENABLE_DRAG_FRAMEWORK
SetDragData(const RefPtr<UnifiedData> & unifiedData,std::string & udKey)1011 int32_t GestureEventHub::SetDragData(const RefPtr<UnifiedData>& unifiedData, std::string& udKey)
1012 {
1013 if (unifiedData == nullptr) {
1014 LOGE("HandleOnDragStart: SetDragData unifiedData is null");
1015 return -1;
1016 }
1017 int32_t ret = UdmfClient::GetInstance()->SetData(unifiedData, udKey);
1018 if (ret != 0) {
1019 LOGE("HandleOnDragStart: UDMF Setdata failed:%{public}d", ret);
1020 }
1021 return ret;
1022 }
GetDragCallback(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)1023 OnDragCallback GestureEventHub::GetDragCallback(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
1024 {
1025 auto ret = [](const DragNotifyMsg& notifyMessage) {};
1026 auto eventHub = hub.Upgrade();
1027 CHECK_NULL_RETURN(eventHub, ret);
1028 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1029 CHECK_NULL_RETURN(pipeline, ret);
1030 auto taskScheduler = pipeline->GetTaskExecutor();
1031 CHECK_NULL_RETURN(taskScheduler, ret);
1032 auto dragDropManager = pipeline->GetDragDropManager();
1033 CHECK_NULL_RETURN(dragDropManager, ret);
1034 auto eventManager = pipeline->GetEventManager();
1035 RefPtr<OHOS::Ace::DragEvent> dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1036 auto callback = [id = Container::CurrentId(), eventHub, dragEvent, taskScheduler, dragDropManager, eventManager](
1037 const DragNotifyMsg& notifyMessage) {
1038 ContainerScope scope(id);
1039 DragRet result = DragRet::DRAG_FAIL;
1040 switch (notifyMessage.result) {
1041 case DragResult::DRAG_SUCCESS:
1042 result = DragRet::DRAG_SUCCESS;
1043 break;
1044 case DragResult::DRAG_FAIL:
1045 result = DragRet::DRAG_FAIL;
1046 break;
1047 default:
1048 break;
1049 }
1050 dragEvent->SetResult(result);
1051 taskScheduler->PostTask(
1052 [eventHub, dragEvent, dragDropManager, eventManager]() {
1053 dragDropManager->SetIsDragged(false);
1054 if (eventManager) {
1055 eventManager->DoMouseActionRelease();
1056 }
1057 if (eventHub->HasOnDragEnd()) {
1058 (eventHub->GetOnDragEnd())(dragEvent);
1059 }
1060 },
1061 TaskExecutor::TaskType::UI);
1062 };
1063 return callback;
1064 }
1065
1066 #endif
IsAccessibilityClickable()1067 bool GestureEventHub::IsAccessibilityClickable()
1068 {
1069 bool ret = IsClickable();
1070 RefPtr<ClickRecognizer> clickRecognizer;
1071 for (auto gestureRecognizer : gestureHierarchy_) {
1072 clickRecognizer = AceType::DynamicCast<ClickRecognizer>(gestureRecognizer);
1073 if (clickRecognizer && clickRecognizer->GetFingers() == 1 && clickRecognizer->GetCount() == 1) {
1074 return true;
1075 }
1076 }
1077 return ret;
1078 }
1079
IsAccessibilityLongClickable()1080 bool GestureEventHub::IsAccessibilityLongClickable()
1081 {
1082 bool ret = IsLongClickable();
1083 RefPtr<LongPressRecognizer> longPressRecognizer;
1084 for (auto gestureRecognizer : gestureHierarchy_) {
1085 longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(gestureRecognizer);
1086 if (longPressRecognizer && longPressRecognizer->GetFingers() == 1) {
1087 return true;
1088 }
1089 }
1090 return ret;
1091 }
1092
ClearUserOnClick()1093 void GestureEventHub::ClearUserOnClick()
1094 {
1095 if (clickEventActuator_) {
1096 clickEventActuator_->ClearUserCallback();
1097 }
1098 }
1099
ClearUserOnTouch()1100 void GestureEventHub::ClearUserOnTouch()
1101 {
1102 if (touchEventActuator_) {
1103 touchEventActuator_->ClearUserCallback();
1104 }
1105 }
1106 } // namespace OHOS::Ace::NG
1107