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
17 #include "core/components/box/drag_drop_event.h"
18
19 #include "core/components/container_modal/container_modal_constants.h"
20 #include "core/gestures/long_press_recognizer.h"
21 #include "core/gestures/pan_recognizer.h"
22 #include "core/gestures/sequenced_recognizer.h"
23 #include "core/pipeline/base/render_node.h"
24
25 namespace OHOS::Ace {
26
27 namespace {
28
29 constexpr int32_t DEFAULT_FINGERS = 1;
30 constexpr int32_t DEFAULT_DURATION = 450;
31 constexpr int32_t DEFAULT_DISTANCE = 5;
32
33 }; // namespace
34
CreateDragDropRecognizer(const WeakPtr<PipelineContext> & pipelineContext)35 void DragDropEvent::CreateDragDropRecognizer(const WeakPtr<PipelineContext>& pipelineContext)
36 {
37 if (dragDropGesture_) {
38 return;
39 }
40
41 auto context = pipelineContext.Upgrade();
42 if (!context) {
43 return;
44 }
45
46 auto longPressRecognizer = AceType::MakeRefPtr<OHOS::Ace::LongPressRecognizer>(
47 context, DEFAULT_DURATION, DEFAULT_FINGERS, false, true, false);
48 longPressRecognizer->SetOnAction(std::bind(&DragDropEvent::LongPressOnAction, this, std::placeholders::_1));
49 PanDirection panDirection;
50 auto panRecognizer =
51 AceType::MakeRefPtr<OHOS::Ace::PanRecognizer>(context, DEFAULT_FINGERS, panDirection, DEFAULT_DISTANCE);
52 panRecognizer->SetOnActionStart(std::bind(&DragDropEvent::PanOnActionStart, this, std::placeholders::_1));
53 panRecognizer->SetOnActionUpdate(std::bind(&DragDropEvent::PanOnActionUpdate, this, std::placeholders::_1));
54 panRecognizer->SetOnActionEnd(std::bind(&DragDropEvent::PanOnActionEnd, this, std::placeholders::_1));
55 panRecognizer->SetOnActionCancel(std::bind(&DragDropEvent::PanOnActionCancel, this));
56
57 std::vector<RefPtr<GestureRecognizer>> recognizers { longPressRecognizer, panRecognizer };
58 dragDropGesture_ = AceType::MakeRefPtr<OHOS::Ace::SequencedRecognizer>(pipelineContext, recognizers);
59 dragDropGesture_->SetIsExternalGesture(true);
60 }
61
LongPressOnAction(const GestureEvent & info)62 void DragDropEvent::LongPressOnAction(const GestureEvent& info)
63 {
64 startPoint_ = info.GetGlobalPoint();
65 }
66
FindDragDropNode(const RefPtr<PipelineContext> & context,const GestureEvent & info)67 RefPtr<DragDropEvent> DragDropEvent::FindDragDropNode(const RefPtr<PipelineContext>& context, const GestureEvent& info)
68 {
69 if (!context) {
70 return nullptr;
71 }
72
73 auto pageRenderNode = context->GetLastPageRender();
74 if (!pageRenderNode) {
75 return nullptr;
76 }
77 auto offset = context->GetStageRect().GetOffset();
78 auto targetRenderNode = pageRenderNode->FindDropChild(info.GetGlobalPoint(), info.GetGlobalPoint() - offset);
79 if (!targetRenderNode) {
80 return nullptr;
81 }
82 return AceType::DynamicCast<DragDropEvent>(targetRenderNode);
83 }
84
AddDataToClipboard(const RefPtr<PipelineContext> & context,const std::string & extraInfo,const std::string & selectedText,const std::string & imageSrc)85 void DragDropEvent::AddDataToClipboard(const RefPtr<PipelineContext>& context, const std::string& extraInfo,
86 const std::string& selectedText, const std::string& imageSrc)
87 {
88 auto seleItemSizeStr = JsonUtil::Create(true);
89 seleItemSizeStr->Put("width", selectedItemSize_.Width());
90 seleItemSizeStr->Put("height", selectedItemSize_.Height());
91 seleItemSizeStr->Put("customDragInfo", extraInfo.c_str());
92 seleItemSizeStr->Put("selectedText", selectedText.c_str());
93 seleItemSizeStr->Put("imageSrc", imageSrc.c_str());
94 MergeClipboardData(context, seleItemSizeStr->ToString());
95 }
96
MergeClipboardData(const RefPtr<PipelineContext> & context,const std::string & newData)97 void DragDropEvent::MergeClipboardData(const RefPtr<PipelineContext>& context, const std::string& newData)
98 {
99 if (!clipboard_) {
100 clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(context->GetTaskExecutor());
101 }
102 if (!clipboardCallback_) {
103 auto callback = [weakDragDropNode = WeakClaim(this), addData = newData](const std::string& data) {
104 auto dragDropNode = weakDragDropNode.Upgrade();
105 if (dragDropNode) {
106 auto clipboardAllData = JsonUtil::Create(true);
107 clipboardAllData->Put("preData", data.c_str());
108 clipboardAllData->Put("newData", addData.c_str());
109 dragDropNode->clipboard_->SetData(clipboardAllData->ToString(), CopyOptions::Local, true);
110 }
111 };
112 clipboardCallback_ = callback;
113 }
114 clipboard_->GetData(clipboardCallback_);
115 }
116
RestoreCilpboardData(const RefPtr<PipelineContext> & context)117 void DragDropEvent::RestoreCilpboardData(const RefPtr<PipelineContext>& context)
118 {
119 if (!clipboard_) {
120 clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(context->GetTaskExecutor());
121 }
122
123 if (!deleteDataCallback_) {
124 auto callback = [weakDragDropNode = WeakClaim(this)](const std::string& data) {
125 auto dragDropNode = weakDragDropNode.Upgrade();
126 if (dragDropNode) {
127 auto json = JsonUtil::ParseJsonString(data);
128 dragDropNode->clipboard_->SetData(json->GetString("preData"));
129 }
130 };
131 deleteDataCallback_ = callback;
132 }
133 clipboard_->GetData(deleteDataCallback_);
134 }
135
UpdatePoint(const RefPtr<PipelineContext> & context,const Point & prePoint)136 Point DragDropEvent::UpdatePoint(const RefPtr<PipelineContext>& context, const Point& prePoint)
137 {
138 if (!context) {
139 return prePoint;
140 }
141
142 auto isContainerModal = context->GetWindowModal() == WindowModal::CONTAINER_MODAL &&
143 context->GetWindowManager()->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING;
144 Point newPoint;
145 if (isContainerModal) {
146 newPoint.SetX(prePoint.GetX() - CONTAINER_BORDER_WIDTH.ConvertToPx() - CONTENT_PADDING.ConvertToPx());
147 newPoint.SetY(prePoint.GetY() - CONTAINER_TITLE_HEIGHT.ConvertToPx());
148 } else {
149 newPoint = prePoint;
150 }
151 return newPoint;
152 }
153
154 } // namespace OHOS::Ace
155