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     int32_t sourceTool = -1;
126     bool getPointSuccess = container->GetCurPointerEventInfo(dragAction->pointer, dragAction->x, dragAction->y,
127         dragAction->sourceType, sourceTool, std::move(stopDragCallback));
128     if (dragAction->sourceType == SOURCE_TYPE_MOUSE) {
129         dragAction->pointer = MOUSE_POINTER_ID;
130     } else if (dragAction->sourceType == SOURCE_TYPE_TOUCH && sourceTool == SOURCE_TOOL_PEN) {
131         dragAction->pointer = 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     auto displayInfo = container->GetDisplayInfo();
142     CHECK_NULL_VOID(displayInfo);
143     dragAction->displayId = static_cast<int32_t>(displayInfo->GetDisplayId());
144 
145     std::vector<ShadowInfoCore> shadowInfos;
146     GetShadowInfoArray(dragAction, shadowInfos);
147     if (shadowInfos.empty()) {
148         TAG_LOGE(AceLogTag::ACE_DRAG, "shadowInfo array is empty");
149         return;
150     }
151     auto pointerId = dragAction->pointer;
152     std::string udKey;
153     std::map<std::string, int64_t> summary;
154     int32_t dataSize = 1;
155     if (dragAction->unifiedData) {
156         int32_t ret = UdmfClient::GetInstance()->SetData(dragAction->unifiedData, udKey);
157         if (ret != 0) {
158             TAG_LOGI(AceLogTag::ACE_DRAG, "udmf set data failed, return value is %{public}d", ret);
159         } else {
160             ret = UdmfClient::GetInstance()->GetSummary(udKey, summary);
161             if (ret != 0) {
162                 TAG_LOGI(AceLogTag::ACE_DRAG, "get summary failed, return value is %{public}d", ret);
163             }
164         }
165         dataSize = static_cast<int32_t>(dragAction->unifiedData->GetSize());
166     }
167     int32_t recordSize = (dataSize != 0 ? dataSize : static_cast<int32_t>(shadowInfos.size()));
168     if (dragAction->previewOption.isNumber) {
169         recordSize = dragAction->previewOption.badgeNumber > 1 ? dragAction->previewOption.badgeNumber : 1;
170     } else if (!dragAction->previewOption.isShowBadge) {
171         recordSize = 1;
172     }
173     auto windowId = container->GetWindowId();
174     auto arkExtraInfoJson = JsonUtil::Create(true);
175     auto pipeline = container->GetPipelineContext();
176     CHECK_NULL_VOID(pipeline);
177     dragAction->dipScale = pipeline->GetDipScale();
178     arkExtraInfoJson->Put("dip_scale", dragAction->dipScale);
179     NG::DragDropFuncWrapper::UpdateExtraInfo(arkExtraInfoJson, dragAction->previewOption);
180     dragData = { shadowInfos, {}, udKey, dragAction->extraParams, arkExtraInfoJson->ToString(), dragAction->sourceType,
181         recordSize, pointerId, dragAction->x, dragAction->y, dragAction->displayId, windowId, true, false, 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(dragAction->pointer, dragAction->instanceId);
264     int32_t ret = InteractionInterface::GetInstance()->StartDrag(dragData.value(), callback);
265     if (ret != 0) {
266         manager->GetDragAction()->dragState = DragAdapterState::INIT;
267         return -1;
268     }
269     HandleCallback(dragAction, DragNotifyMsg {}, DragAdapterStatus::STARTED);
270     pipelineContext->SetIsDragging(true);
271     std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
272     if (dragAction->dragState == DragAdapterState::SENDING) {
273         dragAction->dragState = DragAdapterState::SUCCESS;
274         InteractionInterface::GetInstance()->SetDragWindowVisible(true);
275         auto pipelineContext = container->GetPipelineContext();
276         pipelineContext->OnDragEvent(
277             { dragAction->x, dragAction->y }, DragEventAction::DRAG_EVENT_START_FOR_CONTROLLER);
278         NG::DragDropFuncWrapper::DecideWhetherToStopDragging(
279             { dragAction->x, dragAction->y }, dragAction->extraParams, dragAction->pointer, dragAction->instanceId);
280     }
281     return 0;
282 }
283 
SetDraggingPointerAndPressedState(int32_t currentPointerId,int32_t containerId)284 void DragDropFuncWrapper::SetDraggingPointerAndPressedState(int32_t currentPointerId, int32_t containerId)
285 {
286     auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
287     CHECK_NULL_VOID(pipelineContext);
288     auto manager = pipelineContext->GetDragDropManager();
289     CHECK_NULL_VOID(manager);
290     manager->SetDraggingPointer(currentPointerId);
291     manager->SetDraggingPressedState(true);
292 }
293 
DecideWhetherToStopDragging(const PointerEvent & pointerEvent,const std::string & extraParams,int32_t currentPointerId,int32_t containerId)294 void DragDropFuncWrapper::DecideWhetherToStopDragging(
295     const PointerEvent& pointerEvent, const std::string& extraParams, int32_t currentPointerId, int32_t containerId)
296 {
297     auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
298     CHECK_NULL_VOID(pipelineContext);
299     auto manager = pipelineContext->GetDragDropManager();
300     CHECK_NULL_VOID(manager);
301     if (!manager->IsDraggingPressed(currentPointerId)) {
302         manager->OnDragEnd(pointerEvent, extraParams);
303     }
304 }
305 
UpdateDragPreviewOptionsFromModifier(std::function<void (WeakPtr<FrameNode>)> applyOnNodeSync,DragPreviewOption & option)306 void DragDropFuncWrapper::UpdateDragPreviewOptionsFromModifier(
307     std::function<void(WeakPtr<FrameNode>)> applyOnNodeSync, DragPreviewOption& option)
308 {
309     // create one temporary frame node for receiving the value from the modifier
310     auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
311         []() { return AceType::MakeRefPtr<ImagePattern>(); });
312     CHECK_NULL_VOID(imageNode);
313 
314     // execute the modifier
315     CHECK_NULL_VOID(applyOnNodeSync);
316     applyOnNodeSync(AceType::WeakClaim(AceType::RawPtr(imageNode)));
317 
318     // get values from the temporary frame node
319     auto imageContext = imageNode->GetRenderContext();
320     CHECK_NULL_VOID(imageContext);
321     auto opacity = imageContext->GetOpacity();
322     if (opacity.has_value() && (opacity.value()) <= MAX_OPACITY && (opacity.value()) >= MIN_OPACITY) {
323         option.options.opacity = opacity.value();
324     } else {
325         option.options.opacity = DEFAULT_OPACITY;
326     }
327 
328     auto shadow = imageContext->GetBackShadow();
329     if (shadow.has_value()) {
330         option.options.shadow = shadow.value();
331     }
332 
333     auto borderRadius = imageContext->GetBorderRadius();
334     if (borderRadius.has_value()) {
335         option.options.borderRadius = borderRadius;
336     }
337 
338     auto bgEffect = imageContext->GetBackgroundEffect();
339     if (bgEffect.has_value()) {
340         option.options.blurbgEffect.backGroundEffect = bgEffect.value();
341     } else {
342         auto blurstyletmp = imageContext->GetBackBlurStyle();
343         if (blurstyletmp.has_value()) {
344             bgEffect = BrulStyleToEffection(blurstyletmp);
345             if (bgEffect.has_value()) {
346                 option.options.blurbgEffect.backGroundEffect = bgEffect.value();
347             }
348         }
349     }
350 }
351 
UpdatePreviewOptionDefaultAttr(DragPreviewOption & option)352 void DragDropFuncWrapper::UpdatePreviewOptionDefaultAttr(DragPreviewOption& option)
353 {
354     option.options.opacity = DEFAULT_OPACITY;
355     if (option.isDefaultShadowEnabled) {
356         option.options.shadow = GetDefaultShadow();
357     } else {
358         option.options.shadow = std::nullopt;
359     }
360     if (option.isDefaultRadiusEnabled) {
361         option.options.borderRadius = GetDefaultBorderRadius();
362     } else {
363         option.options.borderRadius = std::nullopt;
364     }
365 }
366 
UpdateExtraInfo(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)367 void DragDropFuncWrapper::UpdateExtraInfo(std::unique_ptr<JsonValue>& arkExtraInfoJson,
368     DragPreviewOption& option)
369 {
370     CHECK_NULL_VOID(arkExtraInfoJson);
371     double opacity = option.options.opacity;
372     arkExtraInfoJson->Put("dip_opacity", opacity);
373     if (option.options.blurbgEffect.backGroundEffect.radius.IsValid()) {
374         option.options.blurbgEffect.ToJsonValue(arkExtraInfoJson);
375     }
376     PrepareShadowParametersForDragData(arkExtraInfoJson, option);
377     PrepareRadiusParametersForDragData(arkExtraInfoJson, option);
378 }
379 
PrepareRadiusParametersForDragData(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)380 void DragDropFuncWrapper::PrepareRadiusParametersForDragData(std::unique_ptr<JsonValue>& arkExtraInfoJson,
381     DragPreviewOption& option)
382 {
383     CHECK_NULL_VOID(arkExtraInfoJson);
384     auto borderRadius = option.options.borderRadius;
385     if (borderRadius.has_value()) {
386         if (borderRadius.value().radiusTopLeft.has_value()) {
387             arkExtraInfoJson->Put("drag_corner_radius1", borderRadius.value().radiusTopLeft.value().Value());
388         }
389         if (borderRadius.value().radiusTopRight.has_value()) {
390             arkExtraInfoJson->Put("drag_corner_radius2", borderRadius.value().radiusTopRight.value().Value());
391         }
392         if (borderRadius.value().radiusBottomRight.has_value()) {
393             arkExtraInfoJson->Put("drag_corner_radius3", borderRadius.value().radiusBottomRight.value().Value());
394         }
395         if (borderRadius.value().radiusBottomLeft.has_value()) {
396             arkExtraInfoJson->Put("drag_corner_radius4", borderRadius.value().radiusBottomLeft.value().Value());
397         }
398     }
399 }
400 
PrepareShadowParametersForDragData(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)401 void DragDropFuncWrapper::PrepareShadowParametersForDragData(std::unique_ptr<JsonValue>& arkExtraInfoJson,
402     DragPreviewOption& option)
403 {
404     CHECK_NULL_VOID(arkExtraInfoJson);
405     auto shadow = option.options.shadow;
406     if (!shadow.has_value() || !shadow->IsValid()) {
407         arkExtraInfoJson->Put("shadow_enable", false);
408         return;
409     }
410     arkExtraInfoJson->Put("drag_type", "non-text");
411     arkExtraInfoJson->Put("shadow_enable", true);
412     ParseShadowInfo(shadow.value(), arkExtraInfoJson);
413 }
414 
ParseShadowInfo(Shadow & shadow,std::unique_ptr<JsonValue> & arkExtraInfoJson)415 void DragDropFuncWrapper::ParseShadowInfo(Shadow& shadow, std::unique_ptr<JsonValue>& arkExtraInfoJson)
416 {
417     CHECK_NULL_VOID(arkExtraInfoJson);
418     arkExtraInfoJson->Put("shadow_is_filled", shadow.GetIsFilled());
419     arkExtraInfoJson->Put("drag_shadow_OffsetX", shadow.GetOffset().GetX());
420     arkExtraInfoJson->Put("drag_shadow_OffsetY", shadow.GetOffset().GetY());
421     arkExtraInfoJson->Put("shadow_mask", shadow.GetShadowType() == ShadowType::BLUR);
422     int32_t argb = static_cast<int32_t>(shadow.GetColor().GetValue());
423     arkExtraInfoJson->Put("drag_shadow_argb", argb);
424     int32_t strategy = static_cast<int32_t>(shadow.GetShadowColorStrategy());
425     arkExtraInfoJson->Put("shadow_color_strategy", strategy);
426     arkExtraInfoJson->Put("shadow_corner", shadow.GetBlurRadius());
427     arkExtraInfoJson->Put("shadow_elevation", shadow.GetElevation());
428     arkExtraInfoJson->Put("shadow_is_hardwareacceleration", shadow.GetHardwareAcceleration());
429 }
430 
GetDefaultShadow()431 std::optional<Shadow> DragDropFuncWrapper::GetDefaultShadow()
432 {
433     auto pipelineContext = PipelineContext::GetCurrentContext();
434     CHECK_NULL_RETURN(pipelineContext, std::nullopt);
435     auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
436     CHECK_NULL_RETURN(shadowTheme, std::nullopt);
437     auto colorMode = SystemProperties::GetColorMode();
438     auto shadow = shadowTheme->GetShadow(ShadowStyle::OuterFloatingSM, colorMode);
439     shadow.SetIsFilled(true);
440     return shadow;
441 }
442 
GetDefaultBorderRadius()443 std::optional<BorderRadiusProperty> DragDropFuncWrapper::GetDefaultBorderRadius()
444 {
445     BorderRadiusProperty borderRadius;
446     borderRadius.SetRadius(PREVIEW_BORDER_RADIUS);
447     return borderRadius;
448 }
449 
RadiusToSigma(float radius)450 float DragDropFuncWrapper::RadiusToSigma(float radius)
451 {
452     return GreatNotEqual(radius, 0.0f) ? BLUR_SIGMA_SCALE * radius + SCALE_HALF : 0.0f;
453 }
454 
BrulStyleToEffection(const std::optional<BlurStyleOption> & blurStyleOp)455 std::optional<EffectOption> DragDropFuncWrapper::BrulStyleToEffection(
456     const std::optional<BlurStyleOption>& blurStyleOp)
457 {
458     auto pipeline = PipelineContext::GetCurrentContext();
459     CHECK_NULL_RETURN(pipeline, std::nullopt);
460     auto blurStyleTheme = pipeline->GetTheme<BlurStyleTheme>();
461     if (!blurStyleTheme) {
462         LOGW("cannot find theme of blurStyle, create blurStyle failed");
463         return std::nullopt;
464     }
465     ThemeColorMode colorMode = blurStyleOp->colorMode;
466     if (blurStyleOp->colorMode == ThemeColorMode::SYSTEM) {
467         colorMode = SystemProperties::GetColorMode() == ColorMode::DARK ? ThemeColorMode::DARK : ThemeColorMode::LIGHT;
468     }
469     auto blurParam = blurStyleTheme->GetBlurParameter(blurStyleOp->blurStyle, colorMode);
470     CHECK_NULL_RETURN(blurParam, std::nullopt);
471     auto ratio = blurStyleOp->scale;
472     auto maskColor = blurParam->maskColor.BlendOpacity(ratio);
473     auto radiusPx = blurParam->radius * pipeline->GetDipScale();
474     auto radiusBlur = RadiusToSigma(radiusPx) * ratio;
475     auto saturation = (blurParam->saturation - 1) * ratio + 1.0;
476     auto brightness = (blurParam->brightness - 1) * ratio + 1.0;
477     Dimension dimen(radiusBlur);
478     EffectOption bgEffection = {dimen, saturation, brightness, maskColor,
479         blurStyleOp->adaptiveColor, blurStyleOp->blurOption};
480     return std::optional<EffectOption>(bgEffection);
481 }
482 
GetScaleWidth(int32_t containerId)483 [[maybe_unused]] double DragDropFuncWrapper::GetScaleWidth(int32_t containerId)
484 {
485     auto pipeline = Container::GetContainer(containerId)->GetPipelineContext();
486     CHECK_NULL_RETURN(pipeline, -1.0f);
487     return DragDropManager::GetMaxWidthBaseOnGridSystem(pipeline);
488 }
489 
SetExtraInfo(int32_t containerId,std::string extraInfo)490 void DragDropFuncWrapper::SetExtraInfo(int32_t containerId, std::string extraInfo)
491 {
492     auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
493     CHECK_NULL_VOID(pipelineContext);
494     auto manager = pipelineContext->GetDragDropManager();
495     CHECK_NULL_VOID(manager);
496     manager->SetExtraInfo(extraInfo);
497 }
498 
499 // returns a node's offset relative to window plus half of self rect size(w, h)
500 // and accumulate every ancestor node's graphic properties such as rotate and transform
501 // ancestor will NOT check boundary of window scene
GetPaintRectCenter(const RefPtr<FrameNode> & frameNode,bool checkWindowBoundary)502 OffsetF DragDropFuncWrapper::GetPaintRectCenter(const RefPtr<FrameNode>& frameNode, bool checkWindowBoundary)
503 {
504     CHECK_NULL_RETURN(frameNode, OffsetF());
505     auto context = frameNode->GetRenderContext();
506     CHECK_NULL_RETURN(context, OffsetF());
507     auto paintRect = context->GetPaintRectWithoutTransform();
508     auto offset = paintRect.GetOffset();
509     PointF pointNode(offset.GetX() + paintRect.Width() / 2.0f, offset.GetY() + paintRect.Height() / 2.0f);
510     context->GetPointTransformRotate(pointNode);
511     auto parent = frameNode->GetAncestorNodeOfFrame();
512     while (parent) {
513         if (checkWindowBoundary && parent->IsWindowBoundary()) {
514             break;
515         }
516         auto renderContext = parent->GetRenderContext();
517         CHECK_NULL_RETURN(renderContext, OffsetF());
518         offset = renderContext->GetPaintRectWithoutTransform().GetOffset();
519         pointNode.SetX(offset.GetX() + pointNode.GetX());
520         pointNode.SetY(offset.GetY() + pointNode.GetY());
521         renderContext->GetPointTransformRotate(pointNode);
522         parent = parent->GetAncestorNodeOfFrame();
523     }
524     return OffsetF(pointNode.GetX(), pointNode.GetY());
525 }
526 
527 // check if expand subwindow
IsExpandDisplay(const RefPtr<PipelineBase> & context)528 bool DragDropFuncWrapper::IsExpandDisplay(const RefPtr<PipelineBase>& context)
529 {
530     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
531     CHECK_NULL_RETURN(pipeline, false);
532     auto theme = pipeline->GetTheme<SelectTheme>();
533     CHECK_NULL_RETURN(theme, false);
534     if (theme->GetExpandDisplay()) {
535         return true;
536     }
537     auto containerId = pipeline->GetInstanceId();
538     containerId = containerId >= MIN_SUBCONTAINER_ID ?
539         SubwindowManager::GetInstance()->GetParentContainerId(containerId) : containerId;
540     auto container = AceEngine::Get().GetContainer(containerId);
541     CHECK_NULL_RETURN(container, false);
542     return container->IsFreeMultiWindow();
543 }
544 
GetCurrentWindowOffset(const RefPtr<PipelineBase> & context)545 OffsetF DragDropFuncWrapper::GetCurrentWindowOffset(const RefPtr<PipelineBase>& context)
546 {
547     if (!IsExpandDisplay(context)) {
548         return OffsetF();
549     }
550     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
551     CHECK_NULL_RETURN(pipeline, OffsetF());
552     auto window = pipeline->GetWindow();
553     CHECK_NULL_RETURN(window, OffsetF());
554     auto windowOffset = window->GetCurrentWindowRect().GetOffset();
555     return OffsetF(windowOffset.GetX(), windowOffset.GetY());
556 }
557 
GetPaintRectCenterToScreen(const RefPtr<FrameNode> & frameNode)558 OffsetF DragDropFuncWrapper::GetPaintRectCenterToScreen(const RefPtr<FrameNode>& frameNode)
559 {
560     auto offset = GetPaintRectCenter(frameNode);
561     CHECK_NULL_RETURN(frameNode, offset);
562     offset += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
563     return offset;
564 }
565 
GetFrameNodeOffsetToScreen(const RefPtr<FrameNode> & frameNode)566 OffsetF DragDropFuncWrapper::GetFrameNodeOffsetToScreen(const RefPtr<FrameNode>& frameNode)
567 {
568     CHECK_NULL_RETURN(frameNode, OffsetF());
569     auto offset = frameNode->GetPositionToWindowWithTransform();
570     offset += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
571     return offset;
572 }
573 
GetPaintRectToScreen(const RefPtr<FrameNode> & frameNode)574 RectF DragDropFuncWrapper::GetPaintRectToScreen(const RefPtr<FrameNode>& frameNode)
575 {
576     CHECK_NULL_RETURN(frameNode, RectF());
577     RectF rect = frameNode->GetTransformRectRelativeToWindow();
578     rect += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
579     return rect;
580 }
581 
UpdateNodePositionToScreen(const RefPtr<FrameNode> & frameNode,OffsetF offset)582 void DragDropFuncWrapper::UpdateNodePositionToScreen(const RefPtr<FrameNode>& frameNode, OffsetF offset)
583 {
584     CHECK_NULL_VOID(frameNode);
585     offset -= GetCurrentWindowOffset(frameNode->GetContextRefPtr());
586     UpdateNodePositionToWindow(frameNode, offset);
587 }
588 
UpdateNodePositionToWindow(const RefPtr<FrameNode> & frameNode,OffsetF offset)589 void DragDropFuncWrapper::UpdateNodePositionToWindow(const RefPtr<FrameNode>& frameNode, OffsetF offset)
590 {
591     CHECK_NULL_VOID(frameNode);
592     auto renderContext = frameNode->GetRenderContext();
593     CHECK_NULL_VOID(renderContext);
594     RefPtr<FrameNode> parentNode = frameNode->GetAncestorNodeOfFrame(true);
595     if (parentNode) {
596         offset -= parentNode->GetPositionToWindowWithTransform();
597     }
598     renderContext->UpdatePosition(OffsetT<Dimension>(Dimension(offset.GetX()), Dimension(offset.GetY())));
599 }
600 
UpdatePositionFromFrameNode(const RefPtr<FrameNode> & targetNode,const RefPtr<FrameNode> & frameNode,float width,float height)601 void DragDropFuncWrapper::UpdatePositionFromFrameNode(const RefPtr<FrameNode>& targetNode,
602     const RefPtr<FrameNode>& frameNode, float width, float height)
603 {
604     CHECK_NULL_VOID(targetNode);
605     CHECK_NULL_VOID(frameNode);
606     auto paintRectCenter = GetPaintRectCenterToScreen(frameNode);
607     auto offset = paintRectCenter - OffsetF(width / 2.0f, height / 2.0f);
608     UpdateNodePositionToScreen(targetNode, offset);
609 }
610 
611 } // namespace OHOS::Ace
612