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