1 /*
2 * Copyright (c) 2024 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 "base/image/image_source.h"
17 #include "base/log/ace_trace.h"
18 #include "base/log/log_wrapper.h"
19 #include "base/memory/ace_type.h"
20 #include "base/subwindow/subwindow_manager.h"
21 #include "core/common/container.h"
22 #include "core/common/interaction/interaction_data.h"
23 #include "core/common/interaction/interaction_interface.h"
24 #include "core/components/container_modal/container_modal_constants.h"
25 #include "core/components_ng/event/gesture_event_hub.h"
26 #include "core/components_ng/manager/drag_drop/drag_drop_behavior_reporter/drag_drop_behavior_reporter.h"
27 #include "core/components_ng/manager/drag_drop/drag_drop_func_wrapper.h"
28 #include "core/components_ng/manager/drag_drop/drag_drop_global_controller.h"
29 #include "core/components_ng/manager/drag_drop/drag_drop_manager.h"
30 #include "core/components_ng/manager/drag_drop/utils/drag_animation_helper.h"
31 #include "core/components_ng/pattern/image/image_pattern.h"
32 #include "core/components_ng/pattern/relative_container/relative_container_pattern.h"
33 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
34 #include "core/components_ng/pattern/text_drag/text_drag_base.h"
35 #include "core/components_ng/pattern/menu/preview/menu_preview_pattern.h"
36 #include "core/common/vibrator/vibrator_utils.h"
37
38 #if defined(PIXEL_MAP_SUPPORTED)
39 #include "image_source.h"
40 #endif
41
42 #include "core/common/udmf/udmf_client.h"
43 #include "core/components_ng/render/adapter/component_snapshot.h"
44 #ifdef WEB_SUPPORTED
45 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
46 #include "core/components_ng/pattern/web/web_pattern.h"
47 #else
48 #include "core/components_ng/pattern/web/cross_platform/web_pattern.h"
49 #endif
50 #endif
51 namespace OHOS::Ace::NG {
52 namespace {
53 #if defined(PIXEL_MAP_SUPPORTED)
54 constexpr int32_t CREATE_PIXELMAP_TIME = 30;
55 constexpr int32_t MAX_BUILDER_DEPTH = 5;
56 #endif
57 constexpr uint32_t EXTRA_INFO_MAX_LENGTH = 200;
58 constexpr int32_t DEFAULT_DRAG_DROP_STATUS = 0;
59 constexpr int32_t NEW_DRAG_DROP_STATUS = 1;
60 constexpr int32_t OLD_DRAG_DROP_STATUS = 3;
61 const std::unordered_set<std::string> OLD_FRAMEWORK_TAG = {
62 V2::WEB_ETS_TAG,
63 V2::TEXTAREA_ETS_TAG,
64 V2::TEXT_ETS_TAG,
65 V2::TEXTINPUT_ETS_TAG,
66 V2::SEARCH_Field_ETS_TAG,
67 V2::RICH_EDITOR_ETS_TAG,
68 };
69 const std::unordered_set<std::string> VALID_TAG = {
70 V2::WEB_ETS_TAG,
71 };
72 constexpr int32_t HALF_PIXELMAP = 2;
73 } // namespace
74 const std::string DEFAULT_MOUSE_DRAG_IMAGE { "/system/etc/device_status/drag_icon/Copy_Drag.svg" };
75
IsPixelMapNeedScale() const76 bool GestureEventHub::IsPixelMapNeedScale() const
77 {
78 auto frameNode = GetFrameNode();
79 CHECK_NULL_RETURN(frameNode, false);
80 auto scale = DragDropFuncWrapper::GetPixelMapScale(frameNode);
81 return scale != 1.0f;
82 }
83
IsDragNewFwk() const84 bool GestureEventHub::IsDragNewFwk() const
85 {
86 return isDragNewFwk_;
87 }
88
CheckNeedDragDropFrameworkStatus(const std::string & tag)89 bool CheckNeedDragDropFrameworkStatus(const std::string& tag)
90 {
91 auto dragDropFrameworkStatus = SystemProperties::GetDragDropFrameworkStatus();
92 if (dragDropFrameworkStatus == DEFAULT_DRAG_DROP_STATUS &&
93 (OLD_FRAMEWORK_TAG.find(tag) != OLD_FRAMEWORK_TAG.end())) {
94 return false;
95 } else if ((dragDropFrameworkStatus == NEW_DRAG_DROP_STATUS) && (VALID_TAG.find(tag) != VALID_TAG.end())) {
96 return false;
97 } else if (dragDropFrameworkStatus == OLD_DRAG_DROP_STATUS) {
98 return false;
99 }
100 return true;
101 }
102
InitDragDropEvent()103 void GestureEventHub::InitDragDropEvent()
104 {
105 auto frameNode = GetFrameNode();
106 if (frameNode && CheckNeedDragDropFrameworkStatus(frameNode->GetTag())) {
107 SetDragDropEvent();
108 return;
109 }
110 auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& info) {
111 auto gestureEventHub = weak.Upgrade();
112 CHECK_NULL_VOID(gestureEventHub);
113 gestureEventHub->HandleOnDragStart(info);
114 };
115
116 auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
117 auto gestureEventHub = weak.Upgrade();
118 CHECK_NULL_VOID(gestureEventHub);
119 gestureEventHub->HandleOnDragUpdate(info);
120 };
121
122 auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
123 auto gestureEventHub = weak.Upgrade();
124 CHECK_NULL_VOID(gestureEventHub);
125 gestureEventHub->HandleOnDragEnd(info);
126 };
127
128 auto actionCancelTask = [weak = WeakClaim(this)]() {
129 auto gestureEventHub = weak.Upgrade();
130 CHECK_NULL_VOID(gestureEventHub);
131 gestureEventHub->HandleOnDragCancel();
132 };
133 auto dragEvent = MakeRefPtr<DragEvent>(
134 std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
135 auto distance = SystemProperties::GetDragStartPanDistanceThreshold();
136 SetDragEvent(dragEvent, { PanDirection::ALL }, DEFAULT_PAN_FINGER, Dimension(distance, DimensionUnit::VP));
137 CHECK_NULL_VOID(dragEventActuator_);
138 dragEventActuator_->SetIsForDragDrop(false);
139 }
140
IsAllowedDrag(RefPtr<EventHub> eventHub)141 bool GestureEventHub::IsAllowedDrag(RefPtr<EventHub> eventHub)
142 {
143 auto frameNode = GetFrameNode();
144 CHECK_NULL_RETURN(frameNode, false);
145 auto pattern = frameNode->GetPattern();
146 CHECK_NULL_RETURN(pattern, false);
147
148 if (frameNode->IsDraggable()) {
149 if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
150 return false;
151 }
152 } else {
153 if (frameNode->IsUserSet()) {
154 return false;
155 }
156 if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
157 return false;
158 }
159 }
160 return true;
161 }
162
StartLongPressActionForWeb()163 void GestureEventHub::StartLongPressActionForWeb()
164 {
165 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start long press action for web");
166 auto pipeline = PipelineContext::GetCurrentContext();
167 CHECK_NULL_VOID(pipeline);
168 auto taskScheduler = pipeline->GetTaskExecutor();
169 CHECK_NULL_VOID(taskScheduler);
170
171 taskScheduler->PostTask(
172 [weak = WeakClaim(this)]() {
173 auto gestureHub = weak.Upgrade();
174 CHECK_NULL_VOID(gestureHub);
175 auto dragEventActuator = gestureHub->dragEventActuator_;
176 CHECK_NULL_VOID(dragEventActuator);
177 dragEventActuator->StartLongPressActionForWeb();
178 },
179 TaskExecutor::TaskType::UI, "ArkUIGestureWebStartLongPress");
180 }
181
CancelDragForWeb()182 void GestureEventHub::CancelDragForWeb()
183 {
184 TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop cancel drag for web");
185 auto pipeline = PipelineContext::GetCurrentContext();
186 CHECK_NULL_VOID(pipeline);
187 auto taskScheduler = pipeline->GetTaskExecutor();
188 CHECK_NULL_VOID(taskScheduler);
189
190 taskScheduler->PostTask(
191 [weak = WeakClaim(this)]() {
192 auto gestureHub = weak.Upgrade();
193 CHECK_NULL_VOID(gestureHub);
194 auto dragEventActuator = gestureHub->dragEventActuator_;
195 CHECK_NULL_VOID(dragEventActuator);
196 dragEventActuator->CancelDragForWeb();
197 },
198 TaskExecutor::TaskType::UI, "ArkUIGestureWebCancelDrag");
199 }
200
ResetDragActionForWeb()201 void GestureEventHub::ResetDragActionForWeb()
202 {
203 TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop reset drag action for web");
204 isReceivedDragGestureInfo_ = false;
205 CHECK_NULL_VOID(dragEventActuator_);
206 dragEventActuator_->ResetDragActionForWeb();
207
208 // fix drag failed when long press drag after 500ms and before 800ms
209 // need to reset the state of the drag manager
210 auto pipeLine = PipelineContext::GetCurrentContext();
211 CHECK_NULL_VOID(pipeLine);
212 auto dragDropManager = pipeLine->GetDragDropManager();
213 CHECK_NULL_VOID(dragDropManager);
214 dragDropManager->ResetDragging();
215 }
216
StartDragTaskForWeb()217 bool GestureEventHub::StartDragTaskForWeb()
218 {
219 if (!isReceivedDragGestureInfo_) {
220 TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop StartDragTaskForWeb failed,"
221 "because not recv gesture info");
222 return false;
223 }
224
225 isReceivedDragGestureInfo_ = false;
226 auto pipeline = PipelineContext::GetCurrentContext();
227 CHECK_NULL_RETURN(pipeline, false);
228 auto taskScheduler = pipeline->GetTaskExecutor();
229 CHECK_NULL_RETURN(taskScheduler, false);
230
231 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop post a task to start drag for web");
232 taskScheduler->PostTask(
233 [weak = WeakClaim(this)]() {
234 auto gestureHub = weak.Upgrade();
235 CHECK_NULL_VOID(gestureHub);
236 auto dragEventActuator = gestureHub->dragEventActuator_;
237 CHECK_NULL_VOID(dragEventActuator);
238 CHECK_NULL_VOID(gestureHub->gestureInfoForWeb_);
239 TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start drag task for web in async task");
240 dragEventActuator->StartDragTaskForWeb(*gestureHub->gestureInfoForWeb_);
241 },
242 TaskExecutor::TaskType::UI, "ArkUIGestureWebStartDrag");
243 return true;
244 }
245
CreatePixelMapFromString(const std::string & filePath)246 RefPtr<PixelMap> CreatePixelMapFromString(const std::string& filePath)
247 {
248 auto imageSource = ImageSource::Create(filePath);
249 CHECK_NULL_RETURN(imageSource, nullptr);
250 RefPtr<PixelMap> pixelMap = imageSource->CreatePixelMap();
251 return pixelMap;
252 }
253
CalcFrameNodeOffsetAndSize(const RefPtr<FrameNode> frameNode,bool isMenuShow)254 void GestureEventHub::CalcFrameNodeOffsetAndSize(const RefPtr<FrameNode> frameNode, bool isMenuShow)
255 {
256 CHECK_NULL_VOID(frameNode);
257 auto frameTag = frameNode->GetTag();
258 auto hostPattern = frameNode->GetPattern<TextDragBase>();
259 if (hostPattern && GetTextDraggable() &&
260 (frameTag == V2::RICH_EDITOR_ETS_TAG || frameTag == V2::TEXT_ETS_TAG || frameTag == V2::TEXTINPUT_ETS_TAG ||
261 frameTag == V2::SEARCH_Field_ETS_TAG)) {
262 frameNodeOffset_ = hostPattern->GetDragUpperLeftCoordinates();
263 frameNodeSize_ = SizeF(0.0f, 0.0f);
264 } else {
265 auto rect = DragDropFuncWrapper::GetPaintRectToScreen(frameNode) -
266 DragDropFuncWrapper::GetCurrentWindowOffset(PipelineContext::GetCurrentContextSafelyWithCheck());
267 frameNodeOffset_ = rect.GetOffset();
268 frameNodeSize_ = rect.GetSize();
269 #ifdef WEB_SUPPORTED
270 if (frameTag == V2::WEB_ETS_TAG) {
271 auto webPattern = frameNode->GetPattern<WebPattern>();
272 if (webPattern) {
273 frameNodeOffset_.SetX(frameNodeOffset_.GetX() + webPattern->GetDragOffset().GetX());
274 frameNodeOffset_.SetY(frameNodeOffset_.GetY() + webPattern->GetDragOffset().GetY());
275 frameNodeSize_ = webPattern->GetDragPixelMapSize();
276 }
277 }
278 #endif
279 }
280
281 // use menuPreview's size and offset for drag framework.
282 if (!frameNode->GetDragPreview().onlyForLifting && isMenuShow && GreatNotEqual(menuPreviewScale_, 0.0f)) {
283 auto menuPreviewRect = DragDropManager::GetMenuPreviewRect();
284 if (GreatNotEqual(menuPreviewRect.Width(), 0.0f) && GreatNotEqual(menuPreviewRect.Height(), 0.0f)) {
285 frameNodeOffset_ = menuPreviewRect.GetOffset();
286 frameNodeSize_ = menuPreviewRect.GetSize();
287 }
288 }
289 }
290
GetDefaultPixelMapScale(const RefPtr<FrameNode> & frameNode,const GestureEvent & info,bool isMenuShow,RefPtr<PixelMap> pixelMap)291 float GestureEventHub::GetDefaultPixelMapScale(
292 const RefPtr<FrameNode>& frameNode, const GestureEvent& info, bool isMenuShow, RefPtr<PixelMap> pixelMap)
293 {
294 float defaultPixelMapScale =
295 info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
296 CHECK_NULL_RETURN(pixelMap, defaultPixelMapScale);
297 // use menuPreviewScale for drag framework. this is not final solution.
298 if (!frameNode->GetDragPreview().onlyForLifting && isMenuShow && GreatNotEqual(menuPreviewScale_, 0.0f)) {
299 auto menuPreviewRectWidth = frameNodeSize_.Width();
300 int32_t originPixelMapWidth = pixelMap->GetWidth();
301 if (GreatNotEqual(menuPreviewRectWidth, 0.0f) && GreatNotEqual(originPixelMapWidth, 0.0f) &&
302 menuPreviewRectWidth < originPixelMapWidth * menuPreviewScale_) {
303 defaultPixelMapScale = menuPreviewRectWidth / originPixelMapWidth;
304 } else {
305 defaultPixelMapScale = menuPreviewScale_;
306 }
307 }
308 return defaultPixelMapScale;
309 }
310
CheckInSceneBoardWindow()311 bool CheckInSceneBoardWindow()
312 {
313 auto container = Container::Current();
314 CHECK_NULL_RETURN(container, false);
315 if (!container->IsSubContainer()) {
316 return container->IsScenceBoardWindow();
317 }
318 auto parentContainerId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
319 container = Container::GetContainer(parentContainerId);
320 CHECK_NULL_RETURN(container, false);
321 return container->IsScenceBoardWindow();
322 }
323
CheckOffsetInPixelMap(OffsetF & result,const SizeF & size)324 void CheckOffsetInPixelMap(OffsetF& result, const SizeF& size)
325 {
326 if (result.GetX() >= 0.0f) {
327 result.SetX(-1.0f);
328 }
329 if (result.GetX() + size.Width() <= 0.0f) {
330 result.SetX(1.0f - size.Width());
331 }
332 if (result.GetY() >= 0.0f) {
333 result.SetY(-1.0f);
334 }
335 if (result.GetY() + size.Height() <= 0.0f) {
336 result.SetY(1.0f - size.Height());
337 }
338 }
339
ParseInnerRect(const std::string & extraInfo,const SizeF & size)340 RectF ParseInnerRect(const std::string& extraInfo, const SizeF& size)
341 {
342 auto innerRect = RectF();
343 if (!CheckInSceneBoardWindow() || extraInfo.empty()) {
344 return innerRect;
345 }
346 auto extraJson = JsonUtil::ParseJsonString(extraInfo);
347 CHECK_NULL_RETURN(extraJson, innerRect);
348 auto extraOffsetX = extraJson->GetInt("drag_offset_x");
349 auto extraOffsetY = extraJson->GetInt("drag_offset_y");
350 if (extraOffsetX <= 0 || extraOffsetY <= 0) {
351 return innerRect;
352 }
353 innerRect.SetOffset(OffsetF(Dimension(extraOffsetX, DimensionUnit::VP).ConvertToPx(),
354 Dimension(extraOffsetY, DimensionUnit::VP).ConvertToPx()));
355 innerRect.SetSize(size);
356 return innerRect;
357 }
358
GetPixelMapOffset(const GestureEvent & info,const SizeF & size,const PreparedInfoForDrag & dragInfoData,const float scale,const RectF & innerRect) const359 OffsetF GestureEventHub::GetPixelMapOffset(const GestureEvent& info, const SizeF& size,
360 const PreparedInfoForDrag& dragInfoData, const float scale, const RectF& innerRect) const
361 {
362 OffsetF result = OffsetF(size.Width() * PIXELMAP_WIDTH_RATE, size.Height() * PIXELMAP_HEIGHT_RATE);
363 auto frameNode = GetFrameNode();
364 CHECK_NULL_RETURN(frameNode, result);
365 auto frameTag = frameNode->GetTag();
366 auto coordinateX = frameNodeOffset_.GetX();
367 auto coordinateY = frameNodeOffset_.GetY();
368 if (!innerRect.IsEmpty() && !NearZero(size.Width()) && !NearZero(size.Height())) {
369 auto rateX = innerRect.Width() / size.Width();
370 auto rateY = innerRect.Height() / size.Height();
371 result.SetX(rateX * (coordinateX + innerRect.GetOffset().GetX() - info.GetGlobalLocation().GetX()));
372 result.SetY(rateY * (coordinateY + innerRect.GetOffset().GetY() - info.GetGlobalLocation().GetY()));
373 CheckOffsetInPixelMap(result, size);
374 return result;
375 }
376 if (NearZero(frameNodeSize_.Width()) || NearZero(frameNodeSize_.Height()) ||
377 NearZero(size.Width()) || NearZero(size.Height())) {
378 result.SetX(scale * (coordinateX - info.GetGlobalLocation().GetX()));
379 result.SetY(scale * (coordinateY - info.GetGlobalLocation().GetY()));
380 } else {
381 if (dragInfoData.isNeedCreateTiled) {
382 result.SetX(-size.Width() / HALF_PIXELMAP);
383 result.SetY(-size.Height() / HALF_PIXELMAP);
384 } else if (frameNode->GetDragPreviewOption().isTouchPointCalculationBasedOnFinalPreviewEnable) {
385 auto centerX = coordinateX + frameNodeSize_.Width() / HALF_PIXELMAP;
386 auto centerY = coordinateY + frameNodeSize_.Height() / HALF_PIXELMAP;
387 coordinateX = centerX - dragInfoData.dragPreviewRect.Width() / HALF_PIXELMAP;
388 coordinateY = centerY - dragInfoData.dragPreviewRect.Height() / HALF_PIXELMAP;
389 auto rateX = (info.GetGlobalLocation().GetX() - coordinateX) / dragInfoData.dragPreviewRect.Width();
390 auto rateY = (info.GetGlobalLocation().GetY() - coordinateY) / dragInfoData.dragPreviewRect.Height();
391 result.SetX(-rateX * size.Width());
392 result.SetY(-rateY * size.Height());
393 } else {
394 auto rateX = (info.GetGlobalLocation().GetX() - coordinateX) / frameNodeSize_.Width();
395 auto rateY = (info.GetGlobalLocation().GetY() - coordinateY) / frameNodeSize_.Height();
396 result.SetX(-rateX * size.Width());
397 result.SetY(-rateY * size.Height());
398 }
399 }
400 CheckOffsetInPixelMap(result, size);
401 TAG_LOGD(AceLogTag::ACE_DRAG, "Get pixelMap offset is %{public}f and %{public}f.", result.GetX(), result.GetY());
402 return result;
403 }
404
ProcessMenuPreviewScale(const RefPtr<FrameNode> imageNode,float & scale,float previewScale,float windowScale,float defaultMenuPreviewScale)405 void GestureEventHub::ProcessMenuPreviewScale(const RefPtr<FrameNode> imageNode, float& scale, float previewScale,
406 float windowScale, float defaultMenuPreviewScale)
407 {
408 auto imageGestureEventHub = imageNode->GetOrCreateGestureEventHub();
409 CHECK_NULL_VOID(imageGestureEventHub);
410 if (!IsPixelMapNeedScale()) {
411 if (CheckInSceneBoardWindow()) {
412 imageGestureEventHub->SetMenuPreviewScale(defaultMenuPreviewScale);
413 } else {
414 //if not in sceneboard,use default drag scale
415 scale = previewScale * windowScale;
416 imageGestureEventHub->SetMenuPreviewScale(previewScale);
417 }
418 } else {
419 imageGestureEventHub->SetMenuPreviewScale(scale);
420 }
421 }
422
GetPreScaledPixelMapIfExist(float targetScale,RefPtr<PixelMap> defaultPixelMap)423 RefPtr<PixelMap> GestureEventHub::GetPreScaledPixelMapIfExist(float targetScale, RefPtr<PixelMap> defaultPixelMap)
424 {
425 ACE_SCOPED_TRACE("drag: get scaled pixmal, %f", targetScale);
426 float preScale = 1.0f;
427 CHECK_NULL_RETURN(dragEventActuator_, defaultPixelMap);
428 auto frameNode = GetFrameNode();
429 RefPtr<PixelMap> preScaledPixelMap;
430 if (!(frameNode && frameNode->GetDragPreview().onlyForLifting)) {
431 preScaledPixelMap = dragEventActuator_->GetPreScaledPixelMapForDragThroughTouch(preScale);
432 }
433 if (preScale == targetScale && preScaledPixelMap != nullptr) {
434 return preScaledPixelMap;
435 }
436 #if defined(PIXEL_MAP_SUPPORTED)
437 preScaledPixelMap = PixelMap::CopyPixelMap(defaultPixelMap);
438 if (!preScaledPixelMap) {
439 TAG_LOGW(AceLogTag::ACE_DRAG, "duplicate PixelMap failed!");
440 preScaledPixelMap = defaultPixelMap;
441 }
442 if (!NearEqual(targetScale, 1.0f)) {
443 preScaledPixelMap->Scale(targetScale, targetScale, AceAntiAliasingOption::HIGH);
444 }
445 #else
446 preScaledPixelMap = defaultPixelMap;
447 #endif
448 return preScaledPixelMap;
449 }
450
GetPixelMapScale(const int32_t height,const int32_t width) const451 float GestureEventHub::GetPixelMapScale(const int32_t height, const int32_t width) const
452 {
453 float scale = 1.0f;
454 if (height == 0 || width == 0) {
455 return scale;
456 }
457 auto frameNode = GetFrameNode();
458 CHECK_NULL_RETURN(frameNode, scale);
459 auto pipeline = frameNode->GetContextRefPtr();
460 CHECK_NULL_RETURN(pipeline, scale);
461 auto dragDropManager = pipeline->GetDragDropManager();
462 CHECK_NULL_RETURN(dragDropManager, scale);
463 auto windowScale = dragDropManager->GetWindowScale();
464 if (!frameNode->GetDragPreviewOption().isScaleEnabled || !(frameNode->GetTag() == V2::WEB_ETS_TAG)) {
465 return scale * windowScale;
466 }
467 int32_t deviceHeight = SystemProperties::GetDevicePhysicalHeight();
468 int32_t deviceWidth = SystemProperties::GetDevicePhysicalWidth();
469 int32_t maxDeviceLength = std::max(deviceHeight, deviceWidth);
470 int32_t minDeviceLength = std::min(deviceHeight, deviceWidth);
471 if (maxDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE > minDeviceLength) {
472 if (height > minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) {
473 scale = static_cast<float>(minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) / height;
474 }
475 } else {
476 if (GetTextDraggable() && height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
477 width > minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) {
478 scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
479 static_cast<float>(minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) / width);
480 } else if (height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
481 width > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) {
482 scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
483 static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / width);
484 }
485 }
486 return scale * windowScale;
487 }
488
GenerateMousePixelMap(const GestureEvent & info)489 void GestureEventHub::GenerateMousePixelMap(const GestureEvent& info)
490 {
491 auto frameNode = GetFrameNode();
492 CHECK_NULL_VOID(frameNode);
493 RefPtr<RenderContext> context;
494 if (GetTextDraggable()) {
495 auto pattern = frameNode->GetPattern<TextDragBase>();
496 CHECK_NULL_VOID(pattern);
497 auto dragNode = pattern->MoveDragNode();
498 CHECK_NULL_VOID(dragNode);
499 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
500 CHECK_NULL_VOID(pipeline);
501 pipeline->FlushPipelineImmediately();
502 context = dragNode->GetRenderContext();
503 } else {
504 context = frameNode->GetRenderContext();
505 }
506 CHECK_NULL_VOID(context);
507 auto thumbnailPixelMap = context->GetThumbnailPixelMap(false, GetTextDraggable());
508 CHECK_NULL_VOID(thumbnailPixelMap);
509 SetPixelMap(thumbnailPixelMap);
510 }
511
HandleNotAllowDrag(const GestureEvent & info)512 void GestureEventHub::HandleNotAllowDrag(const GestureEvent& info)
513 {
514 auto frameNode = GetFrameNode();
515 CHECK_NULL_VOID(frameNode);
516 if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
517 gestureInfoForWeb_ = std::make_shared<GestureEvent>(info);
518 isReceivedDragGestureInfo_ = true;
519 TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop drag gesture info received");
520 }
521 }
522
HandleDragThroughTouch(const RefPtr<FrameNode> frameNode)523 void GestureEventHub::HandleDragThroughTouch(const RefPtr<FrameNode> frameNode)
524 {
525 CHECK_NULL_VOID(frameNode);
526 dragframeNodeInfo_.frameNode = frameNode;
527 auto pipeline = frameNode->GetContextRefPtr();
528 CHECK_NULL_VOID(pipeline);
529 auto dragDropManager = pipeline->GetDragDropManager();
530 CHECK_NULL_VOID(dragDropManager);
531 auto grayedState = dragDropManager->GetGrayedState();
532 if (grayedState) {
533 return;
534 }
535 auto overlayManager = pipeline->GetOverlayManager();
536 CHECK_NULL_VOID(overlayManager);
537 auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
538 if (!gatherNodeChildrenInfo.empty()) {
539 for (const auto& itemFrameNode : gatherNodeChildrenInfo) {
540 auto node = itemFrameNode.preImageNode.Upgrade();
541 CHECK_NULL_VOID(node);
542 dragframeNodeInfo_.gatherFrameNode.push_back(node);
543 DragAnimationHelper::DoDragStartGrayedAnimation(node);
544 }
545 dragframeNodeInfo_.gatherFrameNode.push_back(frameNode);
546 }
547 DragAnimationHelper::DoDragStartGrayedAnimation(frameNode);
548 dragDropManager->SetGrayedState(true);
549 }
550
HandleDragThroughMouse(const RefPtr<FrameNode> frameNode)551 void GestureEventHub::HandleDragThroughMouse(const RefPtr<FrameNode> frameNode)
552 {
553 CHECK_NULL_VOID(frameNode);
554 dragframeNodeInfo_.frameNode = frameNode;
555 auto pipeline = frameNode->GetContextRefPtr();
556 CHECK_NULL_VOID(pipeline);
557 auto dragDropManager = pipeline->GetDragDropManager();
558 CHECK_NULL_VOID(dragDropManager);
559 auto grayedState = dragDropManager->GetGrayedState();
560 if (grayedState) {
561 return;
562 }
563 auto size = GetSelectItemSize();
564 if (size) {
565 auto fatherNode = DragDropFuncWrapper::FindItemParentNode(frameNode);
566 CHECK_NULL_VOID(fatherNode);
567 auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
568 CHECK_NULL_VOID(scrollPattern);
569 auto children = scrollPattern->GetVisibleSelectedItems();
570 dragframeNodeInfo_.gatherFrameNode = children;
571 for (const auto& itemFrameNode : children) {
572 DragAnimationHelper::DoDragStartGrayedAnimation(itemFrameNode);
573 }
574 } else {
575 DragAnimationHelper::DoDragStartGrayedAnimation(frameNode);
576 }
577 dragDropManager->SetGrayedState(true);
578 }
579
IsNeedSwitchToSubWindow(const PreparedInfoForDrag & dragInfoData) const580 bool GestureEventHub::IsNeedSwitchToSubWindow(const PreparedInfoForDrag& dragInfoData) const
581 {
582 auto frameNode = GetFrameNode();
583 CHECK_NULL_RETURN(frameNode, false);
584 auto focusHub = frameNode->GetFocusHub();
585 CHECK_NULL_RETURN(focusHub, false);
586 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
587 CHECK_NULL_RETURN(pipeline, false);
588 auto dragDropManager = pipeline->GetDragDropManager();
589 CHECK_NULL_RETURN(dragDropManager, false);
590 if (dragInfoData.isMenuShow) {
591 return true;
592 }
593 if (dragInfoData.isNeedCreateTiled) {
594 return false;
595 }
596 if (IsPixelMapNeedScale() || DragDropGlobalController::GetInstance().GetAsyncDragCallback() != nullptr) {
597 return true;
598 }
599 CHECK_NULL_RETURN(dragEventActuator_, false);
600 return dragEventActuator_->IsNeedGather();
601 }
602
HandleOnDragStart(const GestureEvent & info)603 void GestureEventHub::HandleOnDragStart(const GestureEvent& info)
604 {
605 TAG_LOGD(AceLogTag::ACE_DRAG, "Start handle onDragStart.");
606 auto frameNode = GetFrameNode();
607 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
608 if (!frameNode || !pipeline || !CheckAllowDrag(info, pipeline, frameNode)) {
609 TAG_LOGE(AceLogTag::ACE_DRAG, "Check not allow drag");
610 HandleNotAllowDrag(info);
611 return;
612 }
613
614 // set menu window touchable
615 auto mainPipeline = PipelineContext::GetMainPipelineContext();
616 DragDropFuncWrapper::SetMenuSubWindowTouchable((mainPipeline != pipeline));
617 // set drag drop status is moving
618 DragDropGlobalController::GetInstance().UpdateDragDropInitiatingStatus(frameNode, DragDropInitiatingStatus::MOVING);
619
620 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
621 SetMouseDragMonitorState(true);
622 }
623
624 CalcFrameNodeOffsetAndSize(frameNode, DragDropGlobalController::GetInstance().IsMenuShowing());
625
626 // create drag event
627 auto event = CreateDragEvent(info, pipeline, frameNode);
628
629 /*
630 * Users may remove frameNode in the js callback function "onDragStart "triggered below,
631 * so save the offset of the framenode relative to the window in advance
632 */
633 DragDropInfo dragPreviewInfo;
634 auto dragDropInfo = GetDragDropInfo(info, frameNode, dragPreviewInfo, event);
635 auto continueFunc = [id = Container::CurrentId(), weak = WeakClaim(this), dragPreviewInfo, info, event,
636 dragDropInfo, frameNode, pipeline]() {
637 ContainerScope scope(id);
638 auto gestureEventHub = weak.Upgrade();
639 CHECK_NULL_VOID(gestureEventHub);
640 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
641 gestureEventHub->SetMouseDragMonitorState(true);
642 }
643 gestureEventHub->DoOnDragStartHandling(info, frameNode, dragDropInfo, event, dragPreviewInfo, pipeline);
644 };
645 auto dragDropManager = pipeline->GetDragDropManager();
646 CHECK_NULL_VOID(dragDropManager);
647 if (DragDropGlobalController::GetInstance().GetDragStartRequestStatus() == DragStartRequestStatus::READY) {
648 DoOnDragStartHandling(info, frameNode, dragDropInfo, event, dragPreviewInfo, pipeline);
649 } else {
650 dragDropManager->SetDelayDragCallBack(continueFunc);
651 TAG_LOGI(AceLogTag::ACE_DRAG, "drag start pended");
652 }
653 }
654
ParsePixelMapAsync(DragDropInfo & dragDropInfo,const DragDropInfo & dragPreviewInfo,const GestureEvent & info)655 bool GestureEventHub::ParsePixelMapAsync(DragDropInfo& dragDropInfo, const DragDropInfo& dragPreviewInfo,
656 const GestureEvent& info)
657 {
658 auto frameNode = GetFrameNode();
659 CHECK_NULL_RETURN(frameNode, false);
660 if (DragDropFuncWrapper::IsNeedCreateTiledPixelMap(frameNode, dragEventActuator_, info.GetSourceDevice())) {
661 ACE_SCOPED_TRACE("drag: create titled pixelMap");
662 dragDropInfo.pixelMap = DragDropFuncWrapper::CreateTiledPixelMap(frameNode);
663 return true;
664 }
665
666 if (dragPreviewInfo.inspectorId != "") {
667 ACE_SCOPED_TRACE("drag: handling with inspector");
668 auto dragPreviewPixelMap = GetDragPreviewPixelMap();
669 TAG_LOGI(AceLogTag::ACE_DRAG, "InspectorId exist, get thumbnail.");
670 if (dragPreviewPixelMap == nullptr) {
671 dragPreviewPixelMap = DragDropFuncWrapper::GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
672 }
673 dragDropInfo.pixelMap = dragPreviewPixelMap;
674 return true;
675 }
676
677 if (info.GetSourceDevice() != SourceType::MOUSE) {
678 if (dragPreviewInfo.pixelMap != nullptr || dragPreviewInfo.customNode != nullptr) {
679 if (dragPreviewPixelMap_ != nullptr) {
680 ACE_SCOPED_TRACE("drag: handling with drag preview");
681 TAG_LOGI(AceLogTag::ACE_DRAG, "Non-mouse dragging, get thumbnail.");
682 dragDropInfo.pixelMap = dragPreviewPixelMap_;
683 return true;
684 }
685 }
686 if (dragDropInfo.pixelMap == nullptr && dragDropInfo.customNode == nullptr &&
687 dragPreviewInfo.pixelMap == nullptr && dragPreviewInfo.customNode == nullptr && pixelMap_ != nullptr &&
688 !frameNode->GetDragPreview().onlyForLifting) {
689 dragDropInfo.pixelMap = pixelMap_;
690 return true;
691 }
692 }
693
694 if (dragPreviewInfo.pixelMap != nullptr) {
695 ACE_SCOPED_TRACE("drag: handling with pixelmap directly");
696 dragDropInfo.pixelMap = dragPreviewInfo.pixelMap;
697 TAG_LOGI(AceLogTag::ACE_DRAG, "PixelMap exist, get thumbnail.");
698 return true;
699 } else if (dragPreviewInfo.customNode != nullptr) {
700 dragDropInfo.customNode = dragPreviewInfo.customNode;
701 }
702 return dragDropInfo.pixelMap;
703 }
704
DoOnDragStartHandling(const GestureEvent & info,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & event,DragDropInfo dragPreviewInfo,const RefPtr<PipelineContext> & pipeline)705 void GestureEventHub::DoOnDragStartHandling(const GestureEvent& info, const RefPtr<FrameNode> frameNode,
706 DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& event, DragDropInfo dragPreviewInfo,
707 const RefPtr<PipelineContext>& pipeline)
708 {
709 GetUnifiedData(frameNode->GetTag(), dragDropInfo, event);
710 // set drag pointer status
711 auto dragDropManager = pipeline->GetDragDropManager();
712 CHECK_NULL_VOID(dragDropManager);
713 dragDropManager->SetDraggingPointer(info.GetPointerId());
714 dragDropManager->SetDraggingPressedState(true);
715
716 if (ParsePixelMapAsync(dragDropInfo, dragPreviewInfo, info)) {
717 OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
718 return;
719 }
720
721 #if defined(PIXEL_MAP_SUPPORTED)
722 if (dragDropInfo.pixelMap == nullptr && dragDropInfo.customNode) {
723 ACE_SCOPED_TRACE("drag: handling for custom builder");
724 StartDragForCustomBuilder(info, pipeline, frameNode, dragDropInfo, event);
725 return;
726 }
727 #endif
728 TAG_LOGI(AceLogTag::ACE_DRAG, "DragDropInfo is empty.");
729 ACE_SCOPED_TRACE("drag: handling without preview");
730 if (!dragDropInfo.pixelMap) {
731 if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && GetTextDraggable() && pixelMap_) {
732 dragDropInfo.pixelMap = pixelMap_;
733 } else {
734 GenerateMousePixelMap(info);
735 dragDropInfo.pixelMap = pixelMap_;
736 }
737 }
738 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && !dragDropInfo.pixelMap) {
739 TAG_LOGD(AceLogTag::ACE_DRAG, "no any pixmap got, get node snapshot final try");
740 ACE_SCOPED_TRACE("drag: no any pixmap got, get node snapshot final try");
741 dragDropInfo.pixelMap = CreatePixelMapFromString(DEFAULT_MOUSE_DRAG_IMAGE);
742 }
743 OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
744 }
745
HideMenu()746 void GestureEventHub::HideMenu()
747 {
748 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
749 CHECK_NULL_VOID(pipeline);
750 auto dragDrogDropManager = pipeline->GetDragDropManager();
751 CHECK_NULL_VOID(dragDrogDropManager);
752 TAG_LOGI(AceLogTag::ACE_DRAG, "Hide menu. showPreviewAnimation false, startDrag true.");
753 SubwindowManager::GetInstance()->HideMenuNG(false, true);
754 auto menuWrapperNode = dragDrogDropManager->GetMenuWrapperNode();
755 CHECK_NULL_VOID(menuWrapperNode);
756 auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
757 CHECK_NULL_VOID(menuWrapperPattern);
758 auto imageNode = menuWrapperPattern->GetPreview();
759 CHECK_NULL_VOID(imageNode);
760 auto imageContext = imageNode->GetRenderContext();
761 CHECK_NULL_VOID(imageContext);
762 imageContext->UpdateOpacity(0.0f);
763 }
764
CalcPreviewPaintRect(const RefPtr<FrameNode> menuWrapperNode,PreparedInfoForDrag & data)765 void CalcPreviewPaintRect(const RefPtr<FrameNode> menuWrapperNode, PreparedInfoForDrag& data)
766 {
767 CHECK_NULL_VOID(menuWrapperNode);
768 auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
769 CHECK_NULL_VOID(menuWrapperPattern);
770 auto menuPreview = menuWrapperPattern->GetPreview();
771 CHECK_NULL_VOID(menuPreview);
772 auto pipeline = PipelineContext::GetCurrentContextPtrSafelyWithCheck();
773 auto menuTheme = pipeline->GetTheme<NG::MenuTheme>();
774 CHECK_NULL_VOID(menuTheme);
775 auto previewBorderRadiusValue = menuTheme->GetPreviewBorderRadius();
776 data.borderRadius = BorderRadiusProperty(previewBorderRadiusValue);
777 auto menuNode = menuWrapperPattern->GetMenu();
778 CHECK_NULL_VOID(menuNode);
779 auto menuPattern = menuNode->GetPattern<MenuPattern>();
780 CHECK_NULL_VOID(menuPattern);
781 auto isShowHoverImage = menuPattern->GetIsShowHoverImage();
782 data.menuPreviewNode = menuPreview;
783 data.menuPreviewRect = DragDropFuncWrapper::GetPaintRectToScreen(menuPreview);
784 if (!isShowHoverImage) {
785 return;
786 }
787 auto animationInfo = menuWrapperPattern->GetPreviewMenuAnimationInfo();
788 auto previewNode = menuWrapperPattern->GetHoverImageCustomPreview();
789 CHECK_NULL_VOID(previewNode);
790 auto previewPattern = previewNode->GetPattern<MenuPreviewPattern>();
791 CHECK_NULL_VOID(previewPattern);
792 auto rate = animationInfo.clipRate;
793 auto clipStartWidth = previewPattern->GetHoverImageAfterScaleWidth();
794 auto clipStartHeight = previewPattern->GetHoverImageAfterScaleHeight();
795 auto clipEndWidth = previewPattern->GetStackAfterScaleActualWidth();
796 auto clipEndHeight = previewPattern->GetStackAfterScaleActualHeight();
797 auto curentWidth = rate * (clipEndWidth - clipStartWidth) + clipStartWidth;
798 auto curentHeight = rate * (clipEndHeight - clipStartHeight) + clipStartHeight;
799 auto centerX = data.menuPreviewRect.GetX() + data.menuPreviewRect.Width() / 2;
800 auto centerY = data.menuPreviewRect.GetY() + data.menuPreviewRect.Height() / 2;
801 auto x = centerX - curentWidth / 2;
802 auto y = centerY - curentHeight / 2;
803 data.menuPreviewRect = RectF(x, y, curentWidth, curentHeight);
804 data.borderRadius = animationInfo.borderRadius;
805 }
806
PrepareDragStartInfo(RefPtr<PipelineContext> & pipeline,PreparedInfoForDrag & data)807 void GestureEventHub::PrepareDragStartInfo(RefPtr<PipelineContext>& pipeline, PreparedInfoForDrag& data)
808 {
809 CHECK_NULL_VOID(pipeline);
810 auto dragDropManager = pipeline->GetDragDropManager();
811 CHECK_NULL_VOID(dragDropManager);
812 auto menuWrapperNode = dragDropManager->GetMenuWrapperNode();
813 CHECK_NULL_VOID(menuWrapperNode);
814 CalcPreviewPaintRect(menuWrapperNode, data);
815 auto previewPaintRect = data.menuPreviewRect;
816 auto relativeContainerNode =
817 FrameNode::GetOrCreateFrameNode(V2::RELATIVE_CONTAINER_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
818 []() { return AceType::MakeRefPtr<OHOS::Ace::NG::RelativeContainerPattern>(); });
819 CHECK_NULL_VOID(relativeContainerNode);
820 data.relativeContainerNode = relativeContainerNode;
821 auto relativeContainerLayoutProperty = relativeContainerNode->GetLayoutProperty();
822 CHECK_NULL_VOID(relativeContainerLayoutProperty);
823 relativeContainerLayoutProperty->UpdateUserDefinedIdealSize(
824 { CalcLength(previewPaintRect.Width(), DimensionUnit::PX),
825 CalcLength(previewPaintRect.Height(), DimensionUnit::PX) });
826 auto relativeContainerRenderContext = relativeContainerNode->GetRenderContext();
827 CHECK_NULL_VOID(relativeContainerRenderContext);
828 relativeContainerRenderContext->UpdateTransformTranslate({ 0, 0, 0.0f });
829 }
830
OnDragStart(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)831 void GestureEventHub::OnDragStart(const GestureEvent& info, const RefPtr<PipelineBase>& context,
832 const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
833 {
834 ACE_SCOPED_TRACE("drag: to start");
835 auto dragNodePipeline = frameNode->GetContextRefPtr();
836 CHECK_NULL_VOID(dragNodePipeline);
837 auto overlayManager = dragNodePipeline->GetOverlayManager();
838 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
839 CHECK_NULL_VOID(pipeline);
840
841 auto dragDropManager = pipeline->GetDragDropManager();
842 CHECK_NULL_VOID(dragDropManager);
843
844 bool needChangeFwkForLeaveWindow = false;
845 if (DragDropGlobalController::GetInstance().GetAsyncDragCallback()) {
846 auto rootNode = dragDropManager->GetRootNode();
847 CHECK_NULL_VOID(rootNode);
848 auto geometryNode = rootNode->GetGeometryNode();
849 CHECK_NULL_VOID(geometryNode);
850 RectF rectF = geometryNode->GetFrameRect();
851 auto point = dragDropManager->GetDragMoveLastPointByCurrentPointer(info.GetPointerId());
852 if (!rectF.IsInRegion(PointF(static_cast<float>(point.GetX()), static_cast<float>(point.GetY())))) {
853 needChangeFwkForLeaveWindow = true;
854 }
855 }
856 auto eventHub = eventHub_.Upgrade();
857 CHECK_NULL_VOID(eventHub);
858 if (dragDropProxy_) {
859 dragDropProxy_ = nullptr;
860 }
861 CHECK_NULL_VOID(dragEvent);
862 auto eventRet = dragEvent->GetResult();
863 if (eventRet == DragRet::DRAG_FAIL || eventRet == DragRet::DRAG_CANCEL) {
864 TAG_LOGI(AceLogTag::ACE_DRAG, "Drag result is %{public}d, stop dragging.", eventRet);
865 FireCustomerOnDragEnd(pipeline, eventHub);
866 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
867 SetMouseDragMonitorState(false);
868 }
869 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::APP_REFUSE_DRAG);
870 return;
871 }
872 std::string udKey;
873 auto unifiedData = dragEvent->GetData();
874 if (unifiedData) {
875 DragDropBehaviorReporter::GetInstance().UpdateRecordSize(unifiedData->GetSize());
876 }
877 int32_t recordsSize = GetBadgeNumber(unifiedData);
878 auto ret = SetDragData(unifiedData, udKey);
879 if (ret != 0) {
880 TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF set data failed, return value is %{public}d", ret);
881 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SET_DATA_FAIL);
882 }
883
884 std::map<std::string, int64_t> summary;
885 ret = UdmfClient::GetInstance()->GetSummary(udKey, summary);
886 if (ret != 0) {
887 TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF get summary failed, return value is %{public}d", ret);
888 }
889 dragDropManager->SetSummaryMap(summary);
890 RefPtr<PixelMap> pixelMap = dragDropInfo.pixelMap;
891 if (pixelMap) {
892 SetPixelMap(pixelMap);
893 } else if (pixelMap == nullptr) {
894 FireCustomerOnDragEnd(pipeline, eventHub);
895 TAG_LOGW(AceLogTag::ACE_DRAG, "Thumbnail pixelMap is empty.");
896 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
897 SetMouseDragMonitorState(false);
898 }
899 return;
900 }
901 auto dragPreviewOptions = frameNode->GetDragPreviewOption();
902 if (dragPreviewOptions.isDefaultDragItemGrayEffectEnabled) {
903 (info.GetSourceDevice() == SourceType::MOUSE) ? HandleDragThroughMouse(frameNode)
904 : HandleDragThroughTouch(frameNode);
905 }
906 SetDragGatherPixelMaps(info);
907 dragDropManager->SetIsMouseDrag(info.GetInputEventType() == InputEventType::MOUSE_BUTTON);
908 bool isMenuShow = DragDropGlobalController::GetInstance().IsMenuShowing();
909 if (isMenuShow) {
910 dragDropManager->SetIsDragWithContextMenu(true);
911 TAG_LOGI(AceLogTag::ACE_DRAG, "Drag with contextMenu.");
912 } else {
913 dragDropManager->SetIsDragWithContextMenu(false);
914 }
915 float defaultPixelMapScale = GetDefaultPixelMapScale(frameNode, info, isMenuShow, pixelMap);
916 auto windowScale = dragDropManager->GetWindowScale();
917 float scale = windowScale * defaultPixelMapScale;
918 auto isNeedCreateTiled =
919 DragDropFuncWrapper::IsNeedCreateTiledPixelMap(frameNode, dragEventActuator_, info.GetSourceDevice());
920 PreparedInfoForDrag data = { isMenuShow, recordsSize, defaultPixelMapScale, isNeedCreateTiled, OffsetF(),
921 OffsetF(), pixelMap, nullptr };
922 data.dragPreviewRect = RectF(0, 0, pixelMap->GetWidth(), pixelMap->GetHeight());
923 dragDropManager->ResetContextMenuDragPosition();
924 RefPtr<Subwindow> subWindow = nullptr;
925 if (!needChangeFwkForLeaveWindow && IsNeedSwitchToSubWindow(data)) {
926 GestureEventHub::PrepareDragStartInfo(pipeline, data);
927 auto imageNode = overlayManager->GetPixelMapContentNode();
928 DragAnimationHelper::CreatePreviewNode(frameNode, imageNode, defaultPixelMapScale, data);
929 CHECK_NULL_VOID(imageNode);
930 data.imageNode = imageNode;
931 data.dragPreviewOffsetToScreen = GetDragPreviewInitPositionToScreen(context, data);
932 float previewScale =
933 info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
934 if (IsPixelMapNeedScale()) {
935 previewScale = DragDropFuncWrapper::GetPixelMapScale(frameNode);
936 scale = previewScale * windowScale;
937 }
938 data.previewScale = previewScale;
939 // use menu preview scale replace default pixelMap scale.
940 if (isMenuShow) {
941 ProcessMenuPreviewScale(imageNode, scale, previewScale, windowScale, defaultPixelMapScale);
942 }
943 {
944 ACE_SCOPED_TRACE("drag: sub window show");
945 auto mainPipeline = PipelineContext::GetMainPipelineContext();
946 subWindow = SubwindowManager::GetInstance()->ShowPreviewNG((pipeline != mainPipeline));
947 }
948 }
949 if (!overlayManager->GetIsOnAnimation()) {
950 if (dragEventActuator_ != nullptr) {
951 dragEventActuator_->SetIsNotInPreviewState(true);
952 }
953 }
954 RefPtr<PixelMap> pixelMapDuplicated = GetPreScaledPixelMapIfExist(scale, pixelMap);
955 CHECK_NULL_VOID(dragEventActuator_);
956 dragEventActuator_->ResetPreScaledPixelMapForDragThroughTouch();
957 dragPreviewPixelMap_ = nullptr;
958 CHECK_NULL_VOID(pixelMapDuplicated);
959 auto width = pixelMapDuplicated->GetWidth();
960 auto height = pixelMapDuplicated->GetHeight();
961 auto extraInfoLimited = dragDropInfo.extraInfo.size() > EXTRA_INFO_MAX_LENGTH
962 ? dragDropInfo.extraInfo.substr(EXTRA_INFO_MAX_LENGTH + 1)
963 : dragDropInfo.extraInfo;
964 auto innerRect = ParseInnerRect(extraInfoLimited, SizeF(width, height));
965 auto pixelMapOffset = GetPixelMapOffset(info, SizeF(width, height), data, scale, innerRect);
966 windowScale = NearZero(windowScale) ? 1.0f : windowScale;
967 dragDropManager->SetPixelMapOffset(pixelMapOffset / windowScale);
968 DragDropFuncWrapper::ResetNode(frameNode);
969 auto arkExtraInfoJson = JsonUtil::Create(true);
970 auto dragNodeGrayscale = pipeline->GetDragNodeGrayscale();
971 auto dipScale = pipeline->GetDipScale();
972 arkExtraInfoJson->Put("scale", scale);
973 arkExtraInfoJson->Put("dip_scale", dipScale);
974 arkExtraInfoJson->Put("drag_node_gray_scale", dragNodeGrayscale);
975 arkExtraInfoJson->Put("event_id", info.GetPointerEventId());
976 UpdateExtraInfo(frameNode, arkExtraInfoJson, scale, data);
977 auto container = Container::Current();
978 CHECK_NULL_VOID(container);
979 DragDropBehaviorReporterTrigger trigger(DragReporterPharse::DRAG_START, container->GetInstanceId());
980 auto windowId = container->GetWindowId();
981 ShadowInfoCore shadowInfo { pixelMapDuplicated, pixelMapOffset.GetX(), pixelMapOffset.GetY() };
982 auto dragMoveLastPoint = dragDropManager->GetDragMoveLastPointByCurrentPointer(info.GetPointerId());
983 DragDataCore dragData { { shadowInfo }, {}, udKey, extraInfoLimited, arkExtraInfoJson->ToString(),
984 static_cast<int32_t>(info.GetSourceDevice()), recordsSize, info.GetPointerId(),
985 static_cast<int32_t>(info.GetSourceTool()), dragMoveLastPoint.GetScreenX(),
986 dragMoveLastPoint.GetScreenY(), info.GetTargetDisplayId(), windowId, true, false, summary };
987 std::string summarys = DragDropFuncWrapper::GetSummaryString(summary);
988 DragDropBehaviorReporter::GetInstance().UpdateSummaryType(summarys);
989 TAG_LOGI(AceLogTag::ACE_DRAG,
990 "Start drag, frameNode is %{public}s, pixelMap width %{public}d height %{public}d, "
991 "scale is %{public}f, udkey %{public}s, recordsSize %{public}d, extraInfo length %{public}d, "
992 "pointerId %{public}d, toolType %{public}d, displayId %{public}d, windowId %{public}d, summary %{public}s, "
993 "eventId %{public}d.",
994 frameNode->GetTag().c_str(), width, height, scale, DragDropFuncWrapper::GetAnonyString(udKey).c_str(),
995 recordsSize, static_cast<int32_t>(extraInfoLimited.length()), info.GetPointerId(),
996 static_cast<int32_t>(info.GetSourceTool()), info.GetTargetDisplayId(), windowId, summarys.c_str(),
997 info.GetPointerEventId());
998 dragDropManager->GetGatherPixelMap(dragData, scale, width, height);
999 {
1000 ACE_SCOPED_TRACE("drag: call msdp start drag");
1001 ret = InteractionInterface::GetInstance()->StartDrag(dragData, GetDragCallback(pipeline, eventHub));
1002 }
1003 if (ret != 0) {
1004 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::DRAGFWK_START_FAIL);
1005 if (subWindow) {
1006 SubwindowManager::GetInstance()->HidePreviewNG();
1007 overlayManager->RemovePixelMap();
1008 }
1009 FireCustomerOnDragEnd(pipeline, eventHub);
1010 TAG_LOGW(AceLogTag::ACE_DRAG, "Start drag failed, return value is %{public}d", ret);
1011 return;
1012 }
1013 StartVibratorByDrag(frameNode);
1014 dragEventActuator_->NotifyDragStart();
1015 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::DRAG_START_SUCCESS);
1016 bool isSwitchedToSubWindow = false;
1017 if (!needChangeFwkForLeaveWindow && subWindow && TryDoDragStartAnimation(context, subWindow, info, data)) {
1018 dragDropManager->SetIsReDragStart(pipeline != dragNodePipeline);
1019 isSwitchedToSubWindow = true;
1020 } else {
1021 dragDropManager->SetIsReDragStart(false);
1022 HideMenu();
1023 DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
1024 }
1025 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && isSwitchedToSubWindow) {
1026 ret = RegisterCoordinationListener(pipeline);
1027 if (ret != 0) {
1028 TAG_LOGW(AceLogTag::ACE_DRAG, "Register coordination listener failed, error is %{public}d", ret);
1029 }
1030 }
1031 dragDropManager->SetPreviewRect(Rect(pixelMapOffset.GetX(), pixelMapOffset.GetY(), width, height));
1032 dragDropManager->ResetRecordSize(static_cast<uint32_t>(recordsSize));
1033 auto eventManager = pipeline->GetEventManager();
1034 CHECK_NULL_VOID(eventManager);
1035 eventManager->DoMouseActionRelease();
1036 eventManager->SetIsDragging(true);
1037 if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && needChangeFwkForLeaveWindow) {
1038 overlayManager->RemovePixelMap();
1039 overlayManager->RemovePreviewBadgeNode();
1040 overlayManager->RemoveGatherNode();
1041 dragEventActuator_->NotifyTransDragWindowToFwk();
1042 pipeline->AddAfterRenderTask([]() {
1043 ACE_SCOPED_TRACE("drag: set drag window visible, touch");
1044 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
1045 });
1046 } else if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && dragEventActuator_ != nullptr &&
1047 dragEventActuator_->GetIsNotInPreviewState()) {
1048 if (!isSwitchedToSubWindow) {
1049 overlayManager->RemovePixelMap();
1050 overlayManager->RemovePreviewBadgeNode();
1051 overlayManager->RemoveGatherNode();
1052 dragEventActuator_->NotifyTransDragWindowToFwk();
1053 pipeline->AddAfterRenderTask([]() {
1054 ACE_SCOPED_TRACE("drag: set drag window visible, touch");
1055 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
1056 });
1057 }
1058 } else if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1059 if (!isSwitchedToSubWindow) {
1060 dragEventActuator_->NotifyTransDragWindowToFwk();
1061 pipeline->AddDragWindowVisibleTask([]() {
1062 ACE_SCOPED_TRACE("drag: set drag window visible, mouse");
1063 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
1064 });
1065 pipeline->RequestFrame();
1066 }
1067 dragDropManager->SetIsDragWindowShow(true);
1068 }
1069 dragDropManager->FireOnEditableTextComponent(frameNode, DragEventType::ENTER);
1070 dragDropProxy_ = dragDropManager->CreateFrameworkDragDropProxy();
1071 CHECK_NULL_VOID(dragDropProxy_);
1072 dragDropProxy_->OnDragStart(info, extraInfoLimited, GetFrameNode());
1073 if (!dragDropManager->IsDraggingPressed(info.GetPointerId())) {
1074 dragDropManager->SetIsDisableDefaultDropAnimation(true);
1075 dragDropManager->OnDragEnd(
1076 DragPointerEvent(info.GetGlobalPoint().GetX(), info.GetGlobalPoint().GetY()), extraInfoLimited);
1077 }
1078 }
1079
StartVibratorByDrag(const RefPtr<FrameNode> & frameNode)1080 void GestureEventHub::StartVibratorByDrag(const RefPtr<FrameNode>& frameNode)
1081 {
1082 bool enableHapticFeedback = frameNode->GetDragPreviewOption().enableHapticFeedback;
1083 auto parent = frameNode->GetAncestorNodeOfFrame(false);
1084 if (parent && parent->GetTag() == V2::RICH_EDITOR_ETS_TAG) {
1085 enableHapticFeedback = parent->GetDragPreviewOption().enableHapticFeedback;
1086 }
1087 if (!enableHapticFeedback || !DragDropGlobalController::GetInstance().IsDragFilterShowing()) {
1088 return;
1089 }
1090 TAG_LOGI(AceLogTag::ACE_DRAG, "Enable haptic feedback, start vibrator by drag.");
1091 VibratorUtils::StartViratorDirectly("haptic.drag");
1092 DragDropGlobalController::GetInstance().UpdateDragFilterShowingStatus(false);
1093 }
1094
UpdateExtraInfo(const RefPtr<FrameNode> & frameNode,std::unique_ptr<JsonValue> & arkExtraInfoJson,float scale,const PreparedInfoForDrag & dragInfoData)1095 void GestureEventHub::UpdateExtraInfo(const RefPtr<FrameNode>& frameNode, std::unique_ptr<JsonValue>& arkExtraInfoJson,
1096 float scale, const PreparedInfoForDrag& dragInfoData)
1097 {
1098 double opacity = frameNode->GetDragPreviewOption().options.opacity;
1099 auto optionInfo = frameNode->GetDragPreviewOption().options;
1100 arkExtraInfoJson->Put("dip_opacity", opacity);
1101 TAG_LOGD(AceLogTag::ACE_DRAG, "The info of opacity update to the framework is %{public}s",
1102 arkExtraInfoJson->ToString().c_str());
1103
1104 if (optionInfo.blurbgEffect.backGroundEffect.radius.IsValid()) {
1105 optionInfo.blurbgEffect.ToJsonValue(arkExtraInfoJson);
1106 }
1107 DragEventActuator::PrepareShadowParametersForDragData(frameNode, arkExtraInfoJson, scale);
1108 if (dragInfoData.isNeedCreateTiled) {
1109 return;
1110 }
1111 DragEventActuator::PrepareRadiusParametersForDragData(frameNode, arkExtraInfoJson);
1112 }
1113
RegisterCoordinationListener(const RefPtr<PipelineBase> & context)1114 int32_t GestureEventHub::RegisterCoordinationListener(const RefPtr<PipelineBase>& context)
1115 {
1116 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1117 CHECK_NULL_RETURN(pipeline, -1);
1118 auto callback = [id = Container::CurrentId(), weak = WeakClaim(RawPtr(pipeline))]() {
1119 ContainerScope scope(id);
1120 auto context = weak.Upgrade();
1121 CHECK_NULL_VOID(context);
1122 auto dragDropManager = context->GetDragDropManager();
1123 CHECK_NULL_VOID(dragDropManager);
1124 auto taskScheduler = context->GetTaskExecutor();
1125 CHECK_NULL_VOID(taskScheduler);
1126 taskScheduler->PostTask([dragDropManager]() { dragDropManager->HideDragPreviewOverlay(); },
1127 TaskExecutor::TaskType::UI, "ArkUIGestureHideDragPreviewOverlay");
1128 };
1129 return InteractionInterface::GetInstance()->RegisterCoordinationListener(callback);
1130 }
1131
HandleOnDragUpdate(const GestureEvent & info)1132 void GestureEventHub::HandleOnDragUpdate(const GestureEvent& info)
1133 {
1134 gestureInfoForWeb_ = std::make_shared<GestureEvent>(info);
1135 }
1136
HandleDragEndAction(const DragframeNodeInfo & info)1137 void GestureEventHub::HandleDragEndAction(const DragframeNodeInfo& info)
1138 {
1139 auto weakFrameNode = info.frameNode;
1140 auto frameNode = weakFrameNode.Upgrade();
1141 CHECK_NULL_VOID(frameNode);
1142 auto dragPreviewOptions = frameNode->GetDragPreviewOption();
1143 if (!dragPreviewOptions.isDefaultDragItemGrayEffectEnabled) {
1144 return;
1145 }
1146 auto pipeline = frameNode->GetContextRefPtr();
1147 CHECK_NULL_VOID(pipeline);
1148 auto dragDropManager = pipeline->GetDragDropManager();
1149 CHECK_NULL_VOID(dragDropManager);
1150 auto state = dragDropManager->GetGrayedState();
1151 if (!state) {
1152 return;
1153 }
1154 if (!info.gatherFrameNode.empty()) {
1155 auto gatherFrameNode = info.gatherFrameNode;
1156 for (const auto& itemFrameNode : gatherFrameNode) {
1157 DragAnimationHelper::SetPreOpacity(itemFrameNode);
1158 }
1159 } else {
1160 DragAnimationHelper::SetPreOpacity(frameNode);
1161 }
1162 dragDropManager->SetGrayedState(false);
1163 }
1164
HandleOnDragEnd(const GestureEvent & info)1165 void GestureEventHub::HandleOnDragEnd(const GestureEvent& info)
1166 {
1167 auto pipeline = NG::PipelineContext::GetCurrentContextSafelyWithCheck();
1168 const static int32_t PLATFORM_VERSION_TEN = 10;
1169 if (pipeline && (pipeline->GetMinPlatformVersion() < PLATFORM_VERSION_TEN)) {
1170 auto eventHub = eventHub_.Upgrade();
1171 CHECK_NULL_VOID(eventHub);
1172
1173 auto frameNode = GetFrameNode();
1174 CHECK_NULL_VOID(frameNode);
1175
1176 // Only the onDrop callback of dragged frame node is triggered.
1177 // The onDrop callback of target frame node is triggered in PipelineContext::OnDragEvent.
1178 if (eventHub->HasOnDrop() || eventHub->HasCustomerOnDrop()) {
1179 RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1180 if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
1181 event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1182 event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1183 } else {
1184 event->SetX(info.GetGlobalPoint().GetX());
1185 event->SetY(info.GetGlobalPoint().GetY());
1186 }
1187 event->SetScreenX(info.GetScreenLocation().GetX());
1188 event->SetScreenY(info.GetScreenLocation().GetY());
1189 event->SetPressedKeyCodes(info.GetPressedKeyCodes());
1190 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event);
1191 eventHub->HandleInternalOnDrop(event, "");
1192 }
1193 }
1194 HandleDragEndAction(dragframeNodeInfo_);
1195 CHECK_NULL_VOID(dragDropProxy_);
1196 dragDropProxy_->DestroyDragWindow();
1197 dragDropProxy_ = nullptr;
1198 }
1199
HandleOnDragCancel()1200 void GestureEventHub::HandleOnDragCancel()
1201 {
1202 CHECK_NULL_VOID(dragDropProxy_);
1203 dragDropProxy_->DestroyDragWindow();
1204 dragDropProxy_ = nullptr;
1205 }
1206
SetDragData(const RefPtr<UnifiedData> & unifiedData,std::string & udKey)1207 int32_t GestureEventHub::SetDragData(const RefPtr<UnifiedData>& unifiedData, std::string& udKey)
1208 {
1209 CHECK_NULL_RETURN(unifiedData, -1);
1210 ACE_SCOPED_TRACE("drag: set drag data to udmf");
1211 return UdmfClient::GetInstance()->SetData(unifiedData, udKey);
1212 }
1213
GetDragCallback(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)1214 OnDragCallbackCore GestureEventHub::GetDragCallback(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
1215 {
1216 auto ret = [](const DragNotifyMsgCore& notifyMessage) {};
1217 auto eventHub = hub.Upgrade();
1218 CHECK_NULL_RETURN(eventHub, ret);
1219 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1220 CHECK_NULL_RETURN(pipeline, ret);
1221 auto taskScheduler = pipeline->GetTaskExecutor();
1222 CHECK_NULL_RETURN(taskScheduler, ret);
1223 auto dragDropManager = pipeline->GetDragDropManager();
1224 CHECK_NULL_RETURN(dragDropManager, ret);
1225 auto eventManager = pipeline->GetEventManager();
1226 RefPtr<OHOS::Ace::DragEvent> dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1227 auto callback = [id = Container::CurrentId(), eventHub, dragEvent, taskScheduler, dragDropManager, eventManager,
1228 dragframeNodeInfo = dragframeNodeInfo_,
1229 gestureEventHubPtr = AceType::Claim(this)](const DragNotifyMsgCore& notifyMessage) {
1230 ContainerScope scope(id);
1231 taskScheduler->PostTask(
1232 [eventHub, dragEvent, dragDropManager, eventManager, notifyMessage, id, dragframeNodeInfo,
1233 gestureEventHubPtr]() {
1234 auto container = Container::GetContainer(id);
1235 if (!container) {
1236 TAG_LOGE(AceLogTag::ACE_DRAG, "handle drag end callback, can not get container.");
1237 return;
1238 }
1239 DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
1240 TAG_LOGI(
1241 AceLogTag::ACE_DRAG, "handle drag end callback, windowId is %{public}d.", container->GetWindowId());
1242 dragDropManager->ResetDragEndOption(notifyMessage, dragEvent, id);
1243 auto ret = InteractionInterface::GetInstance()->UnRegisterCoordinationListener();
1244 if (ret != 0) {
1245 TAG_LOGW(AceLogTag::ACE_DRAG, "Unregister coordination listener failed, error is %{public}d", ret);
1246 }
1247 if (eventManager) {
1248 eventManager->DoMouseActionRelease();
1249 }
1250 if (notifyMessage.isInnerAndOuterTriggerBothNeeded) {
1251 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
1252 }
1253 if (eventHub->HasOnDragEnd()) {
1254 (eventHub->GetOnDragEnd())(dragEvent);
1255 }
1256 gestureEventHubPtr->HandleDragEndAction(dragframeNodeInfo);
1257 auto dragEventActuator = gestureEventHubPtr->GetDragEventActuator();
1258 CHECK_NULL_VOID(dragEventActuator);
1259 dragEventActuator->NotifyDragEnd();
1260 },
1261 TaskExecutor::TaskType::UI, "ArkUIGestureDragEnd");
1262 };
1263 return callback;
1264 }
1265
GetDragDropInfo(const GestureEvent & info,const RefPtr<FrameNode> frameNode,DragDropInfo & dragPreviewInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1266 DragDropInfo GestureEventHub::GetDragDropInfo(const GestureEvent& info, const RefPtr<FrameNode> frameNode,
1267 DragDropInfo& dragPreviewInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1268 {
1269 ACE_SCOPED_TRACE("drag: execute user onDragStart");
1270 DragDropInfo dragDropInfo;
1271 CHECK_NULL_RETURN(dragEventActuator_, dragDropInfo);
1272 dragEventActuator_->SetIsDefaultOnDragStartExecuted(false);
1273 auto eventHub = eventHub_.Upgrade();
1274 CHECK_NULL_RETURN(eventHub, dragDropInfo);
1275 auto extraParams = eventHub->GetDragExtraParams(std::string(), info.GetGlobalPoint(), DragEventType::START);
1276 auto onDragStart = eventHub->GetOnDragStart();
1277 if (!onDragStart && eventHub->HasDefaultOnDragStart()) {
1278 onDragStart = eventHub->GetDefaultOnDragStart();
1279 dragEventActuator_->SetIsDefaultOnDragStartExecuted(true);
1280 }
1281 dragEvent->SetPressedKeyCodes(info.GetPressedKeyCodes());
1282 if (GetTextDraggable() && info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1283 GenerateMousePixelMap(info);
1284 }
1285 dragDropInfo = onDragStart(dragEvent, extraParams);
1286
1287 auto frameTag = frameNode->GetTag();
1288 if (GetTextDraggable() && IsTextCategoryComponent(frameTag)) {
1289 TAG_LOGD(AceLogTag::ACE_DRAG,
1290 "Get drag drop info, pixelmap and customNode are set to null "
1291 "when frameTag is %{public}s",
1292 frameTag.c_str());
1293 dragDropInfo.pixelMap = nullptr;
1294 dragDropInfo.customNode = nullptr;
1295 } else {
1296 auto dragPreview = frameNode->GetDragPreview();
1297 if (dragPreview.onlyForLifting) {
1298 return dragDropInfo;
1299 }
1300 if (!dragPreview.customNode && dragPreview.delayCreating && dragPreview.buildFunc) {
1301 dragPreview.customNode = dragPreview.buildFunc();
1302 }
1303 frameNode->SetDragPreview(dragPreview);
1304 dragPreviewInfo = dragPreview;
1305 }
1306 return dragDropInfo;
1307 }
1308
GetUnifiedData(const std::string & frameTag,DragDropInfo & dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1309 RefPtr<UnifiedData> GestureEventHub::GetUnifiedData(
1310 const std::string& frameTag, DragDropInfo& dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1311 {
1312 auto eventHub = eventHub_.Upgrade();
1313 CHECK_NULL_RETURN(eventHub, nullptr);
1314 auto unifiedData = dragEvent->GetData();
1315 bool hasData = static_cast<bool>(unifiedData);
1316 if (!unifiedData && eventHub->HasDefaultOnDragStart()) {
1317 auto defaultDropInfo = eventHub->GetDefaultOnDragStart()(dragEvent, "");
1318 if (dragDropInfo.extraInfo.empty()) {
1319 dragDropInfo.extraInfo = defaultDropInfo.extraInfo;
1320 }
1321 CHECK_NULL_RETURN(dragEventActuator_, nullptr);
1322 dragEventActuator_->SetIsDefaultOnDragStartExecuted(true);
1323 unifiedData = dragEvent->GetData();
1324 }
1325 auto defaultOnDragStart = eventHub->GetDefaultOnDragStart();
1326 CHECK_NULL_RETURN(defaultOnDragStart, unifiedData);
1327 if (hasData && IsTextCategoryComponent(frameTag) && !dragEventActuator_->IsDefaultOnDragStartExecuted()) {
1328 defaultOnDragStart(dragEvent, "");
1329 }
1330 return unifiedData;
1331 }
1332
SetDragForbiddenForcely(bool isDragForbiddenForWholeSubTree)1333 void GestureEventHub::SetDragForbiddenForcely(bool isDragForbiddenForWholeSubTree)
1334 {
1335 isDragForbiddenForWholeSubTree_ = isDragForbiddenForWholeSubTree;
1336 }
1337
IsDragForbidden() const1338 bool GestureEventHub::IsDragForbidden() const
1339 {
1340 return isDragForbiddenForWholeSubTree_;
1341 }
1342
SetDragGatherPixelMaps(const GestureEvent & info)1343 void GestureEventHub::SetDragGatherPixelMaps(const GestureEvent& info)
1344 {
1345 CHECK_NULL_VOID(dragEventActuator_);
1346 if (!dragEventActuator_->IsNeedGather()) {
1347 return;
1348 }
1349 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1350 SetMouseDragGatherPixelMaps();
1351 } else {
1352 SetNotMouseDragGatherPixelMaps();
1353 }
1354 }
1355
SetMouseDragGatherPixelMaps()1356 void GestureEventHub::SetMouseDragGatherPixelMaps()
1357 {
1358 auto frameNode = GetFrameNode();
1359 CHECK_NULL_VOID(frameNode);
1360 if (frameNode->GetDragPreviewOption().isMultiTiled && !dragEventActuator_->GetRestartDrag()) {
1361 return;
1362 }
1363 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1364 CHECK_NULL_VOID(pipeline);
1365 auto dragDropManager = pipeline->GetDragDropManager();
1366 CHECK_NULL_VOID(dragDropManager);
1367 dragDropManager->ClearGatherPixelMap();
1368 CHECK_NULL_VOID(dragEventActuator_);
1369 auto fatherNode = DragDropFuncWrapper::FindItemParentNode(frameNode);
1370 CHECK_NULL_VOID(fatherNode);
1371 auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1372 CHECK_NULL_VOID(scrollPattern);
1373 auto children = scrollPattern->GetVisibleSelectedItems();
1374 int cnt = 0;
1375 for (const auto& itemFrameNode : children) {
1376 if (itemFrameNode == frameNode) {
1377 continue;
1378 }
1379 CHECK_NULL_VOID(itemFrameNode);
1380 DragEventActuator::GetFrameNodePreviewPixelMap(itemFrameNode);
1381 auto gestureHub = itemFrameNode->GetOrCreateGestureEventHub();
1382 CHECK_NULL_VOID(gestureHub);
1383 auto itemPreviewPixelMap = gestureHub->GetDragPreviewPixelMap();
1384 if (!itemPreviewPixelMap) {
1385 continue;
1386 }
1387 dragDropManager->PushGatherPixelMap(itemPreviewPixelMap);
1388 cnt++;
1389 if (cnt > 1) {
1390 break;
1391 }
1392 }
1393 }
1394
SetNotMouseDragGatherPixelMaps()1395 void GestureEventHub::SetNotMouseDragGatherPixelMaps()
1396 {
1397 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1398 CHECK_NULL_VOID(pipeline);
1399 auto dragDropManager = pipeline->GetDragDropManager();
1400 CHECK_NULL_VOID(dragDropManager);
1401 dragDropManager->ClearGatherPixelMap();
1402 auto mainPipeline = PipelineContext::GetMainPipelineContext();
1403 CHECK_NULL_VOID(mainPipeline);
1404 auto overlayManager = mainPipeline->GetOverlayManager();
1405 CHECK_NULL_VOID(overlayManager);
1406 auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
1407 int cnt = 0;
1408 for (auto iter = gatherNodeChildrenInfo.rbegin(); iter != gatherNodeChildrenInfo.rend(); ++iter) {
1409 auto imageNode = (*iter).imageNode.Upgrade();
1410 CHECK_NULL_VOID(imageNode);
1411 auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
1412 CHECK_NULL_VOID(imageLayoutProperty);
1413 auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value_or(ImageSourceInfo());
1414 auto itemPreviewPixelMap = imageSourceInfo.GetPixmap();
1415 if (!itemPreviewPixelMap) {
1416 continue;
1417 }
1418 dragDropManager->PushGatherPixelMap(itemPreviewPixelMap);
1419 cnt++;
1420 if (cnt > 1) {
1421 break;
1422 }
1423 }
1424 }
1425
GetSelectItemSize()1426 int32_t GestureEventHub::GetSelectItemSize()
1427 {
1428 CHECK_NULL_RETURN(dragEventActuator_, 0);
1429 if (!dragEventActuator_->IsNeedGather()) {
1430 return 0;
1431 }
1432 auto fatherNode = DragDropFuncWrapper::FindItemParentNode(GetFrameNode());
1433 CHECK_NULL_RETURN(fatherNode, 0);
1434 auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1435 CHECK_NULL_RETURN(scrollPattern, 0);
1436 auto children = scrollPattern->GetVisibleSelectedItems();
1437 return children.size();
1438 }
1439
FireCustomerOnDragEnd(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)1440 void GestureEventHub::FireCustomerOnDragEnd(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
1441 {
1442 DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
1443 auto eventHub = hub.Upgrade();
1444 CHECK_NULL_VOID(eventHub);
1445 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1446 CHECK_NULL_VOID(pipeline);
1447 auto dragDropManager = pipeline->GetDragDropManager();
1448 CHECK_NULL_VOID(dragDropManager);
1449 dragDropManager->RemoveDeadlineTimer();
1450 auto dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1451 CHECK_NULL_VOID(dragEvent);
1452 dragEvent->SetResult(DragRet::DRAG_FAIL);
1453 dragEvent->SetDragBehavior(DragBehavior::UNKNOWN);
1454 dragDropManager->DoDragReset();
1455 dragDropManager->SetIsDragged(false);
1456 dragDropManager->ResetDragging();
1457 dragDropManager->SetDraggingPointer(-1);
1458 dragDropManager->SetDraggingPressedState(false);
1459 dragDropManager->ResetDragPreviewInfo();
1460 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
1461 if (eventHub->HasOnDragEnd()) {
1462 (eventHub->GetOnDragEnd())(dragEvent);
1463 }
1464 }
1465
1466 #if defined(PIXEL_MAP_SUPPORTED)
PrintBuilderNode(const RefPtr<UINode> & customNode)1467 void GestureEventHub::PrintBuilderNode(const RefPtr<UINode>& customNode)
1468 {
1469 CHECK_NULL_VOID(customNode);
1470 bool hasImageNode = false;
1471 std::list<RefPtr<FrameNode>> imageNodes;
1472 int32_t depth = 1;
1473 PrintIfImageNode(customNode, depth, hasImageNode, imageNodes);
1474 CheckImageDecode(imageNodes);
1475 imageNodes.clear();
1476 }
1477
PrintIfImageNode(const RefPtr<UINode> & builderNode,int32_t depth,bool & hasImageNode,std::list<RefPtr<FrameNode>> & imageNodes)1478 void GestureEventHub::PrintIfImageNode(
1479 const RefPtr<UINode>& builderNode, int32_t depth, bool& hasImageNode, std::list<RefPtr<FrameNode>>& imageNodes)
1480 {
1481 if (depth > MAX_BUILDER_DEPTH) {
1482 return;
1483 }
1484 if (builderNode->GetTag() == V2::IMAGE_ETS_TAG) {
1485 auto frameNode = AceType::DynamicCast<FrameNode>(builderNode);
1486 CHECK_NULL_VOID(frameNode);
1487 auto pattern = frameNode->GetPattern<ImagePattern>();
1488 CHECK_NULL_VOID(pattern);
1489 hasImageNode = true;
1490 imageNodes.push_back(frameNode);
1491 TAG_LOGI(AceLogTag::ACE_DRAG,
1492 "customNode has ImageNode, syncLoad: %{public}d, decode complete: %{public}d",
1493 pattern->GetSyncLoad(), pattern->GetCanvasImage() != nullptr);
1494 }
1495
1496 auto children = builderNode->GetChildren();
1497 for (const auto& child : children) {
1498 PrintIfImageNode(child, depth + 1, hasImageNode, imageNodes);
1499 }
1500 }
1501
CheckImageDecode(std::list<RefPtr<FrameNode>> & imageNodes)1502 void GestureEventHub::CheckImageDecode(std::list<RefPtr<FrameNode>>& imageNodes)
1503 {
1504 if (imageNodes.empty()) {
1505 return;
1506 }
1507
1508 for (const auto& imageNode : imageNodes) {
1509 auto pattern = imageNode->GetPattern<ImagePattern>();
1510 CHECK_NULL_VOID(pattern);
1511 if (!pattern->GetCanvasImage()) {
1512 TAG_LOGW(AceLogTag::ACE_DRAG, "ImageNode did not complete decoding");
1513 }
1514 }
1515 }
1516
StartDragForCustomBuilderSync(const GestureEvent & info,const RefPtr<PipelineBase> & pipeline,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & event)1517 bool GestureEventHub::StartDragForCustomBuilderSync(const GestureEvent& info, const RefPtr<PipelineBase>& pipeline,
1518 const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& event)
1519 {
1520 SnapshotParam param;
1521 std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
1522 {
1523 ACE_SCOPED_TRACE("drag: try get builder snapshot sync");
1524 pixelMap = ComponentSnapshot::CreateSync(dragDropInfo.customNode, param);
1525 }
1526
1527 if (pixelMap == nullptr) {
1528 // try failed, need fall back to use async way
1529 return false;
1530 }
1531
1532 // get snapshot successfully, go ahead
1533 dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1534 OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
1535 return true;
1536 }
1537
StartDragForCustomBuilder(const GestureEvent & info,const RefPtr<PipelineBase> & pipeline,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & event)1538 void GestureEventHub::StartDragForCustomBuilder(const GestureEvent& info, const RefPtr<PipelineBase>& pipeline,
1539 const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& event)
1540 {
1541 if (StartDragForCustomBuilderSync(info, pipeline, frameNode, dragDropInfo, event)) {
1542 return;
1543 }
1544
1545 TAG_LOGI(AceLogTag::ACE_DRAG, "Snapshot createSync failed, get thumbnail by async.");
1546 auto callback = [id = Container::CurrentId(), pipeline, info, gestureEventHubPtr = AceType::Claim(this), frameNode,
1547 dragDropInfo, event](std::shared_ptr<Media::PixelMap> pixelMap, int32_t arg, std::function<void()>
1548 finishCallback) mutable {
1549 ContainerScope scope(id);
1550 ACE_SCOPED_TRACE("drag: get snapshot async done, post task to UI for next handling");
1551 TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail callback executed.");
1552 if (pixelMap != nullptr) {
1553 dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1554 } else {
1555 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SNAPSHOT_FAIL);
1556 }
1557 auto taskScheduler = pipeline->GetTaskExecutor();
1558 CHECK_NULL_VOID(taskScheduler);
1559 taskScheduler->PostTask(
1560 [pipeline, info, gestureEventHubPtr, frameNode, dragDropInfo, event, finishCallback]() {
1561 TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail finished, start drag.");
1562 if (finishCallback) {
1563 finishCallback();
1564 }
1565 CHECK_NULL_VOID(gestureEventHubPtr);
1566 CHECK_NULL_VOID(frameNode);
1567 gestureEventHubPtr->OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
1568 },
1569 TaskExecutor::TaskType::UI, "ArkUIGestureDragStart");
1570 };
1571 SnapshotParam param;
1572 param.delay = CREATE_PIXELMAP_TIME;
1573 param.checkImageStatus = true;
1574 param.options.waitUntilRenderFinished = true;
1575 ACE_SCOPED_TRACE("drag: try sync failed, to get snapshot async");
1576 NG::ComponentSnapshot::Create(dragDropInfo.customNode, std::move(callback), true, param);
1577 PrintBuilderNode(dragDropInfo.customNode);
1578 }
1579 #endif
1580
GetDragPreviewInitPositionToScreen(const RefPtr<PipelineBase> & context,PreparedInfoForDrag & data)1581 OffsetF GestureEventHub::GetDragPreviewInitPositionToScreen(
1582 const RefPtr<PipelineBase>& context, PreparedInfoForDrag& data)
1583 {
1584 auto frameNode = GetFrameNode();
1585 CHECK_NULL_RETURN(frameNode, OffsetF());
1586 OffsetF previewOffset;
1587 OffsetF pixelMapHalfSize = data.pixelMap ? OffsetF(data.pixelMap->GetWidth() / 2.0f,
1588 data.pixelMap->GetHeight() / 2.0f) : OffsetF();
1589 previewOffset = DragDropFuncWrapper::GetPaintRectCenterToScreen(frameNode) - pixelMapHalfSize;
1590 auto frameTag = frameNode->GetTag();
1591 if (IsPixelMapNeedScale() && GetTextDraggable() && IsTextCategoryComponent(frameTag)) {
1592 auto textDragPattern = frameNode->GetPattern<TextDragBase>();
1593 CHECK_NULL_RETURN(textDragPattern, previewOffset);
1594 auto dragNode = textDragPattern->MoveDragNode();
1595 if (dragNode) {
1596 previewOffset = DragDropFuncWrapper::GetPaintRectCenterToScreen(dragNode) - pixelMapHalfSize;
1597 return previewOffset;
1598 }
1599 }
1600
1601 if (IsPixelMapNeedScale() && frameTag == V2::WEB_ETS_TAG) {
1602 auto offset = DragDropFuncWrapper::GetCurrentWindowOffset(context);
1603 return frameNodeOffset_ + offset;
1604 }
1605
1606 if (data.isMenuShow) {
1607 OffsetF menuPreviewCenter = frameNodeOffset_ + OffsetF(frameNodeSize_.Width(), frameNodeSize_.Height()) / 2.0f;
1608 menuPreviewCenter += DragDropFuncWrapper::GetCurrentWindowOffset(context);
1609 if (data.imageNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT ||
1610 !data.isMenuShow) {
1611 previewOffset = menuPreviewCenter - pixelMapHalfSize + data.dragMovePosition;
1612 }
1613 if ((data.imageNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
1614 data.imageNode->GetDragPreviewOption().sizeChangeEffect ==
1615 DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION) &&
1616 data.isMenuShow) {
1617 previewOffset = menuPreviewCenter - OffsetF(frameNodeSize_.Width(), frameNodeSize_.Height()) / 2.0f +
1618 data.dragMovePosition;
1619 }
1620 }
1621 return previewOffset;
1622 }
1623
GetBadgeNumber(const RefPtr<UnifiedData> & unifiedData)1624 int32_t GestureEventHub::GetBadgeNumber(const RefPtr<UnifiedData>& unifiedData)
1625 {
1626 auto frameNode = GetFrameNode();
1627 CHECK_NULL_RETURN(frameNode, 1);
1628 auto pattern = frameNode->GetPattern();
1629 CHECK_NULL_RETURN(pattern, 1);
1630 int32_t badgeNumber = 1;
1631 pattern->ResetDragOption();
1632 if (pattern->GetDragRecordSize() >= 0) {
1633 badgeNumber = pattern->GetDragRecordSize();
1634 } else if (unifiedData) {
1635 auto recordSize = unifiedData->GetSize();
1636 badgeNumber = recordSize > 1 ? recordSize : 1;
1637 }
1638
1639 auto dragPreviewOptions = frameNode->GetDragPreviewOption();
1640 auto customBadgeNumber = dragPreviewOptions.GetCustomerBadgeNumber();
1641 auto selectItemSize = GetSelectItemSize();
1642 if (customBadgeNumber.has_value()) {
1643 badgeNumber = customBadgeNumber.value();
1644 TAG_LOGI(AceLogTag::ACE_DRAG, "Use custom badge number, value is %{public}d", badgeNumber);
1645 } else if (selectItemSize > 1) {
1646 badgeNumber = selectItemSize;
1647 TAG_LOGI(AceLogTag::ACE_DRAG, "Use select item size, value is %{public}d", badgeNumber);
1648 }
1649 return badgeNumber;
1650 }
1651
TryDoDragStartAnimation(const RefPtr<PipelineBase> & context,const RefPtr<Subwindow> & subWindow,const GestureEvent & info,PreparedInfoForDrag & data)1652 bool GestureEventHub::TryDoDragStartAnimation(const RefPtr<PipelineBase>& context, const RefPtr<Subwindow>& subWindow,
1653 const GestureEvent& info, PreparedInfoForDrag& data)
1654 {
1655 auto frameNode = GetFrameNode();
1656 auto container = Container::Current();
1657 auto eventHub = eventHub_.Upgrade();
1658 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1659 if (!subWindow || !frameNode || !container || !pipeline || !eventHub || !data.imageNode) {
1660 return false;
1661 }
1662
1663 auto dragNodePipeline = frameNode->GetContextRefPtr();
1664 CHECK_NULL_RETURN(dragNodePipeline, false);
1665 auto overlayManager = dragNodePipeline->GetOverlayManager();
1666 CHECK_NULL_RETURN(overlayManager, false);
1667 auto isExpandDisplay = DragDropFuncWrapper::IsExpandDisplay(context);
1668 auto dragDropManager = DragDropFuncWrapper::GetDragDropManagerForDragAnimation(context, dragNodePipeline,
1669 subWindow, isExpandDisplay, container->GetInstanceId());
1670 CHECK_NULL_RETURN(dragDropManager, false);
1671 dragDropManager->SetIsDragWithContextMenu(data.isMenuShow);
1672
1673 // create text node
1674 auto subWindowOffset = isExpandDisplay ? subWindow->GetWindowRect().GetOffset() : OffsetF();
1675 auto textNode = DragAnimationHelper::CreateBadgeTextNode(data.badgeNumber);
1676 data.textNode = textNode;
1677 DragAnimationHelper::SetNodeVisible(textNode, false);
1678 // create gatherNode
1679 auto originGatherNode = overlayManager->GetGatherNode();
1680 OffsetF positionToWindow = originGatherNode ? originGatherNode->GetPositionToWindowWithTransform() : OffsetF();
1681 std::vector<GatherNodeChildInfo> childrenInfo;
1682 auto gatherNode = DragAnimationHelper::GetOrCreateGatherNode(overlayManager, dragEventActuator_, childrenInfo);
1683 data.gatherNode = gatherNode;
1684 auto gatherNodeOffset = isExpandDisplay
1685 ? DragDropManager::GetTouchOffsetRelativeToSubwindow(dragNodePipeline->GetInstanceId()) + positionToWindow
1686 : positionToWindow;
1687 DragEventActuator::UpdateGatherAnimatePosition(childrenInfo, gatherNodeOffset);
1688
1689 // mount node
1690 auto subWindowOverlayManager = subWindow->GetOverlayManager();
1691 CHECK_NULL_RETURN(subWindowOverlayManager, false);
1692 DragEventActuator::MountGatherNode(subWindowOverlayManager, frameNode, gatherNode, childrenInfo);
1693 DragAnimationHelper::MountPixelMap(
1694 subWindowOverlayManager, eventHub->GetOrCreateGestureEventHub(), data, true);
1695
1696 // update position
1697 UpdateNodePositionBeforeStartAnimation(frameNode, data, subWindowOffset);
1698 HideMenu();
1699 pipeline->FlushSyncGeometryNodeTasks();
1700 overlayManager->RemovePixelMap();
1701 DragAnimationHelper::ShowBadgeAnimation(textNode);
1702 DragAnimationHelper::HideDragNodeCopy(overlayManager);
1703
1704 dragDropManager->DoDragStartAnimation(
1705 subWindowOverlayManager, info, eventHub->GetOrCreateGestureEventHub(), data);
1706 return true;
1707 }
1708
UpdateNodePositionBeforeStartAnimation(const RefPtr<FrameNode> & frameNode,PreparedInfoForDrag & data,const OffsetF & subWindowOffset)1709 void GestureEventHub::UpdateNodePositionBeforeStartAnimation(const RefPtr<FrameNode>& frameNode,
1710 PreparedInfoForDrag& data, const OffsetF& subWindowOffset)
1711 {
1712 CHECK_NULL_VOID(frameNode);
1713 if (frameNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT || !data.isMenuShow) {
1714 DragAnimationHelper::UpdateBadgeTextNodePosition(frameNode, data.textNode, data.badgeNumber, data.previewScale,
1715 data.dragPreviewOffsetToScreen - subWindowOffset);
1716 DragDropFuncWrapper::UpdateNodePositionToScreen(data.imageNode, data.dragPreviewOffsetToScreen);
1717 DragAnimationHelper::PreLayout(data.imageNode);
1718 } else {
1719 DragDropFuncWrapper::UpdateNodePositionToScreen(data.relativeContainerNode, data.dragPreviewOffsetToScreen);
1720 DragAnimationHelper::PreLayout(data.relativeContainerNode);
1721 }
1722 }
1723
CheckAllowDrag(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> & frameNode)1724 bool GestureEventHub::CheckAllowDrag(const GestureEvent& info, const RefPtr<PipelineBase>& context,
1725 const RefPtr<FrameNode>& frameNode)
1726 {
1727 auto eventHub = eventHub_.Upgrade();
1728 CHECK_NULL_RETURN(eventHub, false);
1729 CHECK_NULL_RETURN(frameNode, false);
1730 if (!eventHub->HasOnDragStart()) {
1731 TAG_LOGE(AceLogTag::ACE_DRAG, "FrameNode is not set onDragStart event.");
1732 return false;
1733 }
1734 if (!IsAllowedDrag(eventHub)) {
1735 auto pattern = frameNode->GetPattern();
1736 CHECK_NULL_RETURN(pattern, false);
1737 TAG_LOGE(AceLogTag::ACE_DRAG,
1738 "FrameNode is not allow drag, tag is %{public}s"
1739 "draggable is %{public}d, drag start event is %{public}d,"
1740 "default support drag is %{public}d, user set is %{public}d.",
1741 frameNode->GetTag().c_str(), frameNode->IsDraggable(), eventHub->HasOnDragStart(),
1742 pattern->DefaultSupportDrag(), frameNode->IsUserSet());
1743 return false;
1744 }
1745 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1746 CHECK_NULL_RETURN(pipeline, false);
1747 auto eventManager = pipeline->GetEventManager();
1748 CHECK_NULL_RETURN(eventManager, false);
1749 if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && eventManager->IsLastMoveBeforeUp()) {
1750 TAG_LOGE(AceLogTag::ACE_DRAG, "Drag stop because user release mouse button");
1751 return false;
1752 }
1753
1754 return true;
1755 }
1756
CreateDragEvent(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> & frameNode)1757 RefPtr<OHOS::Ace::DragEvent> GestureEventHub::CreateDragEvent(const GestureEvent& info,
1758 const RefPtr<PipelineBase>& context, const RefPtr<FrameNode>& frameNode)
1759 {
1760 RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1761 CHECK_NULL_RETURN(frameNode, event);
1762 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1763 if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
1764 CHECK_NULL_RETURN(pipeline, event);
1765 event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1766 event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1767 } else {
1768 event->SetX(info.GetGlobalPoint().GetX());
1769 event->SetY(info.GetGlobalPoint().GetY());
1770 }
1771 event->SetScreenX(info.GetScreenLocation().GetX());
1772 event->SetScreenY(info.GetScreenLocation().GetY());
1773 event->SetDisplayX(info.GetScreenLocation().GetX());
1774 event->SetDisplayY(info.GetScreenLocation().GetY());
1775 event->SetSourceTool(info.GetSourceTool());
1776 return event;
1777 }
1778
SetMouseDragMonitorState(bool state)1779 void GestureEventHub::SetMouseDragMonitorState(bool state)
1780 {
1781 auto ret = InteractionInterface::GetInstance()->SetMouseDragMonitorState(state);
1782 if (ret != 0) {
1783 TAG_LOGW(AceLogTag::ACE_DRAG, "Set mouse drag monitor state %{public}d failed, return value is %{public}d",
1784 state, ret);
1785 return;
1786 }
1787 TAG_LOGI(AceLogTag::ACE_DRAG, "Set mouse drag monitor state %{public}d success", state);
1788 }
1789
SetBindMenuStatus(bool setIsShow,bool isShow,MenuPreviewMode previewMode)1790 void GestureEventHub::SetBindMenuStatus(bool setIsShow, bool isShow, MenuPreviewMode previewMode)
1791 {
1792 if (setIsShow) {
1793 bindMenuStatus_.isBindCustomMenu = true;
1794 bindMenuStatus_.isShow = isShow;
1795 bindMenuStatus_.isShowPreviewMode = previewMode;
1796 } else {
1797 bindMenuStatus_.isBindLongPressMenu = true;
1798 bindMenuStatus_.longPressPreviewMode = previewMode;
1799 }
1800 }
1801
AddPreviewMenuHandleDragEnd(GestureEventFunc && actionEnd)1802 void GestureEventHub::AddPreviewMenuHandleDragEnd(GestureEventFunc&& actionEnd)
1803 {
1804 if (!scrollableActuator_) {
1805 scrollableActuator_ = MakeRefPtr<ScrollableActuator>(WeakClaim(this));
1806 }
1807 scrollableActuator_->AddPreviewMenuHandleDragEnd(std::move(actionEnd));
1808 }
1809
1810 // Set by user define, which will replace old one.
SetDragEvent(const RefPtr<DragEvent> & dragEvent,PanDirection direction,int32_t fingers,Dimension distance)1811 void GestureEventHub::SetDragEvent(
1812 const RefPtr<DragEvent>& dragEvent, PanDirection direction, int32_t fingers, Dimension distance)
1813 {
1814 if (!dragEventActuator_ || dragEventActuator_->GetIsNewFwk()) {
1815 dragEventActuator_ = MakeRefPtr<DragEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx());
1816 }
1817 dragEventActuator_->ReplaceDragEvent(dragEvent);
1818 }
1819
SetDragDropEvent()1820 void GestureEventHub::SetDragDropEvent()
1821 {
1822 if (!dragEventActuator_ || !dragEventActuator_->GetIsNewFwk()) {
1823 isDragNewFwk_ = true;
1824 dragEventActuator_ = MakeRefPtr<DragDropEventActuator>(WeakClaim(this));
1825 }
1826 }
1827
SetCustomDragEvent(const RefPtr<DragEvent> & dragEvent,PanDirection direction,int32_t fingers,Dimension distance)1828 void GestureEventHub::SetCustomDragEvent(
1829 const RefPtr<DragEvent>& dragEvent, PanDirection direction, int32_t fingers, Dimension distance)
1830 {
1831 if (!dragEventActuator_ || dragEventActuator_->GetIsNewFwk()) {
1832 isDragNewFwk_ = false;
1833 dragEventActuator_ = MakeRefPtr<DragEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx());
1834 }
1835 dragEventActuator_->SetCustomDragEvent(dragEvent);
1836 }
1837
HasDragEvent() const1838 bool GestureEventHub::HasDragEvent() const
1839 {
1840 return dragEventActuator_ && (dragEventActuator_->HasDragEvent() || dragEventActuator_->GetIsNewFwk());
1841 }
1842
RemoveDragEvent()1843 void GestureEventHub::RemoveDragEvent()
1844 {
1845 if (!dragEventActuator_) {
1846 return;
1847 }
1848 if (dragEventActuator_->GetIsNewFwk()) {
1849 dragEventActuator_ = nullptr;
1850 return;
1851 }
1852 dragEventActuator_->ClearDragEvent();
1853 }
1854
SetThumbnailCallback(std::function<void (Offset)> && callback)1855 void GestureEventHub::SetThumbnailCallback(std::function<void(Offset)>&& callback)
1856 {
1857 if (dragEventActuator_) {
1858 dragEventActuator_->SetThumbnailCallback(std::move(callback));
1859 }
1860 }
1861
GetTextDraggable() const1862 bool GestureEventHub::GetTextDraggable() const
1863 {
1864 return textDraggable_;
1865 }
1866
SetTextDraggable(bool draggable)1867 void GestureEventHub::SetTextDraggable(bool draggable)
1868 {
1869 textDraggable_ = draggable;
1870 }
1871
SetIsTextDraggable(bool isTextDraggable)1872 void GestureEventHub::SetIsTextDraggable(bool isTextDraggable)
1873 {
1874 isTextDraggable_ = isTextDraggable;
1875 }
1876
GetIsTextDraggable()1877 bool GestureEventHub::GetIsTextDraggable()
1878 {
1879 return isTextDraggable_;
1880 }
1881
SetPreviewMode(MenuPreviewMode mode)1882 void GestureEventHub::SetPreviewMode(MenuPreviewMode mode)
1883 {
1884 previewMode_ = mode;
1885 }
1886
GetPreviewMode()1887 MenuPreviewMode GestureEventHub::GetPreviewMode()
1888 {
1889 return previewMode_;
1890 }
1891
SetContextMenuShowStatus(bool contextMenuShowStatus)1892 void GestureEventHub::SetContextMenuShowStatus(bool contextMenuShowStatus)
1893 {
1894 contextMenuShowStatus_ = contextMenuShowStatus;
1895 }
1896
GetContextMenuShowStatus()1897 bool GestureEventHub::GetContextMenuShowStatus()
1898 {
1899 return contextMenuShowStatus_;
1900 }
1901
SetMenuBindingType(MenuBindingType menuBindingType)1902 void GestureEventHub::SetMenuBindingType(MenuBindingType menuBindingType)
1903 {
1904 menuBindingType_ = menuBindingType;
1905 }
1906
GetMenuBindingType()1907 MenuBindingType GestureEventHub::GetMenuBindingType()
1908 {
1909 return menuBindingType_;
1910 }
1911
SetPixelMap(RefPtr<PixelMap> pixelMap)1912 void GestureEventHub::SetPixelMap(RefPtr<PixelMap> pixelMap)
1913 {
1914 pixelMap_ = pixelMap;
1915 }
1916
GetPixelMap()1917 RefPtr<PixelMap> GestureEventHub::GetPixelMap()
1918 {
1919 return pixelMap_;
1920 }
1921
SetDragPreviewPixelMap(RefPtr<PixelMap> pixelMap)1922 void GestureEventHub::SetDragPreviewPixelMap(RefPtr<PixelMap> pixelMap)
1923 {
1924 dragPreviewPixelMap_ = pixelMap;
1925 }
1926
GetDragEventActuator()1927 RefPtr<DragEventActuator> GestureEventHub::GetDragEventActuator()
1928 {
1929 return dragEventActuator_;
1930 }
1931
GetDragPreviewPixelMap()1932 RefPtr<PixelMap> GestureEventHub::GetDragPreviewPixelMap()
1933 {
1934 return dragPreviewPixelMap_;
1935 }
1936
SetMenuPreviewScale(float menuPreviewScale)1937 void GestureEventHub::SetMenuPreviewScale(float menuPreviewScale)
1938 {
1939 menuPreviewScale_ = menuPreviewScale;
1940 }
1941
GetMenuPreviewScale() const1942 float GestureEventHub::GetMenuPreviewScale() const
1943 {
1944 return menuPreviewScale_;
1945 }
1946
GetBindMenuStatus() const1947 const BindMenuStatus& GestureEventHub::GetBindMenuStatus() const
1948 {
1949 return bindMenuStatus_;
1950 }
1951
1952 } // namespace OHOS::Ace::NG
1953