2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-toolkit/internal/drag-drop-detector/drag-and-drop-detector-impl.h>
21 #include <dali/public-api/events/point-state.h>
22 #include <dali/public-api/events/touch-event.h>
30 Dali::Toolkit::DragAndDropDetector DragAndDropDetector::New()
32 Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector(new DragAndDropDetector());
37 void DragAndDropDetector::Attach(Dali::Toolkit::Control& control)
41 if(!mControls.empty())
43 auto match = std::find(mControls.begin(), mControls.end(), control);
44 if(match != mControls.end())
49 mControls.push_back(control);
50 control.TouchedSignal().Connect(this, &DragAndDropDetector::OnDrag);
51 mFirstEnter.push_back(control.GetProperty<int>(Actor::Property::ID));
52 mPanGestureDetector.Attach(control);
53 mPanGestureDetector.DetectedSignal().Connect(this, &DragAndDropDetector::OnPan);
57 void DragAndDropDetector::Detach(Dali::Toolkit::Control& control)
59 if(!mControls.empty())
66 auto match = std::find(mControls.begin(), mControls.end(), control);
68 if(match != mControls.end())
70 match->TouchedSignal().Disconnect(this, &DragAndDropDetector::OnDrag);
71 mPanGestureDetector.Detach(*match);
72 mFirstEnter.erase(std::find(mFirstEnter.begin(), mFirstEnter.end(), control.GetProperty<int>(Actor::Property::ID)));
73 mControls.erase(match);
78 void DragAndDropDetector::DetachAll()
80 if(!mControls.empty())
82 auto iter = mControls.begin();
83 for(; iter != mControls.end();)
85 iter->TouchedSignal().Disconnect(this, &DragAndDropDetector::OnDrag);
86 mPanGestureDetector.Detach(*iter);
87 iter = mControls.erase(iter);
91 if(!mFirstEnter.empty())
93 auto iter = mFirstEnter.begin();
94 for(; iter != mFirstEnter.end();)
96 iter = mFirstEnter.erase(iter);
101 uint32_t DragAndDropDetector::GetAttachedControlCount() const
103 return mControls.size();
106 Dali::Toolkit::Control DragAndDropDetector::GetAttachedControl(uint32_t index) const
108 Dali::Toolkit::Control control;
110 if(index < mControls.size())
112 control = mControls[index];
118 void DragAndDropDetector::OnPan(Dali::Actor actor, const PanGesture& gesture)
120 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
122 GestureState state = gesture.GetState();
124 if(state == GestureState::STARTED)
126 mDragLocalPosition = gesture.GetPosition();
128 mDragControl = control;
130 for(auto&& control : mControls)
132 mFirstEnter.push_back(control.GetProperty<int>(Actor::Property::ID));
134 float width = control.GetProperty<float>(Dali::Actor::Property::SIZE_WIDTH);
135 float height = control.GetProperty<float>(Dali::Actor::Property::SIZE_HEIGHT);
136 Vector3 actorPos = control.GetProperty<Vector3>(Dali::Actor::Property::POSITION);
138 mShadowControl = Dali::Toolkit::Control::New();
139 mShadowControl.SetProperty(Actor::Property::POSITION, actorPos);
140 mShadowControl.SetProperty(Actor::Property::SIZE, Vector2(width, height));
141 mShadowControl.SetBackgroundColor(Vector4(0.3f, 0.3f, 0.3f, 0.7f));
142 mShadowControl.SetProperty(Actor::Property::PARENT_ORIGIN, control.GetCurrentProperty<Vector3>(Actor::Property::PARENT_ORIGIN));
143 mShadowControl.SetProperty(Actor::Property::ANCHOR_POINT, control.GetCurrentProperty<Vector3>(Actor::Property::ANCHOR_POINT));
144 control.GetParent().Add(mShadowControl);
145 SetPosition(gesture.GetScreenPosition());
146 EmitStartedSignal(control);
148 if(state == GestureState::CONTINUING)
150 Vector2 screenPosition = gesture.GetScreenPosition();
151 control.GetParent().ScreenToLocal(mLocalPosition.x, mLocalPosition.y, screenPosition.x, screenPosition.y);
152 mShadowControl.SetProperty(Actor::Property::POSITION, Vector2(mLocalPosition.x - mDragLocalPosition.x, mLocalPosition.y - mDragLocalPosition.y));
154 if(state == GestureState::FINISHED)
156 mDragControl.GetParent().Remove(mShadowControl);
157 EmitEndedSignal(control);
161 bool DragAndDropDetector::OnDrag(Dali::Actor actor, const Dali::TouchEvent& data)
163 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
164 PointState::Type type = data.GetState(0);
166 if(type == PointState::MOTION)
168 if(mDragControl != control && mPointDown)
170 auto found = std::find(mFirstEnter.begin(), mFirstEnter.end(), control.GetProperty<int>(Actor::Property::ID));
171 if(mFirstEnter.end() != found)
173 SetPosition(data.GetScreenPosition(0));
174 mFirstEnter.erase(found);
175 EmitEnteredSignal(control);
179 SetPosition(data.GetScreenPosition(0));
180 EmitMovedSignal(control);
185 if(type == PointState::LEAVE)
187 if(mDragControl != control && mPointDown)
189 mFirstEnter.push_back(control.GetProperty<int>(Actor::Property::ID));
190 EmitExitedSignal(control);
194 if(type == PointState::UP)
196 if(mDragControl != control && mPointDown)
198 SetPosition(data.GetScreenPosition(0));
200 SetContent(mDragControl.GetProperty<std::string>(Dali::Actor::Property::NAME));
201 EmitDroppedSignal(control);
206 control.GetParent().Remove(mShadowControl);
213 const std::string& DragAndDropDetector::GetContent() const
218 const Vector2& DragAndDropDetector::GetCurrentScreenPosition() const
220 return mScreenPosition;
223 void DragAndDropDetector::SetContent(const std::string& content)
228 void DragAndDropDetector::ClearContent()
233 void DragAndDropDetector::SetPosition(const Vector2& screenPosition)
235 mScreenPosition = screenPosition;
238 void DragAndDropDetector::EmitStartedSignal(Dali::Toolkit::Control& control)
240 if(!mStartedSignal.Empty())
242 Dali::Toolkit::DragAndDropDetector handle(this);
243 mStartedSignal.Emit(control, handle);
246 void DragAndDropDetector::EmitEnteredSignal(Dali::Toolkit::Control& control)
248 if(!mEnteredSignal.Empty())
250 Dali::Toolkit::DragAndDropDetector handle(this);
251 mEnteredSignal.Emit(control, handle);
255 void DragAndDropDetector::EmitExitedSignal(Dali::Toolkit::Control& control)
257 if(!mExitedSignal.Empty())
259 Dali::Toolkit::DragAndDropDetector handle(this);
260 mExitedSignal.Emit(control, handle);
264 void DragAndDropDetector::EmitMovedSignal(Dali::Toolkit::Control& control)
266 if(!mMovedSignal.Empty())
268 Dali::Toolkit::DragAndDropDetector handle(this);
269 mMovedSignal.Emit(control, handle);
273 void DragAndDropDetector::EmitDroppedSignal(Dali::Toolkit::Control& control)
275 if(!mDroppedSignal.Empty())
277 Dali::Toolkit::DragAndDropDetector handle(this);
278 mDroppedSignal.Emit(control, handle);
282 void DragAndDropDetector::EmitEndedSignal(Dali::Toolkit::Control& control)
284 if(!mEndedSignal.Empty())
286 Dali::Toolkit::DragAndDropDetector handle(this);
287 mEndedSignal.Emit(control, handle);
291 DragAndDropDetector::DragAndDropDetector()
295 mPanGestureDetector = Dali::PanGestureDetector::New();
299 DragAndDropDetector::~DragAndDropDetector()
303 } // namespace Internal
305 } //namespace Toolkit