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 "core/components_ng/manager/drag_drop/drag_drop_func_wrapper.h"
17
18 #include "core/common/ace_engine.h"
19 #include "core/components/common/layout/grid_system_manager.h"
20 #include "core/components/select/select_theme.h"
21 #include "core/components/theme/blur_style_theme.h"
22 #include "core/components/theme/shadow_theme.h"
23 #include "core/components_ng/base/inspector.h"
24 #include "core/components_ng/manager/drag_drop/drag_drop_behavior_reporter/drag_drop_behavior_reporter.h"
25 #include "core/components_ng/manager/drag_drop/drag_drop_global_controller.h"
26 #include "core/components_ng/pattern/grid/grid_item_pattern.h"
27 #include "core/components_ng/pattern/image/image_pattern.h"
28 #include "core/components_ng/pattern/list/list_item_pattern.h"
29 #include "core/components_ng/pattern/text/text_pattern.h"
30 #include "core/components_ng/render/adapter/component_snapshot.h"
31 #include "base/subwindow/subwindow_manager.h"
32
33 namespace OHOS::Ace::NG {
34 namespace {
35 constexpr float DEFAULT_OPACITY = 0.95f;
36 constexpr Dimension PREVIEW_BORDER_RADIUS = 12.0_vp;
37 constexpr float BLUR_SIGMA_SCALE = 0.57735f;
38 constexpr float SCALE_HALF = 0.5f;
39 constexpr float MIN_OPACITY { 0.0f };
40 constexpr float MAX_OPACITY { 1.0f };
41 using DragNotifyMsg = OHOS::Ace::DragNotifyMsg;
42 using OnDragCallback = std::function<void(const DragNotifyMsg&)>;
43 using StopDragCallback = std::function<void()>;
44 constexpr int32_t MOUSE_POINTER_ID = 1001;
45 constexpr int32_t SOURCE_TOOL_PEN = 1;
46 constexpr int32_t SOURCE_TYPE_TOUCH = 2;
47 constexpr int32_t PEN_POINTER_ID = 102;
48 constexpr int32_t SOURCE_TYPE_MOUSE = 1;
49 constexpr size_t SHORT_KEY_LENGTH = 8;
50 constexpr size_t PLAINTEXT_LENGTH = 4;
51 constexpr size_t CONVERT_TIME_BASE = 1000;
52 #if defined(PIXEL_MAP_SUPPORTED)
53 constexpr int32_t CREATE_PIXELMAP_TIME = 80;
54 #endif
55 }
56
CheckInternalDragging(const RefPtr<Container> & container)57 static bool CheckInternalDragging(const RefPtr<Container>& container)
58 {
59 CHECK_NULL_RETURN(container, false);
60 auto pipelineContext = container->GetPipelineContext();
61 if (!pipelineContext || !pipelineContext->IsDragging()) {
62 return false;
63 }
64 return true;
65 }
66
GetShadowInfoArray(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,std::vector<ShadowInfoCore> & shadowInfos)67 void GetShadowInfoArray(
68 std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, std::vector<ShadowInfoCore>& shadowInfos)
69 {
70 auto minScaleWidth = NG::DragDropFuncWrapper::GetScaleWidth(dragAction->instanceId);
71 for (auto& pixelMap : dragAction->pixelMapList) {
72 double scale = 1.0;
73 if (Referenced::RawPtr(pixelMap)) {
74 if (pixelMap->GetWidth() > minScaleWidth && dragAction->previewOption.isScaleEnabled) {
75 scale = minScaleWidth / pixelMap->GetWidth();
76 }
77 auto pixelMapScale = dragAction->windowScale * scale;
78 pixelMap->Scale(pixelMapScale, pixelMapScale, AceAntiAliasingOption::HIGH);
79 }
80 int32_t width = pixelMap->GetWidth();
81 int32_t height = pixelMap->GetHeight();
82 double x = dragAction->touchPointX;
83 double y = dragAction->touchPointY;
84 if (!dragAction->hasTouchPoint) {
85 x = -width * PIXELMAP_WIDTH_RATE;
86 y = -height * PIXELMAP_HEIGHT_RATE;
87 }
88 ShadowInfoCore shadowInfo { pixelMap, -x, -y };
89 shadowInfos.push_back(shadowInfo);
90 }
91 }
92
PostStopDrag(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const RefPtr<Container> & container)93 void PostStopDrag(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, const RefPtr<Container>& container)
94 {
95 CHECK_NULL_VOID(container);
96 auto taskExecutor = container->GetTaskExecutor();
97 CHECK_NULL_VOID(taskExecutor);
98 auto windowId = container->GetWindowId();
99 taskExecutor->PostTask(
100 [dragAction, windowId]() {
101 CHECK_NULL_VOID(dragAction);
102 TAG_LOGI(AceLogTag::ACE_DRAG, "drag state is reject, stop drag, windowId is %{public}d.", windowId);
103 OHOS::Ace::DragDropRet dropResult { OHOS::Ace::DragRet::DRAG_CANCEL, false, windowId,
104 OHOS::Ace::DragBehavior::UNKNOWN };
105 InteractionInterface::GetInstance()->StopDrag(dropResult);
106 InteractionInterface::GetInstance()->SetDragWindowVisible(false);
107 },
108 TaskExecutor::TaskType::UI, "ArkUIDragStop");
109 }
110
ConfirmCurPointerEventInfo(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const RefPtr<Container> & container)111 bool ConfirmCurPointerEventInfo(
112 std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, const RefPtr<Container>& container)
113 {
114 CHECK_NULL_RETURN(dragAction, false);
115 CHECK_NULL_RETURN(container, false);
116 StopDragCallback stopDragCallback = [dragAction, container]() {
117 CHECK_NULL_VOID(dragAction);
118 CHECK_NULL_VOID(container);
119 bool needPostStopDrag = false;
120 if (dragAction->dragState == DragAdapterState::SENDING) {
121 needPostStopDrag = true;
122 }
123 {
124 std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
125 dragAction->dragState = DragAdapterState::REJECT;
126 }
127 if (needPostStopDrag) {
128 PostStopDrag(dragAction, container);
129 }
130 };
131 bool getPointSuccess = container->GetCurPointerEventInfo(dragAction->dragPointerEvent,
132 std::move(stopDragCallback));
133 if (dragAction->dragPointerEvent.sourceType == SOURCE_TYPE_MOUSE) {
134 dragAction->dragPointerEvent.pointerId = MOUSE_POINTER_ID;
135 } else if (dragAction->dragPointerEvent.sourceType == SOURCE_TYPE_TOUCH &&
136 static_cast<int32_t>(dragAction->dragPointerEvent.sourceTool) == SOURCE_TOOL_PEN) {
137 dragAction->dragPointerEvent.pointerId = PEN_POINTER_ID;
138 }
139 return getPointSuccess;
140 }
141
EnvelopedDragData(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,std::optional<DragDataCore> & dragData)142 void EnvelopedDragData(
143 std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, std::optional<DragDataCore>& dragData)
144 {
145 auto container = AceEngine::Get().GetContainer(dragAction->instanceId);
146 CHECK_NULL_VOID(container);
147
148 std::vector<ShadowInfoCore> shadowInfos;
149 GetShadowInfoArray(dragAction, shadowInfos);
150 if (shadowInfos.empty()) {
151 TAG_LOGE(AceLogTag::ACE_DRAG, "shadowInfo array is empty");
152 return;
153 }
154 auto pointerId = dragAction->dragPointerEvent.pointerId;
155 std::string udKey;
156 DragSummaryInfo dragSummaryInfo;
157 int32_t dataSize = 1;
158 DragDropFuncWrapper::EnvelopedData(dragAction, udKey, dragSummaryInfo, dataSize);
159 int32_t recordSize = (dataSize != 0 ? dataSize : static_cast<int32_t>(shadowInfos.size()));
160 if (dragAction->previewOption.isNumber) {
161 recordSize = dragAction->previewOption.badgeNumber > 1 ? dragAction->previewOption.badgeNumber : 1;
162 } else if (!dragAction->previewOption.isShowBadge) {
163 recordSize = 1;
164 }
165 auto windowId = container->GetWindowId();
166 auto arkExtraInfoJson = JsonUtil::Create(true);
167 auto pipeline = container->GetPipelineContext();
168 CHECK_NULL_VOID(pipeline);
169 dragAction->dipScale = pipeline->GetDipScale();
170 arkExtraInfoJson->Put("dip_scale", dragAction->dipScale);
171 arkExtraInfoJson->Put("event_id", dragAction->dragPointerEvent.pointerEventId);
172 NG::DragDropFuncWrapper::UpdateExtraInfo(arkExtraInfoJson, dragAction->previewOption);
173 dragData = { shadowInfos, {}, udKey, dragAction->extraParams, arkExtraInfoJson->ToString(),
174 dragAction->dragPointerEvent.sourceType, recordSize, pointerId, dragAction->dragPointerEvent.displayX,
175 dragAction->dragPointerEvent.displayY, dragAction->dragPointerEvent.displayId, windowId, true, false,
176 dragSummaryInfo.summary, false, dragSummaryInfo.detailedSummary, dragSummaryInfo.summaryFormat,
177 dragSummaryInfo.version, dragSummaryInfo.totalSize };
178 }
179
EnvelopedData(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,std::string & udKey,DragSummaryInfo & dragSummaryInfo,int32_t & dataSize)180 void DragDropFuncWrapper::EnvelopedData(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,
181 std::string& udKey, DragSummaryInfo& dragSummaryInfo, int32_t& dataSize)
182 {
183 CHECK_NULL_VOID(dragAction);
184 int32_t ret = 1;
185 if (dragAction->unifiedData) {
186 ret = UdmfClient::GetInstance()->SetData(dragAction->unifiedData, udKey);
187 if (ret != 0) {
188 TAG_LOGI(AceLogTag::ACE_DRAG, "udmf set data failed, return value is %{public}d", ret);
189 }
190 dataSize = static_cast<int32_t>(dragAction->unifiedData->GetSize());
191 }
192 if (dragAction->dataLoadParams) {
193 ret = UdmfClient::GetInstance()->SetDelayInfo(dragAction->dataLoadParams, udKey);
194 if (ret != 0) {
195 TAG_LOGI(AceLogTag::ACE_DRAG, "udmf set delayInfo failed, return value is %{public}d", ret);
196 }
197 auto recodeCount = dragAction->dataLoadParams->GetRecordCount();
198 dataSize = (recodeCount == 0 || recodeCount > INT32_MAX) ? 1 : static_cast<int32_t>(recodeCount);
199 }
200 if (ret == 0) {
201 ret = UdmfClient::GetInstance()->GetSummary(udKey, dragSummaryInfo);
202 if (ret != 0) {
203 TAG_LOGI(AceLogTag::ACE_DRAG, "get summary failed, return value is %{public}d", ret);
204 }
205 }
206 }
207
HandleCallback(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const OHOS::Ace::DragNotifyMsg & dragNotifyMsg,const DragAdapterStatus & dragStatus)208 void DragDropFuncWrapper::HandleCallback(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,
209 const OHOS::Ace::DragNotifyMsg& dragNotifyMsg, const DragAdapterStatus& dragStatus)
210 {
211 TAG_LOGI(AceLogTag::ACE_DRAG, "drag notify message result is %{public}d.", dragNotifyMsg.result);
212 CHECK_NULL_VOID(dragAction);
213 bool hasHandle = false;
214 {
215 std::lock_guard<std::mutex> lock(dragAction->mutex);
216 hasHandle = dragAction->hasHandle;
217 dragAction->hasHandle = true;
218 }
219 if (hasHandle) {
220 return;
221 }
222 auto container = AceEngine::Get().GetContainer(dragAction->instanceId);
223 CHECK_NULL_VOID(container);
224 if (dragStatus == DragAdapterStatus::ENDED) {
225 auto pipelineContext = container->GetPipelineContext();
226 CHECK_NULL_VOID(pipelineContext);
227 pipelineContext->ResetDragging();
228 }
229 int32_t dragState = static_cast<int32_t>(dragStatus);
230 dragAction->callback(dragNotifyMsg, dragState);
231 }
232
CheckStartAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const RefPtr<Container> & container,const RefPtr<DragDropManager> & manager)233 int32_t CheckStartAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,
234 const RefPtr<Container>& container, const RefPtr<DragDropManager>& manager)
235 {
236 if (CheckInternalDragging(container)) {
237 return -1;
238 }
239 {
240 std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
241 if (manager->GetDragAction() != nullptr && (manager->GetDragAction())->dragState == DragAdapterState::SENDING) {
242 return -1;
243 }
244 dragAction->dragState = DragAdapterState::SENDING;
245 }
246 DragDropFuncWrapper::UpdatePreviewOptionDefaultAttr(dragAction->previewOption);
247 auto isGetPointSuccess = ConfirmCurPointerEventInfo(dragAction, container);
248 if (!isGetPointSuccess) {
249 return -1;
250 }
251 return 0;
252 }
253
StartDragAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)254 int32_t DragDropFuncWrapper::StartDragAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)
255 {
256 CHECK_NULL_RETURN(dragAction, -1);
257 auto pipelineContext = PipelineContext::GetContextByContainerId(dragAction->instanceId);
258 CHECK_NULL_RETURN(pipelineContext, -1);
259 auto manager = pipelineContext->GetDragDropManager();
260 CHECK_NULL_RETURN(manager, -1);
261 auto container = AceEngine::Get().GetContainer(dragAction->instanceId);
262 CHECK_NULL_RETURN(container, -1);
263 auto windowScale = container->GetWindowScale();
264 CHECK_NULL_RETURN(windowScale, -1);
265 dragAction->windowScale = windowScale;
266 manager->SetDragAction(dragAction);
267 if (CheckStartAction(dragAction, container, manager) == -1) {
268 manager->GetDragAction()->dragState = DragAdapterState::INIT;
269 return -1;
270 }
271 std::optional<DragDataCore> dragData;
272 EnvelopedDragData(dragAction, dragData);
273 if (!dragData) {
274 {
275 std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
276 manager->GetDragAction()->dragState = DragAdapterState::INIT;
277 }
278 return -1;
279 }
280 OnDragCallback callback = [dragAction, manager](const OHOS::Ace::DragNotifyMsg& dragNotifyMsg) {
281 {
282 std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
283 dragAction->dragState = DragAdapterState::INIT;
284 manager->SetDragAction(dragAction);
285 }
286 HandleCallback(dragAction, dragNotifyMsg, DragAdapterStatus::ENDED);
287 };
288 NG::DragDropFuncWrapper::SetDraggingPointerAndPressedState(
289 dragAction->dragPointerEvent.pointerId, dragAction->instanceId);
290 int32_t ret = InteractionInterface::GetInstance()->StartDrag(dragData.value(), callback);
291 if (ret != 0) {
292 manager->GetDragAction()->dragState = DragAdapterState::INIT;
293 TAG_LOGE(AceLogTag::ACE_DRAG, "msdp start drag failed.");
294 return -1;
295 }
296 HandleCallback(dragAction, DragNotifyMsg {}, DragAdapterStatus::STARTED);
297 pipelineContext->SetIsDragging(true);
298 TAG_LOGI(AceLogTag::ACE_DRAG, "msdp start drag successfully.");
299 NG::DragDropFuncWrapper::HandleOnDragEvent(dragAction);
300 return 0;
301 }
302
HandleOnDragEvent(const std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)303 void DragDropFuncWrapper::HandleOnDragEvent(
304 const std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)
305 {
306 CHECK_NULL_VOID(dragAction);
307 auto pipelineContext = PipelineContext::GetContextByContainerId(dragAction->instanceId);
308 CHECK_NULL_VOID(pipelineContext);
309 std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
310 if (dragAction->dragState == DragAdapterState::SENDING) {
311 dragAction->dragState = DragAdapterState::SUCCESS;
312 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
313 pipelineContext->OnDragEvent(
314 { dragAction->dragPointerEvent.displayX, dragAction->dragPointerEvent.displayY },
315 DragEventAction::DRAG_EVENT_START_FOR_CONTROLLER);
316 NG::DragDropFuncWrapper::DecideWhetherToStopDragging(
317 { dragAction->dragPointerEvent.displayX, dragAction->dragPointerEvent.displayY }, dragAction->extraParams,
318 dragAction->dragPointerEvent.pointerId, dragAction->instanceId);
319 }
320 }
321
SetDraggingPointerAndPressedState(int32_t currentPointerId,int32_t containerId)322 void DragDropFuncWrapper::SetDraggingPointerAndPressedState(int32_t currentPointerId, int32_t containerId)
323 {
324 auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
325 CHECK_NULL_VOID(pipelineContext);
326 auto manager = pipelineContext->GetDragDropManager();
327 CHECK_NULL_VOID(manager);
328 manager->SetDraggingPointer(currentPointerId);
329 manager->SetDraggingPressedState(true);
330 }
331
RequestDragEndPending()332 int32_t DragDropFuncWrapper::RequestDragEndPending()
333 {
334 if (!DragDropGlobalController::GetInstance().IsOnOnDropPhase()) {
335 return -1;
336 }
337 static std::atomic<int32_t> gDragDropDelayEndRequestId;
338 int32_t id = gDragDropDelayEndRequestId.fetch_add(1);
339 return id;
340 }
341
NotifyDragResult(int32_t requestId,int32_t result)342 int32_t DragDropFuncWrapper::NotifyDragResult(int32_t requestId, int32_t result)
343 {
344 if (!DragDropGlobalController::GetInstance().IsOnOnDropPhase()) {
345 return -1;
346 }
347 return DragDropGlobalController::GetInstance().NotifyDragResult(requestId, result);
348 }
349
NotifyDragEndPendingDone(int32_t requestId)350 int32_t DragDropFuncWrapper::NotifyDragEndPendingDone(int32_t requestId)
351 {
352 if (!DragDropGlobalController::GetInstance().IsOnOnDropPhase()) {
353 return -1;
354 }
355 return DragDropGlobalController::GetInstance().NotifyDragEndPendingDone(requestId);
356 }
357
DecideWhetherToStopDragging(const DragPointerEvent & pointerEvent,const std::string & extraParams,int32_t currentPointerId,int32_t containerId)358 void DragDropFuncWrapper::DecideWhetherToStopDragging(
359 const DragPointerEvent& pointerEvent, const std::string& extraParams, int32_t currentPointerId, int32_t containerId)
360 {
361 auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
362 CHECK_NULL_VOID(pipelineContext);
363 auto manager = pipelineContext->GetDragDropManager();
364 CHECK_NULL_VOID(manager);
365 if (!manager->IsDraggingPressed(currentPointerId)) {
366 manager->OnDragEnd(pointerEvent, extraParams);
367 }
368 }
369
UpdateDragPreviewOptionsFromModifier(std::function<void (WeakPtr<FrameNode>)> applyOnNodeSync,DragPreviewOption & option)370 void DragDropFuncWrapper::UpdateDragPreviewOptionsFromModifier(
371 std::function<void(WeakPtr<FrameNode>)> applyOnNodeSync, DragPreviewOption& option)
372 {
373 // create one temporary frame node for receiving the value from the modifier
374 auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
375 []() { return AceType::MakeRefPtr<ImagePattern>(); });
376 CHECK_NULL_VOID(imageNode);
377
378 // execute the modifier
379 CHECK_NULL_VOID(applyOnNodeSync);
380 applyOnNodeSync(AceType::WeakClaim(AceType::RawPtr(imageNode)));
381
382 // get values from the temporary frame node
383 auto imageContext = imageNode->GetRenderContext();
384 CHECK_NULL_VOID(imageContext);
385 auto opacity = imageContext->GetOpacity();
386 if (opacity.has_value() && (opacity.value()) <= MAX_OPACITY && (opacity.value()) > MIN_OPACITY) {
387 option.options.opacity = opacity.value();
388 } else {
389 option.options.opacity = DEFAULT_OPACITY;
390 }
391
392 auto shadow = imageContext->GetBackShadow();
393 if (shadow.has_value()) {
394 option.options.shadow = shadow.value();
395 }
396
397 auto borderRadius = imageContext->GetBorderRadius();
398 if (borderRadius.has_value()) {
399 option.options.borderRadius = borderRadius;
400 }
401
402 auto bgEffect = imageContext->GetBackgroundEffect();
403 if (bgEffect.has_value()) {
404 option.options.blurbgEffect.backGroundEffect = bgEffect.value();
405 } else {
406 auto blurstyletmp = imageContext->GetBackBlurStyle();
407 if (blurstyletmp.has_value()) {
408 bgEffect = BlurStyleToEffection(blurstyletmp);
409 if (bgEffect.has_value()) {
410 option.options.blurbgEffect.backGroundEffect = bgEffect.value();
411 }
412 }
413 }
414 }
415
UpdatePreviewOptionDefaultAttr(DragPreviewOption & option,bool isMultiSelectionEnabled)416 void DragDropFuncWrapper::UpdatePreviewOptionDefaultAttr(DragPreviewOption& option, bool isMultiSelectionEnabled)
417 {
418 option.options.opacity = DEFAULT_OPACITY;
419 if (option.isDefaultShadowEnabled) {
420 option.options.shadow = GetDefaultShadow();
421 } else {
422 option.options.shadow = std::nullopt;
423 }
424 if (option.isDefaultRadiusEnabled || isMultiSelectionEnabled) {
425 option.options.borderRadius = GetDefaultBorderRadius();
426 } else {
427 option.options.borderRadius = std::nullopt;
428 }
429 }
430
UpdateExtraInfo(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)431 void DragDropFuncWrapper::UpdateExtraInfo(std::unique_ptr<JsonValue>& arkExtraInfoJson,
432 DragPreviewOption& option)
433 {
434 CHECK_NULL_VOID(arkExtraInfoJson);
435 double opacity = option.options.opacity;
436 arkExtraInfoJson->Put("dip_opacity", opacity);
437 if (option.options.blurbgEffect.backGroundEffect.radius.IsValid()) {
438 option.options.blurbgEffect.ToJsonValue(arkExtraInfoJson);
439 }
440 PrepareShadowParametersForDragData(arkExtraInfoJson, option);
441 PrepareRadiusParametersForDragData(arkExtraInfoJson, option);
442 }
443
PrepareRadiusParametersForDragData(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)444 void DragDropFuncWrapper::PrepareRadiusParametersForDragData(std::unique_ptr<JsonValue>& arkExtraInfoJson,
445 DragPreviewOption& option)
446 {
447 CHECK_NULL_VOID(arkExtraInfoJson);
448 auto borderRadius = option.options.borderRadius;
449 if (borderRadius.has_value()) {
450 if (borderRadius.value().radiusTopLeft.has_value()) {
451 arkExtraInfoJson->Put("drag_corner_radius1", borderRadius.value().radiusTopLeft.value().Value());
452 }
453 if (borderRadius.value().radiusTopRight.has_value()) {
454 arkExtraInfoJson->Put("drag_corner_radius2", borderRadius.value().radiusTopRight.value().Value());
455 }
456 if (borderRadius.value().radiusBottomRight.has_value()) {
457 arkExtraInfoJson->Put("drag_corner_radius3", borderRadius.value().radiusBottomRight.value().Value());
458 }
459 if (borderRadius.value().radiusBottomLeft.has_value()) {
460 arkExtraInfoJson->Put("drag_corner_radius4", borderRadius.value().radiusBottomLeft.value().Value());
461 }
462 }
463 }
464
PrepareShadowParametersForDragData(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)465 void DragDropFuncWrapper::PrepareShadowParametersForDragData(std::unique_ptr<JsonValue>& arkExtraInfoJson,
466 DragPreviewOption& option)
467 {
468 CHECK_NULL_VOID(arkExtraInfoJson);
469 auto shadow = option.options.shadow;
470 if (!shadow.has_value() || !shadow->IsValid()) {
471 arkExtraInfoJson->Put("shadow_enable", false);
472 return;
473 }
474 arkExtraInfoJson->Put("drag_type", "non-text");
475 arkExtraInfoJson->Put("shadow_enable", true);
476 ParseShadowInfo(shadow.value(), arkExtraInfoJson);
477 }
478
ParseShadowInfo(Shadow & shadow,std::unique_ptr<JsonValue> & arkExtraInfoJson)479 void DragDropFuncWrapper::ParseShadowInfo(Shadow& shadow, std::unique_ptr<JsonValue>& arkExtraInfoJson)
480 {
481 CHECK_NULL_VOID(arkExtraInfoJson);
482 arkExtraInfoJson->Put("shadow_is_filled", shadow.GetIsFilled());
483 arkExtraInfoJson->Put("drag_shadow_OffsetX", shadow.GetOffset().GetX());
484 arkExtraInfoJson->Put("drag_shadow_OffsetY", shadow.GetOffset().GetY());
485 arkExtraInfoJson->Put("shadow_mask", shadow.GetShadowType() == ShadowType::BLUR);
486 int32_t argb = static_cast<int32_t>(shadow.GetColor().GetValue());
487 arkExtraInfoJson->Put("drag_shadow_argb", argb);
488 int32_t strategy = static_cast<int32_t>(shadow.GetShadowColorStrategy());
489 arkExtraInfoJson->Put("shadow_color_strategy", strategy);
490 arkExtraInfoJson->Put("shadow_corner", shadow.GetBlurRadius());
491 arkExtraInfoJson->Put("shadow_elevation", shadow.GetElevation());
492 arkExtraInfoJson->Put("shadow_is_hardwareacceleration", shadow.GetHardwareAcceleration());
493 }
494
GetDefaultShadow()495 std::optional<Shadow> DragDropFuncWrapper::GetDefaultShadow()
496 {
497 auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
498 CHECK_NULL_RETURN(pipelineContext, std::nullopt);
499 auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
500 CHECK_NULL_RETURN(shadowTheme, std::nullopt);
501 auto colorMode = pipelineContext->GetColorMode();
502 auto shadow = shadowTheme->GetShadow(ShadowStyle::OuterFloatingSM, colorMode);
503 shadow.SetIsFilled(true);
504 return shadow;
505 }
506
GetDefaultBorderRadius()507 std::optional<BorderRadiusProperty> DragDropFuncWrapper::GetDefaultBorderRadius()
508 {
509 BorderRadiusProperty borderRadius;
510 borderRadius.SetRadius(PREVIEW_BORDER_RADIUS);
511 return borderRadius;
512 }
513
RadiusToSigma(float radius)514 float DragDropFuncWrapper::RadiusToSigma(float radius)
515 {
516 return GreatNotEqual(radius, 0.0f) ? BLUR_SIGMA_SCALE * radius + SCALE_HALF : 0.0f;
517 }
518
BlurStyleToEffection(const std::optional<BlurStyleOption> & blurStyleOp)519 std::optional<EffectOption> DragDropFuncWrapper::BlurStyleToEffection(
520 const std::optional<BlurStyleOption>& blurStyleOp)
521 {
522 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
523 CHECK_NULL_RETURN(pipeline, std::nullopt);
524 auto blurStyleTheme = pipeline->GetTheme<BlurStyleTheme>();
525 if (!blurStyleTheme) {
526 TAG_LOGW(AceLogTag::ACE_DRAG, "cannot find theme of blurStyle, create blurStyle failed");
527 return std::nullopt;
528 }
529 CHECK_NULL_RETURN(blurStyleOp, std::nullopt);
530 ThemeColorMode colorMode = blurStyleOp->colorMode;
531 if (blurStyleOp->colorMode == ThemeColorMode::SYSTEM) {
532 colorMode = pipeline->GetColorMode() == ColorMode::DARK ? ThemeColorMode::DARK : ThemeColorMode::LIGHT;
533 }
534 auto blurParam = blurStyleTheme->GetBlurParameter(blurStyleOp->blurStyle, colorMode);
535 CHECK_NULL_RETURN(blurParam, std::nullopt);
536 auto ratio = blurStyleOp->scale;
537 auto maskColor = blurParam->maskColor.BlendOpacity(ratio);
538 auto radiusPx = blurParam->radius * pipeline->GetDipScale();
539 auto radiusBlur = RadiusToSigma(radiusPx) * ratio;
540 auto saturation = (blurParam->saturation - 1) * ratio + 1.0;
541 auto brightness = (blurParam->brightness - 1) * ratio + 1.0;
542 Dimension dimen(radiusBlur);
543 EffectOption bgEffection = {dimen, saturation, brightness, maskColor,
544 blurStyleOp->adaptiveColor, blurStyleOp->blurOption};
545 return std::optional<EffectOption>(bgEffection);
546 }
547
GetScaleWidth(int32_t containerId)548 [[maybe_unused]] double DragDropFuncWrapper::GetScaleWidth(int32_t containerId)
549 {
550 auto container = Container::GetContainer(containerId);
551 CHECK_NULL_RETURN(container, -1.0f);
552 auto pipeline = container->GetPipelineContext();
553 CHECK_NULL_RETURN(pipeline, -1.0f);
554 return DragDropManager::GetMaxWidthBaseOnGridSystem(pipeline);
555 }
556
SetDragStartRequestStatus(DragStartRequestStatus dragStartRequestStatus)557 void DragDropFuncWrapper::SetDragStartRequestStatus(DragStartRequestStatus dragStartRequestStatus) noexcept
558 {
559 auto pipelineContext = PipelineContext::GetCurrentContext();
560 CHECK_NULL_VOID(pipelineContext);
561 auto dragDropManager = pipelineContext->GetDragDropManager();
562 CHECK_NULL_VOID(dragDropManager);
563 dragDropManager->HandleSyncOnDragStart(dragStartRequestStatus);
564 }
565
SetExtraInfo(int32_t containerId,std::string extraInfo)566 void DragDropFuncWrapper::SetExtraInfo(int32_t containerId, std::string extraInfo)
567 {
568 auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
569 CHECK_NULL_VOID(pipelineContext);
570 auto manager = pipelineContext->GetDragDropManager();
571 CHECK_NULL_VOID(manager);
572 manager->SetExtraInfo(extraInfo);
573 }
574
GetSummaryString(const std::map<std::string,int64_t> & summary)575 std::string DragDropFuncWrapper::GetSummaryString(const std::map<std::string, int64_t>& summary)
576 {
577 std::string summarys;
578 for (const auto& [udkey, recordSize] : summary) {
579 std::string str = udkey + "-" + std::to_string(recordSize) + ";";
580 summarys += str;
581 }
582
583 return summarys;
584 }
585
GetAnonyString(const std::string & fullString)586 std::string DragDropFuncWrapper::GetAnonyString(const std::string &fullString)
587 {
588 if (fullString.empty() || fullString.length() == 0) {
589 return "";
590 }
591 std::string middleStr = "******";
592 std::string anonyStr;
593 size_t strLen = fullString.length();
594 if (strLen <= SHORT_KEY_LENGTH) {
595 anonyStr += fullString[0];
596 anonyStr.append(middleStr);
597 anonyStr += fullString[strLen - 1];
598 } else {
599 anonyStr.append(fullString, 0, PLAINTEXT_LENGTH).append(middleStr)
600 .append(fullString, strLen - PLAINTEXT_LENGTH, PLAINTEXT_LENGTH);
601 }
602 return anonyStr;
603 }
604
605 // returns a node's offset relative to window plus half of self rect size(w, h)
606 // and accumulate every ancestor node's graphic properties such as rotate and transform
607 // ancestor will NOT check boundary of window scene
GetPaintRectCenter(const RefPtr<FrameNode> & frameNode,bool checkWindowBoundary)608 OffsetF DragDropFuncWrapper::GetPaintRectCenter(const RefPtr<FrameNode>& frameNode, bool checkWindowBoundary)
609 {
610 CHECK_NULL_RETURN(frameNode, OffsetF());
611 auto context = frameNode->GetRenderContext();
612 CHECK_NULL_RETURN(context, OffsetF());
613 auto paintRect = context->GetPaintRectWithoutTransform();
614 auto offset = paintRect.GetOffset();
615 PointF pointNode(offset.GetX() + paintRect.Width() / 2.0f, offset.GetY() + paintRect.Height() / 2.0f);
616 context->GetPointTransformRotate(pointNode);
617 auto parent = frameNode->GetAncestorNodeOfFrame(false);
618 while (parent) {
619 if (checkWindowBoundary && parent->IsWindowBoundary()) {
620 break;
621 }
622 auto renderContext = parent->GetRenderContext();
623 CHECK_NULL_RETURN(renderContext, OffsetF());
624 offset = renderContext->GetPaintRectWithoutTransform().GetOffset();
625 pointNode.SetX(offset.GetX() + pointNode.GetX());
626 pointNode.SetY(offset.GetY() + pointNode.GetY());
627 renderContext->GetPointTransformRotate(pointNode);
628 parent = parent->GetAncestorNodeOfFrame(false);
629 }
630 return OffsetF(pointNode.GetX(), pointNode.GetY());
631 }
632
633 // check if expand subwindow
IsExpandDisplay(const RefPtr<PipelineBase> & context)634 bool DragDropFuncWrapper::IsExpandDisplay(const RefPtr<PipelineBase>& context)
635 {
636 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
637 CHECK_NULL_RETURN(pipeline, false);
638 auto theme = pipeline->GetTheme<SelectTheme>();
639 CHECK_NULL_RETURN(theme, false);
640 if (theme->GetExpandDisplay()) {
641 return true;
642 }
643 auto containerId = pipeline->GetInstanceId();
644 containerId = containerId >= MIN_SUBCONTAINER_ID ?
645 SubwindowManager::GetInstance()->GetParentContainerId(containerId) : containerId;
646 auto container = AceEngine::Get().GetContainer(containerId);
647 CHECK_NULL_RETURN(container, false);
648 return container->IsFreeMultiWindow() || container->IsUIExtensionWindow();
649 }
650
GetCurrentWindowOffset(const RefPtr<PipelineBase> & context)651 OffsetF DragDropFuncWrapper::GetCurrentWindowOffset(const RefPtr<PipelineBase>& context)
652 {
653 if (!IsExpandDisplay(context)) {
654 return OffsetF();
655 }
656 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
657 CHECK_NULL_RETURN(pipeline, OffsetF());
658 auto window = pipeline->GetWindow();
659 CHECK_NULL_RETURN(window, OffsetF());
660 auto windowOffset = window->GetCurrentWindowRect().GetOffset();
661 return OffsetF(windowOffset.GetX(), windowOffset.GetY());
662 }
663
GetPaintRectCenterToScreen(const RefPtr<FrameNode> & frameNode)664 OffsetF DragDropFuncWrapper::GetPaintRectCenterToScreen(const RefPtr<FrameNode>& frameNode)
665 {
666 auto offset = GetPaintRectCenter(frameNode);
667 CHECK_NULL_RETURN(frameNode, offset);
668 offset += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
669 return offset;
670 }
671
GetFrameNodeOffsetToScreen(const RefPtr<FrameNode> & frameNode)672 OffsetF DragDropFuncWrapper::GetFrameNodeOffsetToScreen(const RefPtr<FrameNode>& frameNode)
673 {
674 CHECK_NULL_RETURN(frameNode, OffsetF());
675 auto offset = frameNode->GetPositionToWindowWithTransform();
676 offset += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
677 return offset;
678 }
679
GetPaintRectToScreen(const RefPtr<FrameNode> & frameNode)680 RectF DragDropFuncWrapper::GetPaintRectToScreen(const RefPtr<FrameNode>& frameNode)
681 {
682 CHECK_NULL_RETURN(frameNode, RectF());
683 RectF rect = frameNode->GetTransformRectRelativeToWindow();
684 rect += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
685 return rect;
686 }
687
UpdateNodePositionToScreen(const RefPtr<FrameNode> & frameNode,OffsetF offset)688 void DragDropFuncWrapper::UpdateNodePositionToScreen(const RefPtr<FrameNode>& frameNode, OffsetF offset)
689 {
690 CHECK_NULL_VOID(frameNode);
691 offset -= GetCurrentWindowOffset(frameNode->GetContextRefPtr());
692 UpdateNodePositionToWindow(frameNode, offset);
693 }
694
UpdateNodePositionToWindow(const RefPtr<FrameNode> & frameNode,OffsetF offset)695 void DragDropFuncWrapper::UpdateNodePositionToWindow(const RefPtr<FrameNode>& frameNode, OffsetF offset)
696 {
697 CHECK_NULL_VOID(frameNode);
698 auto renderContext = frameNode->GetRenderContext();
699 CHECK_NULL_VOID(renderContext);
700 RefPtr<FrameNode> parentNode = frameNode->GetAncestorNodeOfFrame(true);
701 if (parentNode) {
702 offset -= parentNode->GetPositionToWindowWithTransform();
703 }
704 renderContext->UpdatePosition(OffsetT<Dimension>(Dimension(offset.GetX()), Dimension(offset.GetY())));
705 }
706
UpdatePositionFromFrameNode(const RefPtr<FrameNode> & targetNode,const RefPtr<FrameNode> & frameNode,float width,float height)707 void DragDropFuncWrapper::UpdatePositionFromFrameNode(const RefPtr<FrameNode>& targetNode,
708 const RefPtr<FrameNode>& frameNode, float width, float height)
709 {
710 CHECK_NULL_VOID(targetNode);
711 CHECK_NULL_VOID(frameNode);
712 auto paintRectCenter = GetPaintRectCenterToScreen(frameNode);
713 auto offset = paintRectCenter - OffsetF(width / 2.0f, height / 2.0f);
714 UpdateNodePositionToScreen(targetNode, offset);
715 }
716
GetFrameNodeOffsetToWindow(const RefPtr<FrameNode> & targetNode,const RefPtr<FrameNode> & frameNode,float width,float height)717 OffsetF DragDropFuncWrapper::GetFrameNodeOffsetToWindow(const RefPtr<FrameNode>& targetNode,
718 const RefPtr<FrameNode>& frameNode, float width, float height)
719 {
720 CHECK_NULL_RETURN(targetNode, OffsetF());
721 CHECK_NULL_RETURN(frameNode, OffsetF());
722 auto paintRectCenter = GetPaintRectCenterToScreen(frameNode);
723 auto offset = paintRectCenter - OffsetF(width / 2.0f, height / 2.0f);
724 offset -= GetCurrentWindowOffset(targetNode->GetContextRefPtr());
725 auto renderContext = targetNode->GetRenderContext();
726 CHECK_NULL_RETURN(renderContext, OffsetF());
727 RefPtr<FrameNode> parentNode = targetNode->GetAncestorNodeOfFrame(true);
728 if (parentNode) {
729 offset -= parentNode->GetPositionToWindowWithTransform();
730 }
731 return offset;
732 }
733
ConvertPointerEvent(const TouchEvent & touchPoint,DragPointerEvent & event)734 void DragDropFuncWrapper::ConvertPointerEvent(const TouchEvent& touchPoint, DragPointerEvent& event)
735 {
736 event.rawPointerEvent = touchPoint.GetTouchEventPointerEvent();
737 event.pointerEventId = touchPoint.touchEventId;
738 event.pointerId = touchPoint.id;
739 event.windowX = touchPoint.x;
740 event.windowY = touchPoint.y;
741 event.displayX = touchPoint.screenX;
742 event.displayY = touchPoint.screenY;
743 event.globalDisplayX = touchPoint.globalDisplayX;
744 event.globalDisplayY = touchPoint.globalDisplayY;
745 event.deviceId = touchPoint.deviceId;
746 event.displayId = touchPoint.targetDisplayId;
747 event.x = event.windowX;
748 event.y = event.windowY;
749 event.pressedKeyCodes.clear();
750 for (const auto& curCode : touchPoint.pressedKeyCodes_) {
751 event.pressedKeyCodes.emplace_back(static_cast<KeyCode>(curCode));
752 }
753 GetPointerEventAction(touchPoint, event);
754 }
755
GetPointerEventAction(const TouchEvent & touchPoint,DragPointerEvent & event)756 void DragDropFuncWrapper::GetPointerEventAction(const TouchEvent& touchPoint, DragPointerEvent& event)
757 {
758 auto orgAction = touchPoint.type;
759 switch (orgAction) {
760 case TouchType::CANCEL:
761 event.action = PointerAction::CANCEL;
762 break;
763 case TouchType::DOWN:
764 event.action = PointerAction::DOWN;
765 break;
766 case TouchType::MOVE:
767 event.action = PointerAction::MOVE;
768 break;
769 case TouchType::UP:
770 event.action = PointerAction::UP;
771 break;
772 case TouchType::PULL_MOVE:
773 event.action = PointerAction::PULL_MOVE;
774 break;
775 case TouchType::PULL_UP:
776 event.action = PointerAction::PULL_UP;
777 break;
778 case TouchType::PULL_IN_WINDOW:
779 event.action = PointerAction::PULL_IN_WINDOW;
780 break;
781 case TouchType::PULL_OUT_WINDOW:
782 event.action = PointerAction::PULL_OUT_WINDOW;
783 break;
784 default:
785 event.action = PointerAction::UNKNOWN;
786 break;
787 }
788 }
789
GetFrameNodeByKey(const RefPtr<FrameNode> & root,const std::string & key)790 RefPtr<FrameNode> DragDropFuncWrapper::GetFrameNodeByKey(const RefPtr<FrameNode>& root, const std::string& key)
791 {
792 std::queue<RefPtr<UINode>> elements;
793 elements.push(root);
794 RefPtr<UINode> inspectorElement;
795 while (!elements.empty()) {
796 auto current = elements.front();
797 elements.pop();
798 if (key == current->GetInspectorId().value_or("")) {
799 return AceType::DynamicCast<FrameNode>(current);
800 }
801
802 const auto& children = current->GetChildren();
803 for (const auto& child : children) {
804 elements.push(child);
805 }
806 }
807 return nullptr;
808 }
809
GetPointRelativeToMainWindow(const Point & point)810 OffsetF DragDropFuncWrapper::GetPointRelativeToMainWindow(const Point& point)
811 {
812 OffsetF position (static_cast<float>(point.GetX()), static_cast<float>(point.GetY()));
813 auto currentPipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
814 CHECK_NULL_RETURN(currentPipeline, position);
815 auto mainPipeline = PipelineContext::GetMainPipelineContext();
816 CHECK_NULL_RETURN(mainPipeline, position);
817 if (mainPipeline != currentPipeline) {
818 position -= (GetCurrentWindowOffset(mainPipeline) -
819 GetCurrentWindowOffset(currentPipeline));
820 }
821 return position;
822 }
823
IsSelectedItemNode(const RefPtr<UINode> & uiNode)824 bool DragDropFuncWrapper::IsSelectedItemNode(const RefPtr<UINode>& uiNode)
825 {
826 auto frameNode = AceType::DynamicCast<FrameNode>(uiNode);
827 CHECK_NULL_RETURN(frameNode, false);
828 auto gestureHub = frameNode->GetOrCreateGestureEventHub();
829 CHECK_NULL_RETURN(gestureHub, false);
830 auto eventHub = frameNode->GetOrCreateEventHub<EventHub>();
831 CHECK_NULL_RETURN(eventHub, false);
832 auto dragPreview = frameNode->GetDragPreviewOption();
833 if (!dragPreview.isMultiSelectionEnabled) {
834 return false;
835 }
836 bool isAllowedDrag = gestureHub->IsAllowedDrag(eventHub);
837 if (!isAllowedDrag) {
838 return false;
839 }
840 if (frameNode->GetTag() == V2::GRID_ITEM_ETS_TAG) {
841 auto itemPattern = frameNode->GetPattern<GridItemPattern>();
842 CHECK_NULL_RETURN(itemPattern, false);
843 if (itemPattern->IsSelected()) {
844 return true;
845 }
846 }
847 if (frameNode->GetTag() == V2::LIST_ITEM_ETS_TAG) {
848 auto itemPattern = frameNode->GetPattern<ListItemPattern>();
849 CHECK_NULL_RETURN(itemPattern, false);
850 if (itemPattern->IsSelected()) {
851 return true;
852 }
853 }
854 return false;
855 }
856
857 /**
858 * Do some nessessary check before returning the gesture recognizer collection result
859 * to parent during the hittest process. For example, if there is one drag operation
860 * already in our system, it is not allowed to start new interation for drag operation.
861 */
IsGlobalStatusSuitableForDragging()862 bool DragDropFuncWrapper::IsGlobalStatusSuitableForDragging()
863 {
864 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
865 CHECK_NULL_RETURN(pipeline, false);
866 auto dragDropManager = pipeline->GetDragDropManager();
867 CHECK_NULL_RETURN(dragDropManager, false);
868 if (dragDropManager->IsDragging()) {
869 TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, is dragging status");
870 return false;
871 }
872
873 if (dragDropManager->IsMSDPDragging()) {
874 TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, is msdp dragging status");
875 return false;
876 }
877
878 return true;
879 }
880
IsSelfAndParentDragForbidden(const RefPtr<FrameNode> & frameNode)881 bool DragDropFuncWrapper::IsSelfAndParentDragForbidden(const RefPtr<FrameNode>& frameNode)
882 {
883 auto parent = frameNode;
884 while (parent) {
885 auto eventHub = parent->GetOrCreateEventHub<EventHub>();
886 parent = parent->GetAncestorNodeOfFrame(true);
887 if (!eventHub) {
888 continue;
889 }
890 auto gestureEventHub = eventHub->GetGestureEventHub();
891 if (!gestureEventHub) {
892 continue;
893 }
894 if (gestureEventHub->IsDragForbidden()) {
895 return true;
896 }
897 }
898 return false;
899 }
900
IsBelongToMultiItemNode(const RefPtr<FrameNode> & frameNode)901 bool DragDropFuncWrapper::IsBelongToMultiItemNode(const RefPtr<FrameNode>& frameNode)
902 {
903 CHECK_NULL_RETURN(frameNode, false);
904 auto uiNode = frameNode->GetParent();
905 CHECK_NULL_RETURN(uiNode, false);
906 while (!IsSelectedItemNode(uiNode)) {
907 uiNode = uiNode->GetParent();
908 CHECK_NULL_RETURN(uiNode, false);
909 }
910 return true;
911 }
912
CheckIsNeedGather(const RefPtr<FrameNode> & frameNode)913 bool DragDropFuncWrapper::CheckIsNeedGather(const RefPtr<FrameNode>& frameNode)
914 {
915 CHECK_NULL_RETURN(frameNode, false);
916 auto dragPreview = frameNode->GetDragPreviewOption();
917 if (!dragPreview.isMultiSelectionEnabled) {
918 return false;
919 }
920 return IsSelectedItemNode(frameNode);
921 }
922
FindItemParentNode(const RefPtr<FrameNode> & frameNode)923 RefPtr<FrameNode> DragDropFuncWrapper::FindItemParentNode(const RefPtr<FrameNode>& frameNode)
924 {
925 CHECK_NULL_RETURN(frameNode, nullptr);
926 if (frameNode->GetTag() != V2::GRID_ITEM_ETS_TAG && frameNode->GetTag() != V2::LIST_ITEM_ETS_TAG) {
927 return nullptr;
928 }
929 auto parentType = frameNode->GetTag() == V2::GRID_ITEM_ETS_TAG ? V2::GRID_ETS_TAG : V2::LIST_ETS_TAG;
930 auto uiNode = frameNode->GetParent();
931 CHECK_NULL_RETURN(uiNode, nullptr);
932 while (uiNode->GetTag() != parentType) {
933 uiNode = uiNode->GetParent();
934 CHECK_NULL_RETURN(uiNode, nullptr);
935 }
936 return AceType::DynamicCast<FrameNode>(uiNode);
937 }
938
GetGatherNodePreviewPixelMap(const RefPtr<FrameNode> & frameNode)939 RefPtr<PixelMap> DragDropFuncWrapper::GetGatherNodePreviewPixelMap(const RefPtr<FrameNode>& frameNode)
940 {
941 CHECK_NULL_RETURN(frameNode, nullptr);
942 auto dragPreviewInfo = frameNode->GetDragPreview();
943 if (dragPreviewInfo.inspectorId != "") {
944 auto previewPixelMap = GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
945 return previewPixelMap;
946 }
947 if (dragPreviewInfo.pixelMap != nullptr) {
948 return dragPreviewInfo.pixelMap;
949 }
950 auto context = frameNode->GetRenderContext();
951 CHECK_NULL_RETURN(context, nullptr);
952 auto pixelMap = context->GetThumbnailPixelMap(true);
953 return pixelMap;
954 }
955
TrySetDraggableStateAsync(const RefPtr<FrameNode> & frameNode,const TouchRestrict & touchRestrict)956 void DragDropFuncWrapper::TrySetDraggableStateAsync(
957 const RefPtr<FrameNode>& frameNode, const TouchRestrict& touchRestrict)
958 {
959 CHECK_NULL_VOID(frameNode);
960 auto gestureHub = frameNode->GetOrCreateGestureEventHub();
961 CHECK_NULL_VOID(gestureHub);
962 if (frameNode->GetTag() == V2::TEXT_ETS_TAG && !gestureHub->GetIsTextDraggable()) {
963 return;
964 }
965 int64_t downTime = static_cast<int64_t>(touchRestrict.touchEvent.time.time_since_epoch().count());
966 if (DragDropGlobalController::GetInstance().IsAppGlobalDragEnabled()) {
967 InteractionInterface::GetInstance()->SetDraggableStateAsync(true, downTime / CONVERT_TIME_BASE);
968 }
969 }
970
971 /**
972 * check the current node's status to decide if it can initiate one drag operation
973 */
IsCurrentNodeStatusSuitableForDragging(const RefPtr<FrameNode> & frameNode,const TouchRestrict & touchRestrict)974 bool DragDropFuncWrapper::IsCurrentNodeStatusSuitableForDragging(
975 const RefPtr<FrameNode>& frameNode, const TouchRestrict& touchRestrict)
976 {
977 CHECK_NULL_RETURN(frameNode, false);
978 auto gestureHub = frameNode->GetOrCreateGestureEventHub();
979 CHECK_NULL_RETURN(gestureHub, false);
980
981 if (gestureHub->IsDragForbidden() || (!frameNode->IsDraggable() && frameNode->IsCustomerSet()) ||
982 touchRestrict.inputEventType == InputEventType::AXIS ||
983 touchRestrict.touchEvent.convertInfo.first == UIInputEventType::AXIS) {
984 TAG_LOGI(AceLogTag::ACE_DRAG,
985 "No need to collect drag gestures result, drag forbidden set is %{public}d,"
986 "frameNode draggable is %{public}d, custom set is %{public}d",
987 gestureHub->IsDragForbidden(), frameNode->IsDraggable(), frameNode->IsCustomerSet());
988 return false;
989 }
990
991 if (gestureHub->GetTextDraggable()) {
992 auto pattern = frameNode->GetPattern<TextBase>();
993 if (pattern && !pattern->IsSelected() && !pattern->CanAIEntityDrag()) {
994 TrySetDraggableStateAsync(frameNode, touchRestrict);
995 TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, text is not selected.");
996 return false;
997 }
998 }
999
1000 if (IsSelfAndParentDragForbidden(frameNode)) {
1001 TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, parent is drag forbidden.");
1002 return false;
1003 }
1004
1005 return true;
1006 }
RecordMenuWrapperNodeForDrag(int32_t targetId)1007 void DragDropFuncWrapper::RecordMenuWrapperNodeForDrag(int32_t targetId)
1008 {
1009 auto subWindow =
1010 SubwindowManager::GetInstance()->GetSubwindowByType(Container::CurrentId(), SubwindowType::TYPE_MENU);
1011 CHECK_NULL_VOID(subWindow);
1012 auto overlayManager = subWindow->GetOverlayManager();
1013 CHECK_NULL_VOID(overlayManager);
1014 auto menuWrapperNode = overlayManager->GetMenuNode(targetId);
1015 if (!menuWrapperNode) {
1016 auto rootNode = overlayManager->GetRootNode().Upgrade();
1017 CHECK_NULL_VOID(rootNode);
1018 for (const auto& child : rootNode->GetChildren()) {
1019 auto node = AceType::DynamicCast<FrameNode>(child);
1020 if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
1021 menuWrapperNode = node;
1022 break;
1023 }
1024 }
1025 }
1026 CHECK_NULL_VOID(menuWrapperNode);
1027
1028 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1029 CHECK_NULL_VOID(pipeline);
1030 auto dragDropManager = pipeline->GetDragDropManager();
1031 CHECK_NULL_VOID(dragDropManager);
1032 dragDropManager->SetMenuWrapperNode(menuWrapperNode);
1033
1034 auto mainPipeline = PipelineContext::GetMainPipelineContext();
1035 CHECK_NULL_VOID(mainPipeline);
1036 auto dragMainDropManager = mainPipeline->GetDragDropManager();
1037 CHECK_NULL_VOID(dragMainDropManager);
1038 dragMainDropManager->SetMenuWrapperNode(menuWrapperNode);
1039 }
1040
GetFrameNodeByInspectorId(const std::string & inspectorId)1041 RefPtr<FrameNode> DragDropFuncWrapper::GetFrameNodeByInspectorId(const std::string& inspectorId)
1042 {
1043 if (inspectorId.empty()) {
1044 return nullptr;
1045 }
1046
1047 auto frameNode = Inspector::GetFrameNodeByKey(inspectorId);
1048 CHECK_NULL_RETURN(frameNode, nullptr);
1049 auto layoutProperty = frameNode->GetLayoutProperty();
1050 CHECK_NULL_RETURN(layoutProperty, nullptr);
1051
1052 auto visibility = layoutProperty->GetVisibilityValue(VisibleType::VISIBLE);
1053 if (visibility == VisibleType::INVISIBLE || visibility == VisibleType::GONE) {
1054 return nullptr;
1055 }
1056
1057 return frameNode;
1058 }
1059
ApplyNewestOptionExecutedFromModifierToNode(const RefPtr<FrameNode> & optionHolderNode,const RefPtr<FrameNode> & targetNode)1060 void DragDropFuncWrapper::ApplyNewestOptionExecutedFromModifierToNode(
1061 const RefPtr<FrameNode>& optionHolderNode, const RefPtr<FrameNode>& targetNode)
1062 {
1063 auto optionsFromModifier = targetNode->GetDragPreviewOption().options;
1064 ACE_UPDATE_NODE_RENDER_CONTEXT(Opacity, optionsFromModifier.opacity, targetNode);
1065 if (optionsFromModifier.blurbgEffect.backGroundEffect.radius.IsValid()) {
1066 ACE_UPDATE_NODE_RENDER_CONTEXT(BackgroundEffect, optionsFromModifier.blurbgEffect.backGroundEffect, targetNode);
1067 }
1068 if (optionsFromModifier.shadow.has_value()) {
1069 // if shadow is unfilled, set shadow after animation
1070 if (optionsFromModifier.shadow->GetIsFilled()) {
1071 ACE_UPDATE_NODE_RENDER_CONTEXT(BackShadow, optionsFromModifier.shadow.value(), targetNode);
1072 }
1073 }
1074
1075 const auto& target = targetNode->GetRenderContext();
1076 if (optionsFromModifier.borderRadius.has_value()) {
1077 target->UpdateBorderRadius(optionsFromModifier.borderRadius.value());
1078 target->UpdateClipEdge(true);
1079 }
1080 }
1081
ResetNode(const RefPtr<FrameNode> & frameNode)1082 void DragDropFuncWrapper::ResetNode(const RefPtr<FrameNode>& frameNode)
1083 {
1084 CHECK_NULL_VOID(frameNode);
1085 bool defaultAnimationBeforeLifting = frameNode->GetDragPreviewOption().defaultAnimationBeforeLifting;
1086 if (!defaultAnimationBeforeLifting) {
1087 return;
1088 }
1089 auto frameContext = frameNode->GetRenderContext();
1090 CHECK_NULL_VOID(frameContext);
1091 frameContext->UpdateTransformScale({ 1.0f, 1.0f });
1092 auto layoutProperty = frameNode->GetLayoutProperty();
1093 if (layoutProperty) {
1094 layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
1095 }
1096 }
1097
GetDragFrameNodeBorderRadius(const RefPtr<FrameNode> & frameNode)1098 BorderRadiusProperty DragDropFuncWrapper::GetDragFrameNodeBorderRadius(const RefPtr<FrameNode>& frameNode)
1099 {
1100 Dimension defaultDimension(0);
1101 BorderRadiusProperty borderRadius = { defaultDimension, defaultDimension, defaultDimension, defaultDimension };
1102 auto dragPreviewInfo = frameNode->GetDragPreview();
1103 if (dragPreviewInfo.pixelMap != nullptr) {
1104 return borderRadius;
1105 }
1106 RefPtr<FrameNode> targetNode = frameNode;
1107 if (!dragPreviewInfo.inspectorId.empty()) {
1108 targetNode = DragDropFuncWrapper::GetFrameNodeByInspectorId(dragPreviewInfo.inspectorId);
1109 CHECK_NULL_RETURN(targetNode, borderRadius);
1110 } else if (dragPreviewInfo.customNode != nullptr) {
1111 targetNode = AceType::DynamicCast<FrameNode>(dragPreviewInfo.customNode);
1112 CHECK_NULL_RETURN(targetNode, borderRadius);
1113 }
1114 auto targetNodeContext = targetNode->GetRenderContext();
1115 CHECK_NULL_RETURN(targetNodeContext, borderRadius);
1116 if (targetNodeContext->GetBorderRadius().has_value()) {
1117 borderRadius.UpdateWithCheck(targetNodeContext->GetBorderRadius().value());
1118 }
1119 return borderRadius;
1120 }
1121
1122 /* Retrieves a preview PixelMap for a given drag event action.
1123 * This function attempts to obtain a screenshot of a frameNode associated with an inspector ID.
1124 * If the frameNode with the given ID does not exist or hasn't been rendered,
1125 * it falls back to taking a screenshot of the provided frame node.
1126 *
1127 * @param inspectorId A string representing the unique identifier for the frameNode's ID.
1128 * @param selfFrameNode A RefPtr to the frame node associated with the drag event.
1129 * @return A RefPtr to a PixelMap containing the preview image, or nullptr if not found.
1130 */
GetPreviewPixelMap(const std::string & inspectorId,const RefPtr<FrameNode> & selfFrameNode)1131 RefPtr<PixelMap> DragDropFuncWrapper::GetPreviewPixelMap(
1132 const std::string& inspectorId, const RefPtr<FrameNode>& selfFrameNode)
1133 {
1134 // Attempt to retrieve the PixelMap using the inspector ID.
1135 auto previewPixelMap = GetPreviewPixelMapByInspectorId(inspectorId, selfFrameNode);
1136 // If a preview PixelMap was found, return it.
1137 if (previewPixelMap != nullptr) {
1138 return previewPixelMap;
1139 }
1140 // If not found by inspector ID, attempt to get a screenshot of the frame node.
1141 return GetScreenShotPixelMap(selfFrameNode);
1142 }
1143
1144 /* Retrieves a preview PixelMap based on an inspector ID.
1145 * This function attempts to find a frame node associated with the given inspector ID and then takes a screenshot of it.
1146 *
1147 * @param inspectorId The unique identifier for a frameNode.
1148 * @return A RefPtr to a PixelMap containing the preview image, or nullptr if not found or the ID is empty.
1149 */
GetPreviewPixelMapByInspectorId(const std::string & inspectorId,const RefPtr<FrameNode> & frameNode)1150 RefPtr<PixelMap> DragDropFuncWrapper::GetPreviewPixelMapByInspectorId(
1151 const std::string& inspectorId, const RefPtr<FrameNode>& frameNode)
1152 {
1153 // Check for an empty inspector ID and return nullptr if it is empty.
1154 if (inspectorId == "") {
1155 return nullptr;
1156 }
1157
1158 CHECK_NULL_RETURN(frameNode, nullptr);
1159 auto pipeLine = frameNode->GetContextRefPtr();
1160 CHECK_NULL_RETURN(pipeLine, nullptr);
1161 auto rootNode = pipeLine->GetRootElement();
1162 CHECK_NULL_RETURN(rootNode, nullptr);
1163 // Retrieve the frame node using the inspector's ID.
1164 auto dragPreviewFrameNode = DragDropFuncWrapper::GetFrameNodeByKey(rootNode, inspectorId);
1165 CHECK_NULL_RETURN(dragPreviewFrameNode, nullptr);
1166
1167 auto layoutProperty = dragPreviewFrameNode->GetLayoutProperty();
1168 CHECK_NULL_RETURN(layoutProperty, nullptr);
1169
1170 auto visibility = layoutProperty->GetVisibilityValue(VisibleType::VISIBLE);
1171 if (visibility == VisibleType::INVISIBLE || visibility == VisibleType::GONE) {
1172 return nullptr;
1173 }
1174
1175 // Take a screenshot of the frame node and return it as a PixelMap.
1176 return GetScreenShotPixelMap(dragPreviewFrameNode);
1177 }
1178
1179 /* Captures a screenshot of the specified frame node and encapsulates it in a PixelMap.
1180 *
1181 * @param frameNode A RefPtr reference to the frame node from which to capture the screenshot.
1182 * @return A RefPtr to a PixelMap containing the screenshot.
1183 */
GetScreenShotPixelMap(const RefPtr<FrameNode> & frameNode)1184 RefPtr<PixelMap> DragDropFuncWrapper::GetScreenShotPixelMap(const RefPtr<FrameNode>& frameNode)
1185 {
1186 // Ensure the frame node is not nulls before proceeding.
1187 CHECK_NULL_RETURN(frameNode, nullptr);
1188
1189 // Obtain the rendering context from the frame node.
1190 auto context = frameNode->GetRenderContext();
1191
1192 // If the rendering context is not available, return nullptr.
1193 CHECK_NULL_RETURN(context, nullptr);
1194
1195 // Capture and return the thumbnail PixelMap from the rendering context.
1196 return context->GetThumbnailPixelMap(true);
1197 }
1198
CheckIfNeedGetThumbnailPixelMap(const RefPtr<FrameNode> & frameNode,int32_t fingerId)1199 bool DragDropFuncWrapper::CheckIfNeedGetThumbnailPixelMap(const RefPtr<FrameNode>& frameNode, int32_t fingerId)
1200 {
1201 CHECK_NULL_RETURN(frameNode, false);
1202 auto pipeline = frameNode->GetContextRefPtr();
1203 CHECK_NULL_RETURN(pipeline, false);
1204 auto eventManager = pipeline->GetEventManager();
1205 CHECK_NULL_RETURN(eventManager, false);
1206 RefPtr<LongPressRecognizer> recognizer;
1207 auto gestureReferee = eventManager->GetGestureRefereeNG(recognizer);
1208 CHECK_NULL_RETURN(gestureReferee, false);
1209 if (gestureReferee->IsAnySucceedRecognizerExist(fingerId)) {
1210 TAG_LOGI(AceLogTag::ACE_DRAG, "No need to get thumbnail pixelmap with success recognizer.");
1211 return true;
1212 }
1213 return false;
1214 }
1215
CreateTiledPixelMap(const RefPtr<FrameNode> & frameNode)1216 RefPtr<PixelMap> DragDropFuncWrapper::CreateTiledPixelMap(const RefPtr<FrameNode>& frameNode)
1217 {
1218 CHECK_NULL_RETURN(frameNode, nullptr);
1219 auto pipelineContext = frameNode->GetContextRefPtr();
1220 CHECK_NULL_RETURN(pipelineContext, nullptr);
1221 auto manager = pipelineContext->GetOverlayManager();
1222 CHECK_NULL_RETURN(manager, nullptr);
1223 auto fatherNode = DragDropFuncWrapper::FindItemParentNode(frameNode);
1224 CHECK_NULL_RETURN(fatherNode, nullptr);
1225 auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1226 CHECK_NULL_RETURN(scrollPattern, nullptr);
1227 auto children = scrollPattern->GetVisibleSelectedItems();
1228 auto pixelMapinfo = GetTiledPixelMapInfo(children);
1229 RefPtr<PixelMap> tiledPixelMap = nullptr;
1230 #if defined(PIXEL_MAP_SUPPORTED)
1231 CHECK_NULL_RETURN(pixelMapinfo, nullptr);
1232 InitializationOptions opts;
1233 opts.size.SetWidth(pixelMapinfo->pixelMapRect.GetSize().Width());
1234 opts.size.SetHeight(pixelMapinfo->pixelMapRect.GetSize().Height());
1235 opts.srcPixelFormat = pixelMapinfo->srcPixelFormat;
1236 opts.pixelFormat = pixelMapinfo->pixelFormat;
1237 opts.editable = true;
1238 opts.alphaType = pixelMapinfo->alphaType;
1239 tiledPixelMap = PixelMap::Create(opts);
1240 #endif
1241 DrawTiledPixelMap(tiledPixelMap, children, pixelMapinfo->pixelMapRect);
1242 CHECK_NULL_RETURN(tiledPixelMap, nullptr);
1243 return tiledPixelMap;
1244 }
1245
GetTiledPixelMapInfo(const std::vector<RefPtr<FrameNode>> & children)1246 std::shared_ptr<PixelMapInfo> DragDropFuncWrapper::GetTiledPixelMapInfo(const std::vector<RefPtr<FrameNode>>& children)
1247 {
1248 CHECK_NULL_RETURN(children.size(), nullptr);
1249 auto minX = std::numeric_limits<float>::max();
1250 auto minY = std::numeric_limits<float>::max();
1251 auto maxX = std::numeric_limits<float>::lowest();
1252 auto maxY = std::numeric_limits<float>::lowest();
1253
1254 for (auto& node : children) {
1255 auto context = node->GetRenderContext();
1256 CHECK_NULL_RETURN(context, nullptr);
1257 auto pixelMap = context->GetThumbnailPixelMap();
1258 auto gestureHub = node->GetOrCreateGestureEventHub();
1259 gestureHub->SetDragPreviewPixelMap(pixelMap);
1260 CHECK_NULL_RETURN(pixelMap, nullptr);
1261 auto offset = node->GetPositionToWindowWithTransform();
1262 minX = std::min(minX, offset.GetX());
1263 minY = std::min(minY, offset.GetY());
1264 maxX = std::max(maxX, offset.GetX() + pixelMap->GetWidth());
1265 maxY = std::max(maxY, offset.GetY() + pixelMap->GetHeight());
1266 }
1267 auto gestureHub = children.front()->GetOrCreateGestureEventHub();
1268 CHECK_NULL_RETURN(gestureHub, nullptr);
1269 auto dragPreviewPixelMap = gestureHub->GetDragPreviewPixelMap();
1270 CHECK_NULL_RETURN(dragPreviewPixelMap, nullptr);
1271 std::shared_ptr<PixelMapInfo> pixelMapInfo = std::make_shared<PixelMapInfo>();
1272 pixelMapInfo->srcPixelFormat = dragPreviewPixelMap->GetPixelFormat();
1273 pixelMapInfo->pixelFormat = dragPreviewPixelMap->GetPixelFormat();
1274 pixelMapInfo->alphaType = dragPreviewPixelMap->GetAlphaType();
1275 pixelMapInfo->pixelMapRect.SetLeft(minX);
1276 pixelMapInfo->pixelMapRect.SetTop(minY);
1277 pixelMapInfo->pixelMapRect.SetHeight(maxY - minY);
1278 pixelMapInfo->pixelMapRect.SetWidth(maxX - minX);
1279 return pixelMapInfo;
1280 }
1281
DrawTiledPixelMap(const RefPtr<PixelMap> & tiledPixelMap,const std::vector<RefPtr<FrameNode>> & children,const Rect & pixelMapRect)1282 void DragDropFuncWrapper::DrawTiledPixelMap(
1283 const RefPtr<PixelMap>& tiledPixelMap, const std::vector<RefPtr<FrameNode>>& children, const Rect& pixelMapRect)
1284 {
1285 CHECK_NULL_VOID(tiledPixelMap);
1286 for (auto& node : children) {
1287 auto gestureHub = node->GetOrCreateGestureEventHub();
1288 CHECK_NULL_VOID(gestureHub);
1289 auto pixelMap = gestureHub->GetDragPreviewPixelMap();
1290 CHECK_NULL_VOID(pixelMap);
1291 auto offset = node->GetPositionToWindowWithTransform();
1292 auto offsetX = offset.GetX();
1293 auto offsetY = offset.GetY();
1294 auto result =
1295 tiledPixelMap->WritePixels({ pixelMap->GetPixels(), pixelMap->GetByteCount(), 0, pixelMap->GetRowStride(),
1296 { offsetX - pixelMapRect.GetOffset().GetX(), offsetY - pixelMapRect.GetOffset().GetY(),
1297 pixelMap->GetWidth(), pixelMap->GetHeight() },
1298 pixelMap->GetPixelFormat() });
1299 if (result != 0) {
1300 TAG_LOGW(AceLogTag::ACE_DRAG, "Tiled pixelmap Write is failed, the result is %{public}d", result);
1301 return;
1302 }
1303 }
1304 return;
1305 }
1306
IsNeedCreateTiledPixelMap(const RefPtr<FrameNode> & frameNode,const RefPtr<DragEventActuator> dragEventActuator,SourceType type)1307 bool DragDropFuncWrapper::IsNeedCreateTiledPixelMap(
1308 const RefPtr<FrameNode>& frameNode, const RefPtr<DragEventActuator> dragEventActuator, SourceType type)
1309 {
1310 CHECK_NULL_RETURN(frameNode, false);
1311 CHECK_NULL_RETURN(dragEventActuator, false);
1312 auto fatherNode = DragDropFuncWrapper::FindItemParentNode(frameNode);
1313 CHECK_NULL_RETURN(fatherNode, false);
1314 auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1315 CHECK_NULL_RETURN(scrollPattern, false);
1316 if (frameNode->GetDragPreviewOption().isMultiTiled && scrollPattern->GetVisibleSelectedItems().size() > 1 &&
1317 DragDropFuncWrapper::IsSelectedItemNode(frameNode) && !dragEventActuator->GetRestartDrag() &&
1318 type == SourceType::MOUSE) {
1319 return true;
1320 }
1321 return false;
1322 }
1323
GetThumbnailPixelMapForCustomNodeSync(const RefPtr<GestureEventHub> & gestureHub,PixelMapFinishCallback pixelMapCallback)1324 void DragDropFuncWrapper::GetThumbnailPixelMapForCustomNodeSync(
1325 const RefPtr<GestureEventHub>& gestureHub, PixelMapFinishCallback pixelMapCallback)
1326 {
1327 #if defined(PIXEL_MAP_SUPPORTED)
1328 CHECK_NULL_VOID(gestureHub);
1329 auto frameNode = gestureHub->GetFrameNode();
1330 CHECK_NULL_VOID(frameNode);
1331 auto dragPreviewInfo = frameNode->GetDragPreview();
1332 SnapshotParam param;
1333 auto pixelMap = ComponentSnapshot::CreateSync(dragPreviewInfo.customNode, param);
1334 CHECK_NULL_VOID(pixelMap);
1335 auto previewPixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1336 gestureHub->SetPixelMap(previewPixelMap);
1337 gestureHub->SetDragPreviewPixelMap(previewPixelMap);
1338 pixelMapCallback(previewPixelMap, false);
1339 #endif
1340 }
1341
GetThumbnailPixelMapAsync(const RefPtr<GestureEventHub> & gestureHub)1342 void DragDropFuncWrapper::GetThumbnailPixelMapAsync(const RefPtr<GestureEventHub>& gestureHub)
1343 {
1344 CHECK_NULL_VOID(gestureHub);
1345 auto callback = [id = Container::CurrentId(), weakGestureHub = AceType::WeakClaim(AceType::RawPtr(gestureHub))](
1346 const RefPtr<PixelMap>& pixelMap) {
1347 ContainerScope scope(id);
1348 if (pixelMap != nullptr) {
1349 auto taskScheduler = Container::CurrentTaskExecutor();
1350 CHECK_NULL_VOID(taskScheduler);
1351 auto gestureHub = weakGestureHub.Upgrade();
1352 CHECK_NULL_VOID(gestureHub);
1353 taskScheduler->PostTask(
1354 [gestureHub, pixelMap]() {
1355 CHECK_NULL_VOID(gestureHub);
1356 gestureHub->SetPixelMap(pixelMap);
1357 TAG_LOGI(AceLogTag::ACE_DRAG, "Set thumbnail pixelMap async success.");
1358 },
1359 TaskExecutor::TaskType::UI, "ArkUIDragSetPixelMap");
1360 }
1361 };
1362 auto frameNode = gestureHub->GetFrameNode();
1363 CHECK_NULL_VOID(frameNode);
1364 auto context = frameNode->GetRenderContext();
1365 CHECK_NULL_VOID(context);
1366 if (!context->CreateThumbnailPixelMapAsyncTask(true, std::move(callback))) {
1367 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SNAPSHOT_FAIL);
1368 TAG_LOGW(AceLogTag::ACE_DRAG, "Create thumbnail pixelMap async task failed!");
1369 }
1370 }
1371
GetThumbnailPixelMapForCustomNode(const RefPtr<GestureEventHub> & gestureHub,PixelMapFinishCallback pixelMapCallback)1372 void DragDropFuncWrapper::GetThumbnailPixelMapForCustomNode(
1373 const RefPtr<GestureEventHub>& gestureHub, PixelMapFinishCallback pixelMapCallback)
1374 {
1375 #if defined(PIXEL_MAP_SUPPORTED)
1376 CHECK_NULL_VOID(gestureHub);
1377 auto frameNode = gestureHub->GetFrameNode();
1378 CHECK_NULL_VOID(frameNode);
1379 auto dragPreviewInfo = frameNode->GetDragPreview();
1380 auto pipeline = PipelineContext::GetCurrentContext();
1381 CHECK_NULL_VOID(pipeline);
1382 auto callback = [id = Container::CurrentId(), pipeline, gestureHub, pixelMapCallback](
1383 std::shared_ptr<Media::PixelMap> pixelMap, int32_t arg, std::function<void()> finishCallback) {
1384 ContainerScope scope(id);
1385 CHECK_NULL_VOID(pipeline);
1386 auto taskScheduler = pipeline->GetTaskExecutor();
1387 CHECK_NULL_VOID(taskScheduler);
1388 taskScheduler->PostTask(
1389 [finishCallback]() {
1390 if (finishCallback) {
1391 finishCallback();
1392 }
1393 },
1394 TaskExecutor::TaskType::UI, "ArkUIDragRemoveCustomNode");
1395 if (pixelMap != nullptr) {
1396 auto customPixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1397 taskScheduler->PostTask(
1398 [gestureHub, customPixelMap, pixelMapCallback]() {
1399 CHECK_NULL_VOID(gestureHub);
1400 gestureHub->SetPixelMap(customPixelMap);
1401 gestureHub->SetDragPreviewPixelMap(customPixelMap);
1402 pixelMapCallback(customPixelMap, true);
1403 },
1404 TaskExecutor::TaskType::UI, "ArkUIDragSetCustomPixelMap");
1405 } else {
1406 TAG_LOGI(AceLogTag::ACE_DRAG, "PixelMap is null.");
1407 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SNAPSHOT_FAIL);
1408 }
1409 };
1410 SnapshotParam param;
1411 param.delay = CREATE_PIXELMAP_TIME;
1412 param.checkImageStatus = true;
1413 param.options.waitUntilRenderFinished = true;
1414 OHOS::Ace::NG::ComponentSnapshot::Create(dragPreviewInfo.customNode, std::move(callback), true, param);
1415 gestureHub->PrintBuilderNode(dragPreviewInfo.customNode);
1416 #endif
1417 }
1418
GetThumbnailPixelMap(const RefPtr<GestureEventHub> & gestureHub,PixelMapFinishCallback pixelMapCallback,bool isSync)1419 void DragDropFuncWrapper::GetThumbnailPixelMap(
1420 const RefPtr<GestureEventHub>& gestureHub, PixelMapFinishCallback pixelMapCallback, bool isSync)
1421 {
1422 CHECK_NULL_VOID(gestureHub);
1423 auto frameNode = gestureHub->GetFrameNode();
1424 CHECK_NULL_VOID(frameNode);
1425 auto dragPreviewInfo = frameNode->GetDragPreview();
1426 if (dragPreviewInfo.inspectorId != "") {
1427 TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail through inspectorId.");
1428 auto previewPixelMap = GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
1429 gestureHub->SetPixelMap(previewPixelMap);
1430 gestureHub->SetDragPreviewPixelMap(previewPixelMap);
1431 pixelMapCallback(previewPixelMap, false);
1432 } else if (dragPreviewInfo.pixelMap != nullptr) {
1433 TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail through pixelMap.");
1434 gestureHub->SetPixelMap(dragPreviewInfo.pixelMap);
1435 gestureHub->SetDragPreviewPixelMap(dragPreviewInfo.pixelMap);
1436 pixelMapCallback(dragPreviewInfo.pixelMap, false);
1437 } else if (dragPreviewInfo.customNode || (dragPreviewInfo.delayCreating && dragPreviewInfo.buildFunc)) {
1438 TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail through customNode.");
1439 if (!dragPreviewInfo.customNode && dragPreviewInfo.delayCreating && dragPreviewInfo.buildFunc) {
1440 dragPreviewInfo.customNode = dragPreviewInfo.buildFunc();
1441 }
1442 frameNode->SetDragPreview(dragPreviewInfo);
1443 if (isSync) {
1444 GetThumbnailPixelMapForCustomNodeSync(gestureHub, pixelMapCallback);
1445 } else {
1446 GetThumbnailPixelMapForCustomNode(gestureHub, pixelMapCallback);
1447 }
1448 } else {
1449 GetThumbnailPixelMapAsync(gestureHub);
1450 }
1451 }
1452
GetPixelMapScale(const RefPtr<FrameNode> & frameNode)1453 float DragDropFuncWrapper::GetPixelMapScale(const RefPtr<FrameNode>& frameNode)
1454 {
1455 float scale = 1.0f;
1456 CHECK_NULL_RETURN(frameNode, scale);
1457 auto pixelMap = frameNode->GetDragPixelMap();
1458 CHECK_NULL_RETURN(pixelMap, scale);
1459 auto width = pixelMap->GetWidth();
1460 auto height = pixelMap->GetHeight();
1461 auto gestureEvent = frameNode->GetOrCreateGestureEventHub();
1462 CHECK_NULL_RETURN(gestureEvent, scale);
1463 if (frameNode->GetDragPreviewOption().isScaleEnabled && width > 0 && height > 0) {
1464 auto scaleData = DragDropManager::GetScaleInfo(width, height, gestureEvent->GetTextDraggable());
1465 CHECK_NULL_RETURN(scaleData, scale);
1466 scale = scaleData->scale;
1467 }
1468 return scale;
1469 }
1470
IsTextCategoryComponent(const std::string & frameTag)1471 bool DragDropFuncWrapper::IsTextCategoryComponent(const std::string& frameTag)
1472 {
1473 return frameTag == V2::TEXTAREA_ETS_TAG || frameTag == V2::TEXT_ETS_TAG ||
1474 frameTag == V2::TEXTINPUT_ETS_TAG || frameTag == V2::SEARCH_Field_ETS_TAG ||
1475 frameTag == V2::RICH_EDITOR_ETS_TAG;
1476 }
1477
GetDragDropManagerForDragAnimation(const RefPtr<PipelineBase> & context,const RefPtr<PipelineBase> & nodeContext,const RefPtr<Subwindow> & subWindow,bool isExpandDisplay,int32_t instanceId)1478 RefPtr<DragDropManager> DragDropFuncWrapper::GetDragDropManagerForDragAnimation(
1479 const RefPtr<PipelineBase>& context, const RefPtr<PipelineBase>& nodeContext,
1480 const RefPtr<Subwindow>& subWindow, bool isExpandDisplay, int32_t instanceId)
1481 {
1482 auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1483 CHECK_NULL_RETURN(pipeline, nullptr);
1484 auto dragDropManager = pipeline->GetDragDropManager();
1485 auto nodePipeline = AceType::DynamicCast<PipelineContext>(nodeContext);
1486 CHECK_NULL_RETURN(nodePipeline, dragDropManager);
1487 if (nodePipeline == pipeline || isExpandDisplay) {
1488 return dragDropManager;
1489 }
1490 auto mainContainerId = instanceId >= MIN_SUBCONTAINER_ID ?
1491 SubwindowManager::GetInstance()->GetParentContainerId(instanceId) : instanceId;
1492 auto container = Container::GetContainer(mainContainerId);
1493 CHECK_NULL_RETURN(container, dragDropManager);
1494 if (!container->IsSceneBoardWindow()) {
1495 return dragDropManager;
1496 }
1497 CHECK_NULL_RETURN(subWindow, dragDropManager);
1498 subWindow->SetWindowTouchable(false);
1499 auto pixelMapOffset = dragDropManager->GetPixelMapOffset();
1500 dragDropManager = nodePipeline->GetDragDropManager();
1501 dragDropManager->SetPixelMapOffset(pixelMapOffset);
1502 return dragDropManager;
1503 }
1504
SetMenuSubWindowTouchable(bool touchable)1505 void DragDropFuncWrapper::SetMenuSubWindowTouchable(bool touchable)
1506 {
1507 auto containerId = Container::CurrentId();
1508 auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(containerId, SubwindowType::TYPE_MENU);
1509 CHECK_NULL_VOID(subwindow);
1510 subwindow->SetWindowTouchable(touchable);
1511 }
1512
HandleBackPressHideMenu()1513 void DragDropFuncWrapper::HandleBackPressHideMenu()
1514 {
1515 auto mainPipeline = PipelineContext::GetMainPipelineContext();
1516 CHECK_NULL_VOID(mainPipeline);
1517 auto dragDropManager = mainPipeline->GetDragDropManager();
1518 CHECK_NULL_VOID(dragDropManager);
1519 dragDropManager->SetIsDragNodeNeedClean(true);
1520 auto container = AceEngine::Get().GetContainer(mainPipeline->GetInstanceId());
1521 CHECK_NULL_VOID(container);
1522 if (container->IsUIExtensionWindow()) {
1523 auto overlayManager = mainPipeline->GetOverlayManager();
1524 CHECK_NULL_VOID(overlayManager);
1525 overlayManager->RemoveGatherNode();
1526 }
1527 }
1528
ProcessDragDropData(const RefPtr<OHOS::Ace::DragEvent> & dragEvent,std::string & udKey,DragSummaryInfo & dragSummaryInfo,int32_t & ret)1529 void DragDropFuncWrapper::ProcessDragDropData(const RefPtr<OHOS::Ace::DragEvent>& dragEvent, std::string& udKey,
1530 DragSummaryInfo& dragSummaryInfo, int32_t& ret)
1531 {
1532 CHECK_NULL_VOID(dragEvent);
1533 auto unifiedData = dragEvent->GetData();
1534 if (unifiedData) {
1535 DragDropBehaviorReporter::GetInstance().UpdateRecordSize(unifiedData->GetSize());
1536 }
1537 auto dataLoadParams = dragEvent->GetDataLoadParams();
1538 auto isUseDataLoadParams = dragEvent->IsUseDataLoadParams();
1539 if (dataLoadParams && isUseDataLoadParams) {
1540 ACE_SCOPED_TRACE("drag: set delayInfo to udmf");
1541 if (UdmfClient::GetInstance()->SetDelayInfo(dataLoadParams, udKey) != 0) {
1542 TAG_LOGI(AceLogTag::ACE_DRAG, "udmf set delayInfo failed, return value is %{public}d", ret);
1543 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SET_DATA_FAIL);
1544 }
1545 }
1546 if (unifiedData && !isUseDataLoadParams) {
1547 ACE_SCOPED_TRACE("drag: set drag data to udmf");
1548 if (UdmfClient::GetInstance()->SetData(unifiedData, udKey) != 0) {
1549 TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF set data failed, return value is %{public}d", ret);
1550 DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SET_DATA_FAIL);
1551 }
1552 }
1553 ret = UdmfClient::GetInstance()->GetSummary(udKey, dragSummaryInfo);
1554 if (ret != 0) {
1555 TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF get summary failed, return value is %{public}d", ret);
1556 }
1557 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1558 CHECK_NULL_VOID(pipeline);
1559 auto dragDropManager = pipeline->GetDragDropManager();
1560 CHECK_NULL_VOID(dragDropManager);
1561 dragDropManager->SetSummaryMap(dragSummaryInfo.summary);
1562 }
1563
FindWindowScene(RefPtr<FrameNode> & targetNode)1564 RefPtr<UINode> DragDropFuncWrapper::FindWindowScene(RefPtr<FrameNode>& targetNode)
1565 {
1566 CHECK_NULL_RETURN(targetNode, nullptr);
1567 auto pipeline = targetNode->GetContextRefPtr();
1568 CHECK_NULL_RETURN(pipeline, nullptr);
1569 auto container = Container::GetContainer(pipeline->GetInstanceId());
1570 CHECK_NULL_RETURN(container, nullptr);
1571 if (!container->IsSceneBoardWindow()) {
1572 return nullptr;
1573 }
1574 auto parent = targetNode->GetParent();
1575 while (parent && parent->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
1576 parent = parent->GetParent();
1577 }
1578 return parent;
1579 }
1580 } // namespace OHOS::Ace::NG
1581