• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <mutex>
19 
20 #include "base/image/pixel_map.h"
21 #include "base/json/json_util.h"
22 #include "base/subwindow/subwindow_manager.h"
23 #include "core/common/ace_engine.h"
24 #include "core/common/interaction/interaction_interface.h"
25 #include "core/common/udmf/udmf_client.h"
26 #include "core/components/common/layout/grid_system_manager.h"
27 #include "core/components/select/select_theme.h"
28 #include "core/components/theme/blur_style_theme.h"
29 #include "core/components/theme/shadow_theme.h"
30 #include "core/components_ng/manager/drag_drop/drag_drop_manager.h"
31 #include "core/components_ng/pattern/image/image_pattern.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 }
50 
CheckInternalDragging(const RefPtr<Container> & container)51 static bool CheckInternalDragging(const RefPtr<Container>& container)
52 {
53     CHECK_NULL_RETURN(container, false);
54     auto pipelineContext = container->GetPipelineContext();
55     if (!pipelineContext || !pipelineContext->IsDragging()) {
56         return false;
57     }
58     return true;
59 }
60 
GetShadowInfoArray(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,std::vector<ShadowInfoCore> & shadowInfos)61 void GetShadowInfoArray(
62     std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, std::vector<ShadowInfoCore>& shadowInfos)
63 {
64     auto minScaleWidth = NG::DragDropFuncWrapper::GetScaleWidth(dragAction->instanceId);
65     for (auto& pixelMap : dragAction->pixelMapList) {
66         double scale = 1.0;
67         if (pixelMap.GetRawPtr()) {
68             if (pixelMap->GetWidth() > minScaleWidth && dragAction->previewOption.isScaleEnabled) {
69                 scale = minScaleWidth / pixelMap->GetWidth();
70             }
71             auto pixelMapScale = dragAction->windowScale * scale;
72             pixelMap->Scale(pixelMapScale, pixelMapScale, AceAntiAliasingOption::HIGH);
73         }
74         int32_t width = pixelMap->GetWidth();
75         int32_t height = pixelMap->GetHeight();
76         double x = dragAction->touchPointX;
77         double y = dragAction->touchPointY;
78         if (!dragAction->hasTouchPoint) {
79             x = -width * PIXELMAP_WIDTH_RATE;
80             y = -height * PIXELMAP_HEIGHT_RATE;
81         }
82         ShadowInfoCore shadowInfo { pixelMap, -x, -y };
83         shadowInfos.push_back(shadowInfo);
84     }
85 }
86 
PostStopDrag(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const RefPtr<Container> & container)87 void PostStopDrag(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, const RefPtr<Container>& container)
88 {
89     CHECK_NULL_VOID(container);
90     auto taskExecutor = container->GetTaskExecutor();
91     CHECK_NULL_VOID(taskExecutor);
92     auto windowId = container->GetWindowId();
93     taskExecutor->PostTask(
94         [dragAction, windowId]() {
95             CHECK_NULL_VOID(dragAction);
96             TAG_LOGI(AceLogTag::ACE_DRAG, "drag state is reject, stop drag, windowId is %{public}d.", windowId);
97             OHOS::Ace::DragDropRet dropResult { OHOS::Ace::DragRet::DRAG_CANCEL, false, windowId,
98                 OHOS::Ace::DragBehavior::UNKNOWN };
99             InteractionInterface::GetInstance()->StopDrag(dropResult);
100             InteractionInterface::GetInstance()->SetDragWindowVisible(false);
101         },
102         TaskExecutor::TaskType::UI, "ArkUIDragStop");
103 }
104 
ConfirmCurPointerEventInfo(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const RefPtr<Container> & container)105 bool ConfirmCurPointerEventInfo(
106     std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, const RefPtr<Container>& container)
107 {
108     CHECK_NULL_RETURN(dragAction, false);
109     CHECK_NULL_RETURN(container, false);
110     StopDragCallback stopDragCallback = [dragAction, container]() {
111         CHECK_NULL_VOID(dragAction);
112         CHECK_NULL_VOID(container);
113         bool needPostStopDrag = false;
114         if (dragAction->dragState == DragAdapterState::SENDING) {
115             needPostStopDrag = true;
116         }
117         {
118             std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
119             dragAction->dragState = DragAdapterState::REJECT;
120         }
121         if (needPostStopDrag) {
122             PostStopDrag(dragAction, container);
123         }
124     };
125     bool getPointSuccess = container->GetCurPointerEventInfo(dragAction->dragPointerEvent,
126         std::move(stopDragCallback));
127     if (dragAction->dragPointerEvent.sourceType == SOURCE_TYPE_MOUSE) {
128         dragAction->dragPointerEvent.pointerId = MOUSE_POINTER_ID;
129     } else if (dragAction->dragPointerEvent.sourceType == SOURCE_TYPE_TOUCH &&
130         static_cast<int32_t>(dragAction->dragPointerEvent.sourceTool) == SOURCE_TOOL_PEN) {
131         dragAction->dragPointerEvent.pointerId = PEN_POINTER_ID;
132     }
133     return getPointSuccess;
134 }
135 
EnvelopedDragData(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,std::optional<DragDataCore> & dragData)136 void EnvelopedDragData(
137     std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, std::optional<DragDataCore>& dragData)
138 {
139     auto container = AceEngine::Get().GetContainer(dragAction->instanceId);
140     CHECK_NULL_VOID(container);
141 
142     std::vector<ShadowInfoCore> shadowInfos;
143     GetShadowInfoArray(dragAction, shadowInfos);
144     if (shadowInfos.empty()) {
145         TAG_LOGE(AceLogTag::ACE_DRAG, "shadowInfo array is empty");
146         return;
147     }
148     auto pointerId = dragAction->dragPointerEvent.pointerId;
149     std::string udKey;
150     std::map<std::string, int64_t> summary;
151     int32_t dataSize = 1;
152     if (dragAction->unifiedData) {
153         int32_t ret = UdmfClient::GetInstance()->SetData(dragAction->unifiedData, udKey);
154         if (ret != 0) {
155             TAG_LOGI(AceLogTag::ACE_DRAG, "udmf set data failed, return value is %{public}d", ret);
156         } else {
157             ret = UdmfClient::GetInstance()->GetSummary(udKey, summary);
158             if (ret != 0) {
159                 TAG_LOGI(AceLogTag::ACE_DRAG, "get summary failed, return value is %{public}d", ret);
160             }
161         }
162         dataSize = static_cast<int32_t>(dragAction->unifiedData->GetSize());
163     }
164     int32_t recordSize = (dataSize != 0 ? dataSize : static_cast<int32_t>(shadowInfos.size()));
165     if (dragAction->previewOption.isNumber) {
166         recordSize = dragAction->previewOption.badgeNumber > 1 ? dragAction->previewOption.badgeNumber : 1;
167     } else if (!dragAction->previewOption.isShowBadge) {
168         recordSize = 1;
169     }
170     auto windowId = container->GetWindowId();
171     auto arkExtraInfoJson = JsonUtil::Create(true);
172     auto pipeline = container->GetPipelineContext();
173     CHECK_NULL_VOID(pipeline);
174     dragAction->dipScale = pipeline->GetDipScale();
175     arkExtraInfoJson->Put("dip_scale", dragAction->dipScale);
176     arkExtraInfoJson->Put("event_id", dragAction->dragPointerEvent.pointerEventId);
177     NG::DragDropFuncWrapper::UpdateExtraInfo(arkExtraInfoJson, dragAction->previewOption);
178     dragData = { shadowInfos, {}, udKey, dragAction->extraParams, arkExtraInfoJson->ToString(),
179         dragAction->dragPointerEvent.sourceType, recordSize, pointerId, dragAction->dragPointerEvent.displayX,
180         dragAction->dragPointerEvent.displayY, dragAction->dragPointerEvent.displayId, windowId, true, false,
181         summary };
182 }
183 
HandleCallback(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const OHOS::Ace::DragNotifyMsg & dragNotifyMsg,const DragAdapterStatus & dragStatus)184 void HandleCallback(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,
185     const OHOS::Ace::DragNotifyMsg& dragNotifyMsg, const DragAdapterStatus& dragStatus)
186 {
187     TAG_LOGI(AceLogTag::ACE_DRAG, "drag notify message result is %{public}d.", dragNotifyMsg.result);
188     CHECK_NULL_VOID(dragAction);
189     bool hasHandle = false;
190     {
191         std::lock_guard<std::mutex> lock(dragAction->mutex);
192         hasHandle = dragAction->hasHandle;
193         dragAction->hasHandle = true;
194     }
195     if (hasHandle) {
196         return;
197     }
198     auto container = AceEngine::Get().GetContainer(dragAction->instanceId);
199     CHECK_NULL_VOID(container);
200     if (dragStatus == DragAdapterStatus::ENDED) {
201         auto pipelineContext = container->GetPipelineContext();
202         CHECK_NULL_VOID(pipelineContext);
203         pipelineContext->ResetDragging();
204     }
205     int32_t dragState = static_cast<int32_t>(dragStatus);
206     dragAction->callback(dragNotifyMsg, dragState);
207 }
208 
CheckStartAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const RefPtr<Container> & container,const RefPtr<DragDropManager> & manager)209 int32_t CheckStartAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,
210     const RefPtr<Container>& container, const RefPtr<DragDropManager>& manager)
211 {
212     if (CheckInternalDragging(container)) {
213         return -1;
214     }
215     {
216         std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
217         if (manager->GetDragAction() != nullptr && (manager->GetDragAction())->dragState == DragAdapterState::SENDING) {
218             return -1;
219         }
220         dragAction->dragState = DragAdapterState::SENDING;
221     }
222     DragDropFuncWrapper::UpdatePreviewOptionDefaultAttr(dragAction->previewOption);
223     auto isGetPointSuccess = ConfirmCurPointerEventInfo(dragAction, container);
224     if (!isGetPointSuccess) {
225         return -1;
226     }
227     return 0;
228 }
229 
StartDragAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)230 int32_t DragDropFuncWrapper::StartDragAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)
231 {
232     auto pipelineContext = PipelineContext::GetContextByContainerId(dragAction->instanceId);
233     CHECK_NULL_RETURN(pipelineContext, -1);
234     auto manager = pipelineContext->GetDragDropManager();
235     CHECK_NULL_RETURN(manager, -1);
236     auto container = AceEngine::Get().GetContainer(dragAction->instanceId);
237     CHECK_NULL_RETURN(container, -1);
238     auto windowScale = container->GetWindowScale();
239     CHECK_NULL_RETURN(windowScale, -1);
240     dragAction->windowScale = windowScale;
241     manager->SetDragAction(dragAction);
242     if (CheckStartAction(dragAction, container, manager) == -1) {
243         manager->GetDragAction()->dragState = DragAdapterState::INIT;
244         return -1;
245     }
246     std::optional<DragDataCore> dragData;
247     EnvelopedDragData(dragAction, dragData);
248     if (!dragData) {
249         {
250             std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
251             manager->GetDragAction()->dragState = DragAdapterState::INIT;
252         }
253         return -1;
254     }
255     OnDragCallback callback = [dragAction, manager](const OHOS::Ace::DragNotifyMsg& dragNotifyMsg) {
256         {
257             std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
258             dragAction->dragState = DragAdapterState::INIT;
259             manager->SetDragAction(dragAction);
260         }
261         HandleCallback(dragAction, dragNotifyMsg, DragAdapterStatus::ENDED);
262     };
263     NG::DragDropFuncWrapper::SetDraggingPointerAndPressedState(
264         dragAction->dragPointerEvent.pointerId, dragAction->instanceId);
265     int32_t ret = InteractionInterface::GetInstance()->StartDrag(dragData.value(), callback);
266     if (ret != 0) {
267         manager->GetDragAction()->dragState = DragAdapterState::INIT;
268         return -1;
269     }
270     HandleCallback(dragAction, DragNotifyMsg {}, DragAdapterStatus::STARTED);
271     pipelineContext->SetIsDragging(true);
272     NG::DragDropFuncWrapper::HandleOnDragEvent(dragAction);
273     return 0;
274 }
275 
HandleOnDragEvent(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)276 void DragDropFuncWrapper::HandleOnDragEvent(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)
277 {
278     CHECK_NULL_VOID(dragAction);
279     auto pipelineContext = PipelineContext::GetContextByContainerId(dragAction->instanceId);
280     CHECK_NULL_VOID(pipelineContext);
281     std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
282     if (dragAction->dragState == DragAdapterState::SENDING) {
283         dragAction->dragState = DragAdapterState::SUCCESS;
284         InteractionInterface::GetInstance()->SetDragWindowVisible(true);
285         pipelineContext->OnDragEvent(
286             { dragAction->dragPointerEvent.displayX, dragAction->dragPointerEvent.displayY },
287             DragEventAction::DRAG_EVENT_START_FOR_CONTROLLER);
288         NG::DragDropFuncWrapper::DecideWhetherToStopDragging(
289             { dragAction->dragPointerEvent.displayX, dragAction->dragPointerEvent.displayY }, dragAction->extraParams,
290             dragAction->dragPointerEvent.pointerId, dragAction->instanceId);
291     }
292 }
293 
SetDraggingPointerAndPressedState(int32_t currentPointerId,int32_t containerId)294 void DragDropFuncWrapper::SetDraggingPointerAndPressedState(int32_t currentPointerId, int32_t containerId)
295 {
296     auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
297     CHECK_NULL_VOID(pipelineContext);
298     auto manager = pipelineContext->GetDragDropManager();
299     CHECK_NULL_VOID(manager);
300     manager->SetDraggingPointer(currentPointerId);
301     manager->SetDraggingPressedState(true);
302 }
303 
DecideWhetherToStopDragging(const DragPointerEvent & pointerEvent,const std::string & extraParams,int32_t currentPointerId,int32_t containerId)304 void DragDropFuncWrapper::DecideWhetherToStopDragging(
305     const DragPointerEvent& pointerEvent, const std::string& extraParams, int32_t currentPointerId, int32_t containerId)
306 {
307     auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
308     CHECK_NULL_VOID(pipelineContext);
309     auto manager = pipelineContext->GetDragDropManager();
310     CHECK_NULL_VOID(manager);
311     if (!manager->IsDraggingPressed(currentPointerId)) {
312         manager->OnDragEnd(pointerEvent, extraParams);
313     }
314 }
315 
UpdateDragPreviewOptionsFromModifier(std::function<void (WeakPtr<FrameNode>)> applyOnNodeSync,DragPreviewOption & option)316 void DragDropFuncWrapper::UpdateDragPreviewOptionsFromModifier(
317     std::function<void(WeakPtr<FrameNode>)> applyOnNodeSync, DragPreviewOption& option)
318 {
319     // create one temporary frame node for receiving the value from the modifier
320     auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
321         []() { return AceType::MakeRefPtr<ImagePattern>(); });
322     CHECK_NULL_VOID(imageNode);
323 
324     // execute the modifier
325     CHECK_NULL_VOID(applyOnNodeSync);
326     applyOnNodeSync(AceType::WeakClaim(AceType::RawPtr(imageNode)));
327 
328     // get values from the temporary frame node
329     auto imageContext = imageNode->GetRenderContext();
330     CHECK_NULL_VOID(imageContext);
331     auto opacity = imageContext->GetOpacity();
332     if (opacity.has_value() && (opacity.value()) <= MAX_OPACITY && (opacity.value()) >= MIN_OPACITY) {
333         option.options.opacity = opacity.value();
334     } else {
335         option.options.opacity = DEFAULT_OPACITY;
336     }
337 
338     auto shadow = imageContext->GetBackShadow();
339     if (shadow.has_value()) {
340         option.options.shadow = shadow.value();
341     }
342 
343     auto borderRadius = imageContext->GetBorderRadius();
344     if (borderRadius.has_value()) {
345         option.options.borderRadius = borderRadius;
346     }
347 
348     auto bgEffect = imageContext->GetBackgroundEffect();
349     if (bgEffect.has_value()) {
350         option.options.blurbgEffect.backGroundEffect = bgEffect.value();
351     } else {
352         auto blurstyletmp = imageContext->GetBackBlurStyle();
353         if (blurstyletmp.has_value()) {
354             bgEffect = BrulStyleToEffection(blurstyletmp);
355             if (bgEffect.has_value()) {
356                 option.options.blurbgEffect.backGroundEffect = bgEffect.value();
357             }
358         }
359     }
360 }
361 
UpdatePreviewOptionDefaultAttr(DragPreviewOption & option)362 void DragDropFuncWrapper::UpdatePreviewOptionDefaultAttr(DragPreviewOption& option)
363 {
364     option.options.opacity = DEFAULT_OPACITY;
365     if (option.isDefaultShadowEnabled) {
366         option.options.shadow = GetDefaultShadow();
367     } else {
368         option.options.shadow = std::nullopt;
369     }
370     if (option.isDefaultRadiusEnabled) {
371         option.options.borderRadius = GetDefaultBorderRadius();
372     } else {
373         option.options.borderRadius = std::nullopt;
374     }
375 }
376 
UpdateExtraInfo(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)377 void DragDropFuncWrapper::UpdateExtraInfo(std::unique_ptr<JsonValue>& arkExtraInfoJson,
378     DragPreviewOption& option)
379 {
380     CHECK_NULL_VOID(arkExtraInfoJson);
381     double opacity = option.options.opacity;
382     arkExtraInfoJson->Put("dip_opacity", opacity);
383     if (option.options.blurbgEffect.backGroundEffect.radius.IsValid()) {
384         option.options.blurbgEffect.ToJsonValue(arkExtraInfoJson);
385     }
386     PrepareShadowParametersForDragData(arkExtraInfoJson, option);
387     PrepareRadiusParametersForDragData(arkExtraInfoJson, option);
388 }
389 
PrepareRadiusParametersForDragData(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)390 void DragDropFuncWrapper::PrepareRadiusParametersForDragData(std::unique_ptr<JsonValue>& arkExtraInfoJson,
391     DragPreviewOption& option)
392 {
393     CHECK_NULL_VOID(arkExtraInfoJson);
394     auto borderRadius = option.options.borderRadius;
395     if (borderRadius.has_value()) {
396         if (borderRadius.value().radiusTopLeft.has_value()) {
397             arkExtraInfoJson->Put("drag_corner_radius1", borderRadius.value().radiusTopLeft.value().Value());
398         }
399         if (borderRadius.value().radiusTopRight.has_value()) {
400             arkExtraInfoJson->Put("drag_corner_radius2", borderRadius.value().radiusTopRight.value().Value());
401         }
402         if (borderRadius.value().radiusBottomRight.has_value()) {
403             arkExtraInfoJson->Put("drag_corner_radius3", borderRadius.value().radiusBottomRight.value().Value());
404         }
405         if (borderRadius.value().radiusBottomLeft.has_value()) {
406             arkExtraInfoJson->Put("drag_corner_radius4", borderRadius.value().radiusBottomLeft.value().Value());
407         }
408     }
409 }
410 
PrepareShadowParametersForDragData(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)411 void DragDropFuncWrapper::PrepareShadowParametersForDragData(std::unique_ptr<JsonValue>& arkExtraInfoJson,
412     DragPreviewOption& option)
413 {
414     CHECK_NULL_VOID(arkExtraInfoJson);
415     auto shadow = option.options.shadow;
416     if (!shadow.has_value() || !shadow->IsValid()) {
417         arkExtraInfoJson->Put("shadow_enable", false);
418         return;
419     }
420     arkExtraInfoJson->Put("drag_type", "non-text");
421     arkExtraInfoJson->Put("shadow_enable", true);
422     ParseShadowInfo(shadow.value(), arkExtraInfoJson);
423 }
424 
ParseShadowInfo(Shadow & shadow,std::unique_ptr<JsonValue> & arkExtraInfoJson)425 void DragDropFuncWrapper::ParseShadowInfo(Shadow& shadow, std::unique_ptr<JsonValue>& arkExtraInfoJson)
426 {
427     CHECK_NULL_VOID(arkExtraInfoJson);
428     arkExtraInfoJson->Put("shadow_is_filled", shadow.GetIsFilled());
429     arkExtraInfoJson->Put("drag_shadow_OffsetX", shadow.GetOffset().GetX());
430     arkExtraInfoJson->Put("drag_shadow_OffsetY", shadow.GetOffset().GetY());
431     arkExtraInfoJson->Put("shadow_mask", shadow.GetShadowType() == ShadowType::BLUR);
432     int32_t argb = static_cast<int32_t>(shadow.GetColor().GetValue());
433     arkExtraInfoJson->Put("drag_shadow_argb", argb);
434     int32_t strategy = static_cast<int32_t>(shadow.GetShadowColorStrategy());
435     arkExtraInfoJson->Put("shadow_color_strategy", strategy);
436     arkExtraInfoJson->Put("shadow_corner", shadow.GetBlurRadius());
437     arkExtraInfoJson->Put("shadow_elevation", shadow.GetElevation());
438     arkExtraInfoJson->Put("shadow_is_hardwareacceleration", shadow.GetHardwareAcceleration());
439 }
440 
GetDefaultShadow()441 std::optional<Shadow> DragDropFuncWrapper::GetDefaultShadow()
442 {
443     auto pipelineContext = PipelineContext::GetCurrentContext();
444     CHECK_NULL_RETURN(pipelineContext, std::nullopt);
445     auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
446     CHECK_NULL_RETURN(shadowTheme, std::nullopt);
447     auto colorMode = SystemProperties::GetColorMode();
448     auto shadow = shadowTheme->GetShadow(ShadowStyle::OuterFloatingSM, colorMode);
449     shadow.SetIsFilled(true);
450     return shadow;
451 }
452 
GetDefaultBorderRadius()453 std::optional<BorderRadiusProperty> DragDropFuncWrapper::GetDefaultBorderRadius()
454 {
455     BorderRadiusProperty borderRadius;
456     borderRadius.SetRadius(PREVIEW_BORDER_RADIUS);
457     return borderRadius;
458 }
459 
RadiusToSigma(float radius)460 float DragDropFuncWrapper::RadiusToSigma(float radius)
461 {
462     return GreatNotEqual(radius, 0.0f) ? BLUR_SIGMA_SCALE * radius + SCALE_HALF : 0.0f;
463 }
464 
BrulStyleToEffection(const std::optional<BlurStyleOption> & blurStyleOp)465 std::optional<EffectOption> DragDropFuncWrapper::BrulStyleToEffection(
466     const std::optional<BlurStyleOption>& blurStyleOp)
467 {
468     auto pipeline = PipelineContext::GetCurrentContext();
469     CHECK_NULL_RETURN(pipeline, std::nullopt);
470     auto blurStyleTheme = pipeline->GetTheme<BlurStyleTheme>();
471     if (!blurStyleTheme) {
472         LOGW("cannot find theme of blurStyle, create blurStyle failed");
473         return std::nullopt;
474     }
475     ThemeColorMode colorMode = blurStyleOp->colorMode;
476     if (blurStyleOp->colorMode == ThemeColorMode::SYSTEM) {
477         colorMode = SystemProperties::GetColorMode() == ColorMode::DARK ? ThemeColorMode::DARK : ThemeColorMode::LIGHT;
478     }
479     auto blurParam = blurStyleTheme->GetBlurParameter(blurStyleOp->blurStyle, colorMode);
480     CHECK_NULL_RETURN(blurParam, std::nullopt);
481     auto ratio = blurStyleOp->scale;
482     auto maskColor = blurParam->maskColor.BlendOpacity(ratio);
483     auto radiusPx = blurParam->radius * pipeline->GetDipScale();
484     auto radiusBlur = RadiusToSigma(radiusPx) * ratio;
485     auto saturation = (blurParam->saturation - 1) * ratio + 1.0;
486     auto brightness = (blurParam->brightness - 1) * ratio + 1.0;
487     Dimension dimen(radiusBlur);
488     EffectOption bgEffection = {dimen, saturation, brightness, maskColor,
489         blurStyleOp->adaptiveColor, blurStyleOp->blurOption};
490     return std::optional<EffectOption>(bgEffection);
491 }
492 
GetScaleWidth(int32_t containerId)493 [[maybe_unused]] double DragDropFuncWrapper::GetScaleWidth(int32_t containerId)
494 {
495     auto pipeline = Container::GetContainer(containerId)->GetPipelineContext();
496     CHECK_NULL_RETURN(pipeline, -1.0f);
497     return DragDropManager::GetMaxWidthBaseOnGridSystem(pipeline);
498 }
499 
SetExtraInfo(int32_t containerId,std::string extraInfo)500 void DragDropFuncWrapper::SetExtraInfo(int32_t containerId, std::string extraInfo)
501 {
502     auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
503     CHECK_NULL_VOID(pipelineContext);
504     auto manager = pipelineContext->GetDragDropManager();
505     CHECK_NULL_VOID(manager);
506     manager->SetExtraInfo(extraInfo);
507 }
508 
509 // returns a node's offset relative to window plus half of self rect size(w, h)
510 // and accumulate every ancestor node's graphic properties such as rotate and transform
511 // ancestor will NOT check boundary of window scene
GetPaintRectCenter(const RefPtr<FrameNode> & frameNode,bool checkWindowBoundary)512 OffsetF DragDropFuncWrapper::GetPaintRectCenter(const RefPtr<FrameNode>& frameNode, bool checkWindowBoundary)
513 {
514     CHECK_NULL_RETURN(frameNode, OffsetF());
515     auto context = frameNode->GetRenderContext();
516     CHECK_NULL_RETURN(context, OffsetF());
517     auto paintRect = context->GetPaintRectWithoutTransform();
518     auto offset = paintRect.GetOffset();
519     PointF pointNode(offset.GetX() + paintRect.Width() / 2.0f, offset.GetY() + paintRect.Height() / 2.0f);
520     context->GetPointTransformRotate(pointNode);
521     auto parent = frameNode->GetAncestorNodeOfFrame(false);
522     while (parent) {
523         if (checkWindowBoundary && parent->IsWindowBoundary()) {
524             break;
525         }
526         auto renderContext = parent->GetRenderContext();
527         CHECK_NULL_RETURN(renderContext, OffsetF());
528         offset = renderContext->GetPaintRectWithoutTransform().GetOffset();
529         pointNode.SetX(offset.GetX() + pointNode.GetX());
530         pointNode.SetY(offset.GetY() + pointNode.GetY());
531         renderContext->GetPointTransformRotate(pointNode);
532         parent = parent->GetAncestorNodeOfFrame(false);
533     }
534     return OffsetF(pointNode.GetX(), pointNode.GetY());
535 }
536 
537 // check if expand subwindow
IsExpandDisplay(const RefPtr<PipelineBase> & context)538 bool DragDropFuncWrapper::IsExpandDisplay(const RefPtr<PipelineBase>& context)
539 {
540     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
541     CHECK_NULL_RETURN(pipeline, false);
542     auto theme = pipeline->GetTheme<SelectTheme>();
543     CHECK_NULL_RETURN(theme, false);
544     if (theme->GetExpandDisplay()) {
545         return true;
546     }
547     auto containerId = pipeline->GetInstanceId();
548     containerId = containerId >= MIN_SUBCONTAINER_ID ?
549         SubwindowManager::GetInstance()->GetParentContainerId(containerId) : containerId;
550     auto container = AceEngine::Get().GetContainer(containerId);
551     CHECK_NULL_RETURN(container, false);
552     return container->IsFreeMultiWindow();
553 }
554 
GetCurrentWindowOffset(const RefPtr<PipelineBase> & context)555 OffsetF DragDropFuncWrapper::GetCurrentWindowOffset(const RefPtr<PipelineBase>& context)
556 {
557     if (!IsExpandDisplay(context)) {
558         return OffsetF();
559     }
560     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
561     CHECK_NULL_RETURN(pipeline, OffsetF());
562     auto window = pipeline->GetWindow();
563     CHECK_NULL_RETURN(window, OffsetF());
564     auto windowOffset = window->GetCurrentWindowRect().GetOffset();
565     return OffsetF(windowOffset.GetX(), windowOffset.GetY());
566 }
567 
GetPaintRectCenterToScreen(const RefPtr<FrameNode> & frameNode)568 OffsetF DragDropFuncWrapper::GetPaintRectCenterToScreen(const RefPtr<FrameNode>& frameNode)
569 {
570     auto offset = GetPaintRectCenter(frameNode);
571     CHECK_NULL_RETURN(frameNode, offset);
572     offset += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
573     return offset;
574 }
575 
GetFrameNodeOffsetToScreen(const RefPtr<FrameNode> & frameNode)576 OffsetF DragDropFuncWrapper::GetFrameNodeOffsetToScreen(const RefPtr<FrameNode>& frameNode)
577 {
578     CHECK_NULL_RETURN(frameNode, OffsetF());
579     auto offset = frameNode->GetPositionToWindowWithTransform();
580     offset += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
581     return offset;
582 }
583 
GetPaintRectToScreen(const RefPtr<FrameNode> & frameNode)584 RectF DragDropFuncWrapper::GetPaintRectToScreen(const RefPtr<FrameNode>& frameNode)
585 {
586     CHECK_NULL_RETURN(frameNode, RectF());
587     RectF rect = frameNode->GetTransformRectRelativeToWindow();
588     rect += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
589     return rect;
590 }
591 
UpdateNodePositionToScreen(const RefPtr<FrameNode> & frameNode,OffsetF offset)592 void DragDropFuncWrapper::UpdateNodePositionToScreen(const RefPtr<FrameNode>& frameNode, OffsetF offset)
593 {
594     CHECK_NULL_VOID(frameNode);
595     offset -= GetCurrentWindowOffset(frameNode->GetContextRefPtr());
596     UpdateNodePositionToWindow(frameNode, offset);
597 }
598 
UpdateNodePositionToWindow(const RefPtr<FrameNode> & frameNode,OffsetF offset)599 void DragDropFuncWrapper::UpdateNodePositionToWindow(const RefPtr<FrameNode>& frameNode, OffsetF offset)
600 {
601     CHECK_NULL_VOID(frameNode);
602     auto renderContext = frameNode->GetRenderContext();
603     CHECK_NULL_VOID(renderContext);
604     RefPtr<FrameNode> parentNode = frameNode->GetAncestorNodeOfFrame(true);
605     if (parentNode) {
606         offset -= parentNode->GetPositionToWindowWithTransform();
607     }
608     renderContext->UpdatePosition(OffsetT<Dimension>(Dimension(offset.GetX()), Dimension(offset.GetY())));
609 }
610 
UpdatePositionFromFrameNode(const RefPtr<FrameNode> & targetNode,const RefPtr<FrameNode> & frameNode,float width,float height)611 void DragDropFuncWrapper::UpdatePositionFromFrameNode(const RefPtr<FrameNode>& targetNode,
612     const RefPtr<FrameNode>& frameNode, float width, float height)
613 {
614     CHECK_NULL_VOID(targetNode);
615     CHECK_NULL_VOID(frameNode);
616     auto paintRectCenter = GetPaintRectCenterToScreen(frameNode);
617     auto offset = paintRectCenter - OffsetF(width / 2.0f, height / 2.0f);
618     UpdateNodePositionToScreen(targetNode, offset);
619 }
620 
621 } // namespace OHOS::Ace
622