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