2 * Copyright (c) 2020 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>
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.GetProperty< int >( Actor::Property::ID ));
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.GetProperty< int >( Actor::Property::ID )));
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 Gesture::State state = gesture.GetState();
128 if(state == Gesture::Started)
130 mDragLocalPosition = gesture.GetPosition();
132 mDragControl = control;
134 for( auto&& control : mControls)
136 mFirstEnter.push_back(control.GetProperty< int >( Actor::Property::ID ));
138 float width = control.GetProperty<float>(Dali::Actor::Property::SIZE_WIDTH);
139 float height = control.GetProperty<float>(Dali::Actor::Property::SIZE_HEIGHT);
140 Vector3 actorPos = control.GetProperty<Vector3>(Dali::Actor::Property::POSITION);
142 mShadowControl = Dali::Toolkit::Control::New();
143 mShadowControl.SetProperty( Actor::Property::POSITION, actorPos );
144 mShadowControl.SetProperty( Actor::Property::SIZE, Vector2( width, height ) );
145 mShadowControl.SetBackgroundColor(Vector4(0.3f, 0.3f, 0.3f, 0.7f));
146 mShadowControl.SetProperty( Actor::Property::PARENT_ORIGIN, control.GetCurrentProperty< Vector3 >( Actor::Property::PARENT_ORIGIN ) );
147 mShadowControl.SetProperty( Actor::Property::ANCHOR_POINT,control.GetCurrentProperty< Vector3 >( Actor::Property::ANCHOR_POINT ));
148 control.GetParent().Add(mShadowControl);
149 SetPosition(gesture.GetScreenPosition());
150 EmitStartedSignal(control);
152 if(state == Gesture::Continuing)
154 Vector2 screenPosition = gesture.GetScreenPosition();
155 control.GetParent().ScreenToLocal(mLocalPosition.x, mLocalPosition.y, screenPosition.x, screenPosition.y);
156 mShadowControl.SetProperty( Actor::Property::POSITION, Vector2(mLocalPosition.x - mDragLocalPosition.x, mLocalPosition.y - mDragLocalPosition.y));
158 if(state == Gesture::Finished)
160 mDragControl.GetParent().Remove(mShadowControl);
161 EmitEndedSignal(control);
165 bool DragAndDropDetector::OnDrag(Dali::Actor actor, const Dali::TouchEvent& data)
167 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
168 PointState::Type type = data.GetState(0);
170 if(type == PointState::MOTION)
172 if(mDragControl != control && mPointDown)
174 auto found = std::find(mFirstEnter.begin(), mFirstEnter.end(), control.GetProperty< int >( Actor::Property::ID ));
175 if(mFirstEnter.end() != found)
177 SetPosition(data.GetScreenPosition(0));
178 mFirstEnter.erase(found);
179 EmitEnteredSignal(control);
183 SetPosition(data.GetScreenPosition(0));
184 EmitMovedSignal(control);
189 if(type == PointState::LEAVE)
191 if(mDragControl != control && mPointDown)
193 mFirstEnter.push_back(control.GetProperty< int >( Actor::Property::ID ));
194 EmitExitedSignal(control);
198 if(type == PointState::UP)
200 if(mDragControl != control && mPointDown)
202 SetPosition(data.GetScreenPosition(0));
204 SetContent(mDragControl.GetProperty< std::string >( Dali::Actor::Property::NAME ));
205 EmitDroppedSignal(control);
210 control.GetParent().Remove(mShadowControl);
217 const std::string& DragAndDropDetector::GetContent() const
222 const Vector2& DragAndDropDetector::GetCurrentScreenPosition() const
224 return mScreenPosition;
227 void DragAndDropDetector::SetContent( const std::string& content )
232 void DragAndDropDetector::ClearContent()
237 void DragAndDropDetector::SetPosition( const Vector2& screenPosition )
239 mScreenPosition = screenPosition;
242 void DragAndDropDetector::EmitStartedSignal(Dali::Toolkit::Control& control)
244 if( !mStartedSignal.Empty() )
246 Dali::Toolkit::DragAndDropDetector handle( this );
247 mStartedSignal.Emit( control, handle );
250 void DragAndDropDetector::EmitEnteredSignal(Dali::Toolkit::Control& control)
252 if ( !mEnteredSignal.Empty() )
254 Dali::Toolkit::DragAndDropDetector handle( this );
255 mEnteredSignal.Emit( control, handle );
259 void DragAndDropDetector::EmitExitedSignal(Dali::Toolkit::Control& control)
261 if ( !mExitedSignal.Empty() )
263 Dali::Toolkit::DragAndDropDetector handle( this );
264 mExitedSignal.Emit( control, handle );
268 void DragAndDropDetector::EmitMovedSignal(Dali::Toolkit::Control& control)
270 if ( !mMovedSignal.Empty() )
272 Dali::Toolkit::DragAndDropDetector handle( this );
273 mMovedSignal.Emit( control, handle );
277 void DragAndDropDetector::EmitDroppedSignal(Dali::Toolkit::Control& control)
279 if ( !mDroppedSignal.Empty() )
281 Dali::Toolkit::DragAndDropDetector handle( this );
282 mDroppedSignal.Emit( control, handle );
286 void DragAndDropDetector::EmitEndedSignal(Dali::Toolkit::Control& control)
288 if( !mEndedSignal.Empty() )
290 Dali::Toolkit::DragAndDropDetector handle( this );
291 mEndedSignal.Emit( control, handle );
295 DragAndDropDetector::DragAndDropDetector()
299 mPanGestureDetector = Dali::PanGestureDetector::New();
303 DragAndDropDetector::~DragAndDropDetector()
307 } // namespace Internal
309 } //namespace Toolkit