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