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/log/log_wrapper.h"
22 #include "base/memory/ace_type.h"
23 #include "base/subwindow/subwindow_manager.h"
24 #include "base/utils/time_util.h"
25 #include "base/image/image_source.h"
26 #include "core/common/container.h"
27 #include "core/common/interaction/interaction_data.h"
28 #include "core/common/interaction/interaction_interface.h"
29 #include "core/components/common/layout/grid_system_manager.h"
30 #include "core/components/container_modal/container_modal_constants.h"
31 #include "core/components_ng/base/frame_node.h"
32 #include "core/components_ng/event/click_event.h"
33 #include "core/components_ng/event/event_hub.h"
34 #include "core/components_ng/gestures/recognizers/click_recognizer.h"
35 #include "core/components_ng/gestures/recognizers/exclusive_recognizer.h"
36 #include "core/components_ng/gestures/recognizers/long_press_recognizer.h"
37 #include "core/components_ng/gestures/recognizers/pan_recognizer.h"
38 #include "core/components_ng/gestures/recognizers/parallel_recognizer.h"
39 #include "core/components_ng/gestures/recognizers/pinch_recognizer.h"
40 #include "core/components_ng/gestures/recognizers/rotation_recognizer.h"
41 #include "core/components_ng/gestures/recognizers/swipe_recognizer.h"
42 #include "core/components_ng/pattern/text_drag/text_drag_base.h"
43 #include "core/gestures/gesture_info.h"
44 #include "core/pipeline_ng/pipeline_context.h"
45
46 #if defined(PIXEL_MAP_SUPPORTED) && !defined(CROSS_PLATFORM)
47 #include "image_source.h"
48 #endif
49
50 #include "core/common/udmf/udmf_client.h"
51 #include "core/components_ng/render/adapter/component_snapshot.h"
52 namespace OHOS::Ace::NG {
53 namespace {
54 #if defined(PIXEL_MAP_SUPPORTED) && !defined(CROSS_PLATFORM)
55 constexpr int32_t CREATE_PIXELMAP_TIME = 80;
56 #endif
57 constexpr uint32_t EXTRA_INFO_MAX_LENGTH = 200;
58 } // namespace
59 const std::string DEFAULT_MOUSE_DRAG_IMAGE { "/system/etc/device_status/drag_icon/Copy_Drag.svg" };
60 constexpr const char* HIT_TEST_MODE[] = {
61 "HitTestMode.Default",
62 "HitTestMode.Block",
63 "HitTestMode.Transparent",
64 "HitTestMode.None",
65 };
66
GestureEventHub(const WeakPtr<EventHub> & eventHub)67 GestureEventHub::GestureEventHub(const WeakPtr<EventHub>& eventHub) : eventHub_(eventHub) {}
68
GetFrameNode() const69 RefPtr<FrameNode> GestureEventHub::GetFrameNode() const
70 {
71 auto eventHub = eventHub_.Upgrade();
72 return eventHub ? eventHub->GetFrameNode() : nullptr;
73 }
74
ProcessTouchTestHit(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & innerTargets,TouchTestResult & finalResult,int32_t touchId,const PointF & localPoint,const RefPtr<TargetComponent> & targetComponent)75 bool GestureEventHub::ProcessTouchTestHit(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
76 TouchTestResult& innerTargets, TouchTestResult& finalResult, int32_t touchId, const PointF& localPoint,
77 const RefPtr<TargetComponent>& targetComponent)
78 {
79 auto host = GetFrameNode();
80 CHECK_NULL_RETURN(host, false);
81 auto eventHub = eventHub_.Upgrade();
82 auto getEventTargetImpl = eventHub ? eventHub->CreateGetEventTargetImpl() : nullptr;
83 if (scrollableActuator_) {
84 scrollableActuator_->CollectTouchTarget(
85 coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets, localPoint, host, targetComponent);
86 }
87 size_t idx = innerTargets.size();
88 size_t newIdx = 0;
89 if (touchEventActuator_) {
90 touchEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets);
91 }
92 if (clickEventActuator_) {
93 clickEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets);
94 }
95 if (userParallelClickEventActuator_) {
96 auto clickRecognizer = userParallelClickEventActuator_->GetClickRecognizer();
97 if (clickRecognizer) {
98 clickRecognizer->SetGestureInfo(MakeRefPtr<GestureInfo>(GestureTypeName::CLICK, true));
99 clickRecognizer->SetOnAction(userParallelClickEventActuator_->GetClickEvent());
100 clickRecognizer->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
101 clickRecognizer->SetGetEventTargetImpl(getEventTargetImpl);
102 }
103 }
104 if (panEventActuator_) {
105 panEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets);
106 }
107
108 TouchTestResult dragTargets;
109 if (longPressEventActuator_) {
110 longPressEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, dragTargets);
111 }
112 if (dragEventActuator_) {
113 dragEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, dragTargets);
114 }
115
116 std::list<RefPtr<NGGestureRecognizer>> longPressRecognizers;
117 for (const auto& item : dragTargets) {
118 auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(item);
119 if (recognizer) {
120 recognizer->BeginReferee(touchId);
121 recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
122 recognizer->SetTargetComponent(targetComponent);
123 if (AceType::InstanceOf<RecognizerGroup>(recognizer)) {
124 auto group = AceType::DynamicCast<RecognizerGroup>(recognizer);
125 if (group) {
126 group->SetChildrenTargetComponent(targetComponent);
127 }
128 }
129 }
130 longPressRecognizers.emplace_back(AceType::DynamicCast<NGGestureRecognizer>(item));
131 }
132 if (!longPressRecognizers.empty()) {
133 // this node has long press and drag event, combine into parallelRecognizer.
134 if (!nodeParallelRecognizer_) {
135 nodeParallelRecognizer_ = MakeRefPtr<ParallelRecognizer>(std::move(longPressRecognizers));
136 } else {
137 nodeParallelRecognizer_->AddChildren(longPressRecognizers);
138 }
139 innerTargets.emplace_back(nodeParallelRecognizer_);
140 } else {
141 nodeParallelRecognizer_.Reset();
142 }
143
144 std::list<RefPtr<NGGestureRecognizer>> innerRecognizers;
145 for (auto const& eventTarget : innerTargets) {
146 auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(eventTarget);
147 if (recognizer) {
148 auto recognizerGroup = AceType::DynamicCast<RecognizerGroup>(recognizer);
149 if (!recognizerGroup && newIdx >= idx) {
150 recognizer->SetNodeId(host->GetId());
151 recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
152 recognizer->SetTargetComponent(targetComponent);
153 recognizer->SetIsSystemGesture(true);
154 }
155 recognizer->BeginReferee(touchId);
156 innerRecognizers.push_back(std::move(recognizer));
157 } else {
158 eventTarget->SetNodeId(host->GetId());
159 eventTarget->AttachFrameNode(WeakPtr<FrameNode>(host));
160 eventTarget->SetTargetComponent(targetComponent);
161 finalResult.push_back(eventTarget);
162 }
163 newIdx++; // not process previous recognizers
164 }
165
166 ProcessTouchTestHierarchy(coordinateOffset, touchRestrict, innerRecognizers, finalResult, touchId, targetComponent);
167
168 return false;
169 }
170
OnModifyDone()171 void GestureEventHub::OnModifyDone()
172 {
173 if (recreateGesture_) {
174 UpdateGestureHierarchy();
175 recreateGesture_ = false;
176 }
177 }
178
PackInnerRecognizer(const Offset & offset,std::list<RefPtr<NGGestureRecognizer>> & innerRecognizers,int32_t touchId,const RefPtr<TargetComponent> & targetComponent)179 RefPtr<NGGestureRecognizer> GestureEventHub::PackInnerRecognizer(
180 const Offset& offset, std::list<RefPtr<NGGestureRecognizer>>& innerRecognizers, int32_t touchId,
181 const RefPtr<TargetComponent>& targetComponent)
182 {
183 RefPtr<NGGestureRecognizer> current;
184 // Pack inner recognizer include self inner recognizer and children.
185 if (innerRecognizers.size() == 1) {
186 current = *innerRecognizers.begin();
187 } else if (innerRecognizers.size() > 1) {
188 if (!innerExclusiveRecognizer_) {
189 innerExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(innerRecognizers));
190 } else {
191 innerExclusiveRecognizer_->AddChildren(innerRecognizers);
192 }
193 innerExclusiveRecognizer_->SetCoordinateOffset(offset);
194 innerExclusiveRecognizer_->BeginReferee(touchId);
195 auto host = GetFrameNode();
196 innerExclusiveRecognizer_->AttachFrameNode(WeakPtr<FrameNode>(host));
197 innerExclusiveRecognizer_->SetTargetComponent(targetComponent);
198 current = innerExclusiveRecognizer_;
199 }
200
201 return current;
202 }
203
ProcessTouchTestHierarchy(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,std::list<RefPtr<NGGestureRecognizer>> & innerRecognizers,TouchTestResult & finalResult,int32_t touchId,const RefPtr<TargetComponent> & targetComponent)204 void GestureEventHub::ProcessTouchTestHierarchy(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
205 std::list<RefPtr<NGGestureRecognizer>>& innerRecognizers, TouchTestResult& finalResult, int32_t touchId,
206 const RefPtr<TargetComponent>& targetComponent)
207 {
208 auto host = GetFrameNode();
209 if (!host) {
210 for (auto&& recognizer : innerRecognizers) {
211 finalResult.emplace_back(std::move(recognizer));
212 }
213 return;
214 }
215
216 auto offset = Offset(coordinateOffset.GetX(), coordinateOffset.GetY());
217 RefPtr<NGGestureRecognizer> current;
218 current = PackInnerRecognizer(offset, innerRecognizers, touchId, targetComponent);
219 auto eventHub = eventHub_.Upgrade();
220 auto getEventTargetImpl = eventHub ? eventHub->CreateGetEventTargetImpl() : nullptr;
221 auto context = host->GetContext();
222 int32_t parallelIndex = 0;
223 int32_t exclusiveIndex = 0;
224 for (auto const& recognizer : gestureHierarchy_) {
225 if (!recognizer) {
226 continue;
227 }
228 auto recognizerGroup = AceType::DynamicCast<RecognizerGroup>(recognizer);
229 if (recognizerGroup) {
230 recognizerGroup->SetRecognizerInfoRecursively(offset, host, targetComponent, getEventTargetImpl);
231 }
232
233 recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
234 recognizer->SetTargetComponent(targetComponent);
235 recognizer->SetCoordinateOffset(offset);
236 recognizer->BeginReferee(touchId, true);
237 recognizer->SetGetEventTargetImpl(getEventTargetImpl);
238 auto gestureMask = recognizer->GetPriorityMask();
239 if (gestureMask == GestureMask::IgnoreInternal) {
240 // In ignore case, dropped the self inner recognizer and children recognizer.
241 current = recognizer;
242 continue;
243 }
244 auto priority = recognizer->GetPriority();
245 std::list<RefPtr<NGGestureRecognizer>> recognizers { 1, recognizer };
246 if (priority == GesturePriority::Parallel) {
247 if (current) {
248 recognizers.push_front(current);
249 }
250 if (recognizers.size() > 1) {
251 if ((static_cast<int32_t>(externalParallelRecognizer_.size()) <= parallelIndex)) {
252 externalParallelRecognizer_.emplace_back(
253 AceType::MakeRefPtr<ParallelRecognizer>(std::move(recognizers)));
254 } else {
255 externalParallelRecognizer_[parallelIndex]->AddChildren(recognizers);
256 }
257 externalParallelRecognizer_[parallelIndex]->SetCoordinateOffset(offset);
258 externalParallelRecognizer_[parallelIndex]->BeginReferee(touchId);
259 externalParallelRecognizer_[parallelIndex]->AttachFrameNode(WeakPtr<FrameNode>(host));
260 externalParallelRecognizer_[parallelIndex]->SetTargetComponent(targetComponent);
261 current = externalParallelRecognizer_[parallelIndex];
262 parallelIndex++;
263 } else if (recognizers.size() == 1) {
264 current = *recognizers.begin();
265 }
266 } else {
267 if (current) {
268 if (priority == GesturePriority::Low) {
269 recognizers.push_front(current);
270 } else {
271 recognizers.push_back(current);
272 }
273 }
274
275 if (recognizers.size() > 1) {
276 if ((static_cast<int32_t>(externalExclusiveRecognizer_.size()) <= exclusiveIndex)) {
277 externalExclusiveRecognizer_.emplace_back(
278 AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers)));
279 } else {
280 externalExclusiveRecognizer_[exclusiveIndex]->AddChildren(recognizers);
281 }
282 externalExclusiveRecognizer_[exclusiveIndex]->SetCoordinateOffset(offset);
283 externalExclusiveRecognizer_[exclusiveIndex]->BeginReferee(touchId);
284 externalExclusiveRecognizer_[exclusiveIndex]->AttachFrameNode(WeakPtr<FrameNode>(host));
285 externalExclusiveRecognizer_[exclusiveIndex]->SetTargetComponent(targetComponent);
286 current = externalExclusiveRecognizer_[exclusiveIndex];
287 exclusiveIndex++;
288 } else if (recognizers.size() == 1) {
289 current = *recognizers.begin();
290 }
291 }
292 }
293
294 if (current) {
295 finalResult.emplace_back(std::move(current));
296 }
297 }
298
UpdateGestureHierarchy()299 void GestureEventHub::UpdateGestureHierarchy()
300 {
301 auto host = GetFrameNode();
302 CHECK_NULL_VOID(host);
303 bool success = gestures_.size() == gestureHierarchy_.size();
304 if (success) {
305 auto iter = gestures_.begin();
306 auto recognizerIter = gestureHierarchy_.begin();
307 for (; iter != gestures_.end(); iter++, recognizerIter++) {
308 auto newRecognizer = (*iter)->CreateRecognizer();
309 success = success && (*recognizerIter)->ReconcileFrom(newRecognizer);
310 if (!success) {
311 break;
312 }
313 }
314 }
315
316 if (success) {
317 gestures_.clear();
318 return;
319 }
320
321 gestureHierarchy_.clear();
322 for (auto const& gesture : gestures_) {
323 if (!gesture) {
324 continue;
325 }
326 auto recognizer = gesture->CreateRecognizer();
327
328 auto clickRecognizer = AceType::DynamicCast<ClickRecognizer>(recognizer);
329 if (clickRecognizer) {
330 clickRecognizer->SetOnAccessibility(GetOnAccessibilityEventFunc());
331 }
332
333 auto longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(recognizer);
334 if (longPressRecognizer) {
335 longPressRecognizer->SetOnAccessibility(GetOnAccessibilityEventFunc());
336 auto pattern = host->GetPattern();
337 if (pattern && longPressRecognizer->HasAction()) {
338 longPressRecognizer->SetOnLongPressRecorder(pattern->GetLongPressEventRecorder());
339 }
340 }
341
342 if (!recognizer) {
343 continue;
344 }
345 auto priority = gesture->GetPriority();
346 auto gestureMask = gesture->GetGestureMask();
347 recognizer->SetPriority(priority);
348 recognizer->SetPriorityMask(gestureMask);
349 gestureHierarchy_.emplace_back(recognizer);
350 }
351 gestures_.clear();
352 }
353
CombineIntoExclusiveRecognizer(const PointF & globalPoint,const PointF & localPoint,TouchTestResult & result,int32_t touchId)354 void GestureEventHub::CombineIntoExclusiveRecognizer(
355 const PointF& globalPoint, const PointF& localPoint, TouchTestResult& result, int32_t touchId)
356 {
357 TouchTestResult finalResult;
358 std::list<RefPtr<NGGestureRecognizer>> recognizers;
359 const auto coordinateOffset = globalPoint - localPoint;
360 auto offset = Offset(coordinateOffset.GetX(), coordinateOffset.GetY());
361 for (auto const& eventTarget : result) {
362 auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(eventTarget);
363 if (recognizer) {
364 recognizers.push_back(std::move(recognizer));
365 } else {
366 finalResult.push_back(eventTarget);
367 }
368 }
369
370 RefPtr<NGGestureRecognizer> current;
371 if (recognizers.size() == 1) {
372 current = *recognizers.begin();
373 } else if (recognizers.size() > 1) {
374 if (!nodeExclusiveRecognizer_) {
375 nodeExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers));
376 } else {
377 nodeExclusiveRecognizer_->AddChildren(recognizers);
378 }
379 nodeExclusiveRecognizer_->SetCoordinateOffset(offset);
380 nodeExclusiveRecognizer_->BeginReferee(touchId);
381 current = nodeExclusiveRecognizer_;
382 }
383
384 if (current) {
385 finalResult.emplace_back(std::move(current));
386 }
387 result.swap(finalResult);
388 }
389
IsPixelMapNeedScale() const390 bool GestureEventHub::IsPixelMapNeedScale() const
391 {
392 CHECK_NULL_RETURN(pixelMap_, false);
393 auto frameNode = GetFrameNode();
394 CHECK_NULL_RETURN(frameNode, false);
395 auto width = pixelMap_->GetWidth();
396 auto maxWidth = GridSystemManager::GetInstance().GetMaxWidthWithColumnType(GridColumnType::DRAG_PANEL);
397 if (frameNode->GetTag() == V2::WEB_ETS_TAG ||
398 frameNode->GetDragPreviewOption().mode == DragPreviewMode::DISABLE_SCALE || width == 0 || width < maxWidth) {
399 return false;
400 }
401 return true;
402 }
403
InitDragDropEvent()404 void GestureEventHub::InitDragDropEvent()
405 {
406 auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& info) {
407 auto gestureEventHub = weak.Upgrade();
408 CHECK_NULL_VOID(gestureEventHub);
409 gestureEventHub->HandleOnDragStart(info);
410 };
411
412 auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
413 auto gestureEventHub = weak.Upgrade();
414 CHECK_NULL_VOID(gestureEventHub);
415 gestureEventHub->HandleOnDragUpdate(info);
416 };
417
418 auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
419 auto gestureEventHub = weak.Upgrade();
420 CHECK_NULL_VOID(gestureEventHub);
421 gestureEventHub->HandleOnDragEnd(info);
422 };
423
424 auto actionCancelTask = [weak = WeakClaim(this)]() {
425 auto gestureEventHub = weak.Upgrade();
426 CHECK_NULL_VOID(gestureEventHub);
427 gestureEventHub->HandleOnDragCancel();
428 };
429
430 auto dragEvent = MakeRefPtr<DragEvent>(
431 std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
432 SetDragEvent(dragEvent, { PanDirection::ALL }, DEFAULT_PAN_FINGER, DEFAULT_PAN_DISTANCE);
433 }
434
IsAllowedDrag(RefPtr<EventHub> eventHub)435 bool GestureEventHub::IsAllowedDrag(RefPtr<EventHub> eventHub)
436 {
437 auto frameNode = GetFrameNode();
438 CHECK_NULL_RETURN(frameNode, false);
439 auto pattern = frameNode->GetPattern();
440 CHECK_NULL_RETURN(pattern, false);
441
442 if (frameNode->IsDraggable()) {
443 if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
444 return false;
445 }
446 } else {
447 if (frameNode->IsUserSet()) {
448 return false;
449 }
450 if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
451 return false;
452 }
453 }
454 return true;
455 }
456
StartLongPressActionForWeb()457 void GestureEventHub::StartLongPressActionForWeb()
458 {
459 auto pipeline = PipelineContext::GetCurrentContext();
460 CHECK_NULL_VOID(pipeline);
461 auto taskScheduler = pipeline->GetTaskExecutor();
462 CHECK_NULL_VOID(taskScheduler);
463
464 taskScheduler->PostTask(
465 [weak = WeakClaim(this)]() {
466 auto gestureHub = weak.Upgrade();
467 CHECK_NULL_VOID(gestureHub);
468 auto dragEventActuator = gestureHub->dragEventActuator_;
469 CHECK_NULL_VOID(dragEventActuator);
470 dragEventActuator->StartLongPressActionForWeb();
471 },
472 TaskExecutor::TaskType::UI);
473 }
474
CancelDragForWeb()475 void GestureEventHub::CancelDragForWeb()
476 {
477 auto pipeline = PipelineContext::GetCurrentContext();
478 CHECK_NULL_VOID(pipeline);
479 auto taskScheduler = pipeline->GetTaskExecutor();
480 CHECK_NULL_VOID(taskScheduler);
481
482 taskScheduler->PostTask(
483 [weak = WeakClaim(this)]() {
484 auto gestureHub = weak.Upgrade();
485 CHECK_NULL_VOID(gestureHub);
486 auto dragEventActuator = gestureHub->dragEventActuator_;
487 CHECK_NULL_VOID(dragEventActuator);
488 dragEventActuator->CancelDragForWeb();
489 },
490 TaskExecutor::TaskType::UI);
491 }
492
ResetDragActionForWeb()493 void GestureEventHub::ResetDragActionForWeb()
494 {
495 isReceivedDragGestureInfo_ = false;
496 CHECK_NULL_VOID(dragEventActuator_);
497 dragEventActuator_->ResetDragActionForWeb();
498 }
499
StartDragTaskForWeb()500 void GestureEventHub::StartDragTaskForWeb()
501 {
502 if (!isReceivedDragGestureInfo_) {
503 return;
504 }
505
506 isReceivedDragGestureInfo_ = false;
507 auto pipeline = PipelineContext::GetCurrentContext();
508 CHECK_NULL_VOID(pipeline);
509 auto taskScheduler = pipeline->GetTaskExecutor();
510 CHECK_NULL_VOID(taskScheduler);
511
512 taskScheduler->PostTask(
513 [weak = WeakClaim(this)]() {
514 auto gestureHub = weak.Upgrade();
515 CHECK_NULL_VOID(gestureHub);
516 auto dragEventActuator = gestureHub->dragEventActuator_;
517 CHECK_NULL_VOID(dragEventActuator);
518 dragEventActuator->StartDragTaskForWeb(gestureHub->gestureInfoForWeb_);
519 },
520 TaskExecutor::TaskType::UI);
521 }
522
CreatePixelMapFromString(const std::string & filePath)523 RefPtr<PixelMap> CreatePixelMapFromString(const std::string& filePath)
524 {
525 auto imageSource = ImageSource::Create(filePath);
526 CHECK_NULL_RETURN(imageSource, nullptr);
527 RefPtr<PixelMap> pixelMap = imageSource->CreatePixelMap();
528 return pixelMap;
529 }
530
GetPixelMapOffset(const GestureEvent & info,const SizeF & size,const float scale,const bool needScale) const531 OffsetF GestureEventHub::GetPixelMapOffset(
532 const GestureEvent& info, const SizeF& size, const float scale, const bool needScale) const
533 {
534 OffsetF result = OffsetF(size.Width() * PIXELMAP_WIDTH_RATE, size.Height() * PIXELMAP_HEIGHT_RATE);
535 auto frameNode = GetFrameNode();
536 CHECK_NULL_RETURN(frameNode, result);
537 auto frameTag = frameNode->GetTag();
538 if (frameTag == V2::WEB_ETS_TAG) {
539 result.SetX(size.Width() * PIXELMAP_WIDTH_RATE);
540 result.SetY(size.Height() * PIXELMAP_HEIGHT_RATE);
541 } else if (needScale) {
542 result.SetX(size.Width() * PIXELMAP_WIDTH_RATE);
543 result.SetY(PIXELMAP_DRAG_DEFAULT_HEIGHT);
544 } else {
545 auto coordinateX = frameNodeOffset_.GetX() > SystemProperties::GetDevicePhysicalWidth()
546 ? frameNodeOffset_.GetX() - SystemProperties::GetDevicePhysicalWidth()
547 : frameNodeOffset_.GetX();
548 auto coordinateY = frameNodeOffset_.GetY();
549 auto differentScale = (NearZero(frameNodeSize_.Width()) || NearZero(size.Width()))
550 ? 1.0f
551 : frameNodeSize_.Width() * DEFALUT_DRAG_PPIXELMAP_SCALE / size.Width();
552 result.SetX(scale * (coordinateX - info.GetGlobalLocation().GetX()) / differentScale);
553 result.SetY(scale * (coordinateY - info.GetGlobalLocation().GetY()) / differentScale);
554 }
555 if (result.GetX() >= 0.0f) {
556 result.SetX(-1.0f);
557 }
558 if (result.GetX() + size.Width() <= 0.0f) {
559 result.SetX(1.0f - size.Width());
560 }
561 if (result.GetY() >= 0.0f) {
562 result.SetY(-1.0f);
563 }
564 if (result.GetY() + size.Height() <= 0.0f) {
565 result.SetY(1.0f - size.Height());
566 }
567 TAG_LOGD(AceLogTag::ACE_DRAG, "Get pixelMap offset is %{public}f and %{public}f.",
568 result.GetX(), result.GetY());
569 return result;
570 }
571
GetPixelMapScale(const int32_t height,const int32_t width) const572 float GestureEventHub::GetPixelMapScale(const int32_t height, const int32_t width) const
573 {
574 float scale = 1.0f;
575 if (height == 0 || width == 0) {
576 return scale;
577 }
578 auto frameNode = GetFrameNode();
579 CHECK_NULL_RETURN(frameNode, scale);
580 auto pipeline = PipelineContext::GetCurrentContext();
581 CHECK_NULL_RETURN(pipeline, scale);
582 auto dragDropManager = pipeline->GetDragDropManager();
583 CHECK_NULL_RETURN(dragDropManager, scale);
584 auto windowScale = dragDropManager->GetWindowScale();
585 if (frameNode->GetDragPreviewOption().mode == DragPreviewMode::DISABLE_SCALE ||
586 !(frameNode->GetTag() == V2::WEB_ETS_TAG)) {
587 return scale * windowScale;
588 }
589 int32_t deviceHeight = SystemProperties::GetDevicePhysicalHeight();
590 int32_t deviceWidth = SystemProperties::GetDevicePhysicalWidth();
591 int32_t maxDeviceLength = std::max(deviceHeight, deviceWidth);
592 int32_t minDeviceLength = std::min(deviceHeight, deviceWidth);
593 if (maxDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE > minDeviceLength) {
594 if (height > minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) {
595 scale = static_cast<float>(minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) / height;
596 }
597 } else {
598 if (GetTextDraggable() && height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
599 width > minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) {
600 scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
601 static_cast<float>(minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) / width);
602 } else if (height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
603 width > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) {
604 scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
605 static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / width);
606 }
607 }
608 return scale * windowScale;
609 }
610
GenerateMousePixelMap(const GestureEvent & info)611 void GestureEventHub::GenerateMousePixelMap(const GestureEvent& info)
612 {
613 auto frameNode = GetFrameNode();
614 CHECK_NULL_VOID(frameNode);
615 RefPtr<RenderContext> context;
616 if (GetTextDraggable()) {
617 auto pattern = frameNode->GetPattern<TextDragBase>();
618 CHECK_NULL_VOID(pattern);
619 auto dragNode = pattern->MoveDragNode();
620 CHECK_NULL_VOID(dragNode);
621 auto pipeline = PipelineContext::GetCurrentContext();
622 CHECK_NULL_VOID(pipeline);
623 pipeline->FlushPipelineImmediately();
624 context = dragNode->GetRenderContext();
625 } else {
626 context = frameNode->GetRenderContext();
627 }
628 CHECK_NULL_VOID(context);
629 auto thumbnailPixelMap = context->GetThumbnailPixelMap();
630 CHECK_NULL_VOID(thumbnailPixelMap);
631 SetPixelMap(thumbnailPixelMap);
632 }
633
HandleNotallowDrag(const GestureEvent & info)634 void GestureEventHub::HandleNotallowDrag(const GestureEvent& info)
635 {
636 auto frameNode = GetFrameNode();
637 CHECK_NULL_VOID(frameNode);
638 if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
639 gestureInfoForWeb_ = info;
640 isReceivedDragGestureInfo_ = true;
641 }
642 }
643
HandleOnDragStart(const GestureEvent & info)644 void GestureEventHub::HandleOnDragStart(const GestureEvent& info)
645 {
646 TAG_LOGD(AceLogTag::ACE_DRAG, "Start handle onDragStart.");
647 auto eventHub = eventHub_.Upgrade();
648 CHECK_NULL_VOID(eventHub);
649 if (!eventHub->HasOnDragStart()) {
650 TAG_LOGI(AceLogTag::ACE_DRAG, "FrameNode is not set onDragStart event.");
651 return;
652 }
653
654 auto frameNode = GetFrameNode();
655 CHECK_NULL_VOID(frameNode);
656 auto pattern = frameNode->GetPattern();
657 CHECK_NULL_VOID(pattern);
658 if (!IsAllowedDrag(eventHub)) {
659 TAG_LOGI(AceLogTag::ACE_DRAG, "FrameNode is not allow drag, tag is %{public}s, id is %{public}s,"
660 "draggable is %{public}d, drag start event is %{public}d,"
661 "default support drag is %{public}d, user set is %{public}d.",
662 frameNode->GetTag().c_str(), frameNode->GetInspectorId()->c_str(),
663 frameNode->IsDraggable(), eventHub->HasOnDragStart(),
664 pattern->DefaultSupportDrag(), frameNode->IsUserSet());
665 HandleNotallowDrag(info);
666 return;
667 }
668 auto pipeline = PipelineContext::GetCurrentContext();
669 CHECK_NULL_VOID(pipeline);
670 auto eventManager = pipeline->GetEventManager();
671 CHECK_NULL_VOID(eventManager);
672 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && eventManager->IsLastMoveBeforeUp()) {
673 TAG_LOGD(AceLogTag::ACE_DRAG, "Drag stop because user release mouse button");
674 return;
675 }
676 RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
677 if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
678 event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
679 event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
680 } else {
681 event->SetX(info.GetGlobalPoint().GetX());
682 event->SetY(info.GetGlobalPoint().GetY());
683 }
684 event->SetScreenX(info.GetScreenLocation().GetX());
685 event->SetScreenY(info.GetScreenLocation().GetY());
686
687 auto frameTag = frameNode->GetTag();
688 auto hostPattern = frameNode->GetPattern<TextDragBase>();
689 if (hostPattern && GetTextDraggable() && (frameTag == V2::RICH_EDITOR_ETS_TAG || frameTag == V2::TEXT_ETS_TAG ||
690 frameTag == V2::TEXTINPUT_ETS_TAG || frameTag == V2::SEARCH_Field_ETS_TAG)) {
691 frameNodeOffset_ = hostPattern->GetDragUpperLeftCoordinates();
692 frameNodeSize_ = SizeF(0.0f, 0.0f);
693 } else {
694 auto geometryNode = frameNode->GetGeometryNode();
695 if (geometryNode) {
696 frameNodeSize_ = geometryNode->GetFrameSize();
697 } else {
698 frameNodeSize_ = SizeF(0.0f, 0.0f);
699 }
700 auto rectCenter = frameNode->GetPaintRectCenter();
701 frameNodeOffset_ = OffsetF(rectCenter.GetX() - frameNodeSize_.Width() / 2.0f,
702 rectCenter.GetY() - frameNodeSize_.Height() / 2.0f);
703 }
704 /*
705 * Users may remove frameNode in the js callback function "onDragStart "triggered below,
706 * so save the offset of the framenode relative to the window in advance
707 */
708 auto extraParams = eventHub->GetDragExtraParams(std::string(), info.GetGlobalPoint(), DragEventType::START);
709 auto dragDropInfo = (eventHub->GetOnDragStart())(event, extraParams);
710 auto dragPreviewInfo = frameNode->GetDragPreview();
711 auto dragDropManager = pipeline->GetDragDropManager();
712 CHECK_NULL_VOID(dragDropManager);
713 dragDropManager->SetDraggingPointer(info.GetPointerId());
714 dragDropManager->SetDraggingPressedState(true);
715 if (info.GetSourceDevice() != SourceType::MOUSE) {
716 if (dragPreviewInfo.pixelMap != nullptr || dragPreviewInfo.customNode != nullptr) {
717 if (dragPreviewPixelMap_ != nullptr) {
718 dragDropInfo.pixelMap = dragPreviewPixelMap_;
719 OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
720 return;
721 }
722 }
723 }
724
725 if (dragPreviewInfo.pixelMap != nullptr) {
726 dragDropInfo.pixelMap = dragPreviewInfo.pixelMap;
727 OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
728 return;
729 } else if (dragPreviewInfo.customNode != nullptr) {
730 dragDropInfo.customNode = dragPreviewInfo.customNode;
731 }
732 #if defined(PIXEL_MAP_SUPPORTED) && !defined(CROSS_PLATFORM)
733 if (dragDropInfo.pixelMap == nullptr && dragDropInfo.customNode) {
734 auto callback = [id = Container::CurrentId(), pipeline, info, gestureEventHubPtr = AceType::Claim(this),
735 frameNode, dragDropInfo, event](
736 std::shared_ptr<Media::PixelMap> pixelMap, int32_t arg, std::function<void()>) mutable {
737 ContainerScope scope(id);
738 if (pixelMap != nullptr) {
739 dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
740 }
741 auto taskScheduler = pipeline->GetTaskExecutor();
742 CHECK_NULL_VOID(taskScheduler);
743 taskScheduler->PostTask(
744 [pipeline, info, gestureEventHubPtr, frameNode, dragDropInfo, event]() {
745 CHECK_NULL_VOID(gestureEventHubPtr);
746 CHECK_NULL_VOID(frameNode);
747 gestureEventHubPtr->OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
748 },
749 TaskExecutor::TaskType::UI);
750 };
751 NG::ComponentSnapshot::Create(dragDropInfo.customNode, std::move(callback), false, CREATE_PIXELMAP_TIME);
752 return;
753 }
754 #endif
755 OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
756 }
757
OnDragStart(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> frameNode,const DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)758 void GestureEventHub::OnDragStart(const GestureEvent& info, const RefPtr<PipelineBase>& context,
759 const RefPtr<FrameNode> frameNode, const DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
760 {
761 auto eventHub = eventHub_.Upgrade();
762 CHECK_NULL_VOID(eventHub);
763 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
764 CHECK_NULL_VOID(pipeline);
765
766 auto dragDropManager = pipeline->GetDragDropManager();
767 CHECK_NULL_VOID(dragDropManager);
768 if (dragDropProxy_) {
769 dragDropProxy_ = nullptr;
770 }
771 CHECK_NULL_VOID(dragEvent);
772 auto eventRet = dragEvent->GetResult();
773 if (eventRet == DragRet::DRAG_FAIL || eventRet == DragRet::DRAG_CANCEL) {
774 return;
775 }
776 if (GetTextDraggable() && !GetIsTextDraggable()) {
777 TAG_LOGI(AceLogTag::ACE_DRAG, "Start drag, forbidden drag");
778 return;
779 }
780 std::string udKey;
781 int32_t recordsSize = 1;
782 auto unifiedData = dragEvent->GetData();
783 CHECK_NULL_VOID(frameNode);
784 auto pattern = frameNode->GetPattern();
785 CHECK_NULL_VOID(pattern);
786 pattern->ResetDragOption();
787 if (pattern->GetDragRecordSize() >= 0) {
788 recordsSize = pattern->GetDragRecordSize();
789 } else if (unifiedData) {
790 auto recordSize = unifiedData->GetSize();
791 recordsSize = recordSize > 1 ? recordSize : 1;
792 }
793 auto ret = SetDragData(unifiedData, udKey);
794 if (ret != 0) {
795 TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF set data failed, return value is %{public}d", ret);
796 }
797
798 std::map<std::string, int64_t> summary;
799 ret = UdmfClient::GetInstance()->GetSummary(udKey, summary);
800 dragDropManager->SetSummaryMap(summary);
801 RefPtr<PixelMap> pixelMap;
802 if (dragDropInfo.pixelMap != nullptr) {
803 pixelMap = dragDropInfo.pixelMap;
804 SetPixelMap(dragDropInfo.pixelMap);
805 } else if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
806 dragDropManager->SetIsMouseDrag(true);
807 pixelMap = CreatePixelMapFromString(DEFAULT_MOUSE_DRAG_IMAGE);
808 CHECK_NULL_VOID(pixelMap);
809 auto taskScheduler = pipeline->GetTaskExecutor();
810 CHECK_NULL_VOID(taskScheduler);
811 GenerateMousePixelMap(info);
812 if (pixelMap_) {
813 pixelMap = pixelMap_;
814 }
815 } else {
816 CHECK_NULL_VOID(pixelMap_);
817 if (pixelMap == nullptr) {
818 pixelMap = pixelMap_;
819 }
820 }
821 float defaultPixelMapScale =
822 info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
823 float scale = GetPixelMapScale(pixelMap->GetHeight(), pixelMap->GetWidth()) * defaultPixelMapScale;
824 auto overlayManager = pipeline->GetOverlayManager();
825 if (IsPixelMapNeedScale()) {
826 RefPtr<FrameNode> imageNode = overlayManager->GetPixelMapContentNode();
827 DragEventActuator::CreatePreviewNode(frameNode, imageNode);
828 CHECK_NULL_VOID(imageNode);
829 scale = static_cast<float>(imageNode->GetPreviewScaleVal());
830 auto window = SubwindowManager::GetInstance()->ShowPreviewNG();
831 if (window) {
832 overlayManager = window->GetOverlayManager();
833 CHECK_NULL_VOID(overlayManager);
834 DragEventActuator::MountPixelMap(overlayManager, eventHub->GetGestureEventHub(), imageNode);
835 dragDropManager->DoDragStartAnimation(overlayManager, info);
836 if (pixelMap_ != nullptr) {
837 pixelMap = pixelMap_;
838 }
839 }
840 }
841 if (!overlayManager->GetIsOnAnimation()) {
842 if (dragEventActuator_ != nullptr) {
843 dragEventActuator_->SetIsNotInPreviewState(true);
844 }
845 }
846 TAG_LOGI(AceLogTag::ACE_DRAG, "Start drag, animation is %{public}d, pixelMap scale is %{public}f",
847 overlayManager->GetIsOnAnimation(), scale);
848 pixelMap->Scale(scale, scale, AceAntiAliasingOption::HIGH);
849 auto width = pixelMap->GetWidth();
850 auto height = pixelMap->GetHeight();
851 auto pixelMapOffset = GetPixelMapOffset(info, SizeF(width, height), scale, !NearEqual(scale, defaultPixelMapScale));
852 auto extraInfoLimited = dragDropInfo.extraInfo.size() > EXTRA_INFO_MAX_LENGTH
853 ? dragDropInfo.extraInfo.substr(EXTRA_INFO_MAX_LENGTH + 1)
854 : dragDropInfo.extraInfo;
855 auto arkExtraInfoJson = JsonUtil::Create(true);
856 auto dipScale = pipeline->GetDipScale();
857 arkExtraInfoJson->Put("dip_scale", dipScale);
858 ShadowInfoCore shadowInfo { pixelMap, pixelMapOffset.GetX(), pixelMapOffset.GetY() };
859 DragDataCore dragData { { shadowInfo }, {}, udKey, extraInfoLimited, arkExtraInfoJson->ToString(),
860 static_cast<int32_t>(info.GetSourceDevice()), recordsSize, info.GetPointerId(), info.GetScreenLocation().GetX(),
861 info.GetScreenLocation().GetY(), info.GetTargetDisplayId(), true, false, summary };
862 ret = InteractionInterface::GetInstance()->StartDrag(dragData, GetDragCallback(pipeline, eventHub));
863 if (ret != 0) {
864 if (dragDropManager->IsNeedScaleDragPreview()) {
865 SubwindowManager::GetInstance()->HidePreviewNG();
866 overlayManager->RemovePixelMap();
867 }
868 TAG_LOGW(AceLogTag::ACE_DRAG, "Start drag failed, return value is %{public}d", ret);
869 return;
870 }
871 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && IsPixelMapNeedScale()) {
872 ret = RegisterCoordinationListener(pipeline);
873 if (ret != 0) {
874 TAG_LOGW(AceLogTag::ACE_DRAG, "Register coordination listener failed, error is %{public}d", ret);
875 }
876 }
877 dragDropManager->UpdateDragStyle();
878 dragDropManager->SetPreviewRect(Rect(pixelMapOffset.GetX(), pixelMapOffset.GetY(), width, height));
879 dragDropManager->ResetRecordSize(static_cast<uint32_t>(recordsSize));
880 auto eventManager = pipeline->GetEventManager();
881 CHECK_NULL_VOID(eventManager);
882 eventManager->DoMouseActionRelease();
883 eventManager->SetIsDragging(true);
884 if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && dragEventActuator_ != nullptr &&
885 dragEventActuator_->GetIsNotInPreviewState()) {
886 if (!dragDropManager->IsNeedScaleDragPreview()) {
887 overlayManager->RemovePixelMap();
888 pipeline->AddAfterRenderTask([]() { InteractionInterface::GetInstance()->SetDragWindowVisible(true); });
889 }
890 } else if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
891 if (!dragDropManager->IsNeedScaleDragPreview()) {
892 pipeline->AddDragWindowVisibleTask([]() {
893 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
894 });
895 }
896 dragDropManager->SetIsDragWindowShow(true);
897 }
898 dragDropManager->FireOnEditableTextComponent(frameNode, DragEventType::ENTER);
899 dragDropProxy_ = dragDropManager->CreateFrameworkDragDropProxy();
900 CHECK_NULL_VOID(dragDropProxy_);
901 dragDropProxy_->OnDragStart(info, extraInfoLimited, GetFrameNode());
902 if (!dragDropManager->IsDraggingPressed(info.GetPointerId())) {
903 dragDropManager->OnDragEnd(
904 PointerEvent(info.GetGlobalPoint().GetX(), info.GetGlobalPoint().GetY()), extraInfoLimited);
905 }
906 }
907
RegisterCoordinationListener(const RefPtr<PipelineBase> & context)908 int32_t GestureEventHub::RegisterCoordinationListener(const RefPtr<PipelineBase>& context)
909 {
910 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
911 CHECK_NULL_RETURN(pipeline, -1);
912 auto callback = [id = Container::CurrentId(), weak = WeakClaim(RawPtr(pipeline))]() {
913 ContainerScope scope(id);
914 auto context = weak.Upgrade();
915 CHECK_NULL_VOID(context);
916 auto dragDropManager = context->GetDragDropManager();
917 CHECK_NULL_VOID(dragDropManager);
918 auto taskScheduler = context->GetTaskExecutor();
919 CHECK_NULL_VOID(taskScheduler);
920 taskScheduler->PostTask([dragDropManager]() {
921 dragDropManager->HideDragPreviewOverlay();
922 }, TaskExecutor::TaskType::UI);
923 };
924 return InteractionInterface::GetInstance()->RegisterCoordinationListener(callback);
925 }
926
HandleOnDragUpdate(const GestureEvent & info)927 void GestureEventHub::HandleOnDragUpdate(const GestureEvent& info)
928 {
929 gestureInfoForWeb_ = info;
930 CHECK_NULL_VOID(dragDropProxy_);
931 auto pipeline = PipelineContext::GetCurrentContext();
932 CHECK_NULL_VOID(pipeline);
933 auto dragDropManager = pipeline->GetDragDropManager();
934 if (dragDropManager->IsDragged()) {
935 dragDropProxy_->OnDragMove(info);
936 }
937 }
938
HandleOnDragEnd(const GestureEvent & info)939 void GestureEventHub::HandleOnDragEnd(const GestureEvent& info)
940 {
941 auto pipeline = NG::PipelineContext::GetCurrentContext();
942 const static int32_t PLATFORM_VERSION_TEN = 10;
943 if (pipeline && (pipeline->GetMinPlatformVersion() < PLATFORM_VERSION_TEN)) {
944 auto eventHub = eventHub_.Upgrade();
945 CHECK_NULL_VOID(eventHub);
946
947 auto frameNode = GetFrameNode();
948 CHECK_NULL_VOID(frameNode);
949
950 // Only the onDrop callback of dragged frame node is triggered.
951 // The onDrop callback of target frame node is triggered in PipelineContext::OnDragEvent.
952 if (eventHub->HasOnDrop() || eventHub->HasCustomerOnDrop()) {
953 RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
954 if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
955 event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
956 event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
957 } else {
958 event->SetX(info.GetGlobalPoint().GetX());
959 event->SetY(info.GetGlobalPoint().GetY());
960 }
961 event->SetScreenX(info.GetScreenLocation().GetX());
962 event->SetScreenY(info.GetScreenLocation().GetY());
963 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event);
964 eventHub->HandleInternalOnDrop(event, "");
965 }
966 }
967 CHECK_NULL_VOID(dragDropProxy_);
968 dragDropProxy_->DestroyDragWindow();
969 dragDropProxy_ = nullptr;
970 }
971
HandleOnDragCancel()972 void GestureEventHub::HandleOnDragCancel()
973 {
974 CHECK_NULL_VOID(dragDropProxy_);
975 dragDropProxy_->DestroyDragWindow();
976 dragDropProxy_ = nullptr;
977 }
978
SetFocusClickEvent(GestureEventFunc && clickEvent)979 void GestureEventHub::SetFocusClickEvent(GestureEventFunc&& clickEvent)
980 {
981 auto eventHub = eventHub_.Upgrade();
982 CHECK_NULL_VOID(eventHub);
983 auto focusHub = eventHub->GetFocusHub();
984 CHECK_NULL_VOID(focusHub);
985 focusHub->SetOnClickCallback(std::move(clickEvent));
986 }
987
988 // helper function to ensure clickActuator is initialized
CheckClickActuator()989 void GestureEventHub::CheckClickActuator()
990 {
991 if (!clickEventActuator_) {
992 clickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
993 clickEventActuator_->SetOnAccessibility(GetOnAccessibilityEventFunc());
994 }
995
996 if (parallelCombineClick && !userParallelClickEventActuator_) {
997 userParallelClickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
998 userParallelClickEventActuator_->SetOnAccessibility(GetOnAccessibilityEventFunc());
999 }
1000 }
1001
SetUserOnClick(GestureEventFunc && clickEvent)1002 void GestureEventHub::SetUserOnClick(GestureEventFunc&& clickEvent)
1003 {
1004 CheckClickActuator();
1005 if (parallelCombineClick) {
1006 userParallelClickEventActuator_->SetUserCallback(std::move(clickEvent));
1007 SetFocusClickEvent(userParallelClickEventActuator_->GetClickEvent());
1008 } else {
1009 clickEventActuator_->SetUserCallback(std::move(clickEvent));
1010 SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1011 }
1012 }
1013
SetOnGestureJudgeBegin(GestureJudgeFunc && gestureJudgeFunc)1014 void GestureEventHub::SetOnGestureJudgeBegin(GestureJudgeFunc&& gestureJudgeFunc)
1015 {
1016 gestureJudgeFunc_ = std::move(gestureJudgeFunc);
1017 }
1018
SetOnGestureJudgeNativeBegin(GestureJudgeFunc && gestureJudgeFunc)1019 void GestureEventHub::SetOnGestureJudgeNativeBegin(GestureJudgeFunc&& gestureJudgeFunc)
1020 {
1021 gestureJudgeNativeFunc_ = std::move(gestureJudgeFunc);
1022 }
1023
AddClickEvent(const RefPtr<ClickEvent> & clickEvent)1024 void GestureEventHub::AddClickEvent(const RefPtr<ClickEvent>& clickEvent)
1025 {
1026 CheckClickActuator();
1027 clickEventActuator_->AddClickEvent(clickEvent);
1028
1029 SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1030 }
1031
1032 // replace last showMenu callback
BindMenu(GestureEventFunc && showMenu)1033 void GestureEventHub::BindMenu(GestureEventFunc&& showMenu)
1034 {
1035 if (showMenu_) {
1036 RemoveClickEvent(showMenu_);
1037 }
1038 showMenu_ = MakeRefPtr<ClickEvent>(std::move(showMenu));
1039 AddClickEvent(showMenu_);
1040 }
1041
GetOnAccessibilityEventFunc()1042 OnAccessibilityEventFunc GestureEventHub::GetOnAccessibilityEventFunc()
1043 {
1044 auto callback = [weak = WeakClaim(this)](AccessibilityEventType eventType) {
1045 auto gestureHub = weak.Upgrade();
1046 CHECK_NULL_VOID(gestureHub);
1047 auto node = gestureHub->GetFrameNode();
1048 CHECK_NULL_VOID(node);
1049 node->OnAccessibilityEvent(eventType);
1050 };
1051 return callback;
1052 }
1053
ActClick(std::shared_ptr<JsonValue> secComphandle)1054 bool GestureEventHub::ActClick(std::shared_ptr<JsonValue> secComphandle)
1055 {
1056 auto host = GetFrameNode();
1057 CHECK_NULL_RETURN(host, false);
1058 GestureEventFunc click;
1059 GestureEvent info;
1060 std::chrono::microseconds microseconds(GetMicroTickCount());
1061 TimeStamp time(microseconds);
1062 info.SetTimeStamp(time);
1063 EventTarget clickEventTarget;
1064 clickEventTarget.id = host->GetId();
1065 clickEventTarget.type = host->GetTag();
1066 #ifdef SECURITY_COMPONENT_ENABLE
1067 info.SetSecCompHandleEvent(secComphandle);
1068 #endif
1069 auto geometryNode = host->GetGeometryNode();
1070 CHECK_NULL_RETURN(geometryNode, false);
1071 auto offset = geometryNode->GetFrameOffset();
1072 auto size = geometryNode->GetFrameSize();
1073 clickEventTarget.area.SetOffset(DimensionOffset(offset));
1074 clickEventTarget.area.SetHeight(Dimension(size.Height()));
1075 clickEventTarget.area.SetWidth(Dimension(size.Width()));
1076 clickEventTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1077 info.SetTarget(clickEventTarget);
1078 Offset globalOffset(offset.GetX(), offset.GetY());
1079 info.SetGlobalLocation(globalOffset);
1080 if (clickEventActuator_) {
1081 click = clickEventActuator_->GetClickEvent();
1082 CHECK_NULL_RETURN(click, true);
1083 click(info);
1084 return true;
1085 }
1086 RefPtr<ClickRecognizer> clickRecognizer;
1087 for (auto gestureRecognizer : gestureHierarchy_) {
1088 clickRecognizer = AceType::DynamicCast<ClickRecognizer>(gestureRecognizer);
1089 if (clickRecognizer && clickRecognizer->GetFingers() == 1 && clickRecognizer->GetCount() == 1) {
1090 click = clickRecognizer->GetTapActionFunc();
1091 click(info);
1092 host->OnAccessibilityEvent(AccessibilityEventType::CLICK);
1093 return true;
1094 }
1095 }
1096 return false;
1097 }
1098
ActLongClick()1099 bool GestureEventHub::ActLongClick()
1100 {
1101 auto host = GetFrameNode();
1102 CHECK_NULL_RETURN(host, false);
1103 GestureEventFunc click;
1104 GestureEvent info;
1105 std::chrono::microseconds microseconds(GetMicroTickCount());
1106 TimeStamp time(microseconds);
1107 info.SetTimeStamp(time);
1108 EventTarget longPressTarget;
1109 longPressTarget.id = host->GetId();
1110 longPressTarget.type = host->GetTag();
1111 auto geometryNode = host->GetGeometryNode();
1112 CHECK_NULL_RETURN(geometryNode, false);
1113 auto offset = geometryNode->GetFrameOffset();
1114 auto size = geometryNode->GetFrameSize();
1115 longPressTarget.area.SetOffset(DimensionOffset(offset));
1116 longPressTarget.area.SetHeight(Dimension(size.Height()));
1117 longPressTarget.area.SetWidth(Dimension(size.Width()));
1118 longPressTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1119 info.SetTarget(longPressTarget);
1120 Offset globalOffset(offset.GetX(), offset.GetY());
1121 info.SetGlobalLocation(globalOffset);
1122 if (longPressEventActuator_) {
1123 click = longPressEventActuator_->GetGestureEventFunc();
1124 CHECK_NULL_RETURN(click, true);
1125 click(info);
1126 return true;
1127 }
1128 RefPtr<LongPressRecognizer> longPressRecognizer;
1129 for (auto gestureRecognizer : gestureHierarchy_) {
1130 longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(gestureRecognizer);
1131 if (longPressRecognizer && longPressRecognizer->GetFingers() == 1) {
1132 click = longPressRecognizer->GetLongPressActionFunc();
1133 click(info);
1134 host->OnAccessibilityEvent(AccessibilityEventType::LONG_PRESS);
1135 return true;
1136 }
1137 }
1138 return false;
1139 }
1140
GetHitTestModeStr() const1141 std::string GestureEventHub::GetHitTestModeStr() const
1142 {
1143 auto mode = static_cast<int32_t>(hitTestMode_);
1144 if (mode < 0 || mode >= static_cast<int32_t>(std::size(HIT_TEST_MODE))) {
1145 return HIT_TEST_MODE[0];
1146 }
1147 return HIT_TEST_MODE[mode];
1148 }
1149
KeyBoardShortCutClick(const KeyEvent & event,const WeakPtr<NG::FrameNode> & node)1150 bool GestureEventHub::KeyBoardShortCutClick(const KeyEvent& event, const WeakPtr<NG::FrameNode>& node)
1151 {
1152 auto host = node.Upgrade();
1153 CHECK_NULL_RETURN(host, false);
1154 CHECK_NULL_RETURN(clickEventActuator_, false);
1155 auto click = clickEventActuator_->GetClickEvent();
1156 CHECK_NULL_RETURN(click, false);
1157 GestureEvent info;
1158 info.SetSourceDevice(event.sourceType);
1159 info.SetTimeStamp(event.timeStamp);
1160 EventTarget target;
1161 target.id = host->GetId();
1162 target.type = host->GetTag();
1163 auto geometryNode = host->GetGeometryNode();
1164 CHECK_NULL_RETURN(geometryNode, false);
1165 auto offset = geometryNode->GetFrameOffset();
1166 auto size = geometryNode->GetFrameSize();
1167 target.area.SetOffset(DimensionOffset(offset));
1168 target.area.SetHeight(Dimension(size.Height()));
1169 target.area.SetWidth(Dimension(size.Width()));
1170 target.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1171 info.SetTarget(target);
1172 click(info);
1173 return true;
1174 }
1175
SetDragData(const RefPtr<UnifiedData> & unifiedData,std::string & udKey)1176 int32_t GestureEventHub::SetDragData(const RefPtr<UnifiedData>& unifiedData, std::string& udKey)
1177 {
1178 CHECK_NULL_RETURN(unifiedData, -1);
1179 return UdmfClient::GetInstance()->SetData(unifiedData, udKey);
1180 }
1181
GetDragCallback(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)1182 OnDragCallbackCore GestureEventHub::GetDragCallback(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
1183 {
1184 auto ret = [](const DragNotifyMsgCore& notifyMessage) {};
1185 auto eventHub = hub.Upgrade();
1186 CHECK_NULL_RETURN(eventHub, ret);
1187 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1188 CHECK_NULL_RETURN(pipeline, ret);
1189 auto taskScheduler = pipeline->GetTaskExecutor();
1190 CHECK_NULL_RETURN(taskScheduler, ret);
1191 auto dragDropManager = pipeline->GetDragDropManager();
1192 CHECK_NULL_RETURN(dragDropManager, ret);
1193 auto eventManager = pipeline->GetEventManager();
1194 RefPtr<OHOS::Ace::DragEvent> dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1195 auto callback = [id = Container::CurrentId(), eventHub, dragEvent, taskScheduler, dragDropManager, eventManager](
1196 const DragNotifyMsgCore& notifyMessage) {
1197 ContainerScope scope(id);
1198 taskScheduler->PostTask(
1199 [eventHub, dragEvent, dragDropManager, eventManager, notifyMessage]() {
1200 dragDropManager->SetDragResult(notifyMessage, dragEvent);
1201 dragDropManager->SetIsDragged(false);
1202 dragDropManager->ResetDragging();
1203 dragDropManager->SetDraggingPointer(-1);
1204 dragDropManager->SetDraggingPressedState(false);
1205 dragDropManager->ResetDragPreviewInfo();
1206 auto ret = InteractionInterface::GetInstance()->UnRegisterCoordinationListener();
1207 if (ret != 0) {
1208 TAG_LOGW(AceLogTag::ACE_DRAG, "Unregister coordination listener failed, error is %{public}d", ret);
1209 }
1210 if (eventManager) {
1211 eventManager->DoMouseActionRelease();
1212 }
1213 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
1214 if (eventHub->HasOnDragEnd()) {
1215 (eventHub->GetOnDragEnd())(dragEvent);
1216 }
1217 },
1218 TaskExecutor::TaskType::UI);
1219 };
1220 return callback;
1221 }
1222
IsAccessibilityClickable()1223 bool GestureEventHub::IsAccessibilityClickable()
1224 {
1225 bool ret = IsClickable();
1226 RefPtr<ClickRecognizer> clickRecognizer;
1227 for (auto gestureRecognizer : gestureHierarchy_) {
1228 clickRecognizer = AceType::DynamicCast<ClickRecognizer>(gestureRecognizer);
1229 if (clickRecognizer && clickRecognizer->GetFingers() == 1 && clickRecognizer->GetCount() == 1) {
1230 return true;
1231 }
1232 }
1233 return ret;
1234 }
1235
IsAccessibilityLongClickable()1236 bool GestureEventHub::IsAccessibilityLongClickable()
1237 {
1238 bool ret = IsLongClickable();
1239 RefPtr<LongPressRecognizer> longPressRecognizer;
1240 for (auto gestureRecognizer : gestureHierarchy_) {
1241 longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(gestureRecognizer);
1242 if (longPressRecognizer && longPressRecognizer->GetFingers() == 1) {
1243 return true;
1244 }
1245 }
1246 return ret;
1247 }
1248
GetMonopolizeEvents() const1249 bool GestureEventHub::GetMonopolizeEvents() const
1250 {
1251 return monopolizeEvents_;
1252 }
1253
SetMonopolizeEvents(bool monopolizeEvents)1254 void GestureEventHub::SetMonopolizeEvents(bool monopolizeEvents)
1255 {
1256 monopolizeEvents_ = monopolizeEvents;
1257 }
1258
ClearUserOnClick()1259 void GestureEventHub::ClearUserOnClick()
1260 {
1261 if (clickEventActuator_) {
1262 clickEventActuator_->ClearUserCallback();
1263 }
1264 }
1265
ClearUserOnTouch()1266 void GestureEventHub::ClearUserOnTouch()
1267 {
1268 if (touchEventActuator_) {
1269 touchEventActuator_->ClearUserCallback();
1270 }
1271 }
1272
CopyGestures(const RefPtr<GestureEventHub> & gestureEventHub)1273 void GestureEventHub::CopyGestures(const RefPtr<GestureEventHub>& gestureEventHub)
1274 {
1275 CHECK_NULL_VOID(gestureEventHub);
1276 gestures_ = gestureEventHub->backupGestures_;
1277 recreateGesture_ = true;
1278 }
1279
CopyEvent(const RefPtr<GestureEventHub> & gestureEventHub)1280 void GestureEventHub::CopyEvent(const RefPtr<GestureEventHub>& gestureEventHub)
1281 {
1282 CHECK_NULL_VOID(gestureEventHub);
1283 auto originalTouchEventActuator = gestureEventHub->touchEventActuator_;
1284 if (originalTouchEventActuator) {
1285 touchEventActuator_ = MakeRefPtr<TouchEventActuator>();
1286 touchEventActuator_->CopyTouchEvent(originalTouchEventActuator);
1287 }
1288
1289 auto originalClickEventActuator = gestureEventHub->clickEventActuator_;
1290 if (originalClickEventActuator) {
1291 clickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
1292 clickEventActuator_->CopyClickEvent(originalClickEventActuator);
1293 }
1294
1295 auto originalLongPressEventActuator = gestureEventHub->longPressEventActuator_;
1296 if (originalLongPressEventActuator) {
1297 longPressEventActuator_ = MakeRefPtr<LongPressEventActuator>(WeakClaim(this));
1298 longPressEventActuator_->CopyLongPressEvent(originalLongPressEventActuator);
1299 }
1300
1301 auto originalDragEventActuator = gestureEventHub->dragEventActuator_;
1302 if (originalDragEventActuator) {
1303 dragEventActuator_ = MakeRefPtr<DragEventActuator>(WeakClaim(this), originalDragEventActuator->GetDirection(),
1304 originalDragEventActuator->GetFingers(), originalDragEventActuator->GetDistance());
1305 dragEventActuator_->CopyDragEvent(originalDragEventActuator);
1306 }
1307 auto originalShowMenu = gestureEventHub->showMenu_;
1308 if (originalShowMenu) {
1309 if (showMenu_) {
1310 RemoveClickEvent(showMenu_);
1311 }
1312 auto originalGetGestureEventFunc = originalShowMenu->GetGestureEventFunc();
1313 showMenu_= MakeRefPtr<ClickEvent>(std::move(originalGetGestureEventFunc));
1314 AddClickEvent(showMenu_);
1315 }
1316 }
1317 } // namespace OHOS::Ace::NG
1318