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