• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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/event/drag_event.h"
17 
18 #include "base/utils/system_properties.h"
19 #include "base/utils/utils.h"
20 #include "core/common/container.h"
21 #include "core/components_ng/base/frame_node.h"
22 #include "core/components_ng/event/gesture_event_hub.h"
23 #include "core/components_ng/gestures/recognizers/long_press_recognizer.h"
24 #include "core/components_ng/gestures/recognizers/pan_recognizer.h"
25 #include "core/components_ng/gestures/recognizers/sequenced_recognizer.h"
26 #include "core/pipeline_ng/pipeline_context.h"
27 
28 #ifdef ENABLE_DRAG_FRAMEWORK
29 #include "base/msdp/device_status/interfaces/innerkits/interaction/include/interaction_manager.h"
30 #include "base/subwindow/subwindow_manager.h"
31 #include "core/animation/animation_pub.h"
32 #include "core/components/container_modal/container_modal_constants.h"
33 #include "core/components_ng/pattern/image/image_layout_property.h"
34 #include "core/components_ng/pattern/image/image_pattern.h"
35 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
36 #include "core/components_ng/pattern/text/text_base.h"
37 #include "core/components_ng/pattern/text_drag/text_drag_base.h"
38 #include "core/components_ng/pattern/text_drag/text_drag_pattern.h"
39 #include "core/components_ng/render/adapter/rosen_render_context.h"
40 #include "core/components_ng/render/render_context.h"
41 #include "core/components_v2/inspector/inspector_constants.h"
42 #endif // ENABLE_DRAG_FRAMEWORK
43 
44 #ifdef WEB_SUPPORTED
45 #include "core/components_ng/pattern/web/web_pattern.h"
46 #endif // WEB_SUPPORTED
47 
48 namespace OHOS::Ace::NG {
49 namespace {
50 constexpr int32_t PAN_FINGER = 1;
51 constexpr double PAN_DISTANCE = 5.0;
52 constexpr int32_t LONG_PRESS_DURATION = 500;
53 constexpr int32_t PREVIEW_LONG_PRESS_RECONGNIZER = 800;
54 #ifdef ENABLE_DRAG_FRAMEWORK
55 constexpr Dimension FILTER_VALUE(0.0f);
56 constexpr Dimension FILTER_RADIUS(100.0f);
57 constexpr float PIXELMAP_DRAG_SCALE_MULTIPLE = 1.05f;
58 constexpr int32_t PIXELMAP_ANIMATION_TIME = 800;
59 constexpr float SCALE_NUMBER = 0.95f;
60 constexpr int32_t FILTER_TIMES = 250;
61 constexpr float PIXELMAP_ANIMATION_SCALE = 1.1f;
62 constexpr int32_t PIXELMAP_ANIMATION_DURATION = 300;
63 constexpr float SPRING_RESPONSE = 0.416f;
64 constexpr float SPRING_DAMPING_FRACTION = 0.73f;
65 #endif // ENABLE_DRAG_FRAMEWORK
66 } // namespace
67 
DragEventActuator(const WeakPtr<GestureEventHub> & gestureEventHub,PanDirection direction,int32_t fingers,float distance)68 DragEventActuator::DragEventActuator(
69     const WeakPtr<GestureEventHub>& gestureEventHub, PanDirection direction, int32_t fingers, float distance)
70     : gestureEventHub_(gestureEventHub), direction_(direction), fingers_(fingers), distance_(distance)
71 {
72     if (fingers_ < PAN_FINGER) {
73         fingers_ = PAN_FINGER;
74     }
75 
76     if (LessOrEqual(distance_, PAN_DISTANCE)) {
77         distance_ = PAN_DISTANCE;
78     }
79 
80     panRecognizer_ = MakeRefPtr<PanRecognizer>(fingers_, direction_, distance_);
81     longPressRecognizer_ = AceType::MakeRefPtr<LongPressRecognizer>(LONG_PRESS_DURATION, fingers_, false, false);
82     previewLongPressRecognizer_ =
83         AceType::MakeRefPtr<LongPressRecognizer>(PREVIEW_LONG_PRESS_RECONGNIZER, fingers_, false, true);
84     isNotInPreviewState_ = false;
85 }
86 
StartDragTaskForWeb(const GestureEvent & info)87 void DragEventActuator::StartDragTaskForWeb(const GestureEvent& info)
88 {
89     auto gestureInfo = const_cast<GestureEvent&>(info);
90     if (actionStart_) {
91         actionStart_(gestureInfo);
92     }
93 }
94 
StartLongPressActionForWeb()95 void DragEventActuator::StartLongPressActionForWeb()
96 {
97     if (!isReceivedLongPress_) {
98         LOGW("not received long press action, don't start long press action for web");
99         return;
100     }
101     if (longPressUpdate_) {
102         longPressUpdate_(longPressInfo_);
103     }
104     isReceivedLongPress_ = false;
105 }
106 
CancelDragForWeb()107 void DragEventActuator::CancelDragForWeb()
108 {
109     if (actionCancel_) {
110         actionCancel_();
111     }
112 }
113 
OnCollectTouchTarget(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,const GetEventTargetImpl & getEventTargetImpl,TouchTestResult & result)114 void DragEventActuator::OnCollectTouchTarget(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
115     const GetEventTargetImpl& getEventTargetImpl, TouchTestResult& result)
116 {
117     CHECK_NULL_VOID_NOLOG(userCallback_);
118     auto actionStart = [weak = WeakClaim(this), this](GestureEvent& info) {
119         if (SystemProperties::GetDebugEnabled()) {
120             LOGI("DragEvent panRecognizer onActionStart.");
121         }
122         auto actuator = weak.Upgrade();
123         CHECK_NULL_VOID(actuator);
124 #ifdef ENABLE_DRAG_FRAMEWORK
125         auto gestureHub = actuator->gestureEventHub_.Upgrade();
126         CHECK_NULL_VOID(gestureHub);
127         auto frameNode = gestureHub->GetFrameNode();
128         CHECK_NULL_VOID(frameNode);
129         auto renderContext = frameNode->GetRenderContext();
130         if (info.GetSourceDevice() != SourceType::MOUSE) {
131             if (gestureHub->GetTextDraggable()) {
132                 auto pattern = frameNode->GetPattern<TextBase>();
133                 CHECK_NULL_VOID(pattern);
134                 frameNode->SetDraggable(isTextReceivedLongPress_);
135                 if (gestureHub->GetIsTextDraggable()) {
136                     HideTextAnimation(true, info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY());
137                 }
138             } else if (!isNotInPreviewState_) {
139                 HideEventColumn();
140                 HidePixelMap(true, info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY());
141                 HideFilter();
142                 SubwindowManager::GetInstance()->HideMenuNG();
143                 AnimationOption option;
144                 option.SetDuration(PIXELMAP_ANIMATION_DURATION);
145                 option.SetCurve(Curves::SHARP);
146                 AnimationUtils::Animate(
147                     option, [renderContext]() { renderContext->UpdateOpacity(SCALE_NUMBER); },
148                     option.GetOnFinishEvent());
149             }
150         }
151 
152         if (info.GetSourceDevice() == SourceType::MOUSE) {
153             auto pattern = frameNode->GetPattern<TextBase>();
154             if (gestureHub->GetTextDraggable() && pattern) {
155                 if (!pattern->IsSelected() || pattern->GetMouseStatus() == MouseStatus::MOVE) {
156                     frameNode->SetDraggable(false);
157                     return;
158                 }
159                 if (pattern->BetweenSelectedPosition(info.GetGlobalLocation())) {
160                     frameNode->SetDraggable(true);
161                     textDragCallback_(info.GetGlobalLocation());
162                 }
163             }
164         }
165 
166 #endif // ENABLE_DRAG_FRAMEWORK
167        // Trigger drag start event set by user.
168         CHECK_NULL_VOID(actuator->userCallback_);
169         auto userActionStart = actuator->userCallback_->GetActionStartEventFunc();
170         if (userActionStart) {
171             userActionStart(info);
172         }
173         // Trigger custom drag start event
174         CHECK_NULL_VOID(actuator->customCallback_);
175         auto customActionStart = actuator->customCallback_->GetActionStartEventFunc();
176         if (customActionStart) {
177             customActionStart(info);
178         }
179     };
180     actionStart_ = actionStart;
181     panRecognizer_->SetOnActionStart(actionStart);
182 
183 #ifdef ENABLE_DRAG_FRAMEWORK
184     if (touchRestrict.sourceType == SourceType::MOUSE) {
185         auto&& callback = [weakPtr = gestureEventHub_, weak = WeakClaim(this)]() {
186             auto gestureHub = weakPtr.Upgrade();
187             CHECK_NULL_VOID(gestureHub);
188             std::shared_ptr<Media::PixelMap> pixelMap;
189             auto frameNode = gestureHub->GetFrameNode();
190             CHECK_NULL_VOID(frameNode);
191             if (gestureHub->GetTextDraggable()) {
192                 auto pattern = frameNode->GetPattern<TextDragBase>();
193                 CHECK_NULL_VOID(pattern);
194                 auto dragNode = pattern->MoveDragNode();
195                 CHECK_NULL_VOID(dragNode);
196                 auto context = dragNode->GetRenderContext();
197                 CHECK_NULL_VOID(context);
198                 auto thumbnailPixelMap = context->GetThumbnailPixelMap();
199                 CHECK_NULL_VOID(thumbnailPixelMap);
200                 pixelMap = thumbnailPixelMap->GetPixelMapSharedPtr();
201             } else {
202                 auto context = frameNode->GetRenderContext();
203                 CHECK_NULL_VOID(context);
204                 auto thumbnailPixelMap = context->GetThumbnailPixelMap();
205                 CHECK_NULL_VOID(thumbnailPixelMap);
206                 pixelMap = thumbnailPixelMap->GetPixelMapSharedPtr();
207             }
208             CHECK_NULL_VOID(pixelMap);
209             float scale = gestureHub->GetPixelMapScale(pixelMap->GetHeight(), pixelMap->GetWidth());
210             pixelMap->scale(scale, scale);
211             auto pipeline = PipelineContext::GetCurrentContext();
212             CHECK_NULL_VOID(pipeline);
213             auto dragDropManager = pipeline->GetDragDropManager();
214             CHECK_NULL_VOID(dragDropManager);
215             if (!dragDropManager->IsDragged()) {
216                 return;
217             }
218             int32_t width = pixelMap->GetWidth();
219             int32_t height = pixelMap->GetHeight();
220             Msdp::DeviceStatus::ShadowInfo shadowInfo { pixelMap, width * PIXELMAP_WIDTH_RATE,
221                 height * PIXELMAP_HEIGHT_RATE };
222             int ret = Msdp::DeviceStatus::InteractionManager::GetInstance()->UpdateShadowPic(shadowInfo);
223             if (ret != 0) {
224                 LOGE("InteractionManager: UpdateShadowPic error");
225                 return;
226             }
227             if (SystemProperties::GetDebugEnabled()) {
228                 LOGI("In setThumbnailPixelMap callback, set DragWindowVisible true.");
229             }
230             Msdp::DeviceStatus::InteractionManager::GetInstance()->SetDragWindowVisible(true);
231             dragDropManager->SetIsDragWindowShow(true);
232         };
233         auto gestureHub = gestureEventHub_.Upgrade();
234         CHECK_NULL_VOID(gestureHub);
235         if (!gestureHub->HasThumbnailCallback()) {
236             gestureHub->SetThumbnailPixelMapCallback(callback);
237         }
238     };
239 #endif // ENABLE_DRAG_FRAMEWORK
240 
241     auto actionUpdate = [weak = WeakClaim(this)](GestureEvent& info) {
242         if (SystemProperties::GetDebugEnabled()) {
243             LOGI("DragEvent panRecognizer onActionUpdate.");
244         }
245         auto actuator = weak.Upgrade();
246         CHECK_NULL_VOID(actuator);
247         CHECK_NULL_VOID(actuator->userCallback_);
248         auto userActionUpdate = actuator->userCallback_->GetActionUpdateEventFunc();
249         if (userActionUpdate) {
250             userActionUpdate(info);
251         }
252         CHECK_NULL_VOID(actuator->customCallback_);
253         auto customActionUpdate = actuator->customCallback_->GetActionUpdateEventFunc();
254         if (customActionUpdate) {
255             customActionUpdate(info);
256         }
257     };
258     panRecognizer_->SetOnActionUpdate(actionUpdate);
259 
260     auto actionEnd = [weak = WeakClaim(this)](GestureEvent& info) {
261         if (SystemProperties::GetDebugEnabled()) {
262             LOGI("DragEvent panRecognizer onActionEnd.");
263         }
264         auto actuator = weak.Upgrade();
265         CHECK_NULL_VOID(actuator);
266         CHECK_NULL_VOID(actuator->userCallback_);
267         auto userActionEnd = actuator->userCallback_->GetActionEndEventFunc();
268         if (userActionEnd) {
269             userActionEnd(info);
270         }
271         CHECK_NULL_VOID(actuator->customCallback_);
272         auto customActionEnd = actuator->customCallback_->GetActionEndEventFunc();
273         if (customActionEnd) {
274             customActionEnd(info);
275         }
276         actuator->SetIsNotInPreviewState(false);
277     };
278     panRecognizer_->SetOnActionEnd(actionEnd);
279 #ifdef ENABLE_DRAG_FRAMEWORK
280     auto actionCancel = [weak = WeakClaim(this), this]() {
281 #else
282     auto actionCancel = [weak = WeakClaim(this)]() {
283 #endif // ENABLE_DRAG_FRAMEWORK
284         if (SystemProperties::GetDebugEnabled()) {
285             LOGI("DragEvent panRecognizer onActionCancel.");
286         }
287         auto actuator = weak.Upgrade();
288         CHECK_NULL_VOID(actuator);
289 #ifdef ENABLE_DRAG_FRAMEWORK
290         auto gestureHub = actuator->gestureEventHub_.Upgrade();
291         CHECK_NULL_VOID(gestureHub);
292         if (!GetIsBindOverlayValue(actuator)) {
293             if (gestureHub->GetTextDraggable()) {
294                 if (gestureHub->GetIsTextDraggable()) {
295                     HideTextAnimation();
296                 }
297             } else {
298                 auto frameNode = gestureHub->GetFrameNode();
299                 CHECK_NULL_VOID(frameNode);
300                 auto renderContext = frameNode->GetRenderContext();
301                 BorderRadiusProperty borderRadius;
302                 if (renderContext->GetBorderRadius().has_value()) {
303                     borderRadius.UpdateWithCheck(renderContext->GetBorderRadius().value());
304                 }
305                 borderRadius.multiValued = false;
306                 AnimationOption option;
307                 option.SetDuration(PIXELMAP_ANIMATION_DURATION);
308                 option.SetCurve(Curves::FRICTION);
309                 AnimationUtils::Animate(
310                     option,
311                     [renderContext_ = renderContext, borderRadius_ = borderRadius]() {
312                         renderContext_->UpdateBorderRadius(borderRadius_);
313                     },
314                     option.GetOnFinishEvent());
315                 HideEventColumn();
316                 HidePixelMap();
317                 HideFilter();
318             }
319         } else {
320             if (actuator->panRecognizer_->getDeviceType() == SourceType::MOUSE) {
321                 if (!gestureHub->GetTextDraggable()) {
322                     HideEventColumn();
323                     HidePixelMap();
324                     HideFilter();
325                 }
326             }
327         }
328         actuator->SetIsNotInPreviewState(false);
329 #endif // ENABLE_DRAG_FRAMEWORK
330         CHECK_NULL_VOID(actuator->userCallback_);
331         auto userActionCancel = actuator->userCallback_->GetActionCancelEventFunc();
332         if (userActionCancel) {
333             userActionCancel();
334         }
335         CHECK_NULL_VOID(actuator->customCallback_);
336         auto customActionCancel = actuator->customCallback_->GetActionCancelEventFunc();
337         if (customActionCancel) {
338             customActionCancel();
339         }
340     };
341     panRecognizer_->SetIsForDrag(true);
342     panRecognizer_->SetMouseDistance(DRAG_PAN_DISTANCE_MOUSE);
343     actionCancel_ = actionCancel;
344     panRecognizer_->SetOnActionCancel(actionCancel);
345     auto gestureHub = gestureEventHub_.Upgrade();
346     CHECK_NULL_VOID(gestureHub);
347 #ifdef ENABLE_DRAG_FRAMEWORK
348     if (touchRestrict.sourceType == SourceType::MOUSE) {
349         std::vector<RefPtr<NGGestureRecognizer>> recognizers { panRecognizer_ };
350         SequencedRecognizer_ = AceType::MakeRefPtr<SequencedRecognizer>(recognizers);
351         SequencedRecognizer_->RemainChildOnResetStatus();
352         SequencedRecognizer_->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
353         SequencedRecognizer_->SetGetEventTargetImpl(getEventTargetImpl);
354         result.emplace_back(SequencedRecognizer_);
355         return;
356     }
357     auto menuLongPress = gestureHub->GetLongPressRecognizer();
358     if (menuLongPress) {
359         menuLongPress->SetIsForDrag(true);
360     }
361     auto longPressUpdateValue = [weak = WeakClaim(this)](GestureEvent& info) {
362         if (SystemProperties::GetDebugEnabled()) {
363             LOGI("DragEvent longPressRecognizer onActionUpdate.");
364         }
365         auto actuator = weak.Upgrade();
366         CHECK_NULL_VOID(actuator);
367         actuator->SetIsNotInPreviewState(true);
368     };
369     longPressRecognizer_->SetOnActionUpdate(longPressUpdateValue);
370     auto longPressUpdate = [weak = WeakClaim(this)](GestureEvent& info) {
371         if (SystemProperties::GetDebugEnabled()) {
372             LOGI("DragEvent previewLongPressRecognizer onActionUpdate.");
373         }
374         auto actuator = weak.Upgrade();
375         CHECK_NULL_VOID(actuator);
376         auto gestureHub = actuator->gestureEventHub_.Upgrade();
377         CHECK_NULL_VOID(gestureHub);
378         if (gestureHub->GetTextDraggable()) {
379             actuator->SetIsNotInPreviewState(false);
380             if (gestureHub->GetIsTextDraggable()) {
381                 actuator->SetTextAnimation(gestureHub, info.GetGlobalLocation());
382             }
383             return;
384         }
385 
386         bool isAllowedDrag = actuator->IsAllowedDrag();
387         if (!isAllowedDrag) {
388             actuator->longPressInfo_ = info;
389             actuator->isReceivedLongPress_ = true;
390             return;
391         }
392 
393         actuator->SetFilter(actuator);
394         auto pipeline = PipelineContext::GetCurrentContext();
395         CHECK_NULL_VOID(pipeline);
396         auto manager = pipeline->GetOverlayManager();
397         CHECK_NULL_VOID(manager);
398         actuator->SetIsNotInPreviewState(false);
399         actuator->SetPixelMap(actuator);
400         auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(SPRING_RESPONSE, SPRING_DAMPING_FRACTION, 0);
401         auto column = manager->GetPixelMapNode();
402         CHECK_NULL_VOID(column);
403 
404         auto imageNode = AceType::DynamicCast<FrameNode>(column->GetFirstChild());
405         CHECK_NULL_VOID(imageNode);
406         auto imageContext = imageNode->GetRenderContext();
407         CHECK_NULL_VOID(imageContext);
408         AnimationOption option;
409         option.SetDuration(PIXELMAP_ANIMATION_TIME);
410         option.SetCurve(motion);
411         AnimationUtils::Animate(
412             option,
413             [imageContext]() {
414                 imageContext->UpdateTransformScale({ PIXELMAP_DRAG_SCALE_MULTIPLE, PIXELMAP_DRAG_SCALE_MULTIPLE });
415             },
416             option.GetOnFinishEvent());
417         actuator->SetEventColumn(actuator);
418     };
419     longPressUpdate_ = longPressUpdate;
420     previewLongPressRecognizer_->SetOnAction(longPressUpdate);
421 #endif // ENABLE_DRAG_FRAMEWORK
422     previewLongPressRecognizer_->SetGestureHub(gestureEventHub_);
423     auto frameNode = gestureHub->GetFrameNode();
424     CHECK_NULL_VOID(frameNode);
425     auto eventHub = frameNode->GetEventHub<EventHub>();
426     CHECK_NULL_VOID(eventHub);
427     bool isAllowedDrag = gestureHub->IsAllowedDrag(eventHub);
428     if (!longPressRecognizer_->HasThumbnailCallback() && isAllowedDrag) {
429         auto callback = [weakPtr = gestureEventHub_](Offset point) {
430             auto gestureHub = weakPtr.Upgrade();
431             CHECK_NULL_VOID(gestureHub);
432             auto frameNode = gestureHub->GetFrameNode();
433             CHECK_NULL_VOID(frameNode);
434             auto context = frameNode->GetRenderContext();
435             CHECK_NULL_VOID(context);
436             auto pixelMap = context->GetThumbnailPixelMap();
437             gestureHub->SetPixelMap(pixelMap);
438         };
439         longPressRecognizer_->SetThumbnailCallback(std::move(callback));
440     }
441     std::vector<RefPtr<NGGestureRecognizer>> recognizers { longPressRecognizer_, panRecognizer_ };
442     SequencedRecognizer_ = AceType::MakeRefPtr<SequencedRecognizer>(recognizers);
443     SequencedRecognizer_->RemainChildOnResetStatus();
444     SequencedRecognizer_->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
445     SequencedRecognizer_->SetGetEventTargetImpl(getEventTargetImpl);
446     result.emplace_back(SequencedRecognizer_);
447     result.emplace_back(previewLongPressRecognizer_);
448 }
449 
450 #ifdef ENABLE_DRAG_FRAMEWORK
451 void DragEventActuator::SetFilter(const RefPtr<DragEventActuator>& actuator)
452 {
453     if (SystemProperties::GetDebugEnabled()) {
454         LOGI("DragEvent start setFilter.");
455     }
456     auto gestureHub = actuator->gestureEventHub_.Upgrade();
457     CHECK_NULL_VOID(gestureHub);
458     auto frameNode = gestureHub->GetFrameNode();
459     CHECK_NULL_VOID(frameNode);
460     auto parent = frameNode->GetParent();
461     CHECK_NULL_VOID(parent);
462     while (parent->GetDepth() != 1) {
463         parent = parent->GetParent();
464     }
465     auto pipelineContext = PipelineContext::GetCurrentContext();
466     CHECK_NULL_VOID(pipelineContext);
467     auto manager = pipelineContext->GetOverlayManager();
468     CHECK_NULL_VOID(manager);
469     if (!manager->GetHasFilter() && !manager->GetIsOnAnimation()) {
470         if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
471 #ifdef WEB_SUPPORTED
472             auto webPattern = frameNode->GetPattern<WebPattern>();
473             CHECK_NULL_VOID(webPattern);
474             bool isWebmageDrag = webPattern->IsImageDrag();
475             CHECK_NULL_VOID(isWebmageDrag && SystemProperties::GetDeviceType() == DeviceType::PHONE);
476 #endif
477         } else {
478             bool isBindOverlayValue = frameNode->GetLayoutProperty()->GetIsBindOverlayValue(false);
479             CHECK_NULL_VOID_NOLOG(isBindOverlayValue && SystemProperties::GetDeviceType() == DeviceType::PHONE);
480         }
481         // insert columnNode to rootNode
482         auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
483             AceType::MakeRefPtr<LinearLayoutPattern>(true));
484         columnNode->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
485         // set filter
486         LOGI("User Device use default Filter");
487         auto container = Container::Current();
488         if (container && container->IsScenceBoardWindow()) {
489             auto windowScene = manager->FindWindowScene(frameNode);
490             manager->MountFilterToWindowScene(columnNode, windowScene);
491         } else {
492             columnNode->MountToParent(parent);
493             columnNode->OnMountToParentDone();
494             manager->SetHasFilter(true);
495             manager->SetFilterColumnNode(columnNode);
496             parent->MarkDirtyNode(NG::PROPERTY_UPDATE_BY_CHILD_REQUEST);
497         }
498         AnimationOption option;
499         option.SetDuration(FILTER_TIMES);
500         option.SetCurve(Curves::SHARP);
501         columnNode->GetRenderContext()->UpdateBackBlurRadius(FILTER_VALUE);
502         AnimationUtils::Animate(
503             option, [columnNode]() { columnNode->GetRenderContext()->UpdateBackBlurRadius(FILTER_RADIUS); },
504             option.GetOnFinishEvent());
505     }
506     if (SystemProperties::GetDebugEnabled()) {
507         LOGI("DragEvent set filter success.");
508     }
509 }
510 
511 OffsetF DragEventActuator::GetFloatImageOffset(const RefPtr<FrameNode>& frameNode)
512 {
513     auto offsetToWindow = frameNode->GetPaintRectOffset();
514     auto offsetX = offsetToWindow.GetX();
515     auto offsetY = offsetToWindow.GetY();
516 #ifdef WEB_SUPPORTED
517     if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
518         auto webPattern = frameNode->GetPattern<WebPattern>();
519         if (webPattern) {
520             offsetX += webPattern->GetDragOffset().GetX();
521             offsetY += webPattern->GetDragOffset().GetY();
522         }
523     }
524 #endif
525     return OffsetF(offsetX, offsetY);
526 }
527 
528 void DragEventActuator::SetPixelMap(const RefPtr<DragEventActuator>& actuator)
529 {
530     if (SystemProperties::GetDebugEnabled()) {
531         LOGI("DragEvent start set pixelMap");
532     }
533     auto pipelineContext = PipelineContext::GetCurrentContext();
534     CHECK_NULL_VOID(pipelineContext);
535     auto manager = pipelineContext->GetOverlayManager();
536     CHECK_NULL_VOID(manager);
537     if (manager->GetHasPixelMap()) {
538         if (SystemProperties::GetDebugEnabled()) {
539             LOGW("DragDropManager don't have pixelMap, set pixelMap fail.");
540         }
541         return;
542     }
543     auto gestureHub = actuator->gestureEventHub_.Upgrade();
544     CHECK_NULL_VOID(gestureHub);
545     auto frameNode = gestureHub->GetFrameNode();
546     CHECK_NULL_VOID(frameNode);
547     RefPtr<PixelMap> pixelMap = gestureHub->GetPixelMap();
548     CHECK_NULL_VOID(pixelMap);
549     auto width = pixelMap->GetWidth();
550     auto height = pixelMap->GetHeight();
551     auto offsetX = GetFloatImageOffset(frameNode).GetX();
552     auto offsetY = GetFloatImageOffset(frameNode).GetY();
553     // Check web tag.
554     if (pipelineContext->HasFloatTitle()) {
555         offsetX -= static_cast<float>((CONTAINER_BORDER_WIDTH + CONTENT_PADDING).ConvertToPx());
556         offsetY -= static_cast<float>((CONTAINER_TITLE_HEIGHT + CONTAINER_BORDER_WIDTH).ConvertToPx());
557     }
558     // create imageNode
559     auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
560         []() { return AceType::MakeRefPtr<ImagePattern>(); });
561     auto props = imageNode->GetLayoutProperty<ImageLayoutProperty>();
562     props->UpdateImageSourceInfo(ImageSourceInfo(pixelMap));
563     auto targetSize = CalcSize(NG::CalcLength(width), NG::CalcLength(height));
564     props->UpdateUserDefinedIdealSize(targetSize);
565     auto imageContext = imageNode->GetRenderContext();
566     CHECK_NULL_VOID(imageContext);
567     imageContext->UpdatePosition(OffsetT<Dimension>(Dimension(offsetX), Dimension(offsetY)));
568     ClickEffectInfo clickEffectInfo;
569     clickEffectInfo.level = ClickEffectLevel::LIGHT;
570     clickEffectInfo.scaleNumber = SCALE_NUMBER;
571     imageContext->UpdateClickEffectLevel(clickEffectInfo);
572     // create columnNode
573     auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
574         AceType::MakeRefPtr<LinearLayoutPattern>(true));
575     columnNode->AddChild(imageNode);
576     auto hub = columnNode->GetOrCreateGestureEventHub();
577     CHECK_NULL_VOID(hub);
578     hub->SetPixelMap(gestureHub->GetPixelMap());
579     // mount to rootNode
580     auto container = Container::Current();
581     if (container && container->IsScenceBoardWindow()) {
582         auto windowScene = manager->FindWindowScene(frameNode);
583         manager->MountPixelMapToWindowScene(columnNode, windowScene);
584     } else {
585         manager->MountPixelMapToRootNode(columnNode);
586     }
587     imageNode->MarkModifyDone();
588     ShowPixelMapAnimation(imageNode);
589     if (SystemProperties::GetDebugEnabled()) {
590         LOGI("DragEvent set pixelMap success.");
591     }
592 }
593 
594 void DragEventActuator::SetEventColumn(const RefPtr<DragEventActuator>& actuator)
595 {
596     if (SystemProperties::GetDebugEnabled()) {
597         LOGI("DragEvent start set eventColumn.");
598     }
599     auto pipelineContext = PipelineContext::GetCurrentContext();
600     CHECK_NULL_VOID(pipelineContext);
601     auto manager = pipelineContext->GetOverlayManager();
602     CHECK_NULL_VOID(manager);
603     if (manager->GetHasEvent()) {
604         if (SystemProperties::GetDebugEnabled()) {
605             LOGW("DragDropManager don't have event, set event column fail.");
606         }
607         return;
608     }
609     auto rootNode = pipelineContext->GetRootElement();
610     CHECK_NULL_VOID(rootNode);
611     auto geometryNode = rootNode->GetGeometryNode();
612     CHECK_NULL_VOID(geometryNode);
613     auto width = geometryNode->GetFrameSize().Width();
614     auto height = geometryNode->GetFrameSize().Height();
615     // create columnNode
616     auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
617         AceType::MakeRefPtr<LinearLayoutPattern>(true));
618     auto props = columnNode->GetLayoutProperty<LinearLayoutProperty>();
619     auto targetSize = CalcSize(NG::CalcLength(width), NG::CalcLength(height));
620     props->UpdateUserDefinedIdealSize(targetSize);
621     BindClickEvent(columnNode);
622     columnNode->MarkModifyDone();
623     auto container = Container::Current();
624     if (container && container->IsScenceBoardWindow()) {
625         auto gestureHub = actuator->gestureEventHub_.Upgrade();
626         CHECK_NULL_VOID(gestureHub);
627         auto frameNode = gestureHub->GetFrameNode();
628         CHECK_NULL_VOID(frameNode);
629         auto windowScene = manager->FindWindowScene(frameNode);
630         manager->MountEventToWindowScene(columnNode, windowScene);
631     } else {
632         manager->MountEventToRootNode(columnNode);
633     }
634     if (SystemProperties::GetDebugEnabled()) {
635         LOGI("DragEvent set eventColumn success.");
636     }
637 }
638 
639 void DragEventActuator::HideFilter()
640 {
641     auto pipelineContext = PipelineContext::GetCurrentContext();
642     CHECK_NULL_VOID(pipelineContext);
643     auto manager = pipelineContext->GetOverlayManager();
644     CHECK_NULL_VOID(manager);
645     manager->RemoveFilter();
646 }
647 
648 void DragEventActuator::HidePixelMap(bool startDrag, double x, double y)
649 {
650     auto pipelineContext = PipelineContext::GetCurrentContext();
651     CHECK_NULL_VOID(pipelineContext);
652     auto manager = pipelineContext->GetOverlayManager();
653     CHECK_NULL_VOID(manager);
654     manager->RemovePixelMapAnimation(startDrag, x, y);
655 }
656 
657 void DragEventActuator::HideEventColumn()
658 {
659     auto pipelineContext = PipelineContext::GetCurrentContext();
660     CHECK_NULL_VOID(pipelineContext);
661     auto manager = pipelineContext->GetOverlayManager();
662     CHECK_NULL_VOID(manager);
663     manager->RemoveEventColumn();
664 }
665 
666 void DragEventActuator::BindClickEvent(const RefPtr<FrameNode>& columnNode)
667 {
668     auto callback = [this, weak = WeakClaim(this)](GestureEvent& /* info */) {
669         HideEventColumn();
670         HidePixelMap();
671         HideFilter();
672     };
673     auto columnGestureHub = columnNode->GetOrCreateGestureEventHub();
674     CHECK_NULL_VOID(columnGestureHub);
675     auto clickListener = MakeRefPtr<ClickEvent>(std::move(callback));
676     columnGestureHub->AddClickEvent(clickListener);
677 }
678 
679 void DragEventActuator::ShowPixelMapAnimation(const RefPtr<FrameNode>& imageNode)
680 {
681     auto imageContext = imageNode->GetRenderContext();
682     CHECK_NULL_VOID(imageContext);
683     // pixel map animation
684     AnimationOption option;
685     option.SetDuration(PIXELMAP_ANIMATION_DURATION);
686     option.SetCurve(Curves::SHARP);
687     imageContext->UpdateTransformScale({ 1, 1 });
688     auto shadow = imageContext->GetBackShadow();
689     if (!shadow.has_value()) {
690         shadow = Shadow::CreateShadow(ShadowStyle::None);
691     }
692     imageContext->UpdateBackShadow(shadow.value());
693 
694     AnimationUtils::Animate(
695         option,
696         [imageContext, shadow]() mutable {
697             auto color = shadow->GetColor();
698             auto newColor = Color::FromARGB(100, color.GetRed(), color.GetGreen(), color.GetBlue());
699             shadow->SetColor(newColor);
700             imageContext->UpdateBackShadow(shadow.value());
701             imageContext->UpdateTransformScale({ PIXELMAP_ANIMATION_SCALE, PIXELMAP_ANIMATION_SCALE });
702         },
703         option.GetOnFinishEvent());
704 }
705 
706 void DragEventActuator::SetThumbnailCallback(std::function<void(Offset)>&& callback)
707 {
708     textDragCallback_ = callback;
709     longPressRecognizer_->SetThumbnailCallback(std::move(callback));
710 }
711 
712 void DragEventActuator::GetTextPixelMap(bool startDrag)
713 {
714     if (SystemProperties::GetDebugEnabled()) {
715         LOGI("DragEvent start getTextPixelMap.");
716     }
717     auto gestureHub = gestureEventHub_.Upgrade();
718     CHECK_NULL_VOID(gestureHub);
719     bool isAllowedDrag = IsAllowedDrag();
720     if (!gestureHub->GetTextDraggable() || !isAllowedDrag) {
721         if (SystemProperties::GetDebugEnabled()) {
722             LOGW("Text is not draggable, stop get text pixelMap.");
723         }
724         return;
725     }
726     auto frameNode = gestureHub->GetFrameNode();
727     CHECK_NULL_VOID(frameNode);
728     auto pattern = frameNode->GetPattern<TextDragBase>();
729     CHECK_NULL_VOID(pattern);
730     auto pixelMap = gestureHub->GetPixelMap();
731     CHECK_NULL_VOID(pixelMap);
732     auto pipeline = PipelineContext::GetCurrentContext();
733     CHECK_NULL_VOID(pipeline);
734     auto manager = pipeline->GetOverlayManager();
735     CHECK_NULL_VOID(manager);
736     manager->RemovePixelMap();
737     if (!startDrag) {
738         CHECK_NULL_VOID(pattern);
739         pattern->CreateHandles();
740     }
741     auto dragDropManager = pipeline->GetDragDropManager();
742     CHECK_NULL_VOID(dragDropManager);
743     if (!dragDropManager->IsDragged()) {
744         if (SystemProperties::GetDebugEnabled()) {
745             LOGW("DragDropManger is not dragged, stop get text pixelMap.");
746         }
747         return;
748     }
749     std::shared_ptr<Media::PixelMap> mediaPixelMap = pixelMap->GetPixelMapSharedPtr();
750     float scale = gestureHub->GetPixelMapScale(mediaPixelMap->GetHeight(), mediaPixelMap->GetWidth());
751     mediaPixelMap->scale(scale, scale);
752     int32_t width = mediaPixelMap->GetWidth();
753     int32_t height = mediaPixelMap->GetHeight();
754     Msdp::DeviceStatus::ShadowInfo shadowInfo { mediaPixelMap, width * PIXELMAP_WIDTH_RATE,
755         height * PIXELMAP_HEIGHT_RATE };
756     int ret = Msdp::DeviceStatus::InteractionManager::GetInstance()->UpdateShadowPic(shadowInfo);
757     if (ret != 0) {
758         LOGE("InteractionManager: UpdateShadowPic error");
759         return;
760     }
761     if (SystemProperties::GetDebugEnabled()) {
762         LOGI("In function getTextPixelMap, set DragWindowVisible true.");
763     }
764     Msdp::DeviceStatus::InteractionManager::GetInstance()->SetDragWindowVisible(true);
765     dragDropManager->SetIsDragWindowShow(true);
766     gestureHub->SetPixelMap(nullptr);
767 }
768 
769 void DragEventActuator::SetTextAnimation(const RefPtr<GestureEventHub>& gestureHub, const Offset& globalLocation)
770 {
771     if (SystemProperties::GetDebugEnabled()) {
772         LOGI("DragEvent start set textAnimation.");
773     }
774     auto pipelineContext = PipelineContext::GetCurrentContext();
775     CHECK_NULL_VOID(pipelineContext);
776     auto manager = pipelineContext->GetOverlayManager();
777     CHECK_NULL_VOID(manager);
778     manager->SetHasFilter(false);
779     CHECK_NULL_VOID(gestureHub);
780     auto frameNode = gestureHub->GetFrameNode();
781     CHECK_NULL_VOID(frameNode);
782     auto pattern = frameNode->GetPattern<TextDragBase>();
783     auto textBase = frameNode->GetPattern<TextBase>();
784     CHECK_NULL_VOID(pattern);
785     CHECK_NULL_VOID(textBase);
786     if (!textBase->BetweenSelectedPosition(globalLocation)) {
787         if (SystemProperties::GetDebugEnabled()) {
788             LOGW("Position is between selected position, stop set text animation.");
789         }
790         return;
791     }
792     pattern->CloseSelectOverlay();
793     pattern->CloseKeyboard(true);
794     auto dragNode = pattern->MoveDragNode();
795     CHECK_NULL_VOID(dragNode);
796     auto pixelMap = dragNode->GetRenderContext()->GetThumbnailPixelMap();
797     CHECK_NULL_VOID(pixelMap);
798     gestureHub->SetPixelMap(pixelMap);
799     // create columnNode
800     auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
801         AceType::MakeRefPtr<LinearLayoutPattern>(true));
802     columnNode->AddChild(dragNode);
803     // mount to rootNode
804     manager->MountPixelMapToRootNode(columnNode);
805     auto modifier = dragNode->GetPattern<TextDragPattern>()->GetOverlayModifier();
806     modifier->StartAnimate();
807     isTextReceivedLongPress_ = true;
808     if (SystemProperties::GetDebugEnabled()) {
809         LOGI("DragEvent set text animation success.");
810     }
811 }
812 
813 void DragEventActuator::HideTextAnimation(bool startDrag, double globalX, double globalY)
814 {
815     if (SystemProperties::GetDebugEnabled()) {
816         LOGI("DragEvent start hide text animation.");
817     }
818     auto gestureHub = gestureEventHub_.Upgrade();
819     CHECK_NULL_VOID(gestureHub);
820     bool isAllowedDrag = IsAllowedDrag();
821     if (!gestureHub->GetTextDraggable() || !isAllowedDrag) {
822         if (SystemProperties::GetDebugEnabled()) {
823             LOGW("Text is not draggable, stop set hide text animation.");
824         }
825         return;
826     }
827     auto frameNode = gestureHub->GetFrameNode();
828     CHECK_NULL_VOID(frameNode);
829     auto pattern = frameNode->GetPattern<TextDragBase>();
830     CHECK_NULL_VOID(pattern);
831     auto pixelMap = gestureHub->GetPixelMap();
832     CHECK_NULL_VOID(pixelMap);
833     auto removeColumnNode = [id = Container::CurrentId(), startDrag, weakPattern = WeakPtr<TextDragBase>(pattern),
834                                 weakEvent = gestureEventHub_] {
835         ContainerScope scope(id);
836         auto pipeline = PipelineContext::GetCurrentContext();
837         CHECK_NULL_VOID(pipeline);
838         auto manager = pipeline->GetOverlayManager();
839         CHECK_NULL_VOID(manager);
840         manager->RemovePixelMap();
841         if (!startDrag) {
842             auto pattern = weakPattern.Upgrade();
843             CHECK_NULL_VOID(pattern);
844             pattern->CreateHandles();
845         }
846         if (SystemProperties::GetDebugEnabled()) {
847             LOGI("In removeColumnNode callback, set DragWindowVisible true.");
848         }
849         Msdp::DeviceStatus::InteractionManager::GetInstance()->SetDragWindowVisible(true);
850         auto gestureHub = weakEvent.Upgrade();
851         CHECK_NULL_VOID(gestureHub);
852         gestureHub->SetPixelMap(nullptr);
853     };
854     AnimationOption option;
855     option.SetDuration(PIXELMAP_ANIMATION_DURATION);
856     option.SetCurve(Curves::SHARP);
857     option.SetOnFinishEvent(removeColumnNode);
858 
859     auto pipeline = PipelineContext::GetCurrentContext();
860     CHECK_NULL_VOID(pipeline);
861     auto manager = pipeline->GetOverlayManager();
862     auto dragNode = manager->GetPixelMapNode();
863     CHECK_NULL_VOID(dragNode);
864     auto dragFrame = dragNode->GetGeometryNode()->GetFrameRect();
865     auto frameWidth = dragFrame.Width();
866     auto frameHeight = dragFrame.Height();
867     float scale = gestureHub->GetPixelMapScale(pixelMap->GetHeight(), pixelMap->GetWidth());
868     auto context = dragNode->GetRenderContext();
869     CHECK_NULL_VOID(context);
870     context->UpdateTransformScale(VectorF(1.0f, 1.0f));
871     AnimationUtils::Animate(
872         option,
873         [context, startDrag, globalX, globalY, frameWidth, frameHeight, scale]() {
874             if (startDrag) {
875                 context->UpdatePosition(OffsetT<Dimension>(Dimension(globalX + frameWidth * PIXELMAP_WIDTH_RATE),
876                     Dimension(globalY + frameHeight * PIXELMAP_HEIGHT_RATE)));
877                 context->UpdateTransformScale(VectorF(scale, scale));
878                 context->OnModifyDone();
879             }
880         },
881         option.GetOnFinishEvent());
882     if (SystemProperties::GetDebugEnabled()) {
883         LOGI("DragEvent set hide text animation success.");
884     }
885 }
886 bool DragEventActuator::GetIsBindOverlayValue(const RefPtr<DragEventActuator>& actuator)
887 {
888     auto gestureHub = actuator->gestureEventHub_.Upgrade();
889     CHECK_NULL_RETURN(gestureHub, true);
890     auto frameNode = gestureHub->GetFrameNode();
891     CHECK_NULL_RETURN(frameNode, true);
892     bool isBindOverlayValue = frameNode->GetLayoutProperty()->GetIsBindOverlayValue(false);
893     return isBindOverlayValue;
894 }
895 
896 bool DragEventActuator::IsAllowedDrag()
897 {
898     auto gestureHub = gestureEventHub_.Upgrade();
899     CHECK_NULL_RETURN(gestureHub, false);
900     auto frameNode = gestureHub->GetFrameNode();
901     CHECK_NULL_RETURN(frameNode, false);
902     auto eventHub = frameNode->GetEventHub<EventHub>();
903     CHECK_NULL_RETURN(eventHub, false);
904     bool isAllowedDrag = gestureHub->IsAllowedDrag(eventHub);
905     return isAllowedDrag;
906 }
907 #endif // ENABLE_DRAG_FRAMEWORK
908 } // namespace OHOS::Ace::NG
909