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