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 #include <memory>
21 #include <string>
22 #include "drag_event.h"
23
24 #include "base/log/log_wrapper.h"
25 #include "base/memory/ace_type.h"
26 #include "base/subwindow/subwindow_manager.h"
27 #include "base/utils/time_util.h"
28 #include "base/image/image_source.h"
29 #include "core/common/container.h"
30 #include "core/common/interaction/interaction_data.h"
31 #include "core/common/interaction/interaction_interface.h"
32 #include "core/components/common/layout/grid_system_manager.h"
33 #include "core/components/container_modal/container_modal_constants.h"
34 #include "core/components_ng/base/frame_node.h"
35 #include "core/components_ng/event/click_event.h"
36 #include "core/components_ng/event/event_hub.h"
37 #include "core/components_ng/gestures/recognizers/click_recognizer.h"
38 #include "core/components_ng/gestures/recognizers/exclusive_recognizer.h"
39 #include "core/components_ng/gestures/recognizers/long_press_recognizer.h"
40 #include "core/components_ng/gestures/recognizers/pan_recognizer.h"
41 #include "core/components_ng/gestures/recognizers/parallel_recognizer.h"
42 #include "core/components_ng/gestures/recognizers/pinch_recognizer.h"
43 #include "core/components_ng/gestures/recognizers/rotation_recognizer.h"
44 #include "core/components_ng/gestures/recognizers/swipe_recognizer.h"
45 #include "core/components_ng/manager/drag_drop/drag_drop_behavior_reporter/drag_drop_behavior_reporter.h"
46 #include "core/components_ng/manager/drag_drop/drag_drop_func_wrapper.h"
47 #include "core/components_ng/manager/drag_drop/drag_drop_manager.h"
48 #include "core/components_ng/manager/drag_drop/utils/drag_animation_helper.h"
49 #include "core/components_ng/pattern/image/image_pattern.h"
50 #include "core/components_ng/pattern/text_drag/text_drag_base.h"
51 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
52 #include "core/components_ng/pattern/image/image_layout_property.h"
53 #include "core/gestures/gesture_info.h"
54 #include "core/pipeline_ng/pipeline_context.h"
55
56 #if defined(PIXEL_MAP_SUPPORTED)
57 #include "image_source.h"
58 #endif
59
60 #include "core/common/udmf/udmf_client.h"
61 #include "core/components_ng/render/adapter/component_snapshot.h"
62 #ifdef WEB_SUPPORTED
63 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
64 #include "core/components_ng/pattern/web/web_pattern.h"
65 #else
66 #include "core/components_ng/pattern/web/cross_platform/web_pattern.h"
67 #endif
68 #endif
69 namespace OHOS::Ace::NG {
70 namespace {
71 #if defined(PIXEL_MAP_SUPPORTED)
72 constexpr int32_t CREATE_PIXELMAP_TIME = 30;
73 constexpr int32_t MAX_BUILDER_DEPTH = 5;
74 #endif
75 constexpr uint32_t EXTRA_INFO_MAX_LENGTH = 200;
76 constexpr int32_t PIXELMAP_ANIMATION_DURATION = 250;
77 constexpr float PIXELMAP_OPACITY_RATE = 0.95f;
78 } // namespace
79 const std::string DEFAULT_MOUSE_DRAG_IMAGE { "/system/etc/device_status/drag_icon/Copy_Drag.svg" };
80 constexpr const char* HIT_TEST_MODE[] = {
81 "HitTestMode.Default",
82 "HitTestMode.Block",
83 "HitTestMode.Transparent",
84 "HitTestMode.None",
85 };
86
GestureEventHub(const WeakPtr<EventHub> & eventHub)87 GestureEventHub::GestureEventHub(const WeakPtr<EventHub>& eventHub) : eventHub_(eventHub) {}
88
GetFrameNode() const89 RefPtr<FrameNode> GestureEventHub::GetFrameNode() const
90 {
91 auto eventHub = eventHub_.Upgrade();
92 return eventHub ? eventHub->GetFrameNode() : nullptr;
93 }
94
ProcessTouchTestHit(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & innerTargets,TouchTestResult & finalResult,int32_t touchId,const PointF & localPoint,const RefPtr<TargetComponent> & targetComponent,ResponseLinkResult & responseLinkResult)95 bool GestureEventHub::ProcessTouchTestHit(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
96 TouchTestResult& innerTargets, TouchTestResult& finalResult, int32_t touchId, const PointF& localPoint,
97 const RefPtr<TargetComponent>& targetComponent, ResponseLinkResult& responseLinkResult)
98 {
99 auto host = GetFrameNode();
100 CHECK_NULL_RETURN(host, false);
101 auto eventHub = eventHub_.Upgrade();
102 auto getEventTargetImpl = eventHub ? eventHub->CreateGetEventTargetImpl() : nullptr;
103 if (scrollableActuator_) {
104 scrollableActuator_->CollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets,
105 localPoint, host, targetComponent, responseLinkResult);
106 }
107 size_t idx = innerTargets.size();
108 size_t newIdx = 0;
109 if (dragEventActuator_) {
110 dragEventActuator_->AddTouchListener(touchRestrict);
111 }
112 if (touchEventActuator_) {
113 touchEventActuator_->OnCollectTouchTarget(
114 coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets, responseLinkResult);
115 }
116 if (clickEventActuator_ && !redirectClick_) {
117 clickEventActuator_->OnCollectTouchTarget(
118 coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets, responseLinkResult);
119 }
120 if (userParallelClickEventActuator_) {
121 auto clickRecognizer = userParallelClickEventActuator_->GetClickRecognizer();
122 if (clickRecognizer) {
123 clickRecognizer->SetGestureInfo(
124 MakeRefPtr<GestureInfo>(GestureTypeName::CLICK, GestureTypeName::CLICK, true));
125 clickRecognizer->SetOnAction(userParallelClickEventActuator_->GetClickEvent());
126 clickRecognizer->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
127 clickRecognizer->SetGetEventTargetImpl(getEventTargetImpl);
128 }
129 }
130 if (panEventActuator_) {
131 panEventActuator_->OnCollectTouchTarget(
132 coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets, responseLinkResult);
133 }
134
135 TouchTestResult dragTargets;
136 if (longPressEventActuator_) {
137 longPressEventActuator_->OnCollectTouchTarget(
138 coordinateOffset, touchRestrict, getEventTargetImpl, dragTargets, responseLinkResult);
139 }
140 if (dragEventActuator_) {
141 dragEventActuator_->OnCollectTouchTarget(
142 coordinateOffset, touchRestrict, getEventTargetImpl, dragTargets, responseLinkResult);
143 }
144
145 std::list<RefPtr<NGGestureRecognizer>> longPressRecognizers;
146 for (const auto& item : dragTargets) {
147 auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(item);
148 if (recognizer) {
149 recognizer->BeginReferee(touchId);
150 recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
151 recognizer->SetTargetComponent(targetComponent);
152 if (AceType::InstanceOf<RecognizerGroup>(recognizer)) {
153 auto group = AceType::DynamicCast<RecognizerGroup>(recognizer);
154 if (group) {
155 group->SetChildrenTargetComponent(targetComponent);
156 }
157 }
158 }
159 longPressRecognizers.emplace_back(AceType::DynamicCast<NGGestureRecognizer>(item));
160 }
161 if (!longPressRecognizers.empty()) {
162 // this node has long press and drag event, combine into parallelRecognizer.
163 if (!nodeParallelRecognizer_) {
164 nodeParallelRecognizer_ = MakeRefPtr<ParallelRecognizer>(std::move(longPressRecognizers));
165 } else {
166 nodeParallelRecognizer_->AddChildren(longPressRecognizers);
167 }
168 innerTargets.emplace_back(nodeParallelRecognizer_);
169 } else {
170 nodeParallelRecognizer_.Reset();
171 }
172
173 std::list<RefPtr<NGGestureRecognizer>> innerRecognizers;
174 for (auto const& eventTarget : innerTargets) {
175 auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(eventTarget);
176 if (recognizer) {
177 auto recognizerGroup = AceType::DynamicCast<RecognizerGroup>(recognizer);
178 if (!recognizerGroup && newIdx >= idx) {
179 recognizer->SetNodeId(host->GetId());
180 recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
181 recognizer->SetTargetComponent(targetComponent);
182 recognizer->SetIsSystemGesture(true);
183 }
184 recognizer->BeginReferee(touchId);
185 innerRecognizers.push_back(std::move(recognizer));
186 } else {
187 eventTarget->SetNodeId(host->GetId());
188 eventTarget->AttachFrameNode(WeakPtr<FrameNode>(host));
189 eventTarget->SetTargetComponent(targetComponent);
190 finalResult.push_back(eventTarget);
191 }
192 newIdx++; // not process previous recognizers
193 }
194
195 ProcessTouchTestHierarchy(
196 coordinateOffset, touchRestrict, innerRecognizers, finalResult, touchId, targetComponent, responseLinkResult);
197
198 return false;
199 }
200
OnModifyDone()201 void GestureEventHub::OnModifyDone()
202 {
203 if (recreateGesture_) {
204 UpdateGestureHierarchy();
205 recreateGesture_ = false;
206 }
207 }
208
PackInnerRecognizer(const Offset & offset,std::list<RefPtr<NGGestureRecognizer>> & innerRecognizers,int32_t touchId,const RefPtr<TargetComponent> & targetComponent)209 RefPtr<NGGestureRecognizer> GestureEventHub::PackInnerRecognizer(
210 const Offset& offset, std::list<RefPtr<NGGestureRecognizer>>& innerRecognizers, int32_t touchId,
211 const RefPtr<TargetComponent>& targetComponent)
212 {
213 RefPtr<NGGestureRecognizer> current;
214 // Pack inner recognizer include self inner recognizer and children.
215 if (innerRecognizers.size() == 1) {
216 current = *innerRecognizers.begin();
217 } else if (innerRecognizers.size() > 1) {
218 if (!innerExclusiveRecognizer_) {
219 innerExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(innerRecognizers));
220 } else {
221 innerExclusiveRecognizer_->AddChildren(innerRecognizers);
222 }
223 innerExclusiveRecognizer_->SetCoordinateOffset(offset);
224 innerExclusiveRecognizer_->BeginReferee(touchId);
225 auto host = GetFrameNode();
226 innerExclusiveRecognizer_->AttachFrameNode(WeakPtr<FrameNode>(host));
227 innerExclusiveRecognizer_->SetTargetComponent(targetComponent);
228 current = innerExclusiveRecognizer_;
229 }
230
231 return current;
232 }
233
ProcessParallelPriorityGesture(RefPtr<NGGestureRecognizer> & current,std::list<RefPtr<NGGestureRecognizer>> & recognizers,int32_t & parallelIndex,const Offset & offset,int32_t touchId,const RefPtr<TargetComponent> & targetComponent,const RefPtr<FrameNode> & host)234 void GestureEventHub::ProcessParallelPriorityGesture(RefPtr<NGGestureRecognizer>& current,
235 std::list<RefPtr<NGGestureRecognizer>>& recognizers, int32_t& parallelIndex, const Offset& offset, int32_t touchId,
236 const RefPtr<TargetComponent>& targetComponent, const RefPtr<FrameNode>& host)
237 {
238 if (current) {
239 recognizers.push_front(current);
240 }
241 if (recognizers.size() > 1) {
242 if ((static_cast<int32_t>(externalParallelRecognizer_.size()) <= parallelIndex)) {
243 externalParallelRecognizer_.emplace_back(AceType::MakeRefPtr<ParallelRecognizer>(std::move(recognizers)));
244 } else {
245 externalParallelRecognizer_[parallelIndex]->AddChildren(recognizers);
246 }
247 externalParallelRecognizer_[parallelIndex]->SetCoordinateOffset(offset);
248 externalParallelRecognizer_[parallelIndex]->BeginReferee(touchId);
249 externalParallelRecognizer_[parallelIndex]->AttachFrameNode(WeakPtr<FrameNode>(host));
250 externalParallelRecognizer_[parallelIndex]->SetTargetComponent(targetComponent);
251 current = externalParallelRecognizer_[parallelIndex];
252 parallelIndex++;
253 } else if (recognizers.size() == 1) {
254 current = *recognizers.begin();
255 }
256 }
257
ProcessExternalExclusiveRecognizer(RefPtr<NGGestureRecognizer> & current,std::list<RefPtr<NGGestureRecognizer>> & recognizers,int32_t & exclusiveIndex,const Offset & offset,int32_t touchId,const RefPtr<TargetComponent> & targetComponent,const RefPtr<FrameNode> & host,GesturePriority priority)258 void GestureEventHub::ProcessExternalExclusiveRecognizer(RefPtr<NGGestureRecognizer>& current,
259 std::list<RefPtr<NGGestureRecognizer>>& recognizers, int32_t& exclusiveIndex, const Offset& offset, int32_t touchId,
260 const RefPtr<TargetComponent>& targetComponent, const RefPtr<FrameNode>& host, GesturePriority priority)
261 {
262 if (current) {
263 if (priority == GesturePriority::Low) {
264 recognizers.push_front(current);
265 } else {
266 recognizers.push_back(current);
267 }
268 }
269
270 if (recognizers.size() > 1) {
271 if ((static_cast<int32_t>(externalExclusiveRecognizer_.size()) <= exclusiveIndex)) {
272 externalExclusiveRecognizer_.emplace_back(AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers)));
273 } else {
274 externalExclusiveRecognizer_[exclusiveIndex]->AddChildren(recognizers);
275 }
276 externalExclusiveRecognizer_[exclusiveIndex]->SetCoordinateOffset(offset);
277 externalExclusiveRecognizer_[exclusiveIndex]->BeginReferee(touchId);
278 externalExclusiveRecognizer_[exclusiveIndex]->AttachFrameNode(WeakPtr<FrameNode>(host));
279 externalExclusiveRecognizer_[exclusiveIndex]->SetTargetComponent(targetComponent);
280 current = externalExclusiveRecognizer_[exclusiveIndex];
281 exclusiveIndex++;
282 } else if (recognizers.size() == 1) {
283 current = *recognizers.begin();
284 }
285 }
286
ProcessTouchTestHierarchy(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,std::list<RefPtr<NGGestureRecognizer>> & innerRecognizers,TouchTestResult & finalResult,int32_t touchId,const RefPtr<TargetComponent> & targetComponent,ResponseLinkResult & responseLinkResult)287 void GestureEventHub::ProcessTouchTestHierarchy(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
288 std::list<RefPtr<NGGestureRecognizer>>& innerRecognizers, TouchTestResult& finalResult, int32_t touchId,
289 const RefPtr<TargetComponent>& targetComponent, ResponseLinkResult& responseLinkResult)
290 {
291 auto host = GetFrameNode();
292 if (!host) {
293 for (auto&& recognizer : innerRecognizers) {
294 finalResult.emplace_back(std::move(recognizer));
295 }
296 return;
297 }
298
299 auto offset = Offset(coordinateOffset.GetX(), coordinateOffset.GetY());
300 RefPtr<NGGestureRecognizer> current;
301 current = PackInnerRecognizer(offset, innerRecognizers, touchId, targetComponent);
302 auto eventHub = eventHub_.Upgrade();
303 auto getEventTargetImpl = eventHub ? eventHub->CreateGetEventTargetImpl() : nullptr;
304 int32_t parallelIndex = 0;
305 int32_t exclusiveIndex = 0;
306 for (auto const& recognizer : gestureHierarchy_) {
307 if (!recognizer) {
308 continue;
309 }
310 auto recognizerGroup = AceType::DynamicCast<RecognizerGroup>(recognizer);
311 if (recognizerGroup) {
312 recognizerGroup->SetRecognizerInfoRecursively(offset, host, targetComponent, getEventTargetImpl);
313 recognizerGroup->CollectResponseLinkRecognizersRecursively(responseLinkResult);
314 } else {
315 responseLinkResult.emplace_back(recognizer);
316 }
317 recognizer->SetNodeId(host->GetId());
318 recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
319 recognizer->SetTargetComponent(targetComponent);
320 recognizer->SetCoordinateOffset(offset);
321 recognizer->BeginReferee(touchId, true);
322 recognizer->SetGetEventTargetImpl(getEventTargetImpl);
323 auto gestureMask = recognizer->GetPriorityMask();
324 if (gestureMask == GestureMask::IgnoreInternal) {
325 // In ignore case, dropped the self inner recognizer and children recognizer.
326 current = recognizer;
327 continue;
328 }
329 auto priority = recognizer->GetPriority();
330 std::list<RefPtr<NGGestureRecognizer>> recognizers { 1, recognizer };
331 if (priority == GesturePriority::Parallel) {
332 ProcessParallelPriorityGesture(current, recognizers, parallelIndex, offset, touchId, targetComponent, host);
333 } else {
334 ProcessExternalExclusiveRecognizer(
335 current, recognizers, exclusiveIndex, offset, touchId, targetComponent, host, priority);
336 }
337 }
338
339 if (current) {
340 finalResult.emplace_back(std::move(current));
341 }
342 }
343
UpdateGestureHierarchy()344 void GestureEventHub::UpdateGestureHierarchy()
345 {
346 auto host = GetFrameNode();
347 CHECK_NULL_VOID(host);
348 bool success = (gestures_.size() + modifierGestures_.size()) == gestureHierarchy_.size() && !needRecollect_;
349 if (success) {
350 auto iter = gestures_.begin();
351 auto recognizerIter = gestureHierarchy_.begin();
352 for (; iter != gestures_.end(); iter++, recognizerIter++) {
353 auto newRecognizer = (*iter)->CreateRecognizer();
354 success = success && (*recognizerIter)->ReconcileFrom(newRecognizer);
355 if (!success) {
356 break;
357 }
358 }
359 }
360 if (success) {
361 gestures_.clear();
362 return;
363 }
364
365 gestureHierarchy_.clear();
366 for (const auto& gesture : gestures_) {
367 AddGestureToGestureHierarchy(gesture);
368 }
369 for (const auto& gesture : modifierGestures_) {
370 AddGestureToGestureHierarchy(gesture);
371 }
372 needRecollect_ = false;
373 gestures_.clear();
374 }
375
AddGestureToGestureHierarchy(const RefPtr<NG::Gesture> & gesture)376 void GestureEventHub::AddGestureToGestureHierarchy(const RefPtr<NG::Gesture>& gesture)
377 {
378 if (!gesture) {
379 return;
380 }
381 auto recognizer = gesture->CreateRecognizer();
382
383 auto clickRecognizer = AceType::DynamicCast<ClickRecognizer>(recognizer);
384 if (clickRecognizer) {
385 clickRecognizer->SetOnAccessibility(GetOnAccessibilityEventFunc());
386 }
387
388 auto longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(recognizer);
389 if (longPressRecognizer) {
390 longPressRecognizer->SetOnAccessibility(GetOnAccessibilityEventFunc());
391 auto host = GetFrameNode();
392 CHECK_NULL_VOID(host);
393 auto pattern = host->GetPattern();
394 if (pattern && longPressRecognizer->HasAction()) {
395 longPressRecognizer->SetOnLongPressRecorder(pattern->GetLongPressEventRecorder());
396 }
397 }
398
399 if (!recognizer) {
400 return;
401 }
402 auto priority = gesture->GetPriority();
403 auto gestureMask = gesture->GetGestureMask();
404 recognizer->SetPriority(priority);
405 recognizer->SetPriorityMask(gestureMask);
406 gestureHierarchy_.emplace_back(recognizer);
407 }
408
CombineIntoExclusiveRecognizer(const PointF & globalPoint,const PointF & localPoint,TouchTestResult & result,int32_t touchId)409 void GestureEventHub::CombineIntoExclusiveRecognizer(
410 const PointF& globalPoint, const PointF& localPoint, TouchTestResult& result, int32_t touchId)
411 {
412 TouchTestResult finalResult;
413 std::list<RefPtr<NGGestureRecognizer>> recognizers;
414 const auto coordinateOffset = globalPoint - localPoint;
415 auto offset = Offset(coordinateOffset.GetX(), coordinateOffset.GetY());
416 for (auto const& eventTarget : result) {
417 auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(eventTarget);
418 if (recognizer) {
419 recognizers.push_back(std::move(recognizer));
420 } else {
421 finalResult.push_back(eventTarget);
422 }
423 }
424
425 RefPtr<NGGestureRecognizer> current;
426 if (recognizers.size() == 1) {
427 current = *recognizers.begin();
428 } else if (recognizers.size() > 1) {
429 if (!nodeExclusiveRecognizer_) {
430 nodeExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers));
431 } else {
432 nodeExclusiveRecognizer_->AddChildren(recognizers);
433 }
434 nodeExclusiveRecognizer_->SetCoordinateOffset(offset);
435 nodeExclusiveRecognizer_->BeginReferee(touchId);
436 current = nodeExclusiveRecognizer_;
437 }
438
439 if (current) {
440 finalResult.emplace_back(std::move(current));
441 }
442 result.swap(finalResult);
443 }
444
IsPixelMapNeedScale() const445 bool GestureEventHub::IsPixelMapNeedScale() const
446 {
447 CHECK_NULL_RETURN(pixelMap_, false);
448 auto frameNode = GetFrameNode();
449 CHECK_NULL_RETURN(frameNode, false);
450 auto width = pixelMap_->GetWidth();
451 auto maxWidth = DragDropManager::GetMaxWidthBaseOnGridSystem(frameNode->GetContextRefPtr());
452 if (!frameNode->GetDragPreviewOption().isScaleEnabled || width == 0 || width <= maxWidth) {
453 return false;
454 }
455 return true;
456 }
457
InitDragDropEvent()458 void GestureEventHub::InitDragDropEvent()
459 {
460 auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& info) {
461 auto gestureEventHub = weak.Upgrade();
462 CHECK_NULL_VOID(gestureEventHub);
463 gestureEventHub->HandleOnDragStart(info);
464 };
465
466 auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
467 auto gestureEventHub = weak.Upgrade();
468 CHECK_NULL_VOID(gestureEventHub);
469 gestureEventHub->HandleOnDragUpdate(info);
470 };
471
472 auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
473 auto gestureEventHub = weak.Upgrade();
474 CHECK_NULL_VOID(gestureEventHub);
475 gestureEventHub->HandleOnDragEnd(info);
476 };
477
478 auto actionCancelTask = [weak = WeakClaim(this)]() {
479 auto gestureEventHub = weak.Upgrade();
480 CHECK_NULL_VOID(gestureEventHub);
481 gestureEventHub->HandleOnDragCancel();
482 };
483
484 auto dragEvent = MakeRefPtr<DragEvent>(
485 std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
486 auto distance = SystemProperties::GetDragStartPanDistanceThreshold();
487 SetDragEvent(dragEvent, { PanDirection::ALL }, DEFAULT_PAN_FINGER, Dimension(distance, DimensionUnit::VP));
488 }
489
IsAllowedDrag(RefPtr<EventHub> eventHub)490 bool GestureEventHub::IsAllowedDrag(RefPtr<EventHub> eventHub)
491 {
492 auto frameNode = GetFrameNode();
493 CHECK_NULL_RETURN(frameNode, false);
494 auto pattern = frameNode->GetPattern();
495 CHECK_NULL_RETURN(pattern, false);
496
497 if (frameNode->IsDraggable()) {
498 if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
499 return false;
500 }
501 } else {
502 if (frameNode->IsUserSet()) {
503 return false;
504 }
505 if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
506 return false;
507 }
508 }
509 return true;
510 }
511
StartLongPressActionForWeb(bool isFloatImage)512 void GestureEventHub::StartLongPressActionForWeb(bool isFloatImage)
513 {
514 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start long press action for web");
515 auto pipeline = PipelineContext::GetCurrentContext();
516 CHECK_NULL_VOID(pipeline);
517 auto taskScheduler = pipeline->GetTaskExecutor();
518 CHECK_NULL_VOID(taskScheduler);
519
520 taskScheduler->PostTask(
521 [weak = WeakClaim(this), isFloatImage]() {
522 auto gestureHub = weak.Upgrade();
523 CHECK_NULL_VOID(gestureHub);
524 auto dragEventActuator = gestureHub->dragEventActuator_;
525 CHECK_NULL_VOID(dragEventActuator);
526 dragEventActuator->StartLongPressActionForWeb(isFloatImage);
527 },
528 TaskExecutor::TaskType::UI, "ArkUIGestureWebStartLongPress");
529 }
530
CancelDragForWeb()531 void GestureEventHub::CancelDragForWeb()
532 {
533 TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop cancel drag for web");
534 auto pipeline = PipelineContext::GetCurrentContext();
535 CHECK_NULL_VOID(pipeline);
536 auto taskScheduler = pipeline->GetTaskExecutor();
537 CHECK_NULL_VOID(taskScheduler);
538
539 taskScheduler->PostTask(
540 [weak = WeakClaim(this)]() {
541 auto gestureHub = weak.Upgrade();
542 CHECK_NULL_VOID(gestureHub);
543 auto dragEventActuator = gestureHub->dragEventActuator_;
544 CHECK_NULL_VOID(dragEventActuator);
545 dragEventActuator->CancelDragForWeb();
546 },
547 TaskExecutor::TaskType::UI, "ArkUIGestureWebCancelDrag");
548 }
549
ResetDragActionForWeb()550 void GestureEventHub::ResetDragActionForWeb()
551 {
552 TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop reset drag action for web");
553 isReceivedDragGestureInfo_ = false;
554 CHECK_NULL_VOID(dragEventActuator_);
555 dragEventActuator_->ResetDragActionForWeb();
556
557 // fix drag failed when long press drag after 500ms and before 800ms
558 // need to reset the state of the drag manager
559 auto pipeLine = PipelineContext::GetCurrentContext();
560 CHECK_NULL_VOID(pipeLine);
561 auto dragDropManager = pipeLine->GetDragDropManager();
562 CHECK_NULL_VOID(dragDropManager);
563 dragDropManager->ResetDragging();
564 }
565
StartDragTaskForWeb()566 void GestureEventHub::StartDragTaskForWeb()
567 {
568 if (!isReceivedDragGestureInfo_) {
569 TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop StartDragTaskForWeb failed,"
570 "because not recv gesture info");
571 return;
572 }
573
574 isReceivedDragGestureInfo_ = false;
575 auto pipeline = PipelineContext::GetCurrentContext();
576 CHECK_NULL_VOID(pipeline);
577 auto taskScheduler = pipeline->GetTaskExecutor();
578 CHECK_NULL_VOID(taskScheduler);
579
580 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop post a task to start drag for web");
581 taskScheduler->PostTask(
582 [weak = WeakClaim(this)]() {
583 auto gestureHub = weak.Upgrade();
584 CHECK_NULL_VOID(gestureHub);
585 auto dragEventActuator = gestureHub->dragEventActuator_;
586 CHECK_NULL_VOID(dragEventActuator);
587 CHECK_NULL_VOID(gestureHub->gestureInfoForWeb_);
588 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start drag task for web in async task");
589 dragEventActuator->StartDragTaskForWeb(*gestureHub->gestureInfoForWeb_);
590 },
591 TaskExecutor::TaskType::UI, "ArkUIGestureWebStartDrag");
592 }
593
CreatePixelMapFromString(const std::string & filePath)594 RefPtr<PixelMap> CreatePixelMapFromString(const std::string& filePath)
595 {
596 auto imageSource = ImageSource::Create(filePath);
597 CHECK_NULL_RETURN(imageSource, nullptr);
598 RefPtr<PixelMap> pixelMap = imageSource->CreatePixelMap();
599 return pixelMap;
600 }
601
CheckInSceneBoardWindow()602 bool CheckInSceneBoardWindow()
603 {
604 auto container = Container::Current();
605 CHECK_NULL_RETURN(container, false);
606 if (!container->IsSubContainer()) {
607 return container->IsScenceBoardWindow();
608 }
609 auto parentContainerId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
610 container = Container::GetContainer(parentContainerId);
611 CHECK_NULL_RETURN(container, false);
612 return container->IsScenceBoardWindow();
613 }
614
CheckOffsetInPixelMap(OffsetF & result,const SizeF & size)615 void CheckOffsetInPixelMap(OffsetF& result, const SizeF& size)
616 {
617 if (result.GetX() >= 0.0f) {
618 result.SetX(-1.0f);
619 }
620 if (result.GetX() + size.Width() <= 0.0f) {
621 result.SetX(1.0f - size.Width());
622 }
623 if (result.GetY() >= 0.0f) {
624 result.SetY(-1.0f);
625 }
626 if (result.GetY() + size.Height() <= 0.0f) {
627 result.SetY(1.0f - size.Height());
628 }
629 }
630
ParseInnerRect(const std::string & extraInfo,const SizeF & size)631 RectF ParseInnerRect(const std::string& extraInfo, const SizeF& size)
632 {
633 auto innerRect = RectF();
634 if (!CheckInSceneBoardWindow() || extraInfo.empty()) {
635 return innerRect;
636 }
637 auto extraJson = JsonUtil::ParseJsonString(extraInfo);
638 CHECK_NULL_RETURN(extraJson, innerRect);
639 auto extraOffsetX = extraJson->GetInt("drag_offset_x");
640 auto extraOffsetY = extraJson->GetInt("drag_offset_y");
641 if (extraOffsetX <= 0 || extraOffsetY <= 0) {
642 return innerRect;
643 }
644 innerRect.SetOffset(OffsetF(Dimension(extraOffsetX, DimensionUnit::VP).ConvertToPx(),
645 Dimension(extraOffsetY, DimensionUnit::VP).ConvertToPx()));
646 innerRect.SetSize(size);
647 return innerRect;
648 }
649
GetPixelMapOffset(const GestureEvent & info,const SizeF & size,const float scale,bool isCalculateInSubwindow,const RectF & innerRect) const650 OffsetF GestureEventHub::GetPixelMapOffset(
651 const GestureEvent& info, const SizeF& size, const float scale, bool isCalculateInSubwindow,
652 const RectF& innerRect) const
653 {
654 OffsetF result = OffsetF(size.Width() * PIXELMAP_WIDTH_RATE, size.Height() * PIXELMAP_HEIGHT_RATE);
655 auto frameNode = GetFrameNode();
656 CHECK_NULL_RETURN(frameNode, result);
657 auto frameTag = frameNode->GetTag();
658 auto coordinateX = frameNodeOffset_.GetX();
659 auto coordinateY = frameNodeOffset_.GetY();
660 if (!innerRect.IsEmpty() && GreatNotEqual(size.Width(), 0.0f) && GreatNotEqual(size.Height(), 0.0f)) {
661 auto rateX = innerRect.Width() / size.Width();
662 auto rateY = innerRect.Height() / size.Height();
663 result.SetX(rateX * (coordinateX + innerRect.GetOffset().GetX() - info.GetGlobalLocation().GetX()));
664 result.SetY(rateY * (coordinateY + innerRect.GetOffset().GetY() - info.GetGlobalLocation().GetY()));
665 CheckOffsetInPixelMap(result, size);
666 return result;
667 }
668 if (NearZero(frameNodeSize_.Width()) || NearZero(frameNodeSize_.Height()) ||
669 NearZero(size.Width())) {
670 result.SetX(scale * (coordinateX - info.GetGlobalLocation().GetX()));
671 result.SetY(scale * (coordinateY - info.GetGlobalLocation().GetY()));
672 } else {
673 auto rateX = (info.GetGlobalLocation().GetX() - coordinateX) / frameNodeSize_.Width();
674 auto rateY = (info.GetGlobalLocation().GetY() - coordinateY) / frameNodeSize_.Height();
675 result.SetX(-rateX * size.Width());
676 result.SetY(-rateY * size.Height());
677 }
678 CheckOffsetInPixelMap(result, size);
679 TAG_LOGD(AceLogTag::ACE_DRAG, "Get pixelMap offset is %{public}f and %{public}f.",
680 result.GetX(), result.GetY());
681 return result;
682 }
683
GetPreScaledPixelMapIfExist(float targetScale,RefPtr<PixelMap> defaultPixelMap)684 RefPtr<PixelMap> GestureEventHub::GetPreScaledPixelMapIfExist(float targetScale, RefPtr<PixelMap> defaultPixelMap)
685 {
686 float preScale = 1.0f;
687 CHECK_NULL_RETURN(dragEventActuator_, defaultPixelMap);
688 auto frameNode = GetFrameNode();
689 RefPtr<PixelMap> preScaledPixelMap;
690 if (!(frameNode && frameNode->GetDragPreview().onlyForLifting)) {
691 preScaledPixelMap = dragEventActuator_->GetPreScaledPixelMapForDragThroughTouch(preScale);
692 }
693 if (preScale == targetScale && preScaledPixelMap != nullptr) {
694 return preScaledPixelMap;
695 }
696 #if defined(PIXEL_MAP_SUPPORTED)
697 preScaledPixelMap = PixelMap::CopyPixelMap(defaultPixelMap);
698 if (!preScaledPixelMap) {
699 TAG_LOGW(AceLogTag::ACE_DRAG, "duplicate PixelMap failed!");
700 preScaledPixelMap = defaultPixelMap;
701 }
702 if (!NearEqual(targetScale, 1.0f)) {
703 preScaledPixelMap->Scale(targetScale, targetScale, AceAntiAliasingOption::HIGH);
704 }
705 #endif
706 return preScaledPixelMap;
707 }
708
GetPixelMapScale(const int32_t height,const int32_t width) const709 float GestureEventHub::GetPixelMapScale(const int32_t height, const int32_t width) const
710 {
711 float scale = 1.0f;
712 if (height == 0 || width == 0) {
713 return scale;
714 }
715 auto frameNode = GetFrameNode();
716 CHECK_NULL_RETURN(frameNode, scale);
717 auto pipeline = PipelineContext::GetCurrentContext();
718 CHECK_NULL_RETURN(pipeline, scale);
719 auto dragDropManager = pipeline->GetDragDropManager();
720 CHECK_NULL_RETURN(dragDropManager, scale);
721 auto windowScale = dragDropManager->GetWindowScale();
722 if (!frameNode->GetDragPreviewOption().isScaleEnabled || !(frameNode->GetTag() == V2::WEB_ETS_TAG)) {
723 return scale * windowScale;
724 }
725 int32_t deviceHeight = SystemProperties::GetDevicePhysicalHeight();
726 int32_t deviceWidth = SystemProperties::GetDevicePhysicalWidth();
727 int32_t maxDeviceLength = std::max(deviceHeight, deviceWidth);
728 int32_t minDeviceLength = std::min(deviceHeight, deviceWidth);
729 if (maxDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE > minDeviceLength) {
730 if (height > minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) {
731 scale = static_cast<float>(minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) / height;
732 }
733 } else {
734 if (GetTextDraggable() && height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
735 width > minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) {
736 scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
737 static_cast<float>(minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) / width);
738 } else if (height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
739 width > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) {
740 scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
741 static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / width);
742 }
743 }
744 return scale * windowScale;
745 }
746
GenerateMousePixelMap(const GestureEvent & info)747 void GestureEventHub::GenerateMousePixelMap(const GestureEvent& info)
748 {
749 auto frameNode = GetFrameNode();
750 CHECK_NULL_VOID(frameNode);
751 RefPtr<RenderContext> context;
752 if (GetTextDraggable()) {
753 auto pattern = frameNode->GetPattern<TextDragBase>();
754 CHECK_NULL_VOID(pattern);
755 auto dragNode = pattern->MoveDragNode();
756 CHECK_NULL_VOID(dragNode);
757 auto pipeline = PipelineContext::GetCurrentContext();
758 CHECK_NULL_VOID(pipeline);
759 pipeline->FlushPipelineImmediately();
760 context = dragNode->GetRenderContext();
761 } else {
762 context = frameNode->GetRenderContext();
763 }
764 CHECK_NULL_VOID(context);
765 auto thumbnailPixelMap = context->GetThumbnailPixelMap();
766 CHECK_NULL_VOID(thumbnailPixelMap);
767 SetPixelMap(thumbnailPixelMap);
768 }
769
HandleNotallowDrag(const GestureEvent & info)770 void GestureEventHub::HandleNotallowDrag(const GestureEvent& info)
771 {
772 auto frameNode = GetFrameNode();
773 CHECK_NULL_VOID(frameNode);
774 if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
775 gestureInfoForWeb_ = std::make_shared<GestureEvent>(info);
776 isReceivedDragGestureInfo_ = true;
777 TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop drag gesture info received");
778 }
779 }
780
ParsePixelMapAsync(DragDropInfo & dragDropInfo,const DragDropInfo & dragPreviewInfo,const GestureEvent & info)781 bool GestureEventHub::ParsePixelMapAsync(DragDropInfo& dragDropInfo, const DragDropInfo& dragPreviewInfo,
782 const GestureEvent& info)
783 {
784 auto frameNode = GetFrameNode();
785 CHECK_NULL_RETURN(frameNode, false);
786
787 if (dragPreviewInfo.inspectorId != "") {
788 ACE_SCOPED_TRACE("drag: handling with inspector");
789 auto dragPreviewPixelMap = GetDragPreviewPixelMap();
790 TAG_LOGI(AceLogTag::ACE_DRAG, "InspectorId exist, get thumbnail.");
791 if (dragPreviewPixelMap == nullptr) {
792 dragPreviewPixelMap = DragEventActuator::GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
793 }
794 dragDropInfo.pixelMap = dragPreviewPixelMap;
795 return true;
796 }
797
798 if (info.GetSourceDevice() != SourceType::MOUSE) {
799 if (dragPreviewInfo.pixelMap != nullptr || dragPreviewInfo.customNode != nullptr) {
800 if (dragPreviewPixelMap_ != nullptr) {
801 ACE_SCOPED_TRACE("drag: handling with drag preview");
802 TAG_LOGI(AceLogTag::ACE_DRAG, "Non-mouse dragging, get thumbnail.");
803 dragDropInfo.pixelMap = dragPreviewPixelMap_;
804 return true;
805 }
806 }
807 }
808
809 if (dragDropInfo.pixelMap == nullptr && dragDropInfo.customNode == nullptr && dragPreviewInfo.pixelMap == nullptr &&
810 dragPreviewInfo.customNode == nullptr && pixelMap_ != nullptr && !frameNode->GetDragPreview().onlyForLifting) {
811 dragDropInfo.pixelMap = pixelMap_;
812 return true;
813 }
814
815 if (dragPreviewInfo.pixelMap != nullptr) {
816 ACE_SCOPED_TRACE("drag: handling with pixelmap directly");
817 dragDropInfo.pixelMap = dragPreviewInfo.pixelMap;
818 TAG_LOGI(AceLogTag::ACE_DRAG, "PixelMap exist, get thumbnail.");
819 return true;
820 } else if (dragPreviewInfo.customNode != nullptr) {
821 dragDropInfo.customNode = dragPreviewInfo.customNode;
822 }
823 return dragDropInfo.pixelMap;
824 }
825
HideMenu()826 void GestureEventHub::HideMenu()
827 {
828 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
829 CHECK_NULL_VOID(pipeline);
830 auto dragDrogDropManager = pipeline->GetDragDropManager();
831 CHECK_NULL_VOID(dragDrogDropManager);
832 SubwindowManager::GetInstance()->HideMenuNG(false, true);
833 auto menuWrapperNode = dragDrogDropManager->GetMenuWrapperNode();
834 CHECK_NULL_VOID(menuWrapperNode);
835 auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
836 CHECK_NULL_VOID(menuWrapperPattern);
837 auto imageNode = menuWrapperPattern->GetPreview();
838 CHECK_NULL_VOID(imageNode);
839 auto imageContext = imageNode->GetRenderContext();
840 CHECK_NULL_VOID(imageContext);
841 imageContext->UpdateOpacity(0.0f);
842 }
843
HandleOnDragStart(const GestureEvent & info)844 void GestureEventHub::HandleOnDragStart(const GestureEvent& info)
845 {
846 TAG_LOGD(AceLogTag::ACE_DRAG, "Start handle onDragStart.");
847 auto eventHub = eventHub_.Upgrade();
848 CHECK_NULL_VOID(eventHub);
849 if (!eventHub->HasOnDragStart()) {
850 TAG_LOGI(AceLogTag::ACE_DRAG, "FrameNode is not set onDragStart event.");
851 return;
852 }
853
854 auto frameNode = GetFrameNode();
855 CHECK_NULL_VOID(frameNode);
856 auto pattern = frameNode->GetPattern();
857 CHECK_NULL_VOID(pattern);
858 if (!IsAllowedDrag(eventHub)) {
859 TAG_LOGI(AceLogTag::ACE_DRAG, "FrameNode is not allow drag, tag is %{public}s,"
860 "draggable is %{public}d, drag start event is %{public}d,"
861 "default support drag is %{public}d, user set is %{public}d.",
862 frameNode->GetTag().c_str(), frameNode->IsDraggable(), eventHub->HasOnDragStart(),
863 pattern->DefaultSupportDrag(), frameNode->IsUserSet());
864 HandleNotallowDrag(info);
865 return;
866 }
867 auto pipeline = PipelineContext::GetCurrentContext();
868 CHECK_NULL_VOID(pipeline);
869 auto eventManager = pipeline->GetEventManager();
870 CHECK_NULL_VOID(eventManager);
871 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && eventManager->IsLastMoveBeforeUp()) {
872 TAG_LOGI(AceLogTag::ACE_DRAG, "Drag stop because user release mouse button");
873 return;
874 }
875 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
876 SetMouseDragMonitorState(true);
877 }
878
879 RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
880 if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
881 event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
882 event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
883 } else {
884 event->SetX(info.GetGlobalPoint().GetX());
885 event->SetY(info.GetGlobalPoint().GetY());
886 }
887 event->SetScreenX(info.GetScreenLocation().GetX());
888 event->SetScreenY(info.GetScreenLocation().GetY());
889 event->SetDisplayX(info.GetScreenLocation().GetX());
890 event->SetDisplayY(info.GetScreenLocation().GetY());
891 event->SetSourceTool(info.GetSourceTool());
892
893 auto frameTag = frameNode->GetTag();
894 auto hostPattern = frameNode->GetPattern<TextDragBase>();
895 if (hostPattern && GetTextDraggable() && (frameTag == V2::RICH_EDITOR_ETS_TAG || frameTag == V2::TEXT_ETS_TAG ||
896 frameTag == V2::TEXTINPUT_ETS_TAG || frameTag == V2::SEARCH_Field_ETS_TAG)) {
897 frameNodeOffset_ = hostPattern->GetDragUpperLeftCoordinates();
898 frameNodeSize_ = SizeF(0.0f, 0.0f);
899 } else {
900 auto rect = DragDropFuncWrapper::GetPaintRectToScreen(frameNode) -
901 DragDropFuncWrapper::GetCurrentWindowOffset(PipelineContext::GetCurrentContextSafelyWithCheck());
902 frameNodeOffset_ = rect.GetOffset();
903 frameNodeSize_ = rect.GetSize();
904 #ifdef WEB_SUPPORTED
905 if (frameTag == V2::WEB_ETS_TAG) {
906 auto webPattern = frameNode->GetPattern<WebPattern>();
907 if (webPattern) {
908 frameNodeOffset_.SetX(frameNodeOffset_.GetX() + webPattern->GetDragOffset().GetX());
909 frameNodeOffset_.SetY(frameNodeOffset_.GetY() + webPattern->GetDragOffset().GetY());
910 frameNodeSize_ = webPattern->GetDragPixelMapSize();
911 }
912 }
913 #endif
914 }
915 /*
916 * Users may remove frameNode in the js callback function "onDragStart "triggered below,
917 * so save the offset of the framenode relative to the window in advance
918 */
919 DragDropInfo dragPreviewInfo;
920 auto dragDropInfo = GetDragDropInfo(info, frameNode, dragPreviewInfo, event);
921 auto dragDropManager = pipeline->GetDragDropManager();
922 CHECK_NULL_VOID(dragDropManager);
923 dragDropManager->SetDraggingPointer(info.GetPointerId());
924 dragDropManager->SetDraggingPressedState(true);
925 if (ParsePixelMapAsync(dragDropInfo, dragPreviewInfo, info)) {
926 OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
927 return;
928 }
929
930 #if defined(PIXEL_MAP_SUPPORTED)
931 if (dragDropInfo.pixelMap == nullptr && dragDropInfo.customNode) {
932 TAG_LOGI(AceLogTag::ACE_DRAG, "CustomNode exist, get thumbnail.");
933 StartDragForCustomBuilder(info, pipeline, frameNode, dragDropInfo, event);
934 return;
935 }
936 #endif
937 TAG_LOGI(AceLogTag::ACE_DRAG, "DragDropInfo is empty.");
938 if (!dragDropInfo.pixelMap) {
939 if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && GetTextDraggable() && pixelMap_) {
940 dragDropInfo.pixelMap = pixelMap_;
941 } else {
942 GenerateMousePixelMap(info);
943 dragDropInfo.pixelMap = pixelMap_;
944 }
945 }
946 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && !dragDropInfo.pixelMap) {
947 TAG_LOGD(AceLogTag::ACE_DRAG, "no any pixmap got, get node snapshot final try");
948 ACE_SCOPED_TRACE("drag: no any pixmap got, get node snapshot final try");
949 dragDropInfo.pixelMap = CreatePixelMapFromString(DEFAULT_MOUSE_DRAG_IMAGE);
950 }
951 OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
952 }
953
OnDragStart(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)954 void GestureEventHub::OnDragStart(const GestureEvent& info, const RefPtr<PipelineBase>& context,
955 const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
956 {
957 auto eventHub = eventHub_.Upgrade();
958 CHECK_NULL_VOID(eventHub);
959 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
960 CHECK_NULL_VOID(pipeline);
961
962 auto dragDropManager = pipeline->GetDragDropManager();
963 CHECK_NULL_VOID(dragDropManager);
964 if (dragDropProxy_) {
965 dragDropProxy_ = nullptr;
966 }
967 CHECK_NULL_VOID(dragEvent);
968 auto eventRet = dragEvent->GetResult();
969 if (eventRet == DragRet::DRAG_FAIL || eventRet == DragRet::DRAG_CANCEL) {
970 TAG_LOGI(AceLogTag::ACE_DRAG, "Drag result is %{public}d, stop dragging.", eventRet);
971 FireCustomerOnDragEnd(pipeline, eventHub);
972 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
973 SetMouseDragMonitorState(false);
974 }
975 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::APP_REFUSE_DRAG);
976 return;
977 }
978 std::string udKey;
979 int32_t recordsSize = 1;
980 auto unifiedData = GetUnifiedData(frameNode->GetTag(), dragDropInfo, dragEvent);
981 if (unifiedData) {
982 DragDropBehaviorReporter::GetInstance().UpdateRecordSize(unifiedData->GetSize());
983 }
984 CHECK_NULL_VOID(frameNode);
985 auto pattern = frameNode->GetPattern();
986 CHECK_NULL_VOID(pattern);
987 pattern->ResetDragOption();
988 if (pattern->GetDragRecordSize() >= 0) {
989 recordsSize = pattern->GetDragRecordSize();
990 } else if (unifiedData) {
991 auto recordSize = unifiedData->GetSize();
992 recordsSize = recordSize > 1 ? recordSize : 1;
993 }
994 auto ret = SetDragData(unifiedData, udKey);
995 if (ret != 0) {
996 TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF set data failed, return value is %{public}d", ret);
997 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SET_DATA_FAIL);
998 }
999
1000 std::map<std::string, int64_t> summary;
1001 ret = UdmfClient::GetInstance()->GetSummary(udKey, summary);
1002 if (ret != 0) {
1003 TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF get summary failed, return value is %{public}d", ret);
1004 }
1005 dragDropManager->SetSummaryMap(summary);
1006 RefPtr<PixelMap> pixelMap = dragDropInfo.pixelMap;
1007 if (pixelMap) {
1008 SetPixelMap(pixelMap);
1009 } else {
1010 FireCustomerOnDragEnd(pipeline, eventHub);
1011 TAG_LOGW(AceLogTag::ACE_DRAG, "Thumbnail pixelMap is empty.");
1012 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1013 SetMouseDragMonitorState(false);
1014 }
1015 return;
1016 }
1017 SetDragGatherPixelMaps(info);
1018 dragDropManager->SetIsMouseDrag(info.GetInputEventType() == InputEventType::MOUSE_BUTTON);
1019 auto dragPreviewOptions = frameNode->GetDragPreviewOption();
1020 auto badgeNumber = dragPreviewOptions.GetCustomerBadgeNumber();
1021 if (badgeNumber.has_value()) {
1022 recordsSize = badgeNumber.value();
1023 }
1024 auto dragNodePipeline = frameNode->GetContextRefPtr();
1025 CHECK_NULL_VOID(dragNodePipeline);
1026 auto overlayManager = dragNodePipeline->GetOverlayManager();
1027 bool isSwitchToSubWindow = false;
1028 RefPtr<FrameNode> imageNode = nullptr;
1029 RefPtr<FrameNode> textNode = nullptr;
1030 RefPtr<OverlayManager> subWindowOverlayManager = nullptr;
1031 bool isMenuShow = false;
1032 auto mainPipeline = PipelineContext::GetMainPipelineContext();
1033 bool isStartDraggingFromSubWindow = (pipeline != mainPipeline);
1034 auto window = SubwindowManager::GetInstance()->ShowPreviewNG(isStartDraggingFromSubWindow);
1035 if (window) {
1036 subWindowOverlayManager = window->GetOverlayManager();
1037 CHECK_NULL_VOID(subWindowOverlayManager);
1038 isMenuShow = subWindowOverlayManager->IsMenuShow();
1039 }
1040 if (isMenuShow) {
1041 dragDropManager->SetIsDragWithContextMenu(true);
1042 TAG_LOGI(AceLogTag::ACE_DRAG, "Drag with contextMenu.");
1043 } else {
1044 dragDropManager->SetIsDragWithContextMenu(false);
1045 }
1046 float defaultPixelMapScale =
1047 info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
1048 // use menuPreviewScale for drag framework. this is not final solution.
1049 if (!frameNode->GetDragPreview().onlyForLifting && isMenuShow && GreatNotEqual(menuPreviewScale_, 0.0f)) {
1050 auto menuPreviewRect = DragDropManager::GetMenuPreviewRect();
1051 if (GreatNotEqual(menuPreviewRect.Width(), 0.0f) && GreatNotEqual(menuPreviewRect.Height(), 0.0f)) {
1052 frameNodeOffset_ = menuPreviewRect.GetOffset();
1053 frameNodeSize_ = menuPreviewRect.GetSize();
1054 }
1055 auto originPixelMapWidth = pixelMap->GetWidth();
1056 if (GreatNotEqual(menuPreviewRect.Width(), 0.0f) && GreatNotEqual(originPixelMapWidth, 0.0f) &&
1057 menuPreviewRect.Width() < originPixelMapWidth * menuPreviewScale_) {
1058 defaultPixelMapScale = menuPreviewRect.Width() / originPixelMapWidth;
1059 } else {
1060 defaultPixelMapScale = menuPreviewScale_;
1061 }
1062 }
1063 auto windowScale = dragDropManager->GetWindowScale();
1064 float scale = windowScale * defaultPixelMapScale;
1065 auto focusHub = frameNode->GetFocusHub();
1066 bool hasContextMenu = focusHub == nullptr
1067 ? false : focusHub->FindContextMenuOnKeyEvent(OnKeyEventType::CONTEXT_MENU);
1068 bool isBindMenuPreview = GetPreviewMode() != MenuPreviewMode::NONE;
1069 dragDropManager->ResetContextMenuDragPosition();
1070 if (IsNeedSwitchToSubWindow() || isMenuShow) {
1071 imageNode = overlayManager->GetPixelMapContentNode();
1072 DragEventActuator::CreatePreviewNode(frameNode, imageNode, defaultPixelMapScale);
1073 OffsetF previewOffset;
1074 auto originPoint = imageNode->GetPositionToWindowWithTransform();
1075 if (hasContextMenu || isMenuShow) {
1076 auto previewDragMovePosition = dragDropManager->GetUpdateDragMovePosition();
1077 auto ret = SubwindowManager::GetInstance()->GetMenuPreviewCenter(previewOffset);
1078 if (isBindMenuPreview && ret) {
1079 previewOffset = previewOffset - OffsetF(pixelMap->GetWidth() / 2.0f, pixelMap->GetHeight() / 2.0f)
1080 + previewDragMovePosition;
1081 DragEventActuator::UpdatePreviewPositionAndScale(imageNode, previewOffset);
1082 } else {
1083 previewOffset = previewDragMovePosition + originPoint;
1084 DragEventActuator::UpdatePreviewPositionAndScale(imageNode, previewOffset);
1085 }
1086 }
1087
1088 auto frameTag = frameNode->GetTag();
1089 if (IsPixelMapNeedScale() && GetTextDraggable() && IsTextCategoryComponent(frameTag)) {
1090 auto textDragPattern = frameNode->GetPattern<TextDragBase>();
1091 CHECK_NULL_VOID(textDragPattern);
1092 auto dragNode = textDragPattern->MoveDragNode();
1093 if (dragNode) {
1094 auto dragNodeOffset = dragNode->GetPaintRectOffset();
1095 DragEventActuator::UpdatePreviewPositionAndScale(imageNode, dragNodeOffset);
1096 }
1097 }
1098
1099 if (IsPixelMapNeedScale() && frameTag == V2::WEB_ETS_TAG) {
1100 OffsetF webOffset;
1101 CHECK_NULL_VOID(pipeline);
1102 auto window = pipeline->GetWindow();
1103 CHECK_NULL_VOID(window);
1104 auto offset = window->GetCurrentWindowRect().GetOffset();
1105 webOffset.SetX(frameNodeOffset_.GetX() + offset.GetX());
1106 webOffset.SetY(frameNodeOffset_.GetY() + offset.GetY());
1107 DragEventActuator::UpdatePreviewPositionAndScale(imageNode, webOffset);
1108 }
1109
1110 CHECK_NULL_VOID(imageNode);
1111 float previewScale =
1112 info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
1113 if (IsPixelMapNeedScale()) {
1114 previewScale = static_cast<float>(imageNode->GetPreviewScaleVal());
1115 scale = previewScale * windowScale;
1116 }
1117 // use menu preview scale replace default pixelMap scale.
1118 if (isMenuShow) {
1119 auto imageGestureEventHub = imageNode->GetOrCreateGestureEventHub();
1120 CHECK_NULL_VOID(imageGestureEventHub);
1121 if (!IsPixelMapNeedScale()) {
1122 imageGestureEventHub->SetMenuPreviewScale(defaultPixelMapScale);
1123 } else {
1124 imageGestureEventHub->SetMenuPreviewScale(scale);
1125 }
1126 }
1127 auto childSize = badgeNumber.has_value() ? badgeNumber.value() : GetSelectItemSize();
1128 if (childSize > 1) {
1129 recordsSize = childSize;
1130 }
1131 textNode = DragEventActuator::CreateBadgeTextNode(frameNode, childSize, previewScale, true, previewOffset);
1132 if (window) {
1133 isSwitchToSubWindow = true;
1134 overlayManager->RemovePixelMap();
1135 }
1136 }
1137 CHECK_NULL_VOID(overlayManager);
1138 if (!overlayManager->GetIsOnAnimation()) {
1139 if (dragEventActuator_ != nullptr) {
1140 dragEventActuator_->SetIsNotInPreviewState(true);
1141 }
1142 }
1143 RefPtr<PixelMap> pixelMapDuplicated = GetPreScaledPixelMapIfExist(scale, pixelMap);
1144 dragEventActuator_->ResetPreScaledPixelMapForDragThroughTouch();
1145 dragPreviewPixelMap_ = nullptr;
1146 auto width = pixelMapDuplicated->GetWidth();
1147 auto height = pixelMapDuplicated->GetHeight();
1148 auto extraInfoLimited = dragDropInfo.extraInfo.size() > EXTRA_INFO_MAX_LENGTH
1149 ? dragDropInfo.extraInfo.substr(EXTRA_INFO_MAX_LENGTH + 1)
1150 : dragDropInfo.extraInfo;
1151 auto innerRect = ParseInnerRect(extraInfoLimited, SizeF(width, height));
1152 auto pixelMapOffset = OffsetF();
1153 if (isMenuShow && GreatNotEqual(defaultPixelMapScale, 0.0f)) {
1154 pixelMapOffset = GetPixelMapOffset(info, SizeF(width, height), scale / defaultPixelMapScale, true, innerRect);
1155 } else {
1156 pixelMapOffset = GetPixelMapOffset(info, SizeF(width, height), scale);
1157 }
1158 windowScale = NearZero(windowScale) ? 1.0f : windowScale;
1159 dragDropManager->SetPixelMapOffset(pixelMapOffset / windowScale);
1160 DragEventActuator::ResetNode(frameNode);
1161 auto arkExtraInfoJson = JsonUtil::Create(true);
1162 auto dragNodeGrayscale = pipeline->GetDragNodeGrayscale();
1163 auto dipScale = pipeline->GetDipScale();
1164 arkExtraInfoJson->Put("scale", scale);
1165 arkExtraInfoJson->Put("dip_scale", dipScale);
1166 arkExtraInfoJson->Put("drag_node_gray_scale", dragNodeGrayscale);
1167 arkExtraInfoJson->Put("event_id", info.GetPointerEventId());
1168 UpdateExtraInfo(frameNode, arkExtraInfoJson, scale);
1169 auto container = Container::Current();
1170 CHECK_NULL_VOID(container);
1171 DragDropBehaviorReporterTrigger trigger(DragReporterPharse::DRAG_START, container->GetInstanceId());
1172 auto windowId = container->GetWindowId();
1173 ShadowInfoCore shadowInfo { pixelMapDuplicated, pixelMapOffset.GetX(), pixelMapOffset.GetY() };
1174 DragDataCore dragData { { shadowInfo }, {}, udKey, extraInfoLimited, arkExtraInfoJson->ToString(),
1175 static_cast<int32_t>(info.GetSourceDevice()), recordsSize, info.GetPointerId(), info.GetScreenLocation().GetX(),
1176 info.GetScreenLocation().GetY(), info.GetTargetDisplayId(), windowId, true, false, summary };
1177 std::string summarys;
1178 for (const auto& [udkey, recordSize] : summary) {
1179 std::string str = udkey + "-" + std::to_string(recordSize) + ";";
1180 summarys += str;
1181 }
1182 DragDropBehaviorReporter::GetInstance().UpdateSummaryType(summarys);
1183 TAG_LOGI(AceLogTag::ACE_DRAG,
1184 "Start drag, frameNode is %{public}s, pixelMap width %{public}d height %{public}d, "
1185 "scale is %{public}f, udkey %{public}s, recordsSize %{public}d, pointerId %{public}d, "
1186 "displayId %{public}d, windowId %{public}d, summary %{public}s.",
1187 frameNode->GetTag().c_str(), width, height, scale, udKey.c_str(),
1188 recordsSize, info.GetPointerId(), info.GetTargetDisplayId(), windowId, summarys.c_str());
1189 dragDropManager->GetGatherPixelMap(dragData, scale, width, height);
1190 ret = InteractionInterface::GetInstance()->StartDrag(dragData, GetDragCallback(pipeline, eventHub));
1191 if (ret != 0) {
1192 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::DRAGFWK_START_FAIL);
1193 if (dragDropManager->IsNeedDisplayInSubwindow() && subWindowOverlayManager) {
1194 SubwindowManager::GetInstance()->HidePreviewNG();
1195 overlayManager->RemovePixelMap();
1196 }
1197 FireCustomerOnDragEnd(pipeline, eventHub);
1198 TAG_LOGW(AceLogTag::ACE_DRAG, "Start drag failed, return value is %{public}d", ret);
1199 return;
1200 }
1201 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::DRAG_START_SUCCESS);
1202 if (isSwitchToSubWindow && subWindowOverlayManager) {
1203 std::vector<GatherNodeChildInfo> gatherNodeChildrenInfo;
1204 auto gatherNode = DragEventActuator::GetOrCreateGatherNode(overlayManager,
1205 dragEventActuator_, gatherNodeChildrenInfo);
1206 DragEventActuator::MountGatherNode(subWindowOverlayManager, frameNode, gatherNode, gatherNodeChildrenInfo);
1207 DragEventActuator::UpdatePreviewPositionAndScale(
1208 imageNode, imageNode->GetOffsetInSubwindow(window->GetRect().GetOffset()));
1209 if (textNode) {
1210 DragEventActuator::UpdatePreviewPositionAndScale(
1211 textNode, textNode->GetOffsetInSubwindow(window->GetRect().GetOffset()));
1212 }
1213 DragEventActuator::MountPixelMap(
1214 subWindowOverlayManager, eventHub->GetGestureEventHub(), imageNode, textNode, true);
1215 HideMenu();
1216 pipeline->FlushSyncGeometryNodeTasks();
1217 DragAnimationHelper::ShowBadgeAnimation(textNode);
1218 dragDropManager->DoDragStartAnimation(
1219 subWindowOverlayManager, info, eventHub->GetGestureEventHub(), isMenuShow);
1220 if (hasContextMenu) {
1221 //response: 0.347, dampingRatio: 0.99, blendDuration: 0.0
1222 const RefPtr<Curve> curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(0.347f, 0.99f, 0.0f);
1223 AnimationOption option;
1224 option.SetCurve(curve);
1225 option.SetDuration(PIXELMAP_ANIMATION_DURATION);
1226 auto renderContext = imageNode->GetRenderContext();
1227 AnimationUtils::Animate(
1228 option,
1229 [renderContext]() {
1230 if (renderContext) {
1231 renderContext->UpdateOpacity(PIXELMAP_OPACITY_RATE);
1232 }
1233 },
1234 option.GetOnFinishEvent());
1235 }
1236 }
1237 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && IsNeedSwitchToSubWindow()) {
1238 ret = RegisterCoordinationListener(pipeline);
1239 if (ret != 0) {
1240 TAG_LOGW(AceLogTag::ACE_DRAG, "Register coordination listener failed, error is %{public}d", ret);
1241 }
1242 }
1243 dragDropManager->SetPreviewRect(Rect(pixelMapOffset.GetX(), pixelMapOffset.GetY(), width, height));
1244 dragDropManager->ResetRecordSize(static_cast<uint32_t>(recordsSize));
1245 auto eventManager = pipeline->GetEventManager();
1246 CHECK_NULL_VOID(eventManager);
1247 eventManager->DoMouseActionRelease();
1248 eventManager->SetIsDragging(true);
1249 if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && dragEventActuator_ != nullptr &&
1250 dragEventActuator_->GetIsNotInPreviewState()) {
1251 if (!dragDropManager->IsNeedDisplayInSubwindow() && !isMenuShow) {
1252 overlayManager->RemovePixelMap();
1253 overlayManager->RemovePreviewBadgeNode();
1254 overlayManager->RemoveGatherNode();
1255 pipeline->AddAfterRenderTask([]() { InteractionInterface::GetInstance()->SetDragWindowVisible(true); });
1256 }
1257 } else if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1258 if (!dragDropManager->IsNeedDisplayInSubwindow() && !isMenuShow) {
1259 pipeline->AddDragWindowVisibleTask([]() {
1260 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
1261 });
1262 }
1263 dragDropManager->SetIsDragWindowShow(true);
1264 }
1265 dragDropManager->FireOnEditableTextComponent(frameNode, DragEventType::ENTER);
1266 dragDropProxy_ = dragDropManager->CreateFrameworkDragDropProxy();
1267 CHECK_NULL_VOID(dragDropProxy_);
1268 dragDropProxy_->OnDragStart(info, extraInfoLimited, GetFrameNode());
1269 if (!dragDropManager->IsDraggingPressed(info.GetPointerId())) {
1270 dragDropManager->OnDragEnd(
1271 DragPointerEvent(info.GetGlobalPoint().GetX(), info.GetGlobalPoint().GetY()), extraInfoLimited);
1272 }
1273 }
1274
UpdateExtraInfo(const RefPtr<FrameNode> & frameNode,std::unique_ptr<JsonValue> & arkExtraInfoJson,float scale)1275 void GestureEventHub::UpdateExtraInfo(const RefPtr<FrameNode>& frameNode,
1276 std::unique_ptr<JsonValue>& arkExtraInfoJson, float scale)
1277 {
1278 double opacity = frameNode->GetDragPreviewOption().options.opacity;
1279 auto optionInfo = frameNode->GetDragPreviewOption().options;
1280 arkExtraInfoJson->Put("dip_opacity", opacity);
1281 TAG_LOGD(AceLogTag::ACE_DRAG, "The info of opacity update to the framework is %{public}s",
1282 arkExtraInfoJson->ToString().c_str());
1283
1284 if (optionInfo.blurbgEffect.backGroundEffect.radius.IsValid()) {
1285 optionInfo.blurbgEffect.ToJsonValue(arkExtraInfoJson);
1286 }
1287 DragEventActuator::PrepareShadowParametersForDragData(frameNode, arkExtraInfoJson, scale);
1288 DragEventActuator::PrepareRadiusParametersForDragData(frameNode, arkExtraInfoJson);
1289 }
1290
RegisterCoordinationListener(const RefPtr<PipelineBase> & context)1291 int32_t GestureEventHub::RegisterCoordinationListener(const RefPtr<PipelineBase>& context)
1292 {
1293 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1294 CHECK_NULL_RETURN(pipeline, -1);
1295 auto callback = [id = Container::CurrentId(), weak = WeakClaim(RawPtr(pipeline))]() {
1296 ContainerScope scope(id);
1297 auto context = weak.Upgrade();
1298 CHECK_NULL_VOID(context);
1299 auto dragDropManager = context->GetDragDropManager();
1300 CHECK_NULL_VOID(dragDropManager);
1301 auto taskScheduler = context->GetTaskExecutor();
1302 CHECK_NULL_VOID(taskScheduler);
1303 taskScheduler->PostTask([dragDropManager]() { dragDropManager->HideDragPreviewOverlay(); },
1304 TaskExecutor::TaskType::UI, "ArkUIGestureHideDragPreviewOverlay");
1305 };
1306 return InteractionInterface::GetInstance()->RegisterCoordinationListener(callback);
1307 }
1308
HandleOnDragUpdate(const GestureEvent & info)1309 void GestureEventHub::HandleOnDragUpdate(const GestureEvent& info)
1310 {
1311 gestureInfoForWeb_ = std::make_shared<GestureEvent>(info);
1312 CHECK_NULL_VOID(dragDropProxy_);
1313 auto pipeline = PipelineContext::GetCurrentContext();
1314 CHECK_NULL_VOID(pipeline);
1315 auto dragDropManager = pipeline->GetDragDropManager();
1316 if (dragDropManager->IsDragged()) {
1317 dragDropProxy_->OnDragMove(info);
1318 }
1319 if (IsNeedSwitchToSubWindow()) {
1320 DragPointerEvent pointerEvent =
1321 DragPointerEvent(info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY());
1322 dragDropManager->DoDragMoveAnimate(pointerEvent);
1323 }
1324 }
1325
HandleOnDragEnd(const GestureEvent & info)1326 void GestureEventHub::HandleOnDragEnd(const GestureEvent& info)
1327 {
1328 auto pipeline = NG::PipelineContext::GetCurrentContext();
1329 const static int32_t PLATFORM_VERSION_TEN = 10;
1330 if (pipeline && (pipeline->GetMinPlatformVersion() < PLATFORM_VERSION_TEN)) {
1331 auto eventHub = eventHub_.Upgrade();
1332 CHECK_NULL_VOID(eventHub);
1333
1334 auto frameNode = GetFrameNode();
1335 CHECK_NULL_VOID(frameNode);
1336
1337 // Only the onDrop callback of dragged frame node is triggered.
1338 // The onDrop callback of target frame node is triggered in PipelineContext::OnDragEvent.
1339 if (eventHub->HasOnDrop() || eventHub->HasCustomerOnDrop()) {
1340 RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1341 if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
1342 event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1343 event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1344 } else {
1345 event->SetX(info.GetGlobalPoint().GetX());
1346 event->SetY(info.GetGlobalPoint().GetY());
1347 }
1348 event->SetScreenX(info.GetScreenLocation().GetX());
1349 event->SetScreenY(info.GetScreenLocation().GetY());
1350 event->SetPressedKeyCodes(info.GetPressedKeyCodes());
1351 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event);
1352 eventHub->HandleInternalOnDrop(event, "");
1353 }
1354 }
1355 CHECK_NULL_VOID(dragDropProxy_);
1356 dragDropProxy_->DestroyDragWindow();
1357 dragDropProxy_ = nullptr;
1358 }
1359
HandleOnDragCancel()1360 void GestureEventHub::HandleOnDragCancel()
1361 {
1362 CHECK_NULL_VOID(dragDropProxy_);
1363 dragDropProxy_->DestroyDragWindow();
1364 dragDropProxy_ = nullptr;
1365 }
1366
SetFocusClickEvent(GestureEventFunc && clickEvent)1367 void GestureEventHub::SetFocusClickEvent(GestureEventFunc&& clickEvent)
1368 {
1369 auto eventHub = eventHub_.Upgrade();
1370 CHECK_NULL_VOID(eventHub);
1371 auto focusHub = eventHub->GetFocusHub();
1372 CHECK_NULL_VOID(focusHub);
1373 focusHub->SetOnClickCallback(std::move(clickEvent));
1374 }
1375
1376 // helper function to ensure clickActuator is initialized
CheckClickActuator()1377 void GestureEventHub::CheckClickActuator()
1378 {
1379 if (!clickEventActuator_) {
1380 clickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
1381 clickEventActuator_->SetOnAccessibility(GetOnAccessibilityEventFunc());
1382 }
1383
1384 if (parallelCombineClick && !userParallelClickEventActuator_) {
1385 userParallelClickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
1386 userParallelClickEventActuator_->SetOnAccessibility(GetOnAccessibilityEventFunc());
1387 }
1388 }
1389
SetUserOnClick(GestureEventFunc && clickEvent,double distanceThreshold)1390 void GestureEventHub::SetUserOnClick(GestureEventFunc&& clickEvent, double distanceThreshold)
1391 {
1392 CheckClickActuator();
1393 if (parallelCombineClick) {
1394 userParallelClickEventActuator_->SetUserCallback(std::move(clickEvent));
1395 SetFocusClickEvent(userParallelClickEventActuator_->GetClickEvent());
1396 auto clickRecognizer = userParallelClickEventActuator_->GetClickRecognizer();
1397 clickRecognizer->SetDistanceThreshold(distanceThreshold);
1398 } else {
1399 clickEventActuator_->SetUserCallback(std::move(clickEvent));
1400 SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1401 auto clickRecognizer = clickEventActuator_->GetClickRecognizer();
1402 clickRecognizer->SetDistanceThreshold(distanceThreshold);
1403 }
1404 }
1405
SetJSFrameNodeOnClick(GestureEventFunc && clickEvent)1406 void GestureEventHub::SetJSFrameNodeOnClick(GestureEventFunc&& clickEvent)
1407 {
1408 CheckClickActuator();
1409 if (parallelCombineClick) {
1410 userParallelClickEventActuator_->SetJSFrameNodeCallback(std::move(clickEvent));
1411 SetFocusClickEvent(userParallelClickEventActuator_->GetClickEvent());
1412 } else {
1413 clickEventActuator_->SetJSFrameNodeCallback(std::move(clickEvent));
1414 SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1415 }
1416 }
1417
SetOnGestureJudgeBegin(GestureJudgeFunc && gestureJudgeFunc)1418 void GestureEventHub::SetOnGestureJudgeBegin(GestureJudgeFunc&& gestureJudgeFunc)
1419 {
1420 gestureJudgeFunc_ = std::move(gestureJudgeFunc);
1421 }
1422
SetOnTouchIntercept(TouchInterceptFunc && touchInterceptFunc)1423 void GestureEventHub::SetOnTouchIntercept(TouchInterceptFunc&& touchInterceptFunc)
1424 {
1425 touchInterceptFunc_ = std::move(touchInterceptFunc);
1426 }
1427
GetOnTouchIntercept() const1428 TouchInterceptFunc GestureEventHub::GetOnTouchIntercept() const
1429 {
1430 return touchInterceptFunc_;
1431 }
1432
SetShouldBuildinRecognizerParallelWithFunc(ShouldBuiltInRecognizerParallelWithFunc && parallelGestureToFunc)1433 void GestureEventHub::SetShouldBuildinRecognizerParallelWithFunc(
1434 ShouldBuiltInRecognizerParallelWithFunc&& parallelGestureToFunc)
1435 {
1436 shouldBuildinRecognizerParallelWithFunc_ = std::move(parallelGestureToFunc);
1437 }
1438
GetParallelInnerGestureToFunc() const1439 ShouldBuiltInRecognizerParallelWithFunc GestureEventHub::GetParallelInnerGestureToFunc() const
1440 {
1441 return shouldBuildinRecognizerParallelWithFunc_;
1442 }
1443
SetOnGestureRecognizerJudgeBegin(GestureRecognizerJudgeFunc && gestureRecognizerJudgeFunc)1444 void GestureEventHub::SetOnGestureRecognizerJudgeBegin(GestureRecognizerJudgeFunc&& gestureRecognizerJudgeFunc)
1445 {
1446 gestureRecognizerJudgeFunc_ = std::move(gestureRecognizerJudgeFunc);
1447 }
1448
GetOnGestureRecognizerJudgeBegin() const1449 GestureRecognizerJudgeFunc GestureEventHub::GetOnGestureRecognizerJudgeBegin() const
1450 {
1451 return gestureRecognizerJudgeFunc_;
1452 }
1453
SetOnGestureJudgeNativeBegin(GestureJudgeFunc && gestureJudgeFunc)1454 void GestureEventHub::SetOnGestureJudgeNativeBegin(GestureJudgeFunc&& gestureJudgeFunc)
1455 {
1456 gestureJudgeNativeFunc_ = std::move(gestureJudgeFunc);
1457 }
1458
AddClickEvent(const RefPtr<ClickEvent> & clickEvent,double distanceThreshold)1459 void GestureEventHub::AddClickEvent(const RefPtr<ClickEvent>& clickEvent, double distanceThreshold)
1460 {
1461 CheckClickActuator();
1462 clickEventActuator_->AddClickEvent(clickEvent);
1463 clickEventActuator_->AddDistanceThreshold(distanceThreshold);
1464
1465 SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1466 }
1467
AddClickAfterEvent(const RefPtr<ClickEvent> & clickEvent)1468 void GestureEventHub::AddClickAfterEvent(const RefPtr<ClickEvent>& clickEvent)
1469 {
1470 CheckClickActuator();
1471 clickEventActuator_->AddClickAfterEvent(clickEvent);
1472
1473 SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1474 }
1475
1476 // replace last showMenu callback
BindMenu(GestureEventFunc && showMenu)1477 void GestureEventHub::BindMenu(GestureEventFunc&& showMenu)
1478 {
1479 if (showMenu_) {
1480 RemoveClickEvent(showMenu_);
1481 }
1482 showMenu_ = MakeRefPtr<ClickEvent>(std::move(showMenu));
1483 AddClickEvent(showMenu_);
1484 }
1485
GetOnAccessibilityEventFunc()1486 OnAccessibilityEventFunc GestureEventHub::GetOnAccessibilityEventFunc()
1487 {
1488 auto callback = [weak = WeakClaim(this)](AccessibilityEventType eventType) {
1489 auto gestureHub = weak.Upgrade();
1490 CHECK_NULL_VOID(gestureHub);
1491 auto node = gestureHub->GetFrameNode();
1492 CHECK_NULL_VOID(node);
1493 node->OnAccessibilityEvent(eventType);
1494 };
1495 return callback;
1496 }
1497
1498 template<typename T>
AccessibilityRecursionSearchRecognizer(const RefPtr<NGGestureRecognizer> & recognizer)1499 const RefPtr<T> GestureEventHub::AccessibilityRecursionSearchRecognizer(const RefPtr<NGGestureRecognizer>& recognizer)
1500 {
1501 auto CheckRecognizer = [](const RefPtr<NGGestureRecognizer>& recognizer) {
1502 const auto re = AceType::DynamicCast<ClickRecognizer>(recognizer);
1503 if (re != nullptr && re->GetFingers() == 1 && re->GetCount() == 1) {
1504 return true;
1505 } else if (AceType::DynamicCast<LongPressRecognizer>(recognizer) != nullptr &&
1506 AceType::DynamicCast<LongPressRecognizer>(recognizer)->GetFingers() == 1) {
1507 return true;
1508 }
1509 return false;
1510 };
1511
1512 const auto re = AceType::DynamicCast<T>(recognizer);
1513 if (re != nullptr && CheckRecognizer(recognizer)) {
1514 return re;
1515 } else if (AceType::DynamicCast<RecognizerGroup>(recognizer) != nullptr) {
1516 for (const auto& recognizerElement : AceType::DynamicCast<RecognizerGroup>(recognizer)->GetGroupRecognizer()) {
1517 const auto& tmpRecognizer = AccessibilityRecursionSearchRecognizer<T>(recognizerElement);
1518 if (tmpRecognizer != nullptr) {
1519 return tmpRecognizer;
1520 }
1521 }
1522 }
1523 return nullptr;
1524 }
1525
1526 template<typename T>
GetAccessibilityRecognizer()1527 const RefPtr<T> GestureEventHub::GetAccessibilityRecognizer()
1528 {
1529 for (const auto& recognizer : gestureHierarchy_) {
1530 const auto& re = AccessibilityRecursionSearchRecognizer<T>(recognizer);
1531 if (re != nullptr) {
1532 return re;
1533 }
1534 }
1535 return nullptr;
1536 }
1537
ActClick(std::shared_ptr<JsonValue> secComphandle)1538 bool GestureEventHub::ActClick(std::shared_ptr<JsonValue> secComphandle)
1539 {
1540 auto host = GetFrameNode();
1541 CHECK_NULL_RETURN(host, false);
1542 GestureEventFunc click;
1543 GestureEvent info;
1544 std::chrono::microseconds microseconds(GetMicroTickCount());
1545 TimeStamp time(microseconds);
1546 info.SetTimeStamp(time);
1547 EventTarget clickEventTarget;
1548 clickEventTarget.id = host->GetInspectorId().value_or("").c_str();
1549 clickEventTarget.type = host->GetTag();
1550 #ifdef SECURITY_COMPONENT_ENABLE
1551 info.SetSecCompHandleEvent(secComphandle);
1552 #endif
1553 auto geometryNode = host->GetGeometryNode();
1554 CHECK_NULL_RETURN(geometryNode, false);
1555 auto offset = geometryNode->GetFrameOffset();
1556 auto size = geometryNode->GetFrameSize();
1557 clickEventTarget.area.SetOffset(DimensionOffset(offset));
1558 clickEventTarget.area.SetHeight(Dimension(size.Height()));
1559 clickEventTarget.area.SetWidth(Dimension(size.Width()));
1560 clickEventTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1561 info.SetTarget(clickEventTarget);
1562 Offset globalOffset(offset.GetX(), offset.GetY());
1563 info.SetGlobalLocation(globalOffset);
1564 if (clickEventActuator_) {
1565 click = clickEventActuator_->GetClickEvent();
1566 CHECK_NULL_RETURN(click, true);
1567 click(info);
1568 return true;
1569 }
1570 const RefPtr<ClickRecognizer> clickRecognizer = GetAccessibilityRecognizer<ClickRecognizer>();
1571 if (clickRecognizer) {
1572 click = clickRecognizer->GetTapActionFunc();
1573 click(info);
1574 host->OnAccessibilityEvent(AccessibilityEventType::CLICK);
1575 return true;
1576 }
1577 return false;
1578 }
1579
ActLongClick()1580 bool GestureEventHub::ActLongClick()
1581 {
1582 auto host = GetFrameNode();
1583 CHECK_NULL_RETURN(host, false);
1584 GestureEventFunc click;
1585 GestureEvent info;
1586 std::chrono::microseconds microseconds(GetMicroTickCount());
1587 TimeStamp time(microseconds);
1588 info.SetTimeStamp(time);
1589 EventTarget longPressTarget;
1590 longPressTarget.id = host->GetInspectorId().value_or("").c_str();
1591 longPressTarget.type = host->GetTag();
1592 auto geometryNode = host->GetGeometryNode();
1593 CHECK_NULL_RETURN(geometryNode, false);
1594 auto offset = geometryNode->GetFrameOffset();
1595 auto size = geometryNode->GetFrameSize();
1596 longPressTarget.area.SetOffset(DimensionOffset(offset));
1597 longPressTarget.area.SetHeight(Dimension(size.Height()));
1598 longPressTarget.area.SetWidth(Dimension(size.Width()));
1599 longPressTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1600 info.SetTarget(longPressTarget);
1601 Offset globalOffset(offset.GetX(), offset.GetY());
1602 info.SetGlobalLocation(globalOffset);
1603 if (longPressEventActuator_) {
1604 click = longPressEventActuator_->GetGestureEventFunc();
1605 CHECK_NULL_RETURN(click, true);
1606 click(info);
1607 return true;
1608 }
1609 RefPtr<LongPressRecognizer> longPressRecognizer;
1610 for (auto gestureRecognizer : gestureHierarchy_) {
1611 longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(gestureRecognizer);
1612 if (longPressRecognizer && longPressRecognizer->GetFingers() == 1) {
1613 click = longPressRecognizer->GetLongPressActionFunc();
1614 click(info);
1615 host->OnAccessibilityEvent(AccessibilityEventType::LONG_PRESS);
1616 return true;
1617 }
1618 }
1619 return false;
1620 }
1621
GetHitTestModeStr() const1622 std::string GestureEventHub::GetHitTestModeStr() const
1623 {
1624 auto mode = static_cast<int32_t>(hitTestMode_);
1625 if (mode < 0 || mode >= static_cast<int32_t>(std::size(HIT_TEST_MODE))) {
1626 return HIT_TEST_MODE[0];
1627 }
1628 return HIT_TEST_MODE[mode];
1629 }
1630
KeyBoardShortCutClick(const KeyEvent & event,const WeakPtr<NG::FrameNode> & node)1631 bool GestureEventHub::KeyBoardShortCutClick(const KeyEvent& event, const WeakPtr<NG::FrameNode>& node)
1632 {
1633 auto host = node.Upgrade();
1634 CHECK_NULL_RETURN(host, false);
1635 CHECK_NULL_RETURN(clickEventActuator_, false);
1636 auto click = clickEventActuator_->GetClickEvent();
1637 CHECK_NULL_RETURN(click, false);
1638 GestureEvent info;
1639 info.SetSourceDevice(event.sourceType);
1640 info.SetTimeStamp(event.timeStamp);
1641 EventTarget target;
1642 target.id = host->GetInspectorId().value_or("").c_str();
1643 target.type = host->GetTag();
1644 auto geometryNode = host->GetGeometryNode();
1645 CHECK_NULL_RETURN(geometryNode, false);
1646 auto offset = geometryNode->GetFrameOffset();
1647 auto size = geometryNode->GetFrameSize();
1648 target.area.SetOffset(DimensionOffset(offset));
1649 target.area.SetHeight(Dimension(size.Height()));
1650 target.area.SetWidth(Dimension(size.Width()));
1651 target.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1652 info.SetTarget(target);
1653 click(info);
1654 return true;
1655 }
1656
SetDragData(const RefPtr<UnifiedData> & unifiedData,std::string & udKey)1657 int32_t GestureEventHub::SetDragData(const RefPtr<UnifiedData>& unifiedData, std::string& udKey)
1658 {
1659 CHECK_NULL_RETURN(unifiedData, -1);
1660 return UdmfClient::GetInstance()->SetData(unifiedData, udKey);
1661 }
1662
GetDragCallback(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)1663 OnDragCallbackCore GestureEventHub::GetDragCallback(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
1664 {
1665 auto ret = [](const DragNotifyMsgCore& notifyMessage) {};
1666 auto eventHub = hub.Upgrade();
1667 CHECK_NULL_RETURN(eventHub, ret);
1668 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1669 CHECK_NULL_RETURN(pipeline, ret);
1670 auto taskScheduler = pipeline->GetTaskExecutor();
1671 CHECK_NULL_RETURN(taskScheduler, ret);
1672 auto dragDropManager = pipeline->GetDragDropManager();
1673 CHECK_NULL_RETURN(dragDropManager, ret);
1674 auto eventManager = pipeline->GetEventManager();
1675 RefPtr<OHOS::Ace::DragEvent> dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1676 auto callback = [id = Container::CurrentId(), eventHub, dragEvent, taskScheduler, dragDropManager, eventManager](
1677 const DragNotifyMsgCore& notifyMessage) {
1678 ContainerScope scope(id);
1679 taskScheduler->PostTask(
1680 [eventHub, dragEvent, dragDropManager, eventManager, notifyMessage, id]() {
1681 dragDropManager->SetDragResult(notifyMessage, dragEvent);
1682 dragDropManager->SetDragBehavior(notifyMessage, dragEvent);
1683 dragDropManager->DoDragReset();
1684 dragDropManager->SetIsDragged(false);
1685 dragDropManager->SetDraggingPointer(-1);
1686 dragDropManager->SetDraggingPressedState(false);
1687 dragDropManager->ResetDragPreviewInfo();
1688 dragDropManager->HideDragPreviewWindow(id);
1689 dragEvent->SetPressedKeyCodes(dragDropManager->GetDragDropPointerEvent().pressedKeyCodes_);
1690 auto ret = InteractionInterface::GetInstance()->UnRegisterCoordinationListener();
1691 if (ret != 0) {
1692 TAG_LOGW(AceLogTag::ACE_DRAG, "Unregister coordination listener failed, error is %{public}d", ret);
1693 }
1694 if (eventManager) {
1695 eventManager->DoMouseActionRelease();
1696 }
1697 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
1698 if (eventHub->HasOnDragEnd()) {
1699 (eventHub->GetOnDragEnd())(dragEvent);
1700 }
1701 },
1702 TaskExecutor::TaskType::UI, "ArkUIGestureDragEnd");
1703 };
1704 return callback;
1705 }
1706
IsAccessibilityClickable()1707 bool GestureEventHub::IsAccessibilityClickable()
1708 {
1709 return IsClickable() || GetAccessibilityRecognizer<ClickRecognizer>() != nullptr;
1710 }
1711
IsAccessibilityLongClickable()1712 bool GestureEventHub::IsAccessibilityLongClickable()
1713 {
1714 return IsLongClickable() || GetAccessibilityRecognizer<LongPressRecognizer>() != nullptr;
1715 }
1716
GetMonopolizeEvents() const1717 bool GestureEventHub::GetMonopolizeEvents() const
1718 {
1719 return monopolizeEvents_;
1720 }
1721
SetMonopolizeEvents(bool monopolizeEvents)1722 void GestureEventHub::SetMonopolizeEvents(bool monopolizeEvents)
1723 {
1724 monopolizeEvents_ = monopolizeEvents;
1725 }
1726
ClearUserOnClick()1727 void GestureEventHub::ClearUserOnClick()
1728 {
1729 if (clickEventActuator_) {
1730 clickEventActuator_->ClearUserCallback();
1731 }
1732 }
1733
ClearUserOnTouch()1734 void GestureEventHub::ClearUserOnTouch()
1735 {
1736 if (touchEventActuator_) {
1737 touchEventActuator_->ClearUserCallback();
1738 }
1739 }
1740
ClearJSFrameNodeOnClick()1741 void GestureEventHub::ClearJSFrameNodeOnClick()
1742 {
1743 if (clickEventActuator_) {
1744 clickEventActuator_->ClearJSFrameNodeCallback();
1745 }
1746 }
1747
ClearJSFrameNodeOnTouch()1748 void GestureEventHub::ClearJSFrameNodeOnTouch()
1749 {
1750 if (touchEventActuator_) {
1751 touchEventActuator_->ClearJSFrameNodeCallback();
1752 }
1753 }
1754
CopyGestures(const RefPtr<GestureEventHub> & gestureEventHub)1755 void GestureEventHub::CopyGestures(const RefPtr<GestureEventHub>& gestureEventHub)
1756 {
1757 CHECK_NULL_VOID(gestureEventHub);
1758 gestures_ = gestureEventHub->backupGestures_;
1759 modifierGestures_ = gestureEventHub->backupModifierGestures_;
1760 recreateGesture_ = true;
1761 }
1762
CopyEvent(const RefPtr<GestureEventHub> & gestureEventHub)1763 void GestureEventHub::CopyEvent(const RefPtr<GestureEventHub>& gestureEventHub)
1764 {
1765 CHECK_NULL_VOID(gestureEventHub);
1766 auto originalTouchEventActuator = gestureEventHub->touchEventActuator_;
1767 if (originalTouchEventActuator) {
1768 touchEventActuator_ = MakeRefPtr<TouchEventActuator>();
1769 touchEventActuator_->CopyTouchEvent(originalTouchEventActuator);
1770 }
1771
1772 auto originalClickEventActuator = gestureEventHub->clickEventActuator_;
1773 if (originalClickEventActuator) {
1774 clickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
1775 clickEventActuator_->CopyClickEvent(originalClickEventActuator);
1776 }
1777
1778 auto originalLongPressEventActuator = gestureEventHub->longPressEventActuator_;
1779 if (originalLongPressEventActuator) {
1780 longPressEventActuator_ = MakeRefPtr<LongPressEventActuator>(WeakClaim(this));
1781 longPressEventActuator_->CopyLongPressEvent(originalLongPressEventActuator);
1782 }
1783
1784 auto originalDragEventActuator = gestureEventHub->dragEventActuator_;
1785 if (originalDragEventActuator) {
1786 dragEventActuator_ = MakeRefPtr<DragEventActuator>(WeakClaim(this), originalDragEventActuator->GetDirection(),
1787 originalDragEventActuator->GetFingers(), originalDragEventActuator->GetDistance());
1788 dragEventActuator_->CopyDragEvent(originalDragEventActuator);
1789 }
1790 auto originalShowMenu = gestureEventHub->showMenu_;
1791 if (originalShowMenu) {
1792 if (showMenu_) {
1793 RemoveClickEvent(showMenu_);
1794 }
1795 auto originalGetGestureEventFunc = originalShowMenu->GetGestureEventFunc();
1796 showMenu_= MakeRefPtr<ClickEvent>(std::move(originalGetGestureEventFunc));
1797 AddClickEvent(showMenu_);
1798 }
1799 }
1800
IsTextCategoryComponent(const std::string & frameTag)1801 bool GestureEventHub::IsTextCategoryComponent(const std::string& frameTag)
1802 {
1803 return frameTag == V2::TEXTAREA_ETS_TAG || frameTag == V2::TEXT_ETS_TAG ||
1804 frameTag == V2::TEXTINPUT_ETS_TAG || frameTag == V2::SEARCH_Field_ETS_TAG ||
1805 frameTag == V2::RICH_EDITOR_ETS_TAG;
1806 }
1807
SetDragForbiddenForcely(bool isDragForbiddenForWholeSubTree)1808 void GestureEventHub::SetDragForbiddenForcely(bool isDragForbiddenForWholeSubTree)
1809 {
1810 isDragForbiddenForWholeSubTree_ = isDragForbiddenForWholeSubTree;
1811 }
1812
IsDragForbidden() const1813 bool GestureEventHub::IsDragForbidden() const
1814 {
1815 return isDragForbiddenForWholeSubTree_;
1816 }
1817
GetDragDropInfo(const GestureEvent & info,const RefPtr<FrameNode> frameNode,DragDropInfo & dragPreviewInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1818 DragDropInfo GestureEventHub::GetDragDropInfo(const GestureEvent& info, const RefPtr<FrameNode> frameNode,
1819 DragDropInfo& dragPreviewInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1820 {
1821 DragDropInfo dragDropInfo;
1822 CHECK_NULL_RETURN(dragEventActuator_, dragDropInfo);
1823 dragEventActuator_->SetIsDefaultOnDragStartExecuted(false);
1824 auto eventHub = eventHub_.Upgrade();
1825 CHECK_NULL_RETURN(eventHub, dragDropInfo);
1826 auto extraParams = eventHub->GetDragExtraParams(std::string(), info.GetGlobalPoint(), DragEventType::START);
1827 auto onDragStart = eventHub->GetOnDragStart();
1828 if (!onDragStart && eventHub->HasDefaultOnDragStart()) {
1829 onDragStart = eventHub->GetDefaultOnDragStart();
1830 dragEventActuator_->SetIsDefaultOnDragStartExecuted(true);
1831 }
1832 if (GetTextDraggable() && info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1833 GenerateMousePixelMap(info);
1834 }
1835 dragEvent->SetPressedKeyCodes(info.GetPressedKeyCodes());
1836 dragDropInfo = onDragStart(dragEvent, extraParams);
1837
1838 auto frameTag = frameNode->GetTag();
1839 if (GetTextDraggable() && IsTextCategoryComponent(frameTag)) {
1840 TAG_LOGD(AceLogTag::ACE_DRAG, "Get drag drop info, pixelmap and customNode are set to null "
1841 "when frameTag is %{public}s", frameTag.c_str());
1842 dragDropInfo.pixelMap = nullptr;
1843 dragDropInfo.customNode = nullptr;
1844 } else {
1845 auto dragPreview = frameNode->GetDragPreview();
1846 if (dragPreview.onlyForLifting) {
1847 return dragDropInfo;
1848 }
1849 if (!dragPreview.customNode && dragPreview.delayCreating && dragPreview.buildFunc) {
1850 dragPreview.customNode = dragPreview.buildFunc();
1851 }
1852 frameNode->SetDragPreview(dragPreview);
1853 dragPreviewInfo = dragPreview;
1854 }
1855 return dragDropInfo;
1856 }
1857
GetUnifiedData(const std::string & frameTag,DragDropInfo & dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1858 RefPtr<UnifiedData> GestureEventHub::GetUnifiedData(const std::string& frameTag, DragDropInfo& dragDropInfo,
1859 const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1860 {
1861 auto eventHub = eventHub_.Upgrade();
1862 CHECK_NULL_RETURN(eventHub, nullptr);
1863 auto unifiedData = dragEvent->GetData();
1864 bool hasData = static_cast<bool>(unifiedData);
1865 if (!unifiedData && eventHub->HasDefaultOnDragStart()) {
1866 auto defaultDropInfo = eventHub->GetDefaultOnDragStart()(dragEvent, "");
1867 if (dragDropInfo.extraInfo.empty()) {
1868 dragDropInfo.extraInfo = defaultDropInfo.extraInfo;
1869 }
1870 CHECK_NULL_RETURN(dragEventActuator_, nullptr);
1871 dragEventActuator_->SetIsDefaultOnDragStartExecuted(true);
1872 unifiedData = dragEvent->GetData();
1873 }
1874 auto defaultOnDragStart = eventHub->GetDefaultOnDragStart();
1875 CHECK_NULL_RETURN(defaultOnDragStart, unifiedData);
1876 if (hasData && IsTextCategoryComponent(frameTag) && !dragEventActuator_->IsDefaultOnDragStartExecuted()) {
1877 defaultOnDragStart(dragEvent, "");
1878 }
1879 return unifiedData;
1880 }
1881
SetOnTouchEvent(TouchEventFunc && touchEventFunc)1882 void GestureEventHub::SetOnTouchEvent(TouchEventFunc&& touchEventFunc)
1883 {
1884 if (!touchEventActuator_) {
1885 touchEventActuator_ = MakeRefPtr<TouchEventActuator>();
1886 }
1887 touchEventActuator_->SetOnTouchEvent(std::move(touchEventFunc));
1888 }
1889
SetJSFrameNodeOnTouchEvent(TouchEventFunc && touchEventFunc)1890 void GestureEventHub::SetJSFrameNodeOnTouchEvent(TouchEventFunc&& touchEventFunc)
1891 {
1892 if (!touchEventActuator_) {
1893 touchEventActuator_ = MakeRefPtr<TouchEventActuator>();
1894 }
1895 touchEventActuator_->SetJSFrameNodeOnTouchEvent(std::move(touchEventFunc));
1896 }
1897
SetResponseRegion(const std::vector<DimensionRect> & responseRegion)1898 void GestureEventHub::SetResponseRegion(const std::vector<DimensionRect>& responseRegion)
1899 {
1900 responseRegion_ = responseRegion;
1901 if (!responseRegion_.empty()) {
1902 isResponseRegion_ = true;
1903 }
1904 if (responseRegionFunc_) {
1905 responseRegionFunc_(responseRegion_);
1906 }
1907 }
1908
RemoveLastResponseRect()1909 void GestureEventHub::RemoveLastResponseRect()
1910 {
1911 if (responseRegion_.empty()) {
1912 isResponseRegion_ = false;
1913 return;
1914 }
1915 responseRegion_.pop_back();
1916 if (responseRegion_.empty()) {
1917 isResponseRegion_ = false;
1918 }
1919
1920 if (responseRegionFunc_) {
1921 responseRegionFunc_(responseRegion_);
1922 }
1923 }
1924
RemoveGesturesByTag(const std::string & gestureTag)1925 void GestureEventHub::RemoveGesturesByTag(const std::string& gestureTag)
1926 {
1927 bool needRecollect = false;
1928 for (auto iter = modifierGestures_.begin(); iter != modifierGestures_.end();) {
1929 auto tag = (*iter)->GetTag();
1930 if (tag.has_value() && tag.value() == gestureTag) {
1931 iter = modifierGestures_.erase(iter);
1932 backupModifierGestures_.remove(*iter);
1933 needRecollect = true;
1934 } else {
1935 auto group = AceType::DynamicCast<GestureGroup>(*iter);
1936 if (group) {
1937 group->RemoveChildrenByTag(gestureTag, needRecollect);
1938 }
1939 iter++;
1940 }
1941 }
1942 if (needRecollect) {
1943 recreateGesture_ = true;
1944 needRecollect_ = true;
1945 OnModifyDone();
1946 }
1947 }
1948
ClearModifierGesture()1949 void GestureEventHub::ClearModifierGesture()
1950 {
1951 modifierGestures_.clear();
1952 backupModifierGestures_.clear();
1953 recreateGesture_ = true;
1954 OnModifyDone();
1955 }
1956
IsNeedSwitchToSubWindow() const1957 bool GestureEventHub::IsNeedSwitchToSubWindow() const
1958 {
1959 auto frameNode = GetFrameNode();
1960 CHECK_NULL_RETURN(frameNode, false);
1961 auto focusHub = frameNode->GetFocusHub();
1962 CHECK_NULL_RETURN(focusHub, false);
1963 if (IsPixelMapNeedScale()) {
1964 return true;
1965 }
1966 CHECK_NULL_RETURN(dragEventActuator_, false);
1967 return dragEventActuator_->IsNeedGather();
1968 }
1969
SetDragGatherPixelMaps(const GestureEvent & info)1970 void GestureEventHub::SetDragGatherPixelMaps(const GestureEvent& info)
1971 {
1972 CHECK_NULL_VOID(dragEventActuator_);
1973 if (!dragEventActuator_->IsNeedGather()) {
1974 return;
1975 }
1976 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1977 SetMouseDragGatherPixelMaps();
1978 } else {
1979 SetNotMouseDragGatherPixelMaps();
1980 }
1981 }
1982
ClearGesture()1983 void GestureEventHub::ClearGesture()
1984 {
1985 gestures_.clear();
1986 backupGestures_.clear();
1987 recreateGesture_ = true;
1988 }
1989
SetMouseDragGatherPixelMaps()1990 void GestureEventHub::SetMouseDragGatherPixelMaps()
1991 {
1992 auto frameNode = GetFrameNode();
1993 CHECK_NULL_VOID(frameNode);
1994 auto pipeline = PipelineContext::GetCurrentContext();
1995 CHECK_NULL_VOID(pipeline);
1996 auto dragDropManager = pipeline->GetDragDropManager();
1997 CHECK_NULL_VOID(dragDropManager);
1998 dragDropManager->ClearGatherPixelMap();
1999 CHECK_NULL_VOID(dragEventActuator_);
2000 auto fatherNode = dragEventActuator_->GetItemParentNode();
2001 CHECK_NULL_VOID(fatherNode);
2002 auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
2003 CHECK_NULL_VOID(scrollPattern);
2004 auto children = scrollPattern->GetVisibleSelectedItems();
2005 int cnt = 0;
2006 for (const auto& itemFrameNode : children) {
2007 if (itemFrameNode == frameNode) {
2008 continue;
2009 }
2010 CHECK_NULL_VOID(itemFrameNode);
2011 DragEventActuator::GetFrameNodePreviewPixelMap(itemFrameNode);
2012 auto gestureHub = itemFrameNode->GetOrCreateGestureEventHub();
2013 CHECK_NULL_VOID(gestureHub);
2014 dragDropManager->PushGatherPixelMap(gestureHub->GetDragPreviewPixelMap());
2015 cnt++;
2016 if (cnt > 1) {
2017 break;
2018 }
2019 }
2020 }
2021
SetNotMouseDragGatherPixelMaps()2022 void GestureEventHub::SetNotMouseDragGatherPixelMaps()
2023 {
2024 auto pipeline = PipelineContext::GetCurrentContext();
2025 CHECK_NULL_VOID(pipeline);
2026 auto dragDropManager = pipeline->GetDragDropManager();
2027 CHECK_NULL_VOID(dragDropManager);
2028 dragDropManager->ClearGatherPixelMap();
2029 auto mainPipeline = PipelineContext::GetMainPipelineContext();
2030 CHECK_NULL_VOID(mainPipeline);
2031 auto overlayManager = mainPipeline->GetOverlayManager();
2032 CHECK_NULL_VOID(overlayManager);
2033 auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
2034 int cnt = 0;
2035 for (auto iter = gatherNodeChildrenInfo.rbegin(); iter != gatherNodeChildrenInfo.rend(); ++iter) {
2036 auto imageNode = (*iter).imageNode.Upgrade();
2037 CHECK_NULL_VOID(imageNode);
2038 auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
2039 CHECK_NULL_VOID(imageLayoutProperty);
2040 auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value_or(ImageSourceInfo());
2041 dragDropManager->PushGatherPixelMap(imageSourceInfo.GetPixmap());
2042 cnt++;
2043 if (cnt > 1) {
2044 break;
2045 }
2046 }
2047 }
2048
GetSelectItemSize()2049 int32_t GestureEventHub::GetSelectItemSize()
2050 {
2051 CHECK_NULL_RETURN(dragEventActuator_, 0);
2052 if (!dragEventActuator_->IsNeedGather()) {
2053 return 0;
2054 }
2055 auto fatherNode = dragEventActuator_->GetItemParentNode();
2056 CHECK_NULL_RETURN(fatherNode, 0);
2057 auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
2058 CHECK_NULL_RETURN(scrollPattern, 0);
2059 auto children = scrollPattern->GetVisibleSelectedItems();
2060 return children.size();
2061 }
2062
FireCustomerOnDragEnd(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)2063 void GestureEventHub::FireCustomerOnDragEnd(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
2064 {
2065 auto eventHub = hub.Upgrade();
2066 CHECK_NULL_VOID(eventHub);
2067 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
2068 CHECK_NULL_VOID(pipeline);
2069 auto dragDropManager = pipeline->GetDragDropManager();
2070 CHECK_NULL_VOID(dragDropManager);
2071 auto dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
2072 CHECK_NULL_VOID(dragEvent);
2073 dragEvent->SetResult(DragRet::DRAG_FAIL);
2074 dragEvent->SetDragBehavior(DragBehavior::UNKNOWN);
2075 dragDropManager->DoDragReset();
2076 dragDropManager->SetIsDragged(false);
2077 dragDropManager->ResetDragging();
2078 dragDropManager->SetDraggingPointer(-1);
2079 dragDropManager->SetDraggingPressedState(false);
2080 dragDropManager->ResetDragPreviewInfo();
2081 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
2082 if (eventHub->HasOnDragEnd()) {
2083 (eventHub->GetOnDragEnd())(dragEvent);
2084 }
2085 }
2086
2087 #if defined(PIXEL_MAP_SUPPORTED)
PrintBuilderNode(const RefPtr<UINode> & customNode)2088 void GestureEventHub::PrintBuilderNode(const RefPtr<UINode>& customNode)
2089 {
2090 CHECK_NULL_VOID(customNode);
2091 bool hasImageNode = false;
2092 std::list<RefPtr<FrameNode>> imageNodes;
2093 int32_t depth = 1;
2094 PrintIfImageNode(customNode, depth, hasImageNode, imageNodes);
2095 CheckImageDecode(imageNodes);
2096 imageNodes.clear();
2097 }
2098
PrintIfImageNode(const RefPtr<UINode> & builderNode,int32_t depth,bool & hasImageNode,std::list<RefPtr<FrameNode>> & imageNodes)2099 void GestureEventHub::PrintIfImageNode(
2100 const RefPtr<UINode>& builderNode, int32_t depth, bool& hasImageNode, std::list<RefPtr<FrameNode>>& imageNodes)
2101 {
2102 if (depth > MAX_BUILDER_DEPTH) {
2103 return;
2104 }
2105 if (builderNode->GetTag() == V2::IMAGE_ETS_TAG) {
2106 auto frameNode = AceType::DynamicCast<FrameNode>(builderNode);
2107 CHECK_NULL_VOID(frameNode);
2108 auto pattern = frameNode->GetPattern<ImagePattern>();
2109 CHECK_NULL_VOID(pattern);
2110 hasImageNode = true;
2111 imageNodes.push_back(frameNode);
2112 TAG_LOGI(AceLogTag::ACE_DRAG,
2113 "customNode has ImageNode, syncLoad: %{public}d, decode complete: %{public}d",
2114 pattern->GetSyncLoad(), pattern->GetCanvasImage() != nullptr);
2115 }
2116
2117 auto children = builderNode->GetChildren();
2118 for (const auto& child : children) {
2119 PrintIfImageNode(child, depth + 1, hasImageNode, imageNodes);
2120 }
2121 }
2122
CheckImageDecode(std::list<RefPtr<FrameNode>> & imageNodes)2123 void GestureEventHub::CheckImageDecode(std::list<RefPtr<FrameNode>>& imageNodes)
2124 {
2125 if (imageNodes.empty()) {
2126 return;
2127 }
2128
2129 for (const auto& imageNode : imageNodes) {
2130 auto pattern = imageNode->GetPattern<ImagePattern>();
2131 CHECK_NULL_VOID(pattern);
2132 if (!pattern->GetCanvasImage()) {
2133 TAG_LOGW(
2134 AceLogTag::ACE_DRAG, "ImageNode did not complete decoding.");
2135 }
2136 }
2137 }
2138
StartDragForCustomBuilder(const GestureEvent & info,const RefPtr<PipelineBase> & pipeline,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & event)2139 void GestureEventHub::StartDragForCustomBuilder(const GestureEvent& info, const RefPtr<PipelineBase>& pipeline,
2140 const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& event)
2141 {
2142 SnapshotParam param;
2143 param.delay = CREATE_PIXELMAP_TIME;
2144 param.checkImageStatus = true;
2145 param.options.waitUntilRenderFinished = true;
2146 std::shared_ptr<Media::PixelMap> pixelMap = ComponentSnapshot::CreateSync(dragDropInfo.customNode, param);
2147 if (pixelMap != nullptr) {
2148 dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
2149 OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
2150 return;
2151 }
2152 TAG_LOGI(AceLogTag::ACE_DRAG, "Snapshot createSync failed, get thumbnail by async.");
2153 auto callback = [id = Container::CurrentId(), pipeline, info, gestureEventHubPtr = AceType::Claim(this), frameNode,
2154 dragDropInfo, event](std::shared_ptr<Media::PixelMap> pixelMap, int32_t arg, std::function<void()>
2155 finishCallback) mutable {
2156 ContainerScope scope(id);
2157 TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail callback executed.");
2158 if (pixelMap != nullptr) {
2159 dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
2160 } else {
2161 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SNAPSHOT_FAIL);
2162 }
2163 auto taskScheduler = pipeline->GetTaskExecutor();
2164 CHECK_NULL_VOID(taskScheduler);
2165 taskScheduler->PostTask(
2166 [pipeline, info, gestureEventHubPtr, frameNode, dragDropInfo, event, finishCallback]() {
2167 if (finishCallback) {
2168 finishCallback();
2169 }
2170 CHECK_NULL_VOID(gestureEventHubPtr);
2171 CHECK_NULL_VOID(frameNode);
2172 gestureEventHubPtr->OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
2173 },
2174 TaskExecutor::TaskType::UI, "ArkUIGestureDragStart");
2175 };
2176 NG::ComponentSnapshot::Create(dragDropInfo.customNode, std::move(callback), true, param);
2177 PrintBuilderNode(dragDropInfo.customNode);
2178 }
2179 #endif
2180
SetMouseDragMonitorState(bool state)2181 void GestureEventHub::SetMouseDragMonitorState(bool state)
2182 {
2183 auto ret = InteractionInterface::GetInstance()->SetMouseDragMonitorState(state);
2184 if (ret != 0) {
2185 TAG_LOGW(AceLogTag::ACE_DRAG, "Set mouse drag monitor state %{public}d failed, return value is %{public}d",
2186 state, ret);
2187 return;
2188 }
2189 TAG_LOGI(AceLogTag::ACE_DRAG, "Set mouse drag monitor state %{public}d success", state);
2190 }
2191
SetBindMenuStatus(bool setIsShow,bool isShow,MenuPreviewMode previewMode)2192 void GestureEventHub::SetBindMenuStatus(bool setIsShow, bool isShow, MenuPreviewMode previewMode)
2193 {
2194 if (setIsShow) {
2195 bindMenuStatus_.isBindCustomMenu = true;
2196 bindMenuStatus_.isShow = isShow;
2197 bindMenuStatus_.isShowPreviewMode = previewMode;
2198 } else {
2199 bindMenuStatus_.isBindLongPressMenu = true;
2200 bindMenuStatus_.longPressPreviewMode = previewMode;
2201 }
2202 }
2203
IsGestureEmpty() const2204 bool GestureEventHub::IsGestureEmpty() const
2205 {
2206 return gestures_.empty();
2207 }
2208
IsPanEventEmpty() const2209 bool GestureEventHub::IsPanEventEmpty() const
2210 {
2211 if (panEventActuator_) {
2212 return panEventActuator_->IsPanEventEmpty();
2213 }
2214 return true;
2215 }
2216
DumpVelocityInfoFroPanEvent(int32_t fingerId)2217 void GestureEventHub::DumpVelocityInfoFroPanEvent(int32_t fingerId)
2218 {
2219 CHECK_NULL_VOID(panEventActuator_);
2220 panEventActuator_->DumpVelocityInfo(fingerId);
2221 }
2222 } // namespace OHOS::Ace::NG
2223