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-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.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 if(gesture.state == Gesture::Started)
128 mDragLocalPosition = gesture.position;
130 mDragControl = control;
132 for( auto&& control : mControls)
134 mFirstEnter.push_back(control.GetProperty< int >( Actor::Property::ID ));
136 float width = control.GetProperty<float>(Dali::Actor::Property::SIZE_WIDTH);
137 float height = control.GetProperty<float>(Dali::Actor::Property::SIZE_HEIGHT);
138 Vector3 actorPos = control.GetProperty<Vector3>(Dali::Actor::Property::POSITION);
140 mShadowControl = Dali::Toolkit::Control::New();
141 mShadowControl.SetProperty( Actor::Property::POSITION, actorPos );
142 mShadowControl.SetProperty( Actor::Property::SIZE, Vector2( width, height ) );
143 mShadowControl.SetBackgroundColor(Vector4(0.3f, 0.3f, 0.3f, 0.7f));
144 mShadowControl.SetProperty( Actor::Property::PARENT_ORIGIN, control.GetCurrentProperty< Vector3 >( Actor::Property::PARENT_ORIGIN ) );
145 mShadowControl.SetProperty( Actor::Property::ANCHOR_POINT,control.GetCurrentProperty< Vector3 >( Actor::Property::ANCHOR_POINT ));
146 control.GetParent().Add(mShadowControl);
147 SetPosition(gesture.screenPosition);
148 EmitStartedSignal(control);
150 if(gesture.state == Gesture::Continuing)
152 Vector2 screenPosition = gesture.screenPosition;
153 control.GetParent().ScreenToLocal(mLocalPosition.x, mLocalPosition.y, screenPosition.x, screenPosition.y);
154 mShadowControl.SetProperty( Actor::Property::POSITION, Vector2(mLocalPosition.x - mDragLocalPosition.x, mLocalPosition.y - mDragLocalPosition.y));
156 if(gesture.state == Gesture::Finished)
158 mDragControl.GetParent().Remove(mShadowControl);
159 EmitEndedSignal(control);
163 bool DragAndDropDetector::OnDrag(Dali::Actor actor, const Dali::TouchData& data)
165 Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
166 PointState::Type type = data.GetState(0);
168 if(type == PointState::MOTION)
170 if(mDragControl != control && mPointDown)
172 auto found = std::find(mFirstEnter.begin(), mFirstEnter.end(), control.GetProperty< int >( Actor::Property::ID ));
173 if(mFirstEnter.end() != found)
175 SetPosition(data.GetScreenPosition(0));
176 mFirstEnter.erase(found);
177 EmitEnteredSignal(control);
181 SetPosition(data.GetScreenPosition(0));
182 EmitMovedSignal(control);
187 if(type == PointState::LEAVE)
189 if(mDragControl != control && mPointDown)
191 mFirstEnter.push_back(control.GetProperty< int >( Actor::Property::ID ));
192 EmitExitedSignal(control);
196 if(type == PointState::UP)
198 if(mDragControl != control && mPointDown)
200 SetPosition(data.GetScreenPosition(0));
202 SetContent(mDragControl.GetProperty< std::string >( Dali::Actor::Property::NAME ));
203 EmitDroppedSignal(control);
208 control.GetParent().Remove(mShadowControl);
215 const std::string& DragAndDropDetector::GetContent() const
220 const Vector2& DragAndDropDetector::GetCurrentScreenPosition() const
222 return mScreenPosition;
225 void DragAndDropDetector::SetContent( const std::string& content )
230 void DragAndDropDetector::ClearContent()
235 void DragAndDropDetector::SetPosition( const Vector2& screenPosition )
237 mScreenPosition = screenPosition;
240 void DragAndDropDetector::EmitStartedSignal(Dali::Toolkit::Control& control)
242 if( !mStartedSignal.Empty() )
244 Dali::Toolkit::DragAndDropDetector handle( this );
245 mStartedSignal.Emit( control, handle );
248 void DragAndDropDetector::EmitEnteredSignal(Dali::Toolkit::Control& control)
250 if ( !mEnteredSignal.Empty() )
252 Dali::Toolkit::DragAndDropDetector handle( this );
253 mEnteredSignal.Emit( control, handle );
257 void DragAndDropDetector::EmitExitedSignal(Dali::Toolkit::Control& control)
259 if ( !mExitedSignal.Empty() )
261 Dali::Toolkit::DragAndDropDetector handle( this );
262 mExitedSignal.Emit( control, handle );
266 void DragAndDropDetector::EmitMovedSignal(Dali::Toolkit::Control& control)
268 if ( !mMovedSignal.Empty() )
270 Dali::Toolkit::DragAndDropDetector handle( this );
271 mMovedSignal.Emit( control, handle );
275 void DragAndDropDetector::EmitDroppedSignal(Dali::Toolkit::Control& control)
277 if ( !mDroppedSignal.Empty() )
279 Dali::Toolkit::DragAndDropDetector handle( this );
280 mDroppedSignal.Emit( control, handle );
284 void DragAndDropDetector::EmitEndedSignal(Dali::Toolkit::Control& control)
286 if( !mEndedSignal.Empty() )
288 Dali::Toolkit::DragAndDropDetector handle( this );
289 mEndedSignal.Emit( control, handle );
293 DragAndDropDetector::DragAndDropDetector()
297 mPanGestureDetector = Dali::PanGestureDetector::New();
301 DragAndDropDetector::~DragAndDropDetector()
305 } // namespace Internal
307 } //namespace Toolkit