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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_DRAG_EVENT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_DRAG_EVENT_H
18 
19 #include <functional>
20 #include <list>
21 
22 #include "base/memory/ace_type.h"
23 #include "base/memory/referenced.h"
24 #include "core/components_ng/event/gesture_event_actuator.h"
25 #include "core/components_ng/gestures/recognizers/sequenced_recognizer.h"
26 #include "core/gestures/drag_event.h"
27 #include "core/components/common/properties/decoration.h"
28 
29 namespace OHOS::Ace::NG {
30 
31 class GestureEventHub;
32 class PanRecognizer;
33 class LongPressRecognizer;
34 class FrameNode;
35 class OverlayManager;
36 class ScrollablePattern;
37 struct GatherNodeChildInfo;
38 
39 class DragEvent : public AceType {
DECLARE_ACE_TYPE(DragEvent,AceType)40     DECLARE_ACE_TYPE(DragEvent, AceType)
41 public:
42     DragEvent(GestureEventFunc&& actionStart, GestureEventFunc&& actionUpdate, GestureEventFunc&& actionEnd,
43         GestureEventNoParameter&& actionCancel)
44         : actionStart_(std::move(actionStart)), actionUpdate_(std::move(actionUpdate)),
45           actionEnd_(std::move(actionEnd)), actionCancel_(std::move(actionCancel))
46     {}
47     ~DragEvent() override = default;
48 
GetActionStartEventFunc()49     const GestureEventFunc& GetActionStartEventFunc() const
50     {
51         return actionStart_;
52     }
53 
GetActionUpdateEventFunc()54     const GestureEventFunc& GetActionUpdateEventFunc() const
55     {
56         return actionUpdate_;
57     }
58 
GetActionEndEventFunc()59     const GestureEventFunc& GetActionEndEventFunc() const
60     {
61         return actionEnd_;
62     }
63 
GetActionCancelEventFunc()64     const GestureEventNoParameter& GetActionCancelEventFunc() const
65     {
66         return actionCancel_;
67     }
68 
GetLongPressEventFunc()69     const GestureEventFunc& GetLongPressEventFunc() const
70     {
71         return actionLongPress_;
72     }
73 
SetLongPressEventFunc(GestureEventFunc && actionLongPress)74     void SetLongPressEventFunc(GestureEventFunc&& actionLongPress)
75     {
76         actionLongPress_ = std::move(actionLongPress);
77     }
78 
GetPressedKeyCodes()79     const std::vector<KeyCode>& GetPressedKeyCodes() const
80     {
81         return pressedKeyCodes_;
82     }
83 
SetPressedKeyCodes(const std::vector<KeyCode> & pressedKeyCodes)84     void SetPressedKeyCodes(const std::vector<KeyCode>& pressedKeyCodes)
85     {
86         pressedKeyCodes_ = pressedKeyCodes;
87     }
88 
89 private:
90     GestureEventFunc actionStart_;
91     GestureEventFunc actionUpdate_;
92     GestureEventFunc actionEnd_;
93     GestureEventNoParameter actionCancel_;
94     GestureEventFunc actionLongPress_;
95     std::vector<KeyCode> pressedKeyCodes_;
96 };
97 
98 class ACE_EXPORT DragEventActuator : public GestureEventActuator {
99     DECLARE_ACE_TYPE(DragEventActuator, GestureEventActuator)
100 public:
101     DragEventActuator(
102         const WeakPtr<GestureEventHub>& gestureEventHub, PanDirection direction, int32_t fingers, float distance);
103     ~DragEventActuator() override = default;
104 
ReplaceDragEvent(const RefPtr<DragEvent> & dragEvent)105     void ReplaceDragEvent(const RefPtr<DragEvent>& dragEvent)
106     {
107         if (userCallback_) {
108             userCallback_.Reset();
109         }
110         userCallback_ = dragEvent;
111     }
112 
SetCustomDragEvent(const RefPtr<DragEvent> & dragEvent)113     void SetCustomDragEvent(const RefPtr<DragEvent>& dragEvent)
114     {
115         if (customCallback_) {
116             customCallback_.Reset();
117         }
118         customCallback_ = dragEvent;
119     }
120 
HasDragEvent()121     bool HasDragEvent() const
122     {
123         return static_cast<bool>(userCallback_);
124     }
125 
ClearDragEvent()126     void ClearDragEvent()
127     {
128         if (userCallback_) {
129             userCallback_.Reset();
130         }
131         if (customCallback_) {
132             customCallback_.Reset();
133         }
134     }
135 
136     void OnCollectTouchTarget(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
137         const GetEventTargetImpl& getEventTargetImpl, TouchTestResult& result,
138         ResponseLinkResult& responseLinkResult) override;
139     void SetThumbnailCallback(std::function<void(Offset)>&& callback);
140     void SetFilter(const RefPtr<DragEventActuator>& actuator);
141     static void UpdatePreviewPositionAndScale(
142         const RefPtr<FrameNode>& imageNode, const OffsetF& frameOffset, float scale = -1.0f);
143     static void UpdatePreviewAttr(const RefPtr<FrameNode>& frameNode, const RefPtr<FrameNode>& imageNode);
144     static void CreatePreviewNode(
145         const RefPtr<FrameNode>& frameNode, RefPtr<FrameNode>& imageNode, float dragPreviewScale);
146     static void SetPreviewDefaultAnimateProperty(const RefPtr<FrameNode>& imageNode);
147     static void MountPixelMap(const RefPtr<OverlayManager>& overlayManager, const RefPtr<GestureEventHub>& manager,
148         const RefPtr<FrameNode>& imageNode, const RefPtr<FrameNode>& textNode, bool isDragPixelMap = false);
149     static RefPtr<PixelMap> GetPreviewPixelMap(const std::string& inspectorId, const RefPtr<FrameNode>& selfFrameNode);
150     static RefPtr<PixelMap> GetPreviewPixelMapByInspectorId(const std::string& inspectorId);
151     static RefPtr<PixelMap> GetScreenShotPixelMap(const RefPtr<FrameNode>& frameNode);
152     static void ExecutePreDragAction(const PreDragStatus preDragStatus, const RefPtr<FrameNode>& frameNode = nullptr);
153     void SetPixelMap(const RefPtr<DragEventActuator>& actuator);
154     void SetEventColumn(const RefPtr<DragEventActuator>& actuator);
155     void HideFilter();
156     void HidePixelMap(bool startDrag = false, double x = 0, double y = 0, bool showAnimation = true);
157     void HideEventColumn();
158     void BindClickEvent(const RefPtr<FrameNode>& columnNode);
159     void ShowPixelMapAnimation(const RefPtr<FrameNode>& imageNode, const RefPtr<FrameNode>& frameNode,
160         bool hasContextMenu);
161     void SetTextAnimation(const RefPtr<GestureEventHub>& gestureHub, const Offset& globalLocation);
162     void HideTextAnimation(bool startDrag = false, double globalX = 0, double globalY = 0);
163     bool GetIsBindOverlayValue(const RefPtr<DragEventActuator>& actuator);
164     bool IsAllowedDrag();
165     void SetDragDampStartPointInfo(const Point& point, int32_t pointerId);
166     void HandleDragDampingMove(const Point& point, int32_t pointerId, bool isRedragStart = false);
167     void SetTextPixelMap(const RefPtr<GestureEventHub>& gestureHub);
168     void RestartDragTask(const GestureEvent& info);
169     static OffsetF GetFloatImageOffset(const RefPtr<FrameNode>& frameNode, const RefPtr<PixelMap>& pixelMap);
GetDirection()170     PanDirection GetDirection() const
171     {
172         return direction_;
173     }
174 
GetFingers()175     int32_t GetFingers() const
176     {
177         return fingers_;
178     }
179 
GetDistance()180     float GetDistance() const
181     {
182         return distance_;
183     }
184 
185     bool IsNotNeedShowPreviewForWeb(const RefPtr<FrameNode>& frameNode);
186     void StartDragTaskForWeb(const GestureEvent& info);
187     void StartLongPressActionForWeb(bool isFloatImage = true);
188     void CancelDragForWeb();
ResetDragActionForWeb()189     void ResetDragActionForWeb() {
190         if (isReceivedLongPress_) {
191             isReceivedLongPress_ = false;
192         }
193         isFloatImage_ = true;
194     }
195 
SetIsNotInPreviewState(bool isNotInPreviewState)196     void SetIsNotInPreviewState(bool isNotInPreviewState)
197     {
198         isNotInPreviewState_ = isNotInPreviewState;
199     }
200 
GetIsNotInPreviewState()201     bool GetIsNotInPreviewState() const
202     {
203         return isNotInPreviewState_;
204     }
205 
SetIsDragUserReject(bool isDragUserReject)206     void SetIsDragUserReject(bool isDragUserReject)
207     {
208         isDragUserReject_ = isDragUserReject;
209     }
210 
IsDragUserReject()211     bool IsDragUserReject() const
212     {
213         return isDragUserReject_;
214     }
215 
SetIsDefaultOnDragStartExecuted(bool defaultOnDragStartExecuted)216     void SetIsDefaultOnDragStartExecuted(bool defaultOnDragStartExecuted)
217     {
218         defaultOnDragStartExecuted_ = defaultOnDragStartExecuted;
219     }
220 
IsDefaultOnDragStartExecuted()221     bool IsDefaultOnDragStartExecuted() const
222     {
223         return defaultOnDragStartExecuted_;
224     }
225 
GetOptionsAfterApplied()226     const OptionsAfterApplied& GetOptionsAfterApplied()
227     {
228         return optionsAfterApplied_;
229     }
230 
231     void CopyDragEvent(const RefPtr<DragEventActuator>& dragEventActuator);
232 
233     void SetGatherNodeAboveFilter(const RefPtr<DragEventActuator>& actuator);
234     bool IsBelongToMultiItemNode(const RefPtr<FrameNode>& frameNode);
235     bool IsSelectedItemNode(const RefPtr<UINode>& uiNode);
236     void FindItemParentNode(const RefPtr<FrameNode>& frameNode);
237     bool IsNeedGather() const;
238     static RefPtr<FrameNode> GetOrCreateGatherNode(const RefPtr<NG::OverlayManager>& overlayManager,
239         const RefPtr<DragEventActuator>& actuator, std::vector<GatherNodeChildInfo>& gatherNodeChildrenInfo);
240     static RefPtr<FrameNode> CreateGatherNode(const RefPtr<DragEventActuator>& actuator);
241     static RefPtr<FrameNode> CreateImageNode(const RefPtr<FrameNode>& frameNode,
242         GatherNodeChildInfo& gatherNodeChildInfo);
243     static void MarkDirtyGatherNode(const RefPtr<FrameNode>& gatherNode);
244     static void ResetNode(const RefPtr<FrameNode>& frameNode);
245     static void MountGatherNode(const RefPtr<OverlayManager>& overlayManager, const RefPtr<FrameNode>& frameNode,
246         const RefPtr<FrameNode>& gatherNode, const std::vector<GatherNodeChildInfo>& gatherNodeChildrenInfo);
247     static void GetFrameNodePreviewPixelMap(const RefPtr<FrameNode>& frameNode);
248     void SetGatherNode(const RefPtr<FrameNode>& gatherNode);
249     RefPtr<FrameNode> GetGatherNode() const;
250     const std::vector<GatherNodeChildInfo>& GetGatherNodeChildrenInfo() const;
251     void ClearGatherNodeChildrenInfo();
252     void PushBackGatherNodeChild(GatherNodeChildInfo& gatherNodeChild);
253     void AddTouchListener(const TouchRestrict& touchRestrict) override;
254     void HandleTouchUpEvent();
255     void HandleTouchMoveEvent();
256     void HandleTouchCancelEvent();
257     const RefPtr<FrameNode> GetItemParentNode() const;
258     RefPtr<FrameNode> GetFrameNode();
259     static void PrepareShadowParametersForDragData(const RefPtr<FrameNode>& frameNode,
260        std::unique_ptr<JsonValue>& arkExtraInfoJson, float scale);
261     static void PrepareRadiusParametersForDragData(const RefPtr<FrameNode>& frameNode,
262         std::unique_ptr<JsonValue>& arkExtraInfoJson);
263     static void ParseShadowInfo(Shadow& shadow, std::unique_ptr<JsonValue>& arkExtraInfoJson);
264     static std::optional<Shadow> GetDefaultShadow();
265     static std::optional<BorderRadiusProperty> GetDefaultBorderRadius();
266 
267     inline static void FlushSyncGeometryNodeTasks();
268 
269     void ShowPreviewBadgeAnimation(
270         const RefPtr<DragEventActuator>& dragEventActuator, const RefPtr<OverlayManager>& manager);
271     static RefPtr<FrameNode> CreateBadgeTextNode(const RefPtr<FrameNode>& frameNode, int32_t childSize,
272         float previewScale, bool isUsePixelMapOffset = false, OffsetF previewOffset = { 0.0f, 0.0f });
273 
274     void GetThumbnailPixelMapAsync(const RefPtr<GestureEventHub>& gestureHub);
275     void SetResponseRegionFull();
276     void ResetResponseRegion();
277     static void ResetDragStatus();
278     void PrepareFinalPixelMapForDragThroughTouch(RefPtr<PixelMap> pixelMap, bool immediately);
279     void DoPixelMapScaleForDragThroughTouch(RefPtr<PixelMap> pixelMap, float targetScale);
280     RefPtr<PixelMap> GetPreScaledPixelMapForDragThroughTouch(float& preScale);
281     void ResetPreScaledPixelMapForDragThroughTouch();
282 
283 private:
284     void UpdatePreviewOptionFromModifier(const RefPtr<FrameNode>& frameNode);
285     void UpdatePreviewOptionDefaultAttr(const RefPtr<FrameNode>& frameNode);
286     static void SetImageNodeInitAttr(const RefPtr<FrameNode>& frameNode, const RefPtr<FrameNode>& imageNode);
287     static void SetImageNodeFinishAttr(const RefPtr<FrameNode>& frameNode, const RefPtr<FrameNode>& imageNode);
288     static void ApplyNewestOptionExecutedFromModifierToNode(
289         const RefPtr<FrameNode>& optionHolderNode, const RefPtr<FrameNode>& targetNode);
290     // check global dragging status
291     bool IsGlobalStatusSuitableForDragging();
292     // check the current node's status to decide if it can initiate one drag operation
293     bool IsCurrentNodeStatusSuitableForDragging(
294         const RefPtr<FrameNode>& frameNode, const TouchRestrict& touchRestrict);
295     bool IsSelfAndParentDragForbidden(const RefPtr<FrameNode>& frameNode) const;
296     std::optional<EffectOption> BrulStyleToEffection(const std::optional<BlurStyleOption>& blurStyleOp);
297     float RadiusToSigma(float radius);
298     void RecordMenuWrapperNodeForDrag(int32_t targetId);
299     void HandleOnPanActionCancel();
300 
301 private:
302     WeakPtr<GestureEventHub> gestureEventHub_;
303     WeakPtr<FrameNode> itemParentNode_;
304     RefPtr<DragEvent> userCallback_;
305     RefPtr<DragEvent> customCallback_;
306     RefPtr<PanRecognizer> panRecognizer_;
307     RefPtr<LongPressRecognizer> longPressRecognizer_;
308     RefPtr<LongPressRecognizer> previewLongPressRecognizer_;
309     RefPtr<SequencedRecognizer> SequencedRecognizer_;
310     RefPtr<FrameNode> gatherNode_;
311     RefPtr<TouchEventImpl> touchListener_;
312 
313     RefPtr<PixelMap> textPixelMap_;
314     RefPtr<PixelMap> preScaledPixelMap_;
315     std::function<void(GestureEvent&)> actionStart_;
316     std::function<void(GestureEvent&)> longPressUpdate_;
317     std::function<void()> actionCancel_;
318     std::function<void(Offset)> textDragCallback_;
319     GestureEvent longPressInfo_;
320     bool isReceivedLongPress_ = false;
321     bool isFloatImage_ = true;
322     bool isNotInPreviewState_ = false;
323     std::vector<GatherNodeChildInfo> gatherNodeChildrenInfo_;
324     std::vector<DimensionRect> responseRegion_;
325     bool isSelectedItemNode_ = false;
326     bool isOnBeforeLiftingAnimation = false;
327     bool isDragPrepareFinish_ = false;
328 
329     bool isDragUserReject_ = false;
330     bool defaultOnDragStartExecuted_ = false;
331     bool isResponseRegionFull = false;
332     OptionsAfterApplied optionsAfterApplied_;
333 
334     PanDirection direction_;
335     int32_t fingers_ = 1;
336     float distance_ = 0.0f;
337     float preScaleValue_ = 1.0f;
338     bool isRedragStart_ = false;
339 };
340 
341 } // namespace OHOS::Ace::NG
342 
343 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_DRAG_EVENT_H
344