2 * Copyright (c) 2018 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-data.h>
33 Dali::Toolkit::DragAndDropDetector DragAndDropDetector::New()
35 Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector(new DragAndDropDetector());
40 void DragAndDropDetector::Attach(Dali::Toolkit::Control& control)
44 if(!mControls.empty())
46 auto match = std::find(mControls.begin(), mControls.end(), control);
47 if(match != mControls.end())
52 mControls.push_back(control);
53 control.TouchSignal().Connect(this, &DragAndDropDetector::OnDrag);
54 mFirstEnter.push_back(control.GetId());
55 mPanGestureDetector.Attach(control);
56 mPanGestureDetector.DetectedSignal().Connect(this, &DragAndDropDetector::OnPan);
61 void DragAndDropDetector::Detach(Dali::Toolkit::Control& control)
63 if(!mControls.empty())
70 auto match = std::find(mControls.begin(), mControls.end(), control);
72 if(match != mControls.end())
74 match->TouchSignal().Disconnect(this, &DragAndDropDetector::OnDrag);
75 mPanGestureDetector.Detach(*match);
76 mFirstEnter.erase(std::find(mFirstEnter.begin(), mFirstEnter.end(), control.GetId()));
77 mControls.erase(match);
82 void DragAndDropDetector::DetachAll()
84 if(!mControls.empty())
86 auto iter = mControls.begin();
87 for(;iter != mControls.end();)
89 iter->TouchSignal().Disconnect(this, &DragAndDropDetector::OnDrag);
90 mPanGestureDetector.Detach(*iter);
91 iter = mControls.erase(iter);
95 if(!mFirstEnter.empty())
97 auto iter = mFirstEnter.begin();
98 for(;iter != mFirstEnter.end();)
100 iter = mFirstEnter.erase(iter);
105 uint32_t DragAndDropDetector::GetAttachedControlCount() const
107 return mControls.size();
110 Dali::Toolkit::Control DragAndDropDetector::GetAttachedControl(uint32_t index) const
112 Dali::Toolkit::Control control;
114 if(index < mControls.size())
116 control = mControls[index];
122 void DragAndDropDetector::OnPan(Dali::Actor actor, const PanGesture& gesture)
124 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
126 if(gesture.state == Gesture::Started)
128 mDragLocalPosition = gesture.position;
130 if(gesture.state == Gesture::Continuing)
132 Vector2 screenPosition = gesture.screenPosition;
133 control.GetParent().ScreenToLocal(mLocalPosition.x, mLocalPosition.y, screenPosition.x, screenPosition.y);
134 mShadowControl.SetPosition(mLocalPosition.x - mDragLocalPosition.x, mLocalPosition.y - mDragLocalPosition.y);
136 if(gesture.state == Gesture::Finished)
138 mDragControl.GetParent().Remove(mShadowControl);
139 EmitEndedSignal(control);
143 bool DragAndDropDetector::OnDrag(Dali::Actor actor, const Dali::TouchData& data)
145 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
146 PointState::Type type = data.GetState(0);
147 if(type == PointState::DOWN)
150 mDragControl = control;
152 for( auto&& control : mControls)
154 mFirstEnter.push_back(control.GetId());
156 float width = control.GetProperty<float>(Dali::Actor::Property::SIZE_WIDTH);
157 float height = control.GetProperty<float>(Dali::Actor::Property::SIZE_HEIGHT);
158 Vector3 actorPos = control.GetProperty<Vector3>(Dali::Actor::Property::POSITION);
160 mShadowControl = Dali::Toolkit::Control::New();
161 mShadowControl.SetPosition(actorPos);
162 mShadowControl.SetSize(width, height);
163 mShadowControl.SetBackgroundColor(Vector4(0.3f, 0.3f, 0.3f, 0.7f));
164 mShadowControl.SetParentOrigin(control.GetCurrentParentOrigin());
165 mShadowControl.SetAnchorPoint(control.GetCurrentAnchorPoint());
166 control.GetParent().Add(mShadowControl);
167 SetPosition(data.GetScreenPosition(0));
168 EmitStartedSignal(control);
171 if(type == PointState::MOTION)
173 if(mDragControl != control && mPointDown)
175 auto found = std::find(mFirstEnter.begin(), mFirstEnter.end(), control.GetId());
176 if(mFirstEnter.end() != found)
178 SetPosition(data.GetScreenPosition(0));
179 mFirstEnter.erase(found);
180 EmitEnteredSignal(control);
184 SetPosition(data.GetScreenPosition(0));
185 EmitMovedSignal(control);
190 if(type == PointState::LEAVE)
192 if(mDragControl != control && mPointDown)
194 mFirstEnter.push_back(control.GetId());
195 EmitExitedSignal(control);
199 if(type == PointState::UP)
201 if(mDragControl != control && mPointDown)
203 SetPosition(data.GetScreenPosition(0));
205 SetContent(mDragControl.GetName());
206 EmitDroppedSignal(control);
211 control.GetParent().Remove(mShadowControl);
218 const std::string& DragAndDropDetector::GetContent() const
223 const Vector2& DragAndDropDetector::GetCurrentScreenPosition() const
225 return mScreenPosition;
228 void DragAndDropDetector::SetContent( const std::string& content )
233 void DragAndDropDetector::ClearContent()
238 void DragAndDropDetector::SetPosition( const Vector2& screenPosition )
240 mScreenPosition = screenPosition;
243 void DragAndDropDetector::EmitStartedSignal(Dali::Toolkit::Control& control)
245 if( !mStartedSignal.Empty() )
247 Dali::Toolkit::DragAndDropDetector handle( this );
248 mStartedSignal.Emit( control, handle );
251 void DragAndDropDetector::EmitEnteredSignal(Dali::Toolkit::Control& control)
253 if ( !mEnteredSignal.Empty() )
255 Dali::Toolkit::DragAndDropDetector handle( this );
256 mEnteredSignal.Emit( control, handle );
260 void DragAndDropDetector::EmitExitedSignal(Dali::Toolkit::Control& control)
262 if ( !mExitedSignal.Empty() )
264 Dali::Toolkit::DragAndDropDetector handle( this );
265 mExitedSignal.Emit( control, handle );
269 void DragAndDropDetector::EmitMovedSignal(Dali::Toolkit::Control& control)
271 if ( !mMovedSignal.Empty() )
273 Dali::Toolkit::DragAndDropDetector handle( this );
274 mMovedSignal.Emit( control, handle );
278 void DragAndDropDetector::EmitDroppedSignal(Dali::Toolkit::Control& control)
280 if ( !mDroppedSignal.Empty() )
282 Dali::Toolkit::DragAndDropDetector handle( this );
283 mDroppedSignal.Emit( control, handle );
287 void DragAndDropDetector::EmitEndedSignal(Dali::Toolkit::Control& control)
289 if( !mEndedSignal.Empty() )
291 Dali::Toolkit::DragAndDropDetector handle( this );
292 mEndedSignal.Emit( control, handle );
296 DragAndDropDetector::DragAndDropDetector()
300 mPanGestureDetector = Dali::PanGestureDetector::New();
304 DragAndDropDetector::~DragAndDropDetector()
308 } // namespace Internal
310 } //namespace Toolkit