add drag&drop support in actor level 88/190288/15
authorjunqing.ma <junqing.ma@samsung.com>
Sun, 30 Sep 2018 02:26:35 +0000 (10:26 +0800)
committerjunqing.ma <junqing.ma@samsung.com>
Thu, 8 Nov 2018 03:52:39 +0000 (11:52 +0800)
Change-Id: I6d97964a68b6c9b3d8f13e6b3515df1e60695d73

automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/utc-Dali-DragAndDropDetector.cpp [new file with mode: 0755]
build/tizen/dali-toolkit/Makefile.am
dali-toolkit/devel-api/drag-drop-detector/drag-and-drop-detector.cpp [new file with mode: 0755]
dali-toolkit/devel-api/drag-drop-detector/drag-and-drop-detector.h [new file with mode: 0755]
dali-toolkit/devel-api/file.list
dali-toolkit/internal/drag-drop-detector/drag-and-drop-detector-impl.cpp [new file with mode: 0755]
dali-toolkit/internal/drag-drop-detector/drag-and-drop-detector-impl.h [new file with mode: 0755]
dali-toolkit/internal/file.list

index fe9102e..e0b1cab 100755 (executable)
@@ -76,6 +76,7 @@ SET(TC_SOURCES
   utc-Dali-AsyncImageLoader.cpp
   utc-Dali-SyncImageLoader.cpp
   utc-Dali-ControlWrapper.cpp
   utc-Dali-AsyncImageLoader.cpp
   utc-Dali-SyncImageLoader.cpp
   utc-Dali-ControlWrapper.cpp
+  utc-Dali-DragAndDropDetector.cpp
 )
 
 # Append list of test harness files (Won't get parsed for test cases)
 )
 
 # Append list of test harness files (Won't get parsed for test cases)
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-DragAndDropDetector.cpp b/automated-tests/src/dali-toolkit/utc-Dali-DragAndDropDetector.cpp
new file mode 100755 (executable)
index 0000000..8e574b4
--- /dev/null
@@ -0,0 +1,607 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+#include <stdlib.h>
+
+// Need to override adaptor classes for toolkit test harness, so include
+// test harness headers before dali headers.
+#include <dali-toolkit-test-suite-utils.h>
+
+#include <dali-toolkit/devel-api/drag-drop-detector/drag-and-drop-detector.h>
+#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/events/pan-gesture-event.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+void utc_dali_toolkit_drag_drop_detector_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_toolkit_drag_drop_detector_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+namespace
+{
+  const int RENDER_FRAME_INTERVAL = 16;
+  struct SignalData
+  {
+    SignalData()
+    :functorCalled(false),
+    control(),
+    detector()
+    {
+    }
+
+    void Reset()
+    {
+      functorCalled = false;
+      control.Reset();
+    }
+
+    bool functorCalled;
+    Control control;
+    Dali::Toolkit::DragAndDropDetector detector;
+  };
+
+  struct DragSignalFunctor
+  {
+    DragSignalFunctor(SignalData& data, bool returnValue = true)
+    :signalData(data),
+    returnValue(returnValue)
+    {
+    }
+
+    bool operator()(Control control, Dali::Toolkit::DragAndDropDetector detector)
+    {
+      signalData.functorCalled = true;
+      signalData.control = control;
+      signalData.detector = detector;
+      return returnValue;
+    }
+
+    SignalData& signalData;
+    bool returnValue;
+    };
+
+  Integration::TouchEvent GenerateSingleTouch(TouchPoint::State state, const Vector2& screenPosition)
+  {
+    Integration::TouchEvent touchEvent;
+    Integration::Point point;
+    point.SetState(static_cast<PointState::Type>(state));
+    point.SetScreenPosition(screenPosition);
+    touchEvent.points.push_back(point);
+    return touchEvent;
+  }
+
+  Integration::PanGestureEvent GeneratePan(
+    Gesture::State state,
+    Vector2 previousPosition,
+    Vector2 currentPosition,
+    unsigned long timeDelta,
+    unsigned int numberOfTouches = 1,
+    unsigned int time = 1u)
+  {
+    Integration::PanGestureEvent pan(state);
+    pan.previousPosition = previousPosition;
+    pan.currentPosition = currentPosition;
+    pan.timeDelta = timeDelta;
+    pan.numberOfTouches = numberOfTouches;
+    pan.time = time;
+
+    return pan;
+  }
+
+}
+
+int UtcDaliDragAndDropDetectorConstructorN(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector;
+  DALI_TEST_CHECK(!detector);
+
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorConstructorP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  DALI_TEST_CHECK(detector);
+
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorAttachN(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control;
+  detector.Attach(control);
+
+  DALI_TEST_EQUALS(0, detector.GetAttachedControlCount(), TEST_LOCATION);
+  Control control1 = Control::New();
+  detector.Attach(control1);
+  DALI_TEST_EQUALS(1, detector.GetAttachedControlCount(), TEST_LOCATION);
+  detector.Attach(control1);
+  DALI_TEST_EQUALS(1, detector.GetAttachedControlCount(), TEST_LOCATION);
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorAttachP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control = Control::New();
+
+  detector.Attach(control);
+  DALI_TEST_EQUALS(1, detector.GetAttachedControlCount(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorDetachN(void)
+  {
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control1;
+  Control control2 = Control::New();
+
+  detector.Attach(control1);
+  detector.Attach(control2);
+  DALI_TEST_EQUALS(1, detector.GetAttachedControlCount(), TEST_LOCATION);
+
+  detector.Detach(control2);
+  DALI_TEST_EQUALS(0, detector.GetAttachedControlCount(), TEST_LOCATION);
+
+  detector.Detach(control1);
+  DALI_TEST_EQUALS(0, detector.GetAttachedControlCount(), TEST_LOCATION);
+
+  END_TEST;
+
+}
+
+int UtcDaliDragAndDropDetectorDetachP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control1 = Control::New();
+  Control control2 = Control::New();
+  Control control3;
+
+  detector.Attach(control1);
+  detector.Attach(control2);
+  detector.Attach(control3);
+
+  DALI_TEST_EQUALS(2, detector.GetAttachedControlCount(), TEST_LOCATION);
+
+  detector.Detach(control3);
+  DALI_TEST_EQUALS(2, detector.GetAttachedControlCount(), TEST_LOCATION);
+  detector.Detach(control2);
+  DALI_TEST_EQUALS(1, detector.GetAttachedControlCount(), TEST_LOCATION);
+
+  detector.Detach(control1);
+  DALI_TEST_EQUALS(0, detector.GetAttachedControlCount(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorDetachAllN(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  detector.DetachAll();
+  DALI_TEST_EQUALS(0, detector.GetAttachedControlCount(), TEST_LOCATION);
+
+  END_TEST;
+}
+int UtcDaliDragAndDropDetectorDetachAllP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control1 = Control::New();
+  Control control2 = Control::New();
+
+  detector.Attach(control1);
+  detector.Attach(control2);
+  detector.DetachAll();
+  DALI_TEST_EQUALS(0, detector.GetAttachedControlCount(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorGetAttachedControlCountP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control1 = Control::New();
+  Control control2 = Control::New();
+
+  detector.Attach(control1);
+  detector.Attach(control2);
+  DALI_TEST_EQUALS(2, detector.GetAttachedControlCount(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorGetAttachedControlN(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control1 = Control::New();
+  Control control2 = Control::New();
+
+  detector.Attach(control1);
+
+  Control control = detector.GetAttachedControl(1);
+  DALI_TEST_CHECK(!control);
+
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorGetAttachedControlP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control1 = Control::New();
+  Control control2 = Control::New();
+
+  detector.Attach(control1);
+  detector.Attach(control2);
+  Control control = detector.GetAttachedControl(1);
+  DALI_TEST_CHECK(control);
+  DALI_TEST_EQUALS(control2, control, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorStartSignal(void)
+{
+  TestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control = Control::New();
+  control.SetSize(100.0f, 100.0f);
+  control.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  Stage::GetCurrent().Add(control);
+  detector.Attach(control);
+
+  application.SendNotification();
+  application.Render(RENDER_FRAME_INTERVAL);
+
+  DALI_TEST_CHECK(detector);
+  DALI_TEST_CHECK(control);
+
+  SignalData data;
+  DragSignalFunctor functor(data);
+  detector.StartedSignal().Connect(&application, functor);
+
+  Vector2 screenCoordinates(10.0f, 10.0f);
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Down, screenCoordinates));
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(control, data.control, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(10.0f, 10.0f), data.detector.GetCurrentScreenPosition(), TEST_LOCATION);
+  data.Reset();
+
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorEnteredSignal(void)
+{
+  TestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control1 = Control::New();
+  Control control2 = Control::New();
+  control1.SetSize(100.0f,100.0f);
+  control2.SetSize(100.0f, 100.0f);
+  control1.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  control2.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  control1.SetParentOrigin(ParentOrigin::TOP_LEFT);
+  control2.SetParentOrigin(ParentOrigin::TOP_LEFT);
+  control1.SetPosition(0.0f, 0.0f);
+  control2.SetPosition(0.0f, 100.0f);
+
+  Stage::GetCurrent().Add(control1);
+  Stage::GetCurrent().Add(control2);
+
+  detector.Attach(control1);
+  detector.Attach(control2);
+
+  application.SendNotification();
+  application.Render(RENDER_FRAME_INTERVAL);
+
+  SignalData data;
+  DragSignalFunctor functor(data);
+  detector.EnteredSignal().Connect(&application, functor);
+
+  Vector2 screenCoordinates(10.0f, 10.0f);
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Down, screenCoordinates));
+
+  screenCoordinates.x = 10.0f;
+  screenCoordinates.y = 110.0f;
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Motion, screenCoordinates));
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(control2, data.control, TEST_LOCATION);
+
+  data.Reset();
+
+  END_TEST;
+
+}
+
+int UtcDaliDragAndDropDetectorMovedSignal(void)
+{
+  TestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control1 = Control::New();
+  Control control2 = Control::New();
+  control1.SetSize(100.0f,100.0f);
+  control2.SetSize(100.0f, 100.0f);
+  control1.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  control2.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  control1.SetParentOrigin(ParentOrigin::TOP_LEFT);
+  control2.SetParentOrigin(ParentOrigin::TOP_LEFT);
+  control1.SetPosition(0.0f, 0.0f);
+  control2.SetPosition(0.0f, 100.0f);
+
+  Stage::GetCurrent().Add(control1);
+  Stage::GetCurrent().Add(control2);
+
+  detector.Attach(control1);
+  detector.Attach(control2);
+
+  application.SendNotification();
+  application.Render(RENDER_FRAME_INTERVAL);
+
+  SignalData data;
+  DragSignalFunctor functor(data);
+  detector.MovedSignal().Connect(&application, functor);
+
+  Vector2 screenCoordinates(10.0f, 10.0f);
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Down, screenCoordinates));
+
+  screenCoordinates.x = 10.0f;
+  screenCoordinates.y = 110.0f;
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Motion, screenCoordinates));
+
+  screenCoordinates.x = 10.0f;
+  screenCoordinates.y = 120.0f;
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Motion, screenCoordinates));
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(10.0f, 120.0f), data.detector.GetCurrentScreenPosition(), TEST_LOCATION);
+  DALI_TEST_EQUALS(control2, data.control, TEST_LOCATION);
+
+  data.Reset();
+
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorExitedSignal(void)
+{
+  TestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control1 = Control::New();
+  Control control2 = Control::New();
+  control1.SetSize(100.0f,100.0f);
+  control2.SetSize(100.0f, 100.0f);
+  control1.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  control2.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  control1.SetParentOrigin(ParentOrigin::TOP_LEFT);
+  control2.SetParentOrigin(ParentOrigin::TOP_LEFT);
+  control1.SetPosition(0.0f, 0.0f);
+  control2.SetPosition(0.0f, 100.0f);
+
+  control1.SetLeaveRequired(true);
+  control2.SetLeaveRequired(true);
+
+  Stage::GetCurrent().Add(control1);
+  Stage::GetCurrent().Add(control2);
+
+  detector.Attach(control1);
+  detector.Attach(control2);
+
+  application.SendNotification();
+  application.Render(RENDER_FRAME_INTERVAL);
+
+  SignalData data;
+  DragSignalFunctor functor(data);
+  detector.ExitedSignal().Connect(&application, functor);
+
+  Vector2 screenCoordinates(10.0f, 10.0f);
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Down, screenCoordinates));
+
+  screenCoordinates.x = 10.0f;
+  screenCoordinates.y = 110.0f;
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Motion, screenCoordinates));
+
+  screenCoordinates.x = 20.0f;
+  screenCoordinates.y = 20.0f;
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Motion, screenCoordinates));
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(control2, data.control, TEST_LOCATION);
+
+  data.Reset();
+
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorDroppedSignal(void)
+{
+  TestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control1 = Control::New();
+  Control control2 = Control::New();
+  control1.SetSize(100.0f,100.0f);
+  control2.SetSize(100.0f, 100.0f);
+  control1.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  control2.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  control1.SetParentOrigin(ParentOrigin::TOP_LEFT);
+  control2.SetParentOrigin(ParentOrigin::TOP_LEFT);
+  control1.SetPosition(0.0f, 0.0f);
+  control2.SetPosition(0.0f, 100.0f);
+
+  Stage::GetCurrent().Add(control1);
+  Stage::GetCurrent().Add(control2);
+
+  detector.Attach(control1);
+  detector.Attach(control2);
+
+  application.SendNotification();
+  application.Render(RENDER_FRAME_INTERVAL);
+
+  SignalData data;
+  DragSignalFunctor functor(data);
+  detector.DroppedSignal().Connect(&application, functor);
+
+  Vector2 screenCoordinates(10.0f, 10.0f);
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Down, screenCoordinates));
+
+  screenCoordinates.x = 10.0f;
+  screenCoordinates.y = 110.0f;
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Motion, screenCoordinates));
+
+  screenCoordinates.x = 10.0f;
+  screenCoordinates.y = 112.0f;
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Up, screenCoordinates));
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(control2, data.control, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(10.0f, 112.0f), data.detector.GetCurrentScreenPosition(), TEST_LOCATION);
+  DALI_TEST_EQUALS(true, detector.GetContent().empty(), TEST_LOCATION);
+
+  data.Reset();
+
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorEndedSignal(void)
+{
+  TestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control1 = Control::New();
+  Control control2 = Control::New();
+  control1.SetSize(100.0f,100.0f);
+  control2.SetSize(100.0f, 100.0f);
+  control1.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  control2.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  control1.SetParentOrigin(ParentOrigin::TOP_LEFT);
+  control2.SetParentOrigin(ParentOrigin::TOP_LEFT);
+  control1.SetPosition(0.0f, 0.0f);
+  control2.SetPosition(0.0f, 100.0f);
+
+  Stage::GetCurrent().Add(control1);
+  Stage::GetCurrent().Add(control2);
+
+  application.SendNotification();
+  application.Render(RENDER_FRAME_INTERVAL);
+
+  detector.Attach(control1);
+  detector.Attach(control2);
+
+  SignalData data;
+  DragSignalFunctor functor(data);
+  detector.EndedSignal().Connect(&application, functor);
+
+  application.ProcessEvent(GeneratePan(Gesture::Possible, Vector2(10.0f, 10.0f), Vector2(12.0f, 12.0f), 10));
+  application.ProcessEvent(GeneratePan(Gesture::Started, Vector2(10.0f, 10.0f), Vector2(12.0f, 12.0f), 10));
+
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Down, Vector2(10.0f, 10.0f)));
+
+  application.ProcessEvent(GeneratePan(Gesture::Continuing, Vector2(10.0f, 10.0f), Vector2(120.0f, 12.0f), 10));
+  application.ProcessEvent(GeneratePan(Gesture::Finished, Vector2(120.0f, 12.0f), Vector2(120.0f, 20.0f), 10));
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(control1, data.control, TEST_LOCATION);
+  data.Reset();
+
+  END_TEST;
+}
+
+int UtcDaliDragAndDropDetectorGetContent(void)
+{
+  TestApplication application;
+
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector::New();
+  Control control1 = Control::New();
+  Control control2 = Control::New();
+  control1.SetName("control1");
+  control2.SetName("control2");
+  control1.SetSize(100.0f,100.0f);
+  control2.SetSize(100.0f, 100.0f);
+  control1.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  control2.SetAnchorPoint(AnchorPoint::TOP_LEFT);
+  control1.SetParentOrigin(ParentOrigin::TOP_LEFT);
+  control2.SetParentOrigin(ParentOrigin::TOP_LEFT);
+  control1.SetPosition(0.0f, 0.0f);
+  control2.SetPosition(0.0f, 100.0f);
+
+  Stage::GetCurrent().Add(control1);
+  Stage::GetCurrent().Add(control2);
+
+  detector.Attach(control1);
+  detector.Attach(control2);
+
+  application.SendNotification();
+  application.Render(RENDER_FRAME_INTERVAL);
+
+  SignalData data;
+  DragSignalFunctor functor(data);
+  detector.DroppedSignal().Connect(&application, functor);
+
+  Vector2 screenCoordinates(10.0f, 10.0f);
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Down, screenCoordinates));
+
+  screenCoordinates.x = 10.0f;
+  screenCoordinates.y = 110.0f;
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Motion, screenCoordinates));
+
+  screenCoordinates.x = 10.0f;
+  screenCoordinates.y = 112.0f;
+  application.ProcessEvent(GenerateSingleTouch(TouchPoint::Up, screenCoordinates));
+
+  DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+  DALI_TEST_EQUALS(control2, data.control, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector2(10.0f, 112.0f), data.detector.GetCurrentScreenPosition(), TEST_LOCATION);
+  DALI_TEST_EQUALS("control1", detector.GetContent(), TEST_LOCATION);
+
+  data.Reset();
+
+  END_TEST;
+}
index 3d77bb8..53a4788 100644 (file)
@@ -160,6 +160,7 @@ develapitextselectionpopupdir = $(develapicontrolsdir)/text-controls
 develapitextdir =               $(develapidir)/text
 develapivisualfactorydir =      $(develapidir)/visual-factory
 develapivisualsdir =            $(develapidir)/visuals
 develapitextdir =               $(develapidir)/text
 develapivisualfactorydir =      $(develapidir)/visual-factory
 develapivisualsdir =            $(develapidir)/visuals
+develapidragdropdir =           $(develapidir)/drag-drop-detector
 
 # devel headers
 develapi_HEADERS =                  $(devel_api_header_files)
 
 # devel headers
 develapi_HEADERS =                  $(devel_api_header_files)
@@ -192,6 +193,7 @@ develapitooltip_HEADERS =           $(devel_api_tooltip_header_files)
 develapitransitioneffects_HEADERS = $(devel_api_transition_effects_header_files)
 develapitextselectionpopup_HEADERS = $(devel_api_text_controls_header_files)
 develapitext_HEADERS =              $(devel_api_text_header_files)
 develapitransitioneffects_HEADERS = $(devel_api_transition_effects_header_files)
 develapitextselectionpopup_HEADERS = $(devel_api_text_controls_header_files)
 develapitext_HEADERS =              $(devel_api_text_header_files)
+develapidragdrop_HEADERS =          $(devel_api_drag_and_drop_detector_header_files)
 
 # public api source
 publicapidir =                     $(topleveldir)/public-api
 
 # public api source
 publicapidir =                     $(topleveldir)/public-api
diff --git a/dali-toolkit/devel-api/drag-drop-detector/drag-and-drop-detector.cpp b/dali-toolkit/devel-api/drag-drop-detector/drag-and-drop-detector.cpp
new file mode 100755 (executable)
index 0000000..bbbcf51
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/devel-api/drag-drop-detector/drag-and-drop-detector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/drag-drop-detector/drag-and-drop-detector-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+DragAndDropDetector::DragAndDropDetector()
+{
+}
+
+DragAndDropDetector::~DragAndDropDetector()
+{
+}
+
+DragAndDropDetector DragAndDropDetector::New()
+{
+  return Internal::DragAndDropDetector::New();
+}
+
+void DragAndDropDetector::Attach(Control control)
+{
+  GetImplementation(*this).Attach(control);
+}
+
+void DragAndDropDetector::Detach(Control control)
+{
+  GetImplementation(*this).Detach(control);
+}
+
+void DragAndDropDetector::DetachAll()
+{
+  GetImplementation(*this).DetachAll();
+}
+
+uint32_t DragAndDropDetector::GetAttachedControlCount() const
+{
+  return GetImplementation(*this).GetAttachedControlCount();
+}
+
+Control DragAndDropDetector::GetAttachedControl(uint32_t index) const
+{
+  return GetImplementation(*this).GetAttachedControl(index);
+}
+
+const std::string& DragAndDropDetector::GetContent() const
+{
+  return GetImplementation(*this).GetContent();
+}
+
+const Vector2& DragAndDropDetector::GetCurrentScreenPosition() const
+{
+  return GetImplementation(*this).GetCurrentScreenPosition();
+}
+
+DragAndDropDetector::DragAndDropSignal& DragAndDropDetector::StartedSignal()
+{
+  return GetImplementation(*this).StartedSignal();
+}
+
+DragAndDropDetector::DragAndDropSignal& DragAndDropDetector::EnteredSignal()
+{
+  return GetImplementation(*this).EnteredSignal();
+}
+
+DragAndDropDetector::DragAndDropSignal& DragAndDropDetector::ExitedSignal()
+{
+  return GetImplementation(*this).ExitedSignal();
+}
+
+DragAndDropDetector::DragAndDropSignal& DragAndDropDetector::MovedSignal()
+{
+  return GetImplementation(*this).MovedSignal();
+}
+
+DragAndDropDetector::DragAndDropSignal& DragAndDropDetector::DroppedSignal()
+{
+  return GetImplementation(*this).DroppedSignal();
+}
+
+DragAndDropDetector::DragAndDropSignal& DragAndDropDetector::EndedSignal()
+{
+  return GetImplementation(*this).EndedSignal();
+}
+
+DragAndDropDetector::DragAndDropDetector( Internal::DragAndDropDetector* detector )
+: BaseHandle( detector )
+{
+}
+
+} //namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/drag-drop-detector/drag-and-drop-detector.h b/dali-toolkit/devel-api/drag-drop-detector/drag-and-drop-detector.h
new file mode 100755 (executable)
index 0000000..2bd34db
--- /dev/null
@@ -0,0 +1,272 @@
+#ifndef __DALI_DRAG_AND_DROP_DETECTOR_H__
+#define __DALI_DRAG_AND_DROP_DETECTOR_H__
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-handle.h>
+#include <dali/public-api/signals/dali-signal.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/dali-toolkit-common.h>
+
+#include <dali-toolkit/public-api/controls/control.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+class DragAndDropDetector;
+}
+
+/**
+ * @brief The DragAndDropDetector%s provides signals when draggable objects are dragged into other object.
+ *
+ * It provides signals for when the draggable object start drag, draggable object enters other object, moves around in other object,
+ * leaves other object, dropped into other object and finally when the drag ended.
+ *
+ * The basic usage is shown below:
+ *
+ * @code
+ *
+ *  void Example()
+ *  {
+ *    DragAndDropDetector detector = DragAndDropDetector::New();
+ *
+ *    // Get notifications when the draggable item start drag
+ *    detector.StartedSignal().Connect( &OnStarted );
+ *
+ *    // Get notifications when the draggable item enters other item
+ *    detector.EnteredSignal().Connect( &OnEntered );
+ *
+ *    // Get notifications when the draggable item leaves other item
+ *    detector.ExitedSignal().Connect( &OnExited );
+ *
+ *    // Get notifications when the draggable item is moved within other item
+ *    detector.MovedSignal().Connect( &OnMoved );
+ *
+ *    // Get notifications when the draggable item is dropped
+ *    detector.DroppedSignal().Connect( &OnDropped );
+ *
+ *    // Get notifications when the draggable object drag ended
+ *    detector.EndedSignal().Connect( &OnEnded );
+ *  }
+ *
+ *  void OnStarted( Control control, DragAndDropDetector detector )
+ *  {
+ *    // Query the new values
+ *    std::cout << "Position = " << detector.GetCurrentScreenPosition() << std::endl;
+ *  }
+ *
+ *  void OnEntered( Control control, DragAndDropDetector detector )
+ *  {
+ *    // Change mode as required
+ *  }
+ *
+ *  void OnExited( Control control, DragAndDropDetector detector )
+ *  {
+ *    // Change mode as required
+ *  }
+ *
+ *  void OnMoved( Control control, DragAndDropDetector detector )
+ *  {
+ *    // Query the new values
+ *    std::cout << "Position = " << detector.GetCurrentScreenPosition() << std::endl;
+ *  }
+ *
+ *  void OnDropped( Control control, DragAndDropDetector detector )
+ *  {
+ *    // Query the new values
+ *    std::cout << "Position = " << detector.GetCurrentScreenPosition() << ", Content = " << detector.GetContent() << std::endl;
+ *  }
+ *
+ *  void OnEnded( Control control, DragAndDropDetector detector )
+ *  {
+ *    // Change mode as required
+ *  }
+ *
+ * @endcode
+ */
+class DALI_TOOLKIT_API DragAndDropDetector : public BaseHandle
+{
+public:
+
+  // Typedefs
+
+  using DragAndDropSignal = Signal< void ( Control, DragAndDropDetector ) >; ///< Drag & Drop signal
+
+  /**
+   * @brief Create an initialized DragAndDropDetector.
+   *
+   * @return A handle to a newly allocated Dali DragAndDropDetector
+   */
+  static DragAndDropDetector New();
+
+  /**
+   * @brief Create an uninitialized handle.
+   *
+   * This can be initialized with DragAndDropDetector::New().
+   */
+  DragAndDropDetector();
+
+  /**
+   * @brief Destructor
+   *
+   * This is non-virtual since derived Handle types must not contain data or virtual methods.
+   */
+  ~DragAndDropDetector();
+
+  /**
+   * @brief Returns the dropped content.
+   *
+   * @return A reference to the string representing the dropped content.
+   */
+  const std::string& GetContent() const;
+
+  /**
+   * @brief Attaches a Control to the detector.
+   *
+   * @note You can attach several controls to a DragAndDropDetector.
+   * DragAndDropDetector will keep a handle to the control and keep it alive as long as
+   * DragAndDropDetector is deleted or Detach is called.
+   */
+  void Attach(Control control);
+
+  /**
+   * @brief Detaches the attached control from the detector.
+   *
+   * @pre The specified control has been attached to the DragAndDropDetector.
+   */
+  void Detach(Control control);
+
+  /**
+   * @brief Detaches all attached control from the detector.
+   *
+   * @pre At least one control has been attached to the DragAndDropDetector.
+   */
+  void DetachAll();
+
+  /**
+   * @brief Returns the number of controls attached to the DragAndDropDetector.
+   *
+   * @pre The DragAndDropDetector has been initialized.
+   */
+  uint32_t GetAttachedControlCount() const;
+
+  /**
+   * @brief Returns a control by index. An empty handle if the index is not valid.
+   *
+   * @pre The DragAndDropDetector has been initialized.
+   */
+  Control GetAttachedControl(uint32_t index) const;
+
+  /**
+   * @brief Returns the current position of the dragged object.
+   *
+   * This is the dropped position when an object is dropped.
+   * @return The current screen position.
+   */
+  const Vector2& GetCurrentScreenPosition() const;
+
+  // Signals
+  /**
+   * @brief This is emitted when a dragged object start drag.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallback( Control control, DragAndDropDetector detector );
+   * @endcode
+   * @return The signal to connect to.
+   */
+  DragAndDropSignal& StartedSignal();
+
+  /**
+   * @brief This is emitted when a dragged object enters other object.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallback( Control control, DragAndDropDetector detector );
+   * @endcode
+   * @return The signal to connect to.
+   */
+  DragAndDropSignal& EnteredSignal();
+
+  /**
+   * @brief This is emitted when a dragged object leaves other object.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallback( Control control, DragAndDropDetector detector );
+   * @endcode
+   * @return The signal to connect to.
+   */
+  DragAndDropSignal& ExitedSignal();
+
+  /**
+   * @brief This is emitted when a dragged object is moved within other object.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallback( Control control, DragAndDropDetector detector );
+   * @endcode
+   * @return The signal to connect to.
+   */
+  DragAndDropSignal& MovedSignal();
+
+  /**
+   * @brief This is emitted when a dragged object is dropped within other object.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallback( Control control, DragAndDropDetector detector );
+   * @endcode
+   * @return The signal to connect to.
+   */
+  DragAndDropSignal& DroppedSignal();
+
+  /**
+   * @brief This is emitted when a dragged object drag ended.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallback( Control control, DragAndDropDetector detector );
+   * @endcode
+   * @return The signal to connect to.
+   */
+  DragAndDropSignal& EndedSignal();
+
+public: // Not intended for application developers
+
+  /**
+   * @brief This constructor is used by DragAndDropDetector::Get().
+   *
+   * @param[in] detector A pointer to the drag and drop detector.
+   */
+  explicit DALI_INTERNAL DragAndDropDetector( Internal::DragAndDropDetector* detector );
+};
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_DRAG_AND_DROP_DETECTOR_H__
index 1cad2f5..14cb246 100755 (executable)
@@ -54,7 +54,8 @@ devel_api_src_files = \
   $(devel_api_src_dir)/visual-factory/transition-data.cpp \
   $(devel_api_src_dir)/visual-factory/visual-factory.cpp \
   $(devel_api_src_dir)/visual-factory/visual-base.cpp \
   $(devel_api_src_dir)/visual-factory/transition-data.cpp \
   $(devel_api_src_dir)/visual-factory/visual-factory.cpp \
   $(devel_api_src_dir)/visual-factory/visual-base.cpp \
-  $(devel_api_src_dir)/controls/gaussian-blur-view/gaussian-blur-view.cpp
+  $(devel_api_src_dir)/controls/gaussian-blur-view/gaussian-blur-view.cpp \
+  $(devel_api_src_dir)/drag-drop-detector/drag-and-drop-detector.cpp
 
 # Add devel header files here
 
 
 # Add devel header files here
 
@@ -197,3 +198,6 @@ devel_api_gaussian_blur_view_header_files = \
 
 devel_api_web_view_header_files = \
   $(devel_api_src_dir)/controls/web-view/web-view.h
 
 devel_api_web_view_header_files = \
   $(devel_api_src_dir)/controls/web-view/web-view.h
+
+devel_api_drag_and_drop_detector_header_files = \
+  $(devel_api_src_dir)/drag-drop-detector/drag-and-drop-detector.h
diff --git a/dali-toolkit/internal/drag-drop-detector/drag-and-drop-detector-impl.cpp b/dali-toolkit/internal/drag-drop-detector/drag-and-drop-detector-impl.cpp
new file mode 100755 (executable)
index 0000000..c26e4ae
--- /dev/null
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/drag-drop-detector/drag-and-drop-detector-impl.h>
+
+#include <dali/public-api/events/point-state.h>
+#include <dali/public-api/events/touch-data.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+Dali::Toolkit::DragAndDropDetector DragAndDropDetector::New()
+{
+  Dali::Toolkit::DragAndDropDetector detector = Dali::Toolkit::DragAndDropDetector(new DragAndDropDetector());
+
+  return detector;
+}
+
+void DragAndDropDetector::Attach(Dali::Toolkit::Control& control)
+{
+  if(control)
+  {
+    if(!mControls.empty())
+    {
+      auto match = std::find(mControls.begin(), mControls.end(), control);
+      if(match != mControls.end())
+      {
+        return;
+      }
+    }
+    mControls.push_back(control);
+    control.TouchSignal().Connect(this, &DragAndDropDetector::OnDrag);
+    mFirstEnter.push_back(control.GetId());
+    mPanGestureDetector.Attach(control);
+    mPanGestureDetector.DetectedSignal().Connect(this, &DragAndDropDetector::OnPan);
+  }
+
+}
+
+void DragAndDropDetector::Detach(Dali::Toolkit::Control& control)
+{
+  if(!mControls.empty())
+  {
+    if(!control)
+    {
+      return;
+    }
+
+    auto match = std::find(mControls.begin(), mControls.end(), control);
+
+    if(match != mControls.end())
+    {
+      match->TouchSignal().Disconnect(this, &DragAndDropDetector::OnDrag);
+      mPanGestureDetector.Detach(*match);
+      mFirstEnter.erase(std::find(mFirstEnter.begin(), mFirstEnter.end(), control.GetId()));
+      mControls.erase(match);
+    }
+  }
+}
+
+void DragAndDropDetector::DetachAll()
+{
+  if(!mControls.empty())
+  {
+    auto iter = mControls.begin();
+    for(;iter != mControls.end();)
+    {
+      iter->TouchSignal().Disconnect(this, &DragAndDropDetector::OnDrag);
+      mPanGestureDetector.Detach(*iter);
+      iter = mControls.erase(iter);
+    }
+  }
+
+  if(!mFirstEnter.empty())
+  {
+    auto iter = mFirstEnter.begin();
+    for(;iter != mFirstEnter.end();)
+    {
+      iter = mFirstEnter.erase(iter);
+    }
+  }
+}
+
+uint32_t DragAndDropDetector::GetAttachedControlCount() const
+{
+  return mControls.size();
+}
+
+Dali::Toolkit::Control DragAndDropDetector::GetAttachedControl(uint32_t index) const
+{
+  Dali::Toolkit::Control control;
+
+  if(index < mControls.size())
+  {
+    control = mControls[index];
+  }
+
+  return control;
+}
+
+void DragAndDropDetector::OnPan(Dali::Actor actor, const PanGesture& gesture)
+{
+  Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
+
+  if(gesture.state == Gesture::Started)
+  {
+    mDragLocalPosition = gesture.position;
+  }
+  if(gesture.state == Gesture::Continuing)
+  {
+      Vector2 screenPosition = gesture.screenPosition;
+      control.GetParent().ScreenToLocal(mLocalPosition.x, mLocalPosition.y, screenPosition.x, screenPosition.y);
+      mShadowControl.SetPosition(mLocalPosition.x - mDragLocalPosition.x, mLocalPosition.y - mDragLocalPosition.y);
+  }
+  if(gesture.state == Gesture::Finished)
+  {
+    mDragControl.GetParent().Remove(mShadowControl);
+    EmitEndedSignal(control);
+  }
+}
+
+bool DragAndDropDetector::OnDrag(Dali::Actor actor, const Dali::TouchData& data)
+{
+  Dali::Toolkit::Control control = Dali::Toolkit::Control::DownCast(actor);
+  PointState::Type type = data.GetState(0);
+  if(type == PointState::DOWN)
+  {
+    mPointDown = true;
+    mDragControl = control;
+    mFirstEnter.clear();
+    for( auto&& control : mControls)
+    {
+      mFirstEnter.push_back(control.GetId());
+    }
+    float width = control.GetProperty<float>(Dali::Actor::Property::SIZE_WIDTH);
+    float height = control.GetProperty<float>(Dali::Actor::Property::SIZE_HEIGHT);
+    Vector3 actorPos = control.GetProperty<Vector3>(Dali::Actor::Property::POSITION);
+
+    mShadowControl = Dali::Toolkit::Control::New();
+    mShadowControl.SetPosition(actorPos);
+    mShadowControl.SetSize(width, height);
+    mShadowControl.SetBackgroundColor(Vector4(0.3f, 0.3f, 0.3f, 0.7f));
+    mShadowControl.SetParentOrigin(control.GetCurrentParentOrigin());
+    mShadowControl.SetAnchorPoint(control.GetCurrentAnchorPoint());
+    control.GetParent().Add(mShadowControl);
+    SetPosition(data.GetScreenPosition(0));
+    EmitStartedSignal(control);
+  }
+
+  if(type == PointState::MOTION)
+  {
+    if(mDragControl != control && mPointDown)
+    {
+      auto found = std::find(mFirstEnter.begin(), mFirstEnter.end(), control.GetId());
+      if(mFirstEnter.end() != found)
+      {
+        SetPosition(data.GetScreenPosition(0));
+        mFirstEnter.erase(found);
+        EmitEnteredSignal(control);
+      }
+      else
+      {
+        SetPosition(data.GetScreenPosition(0));
+        EmitMovedSignal(control);
+      }
+    }
+  }
+
+  if(type == PointState::LEAVE)
+  {
+    if(mDragControl != control && mPointDown)
+    {
+      mFirstEnter.push_back(control.GetId());
+      EmitExitedSignal(control);
+    }
+  }
+
+  if(type == PointState::UP)
+  {
+    if(mDragControl != control && mPointDown)
+    {
+      SetPosition(data.GetScreenPosition(0));
+      ClearContent();
+      SetContent(mDragControl.GetName());
+      EmitDroppedSignal(control);
+    }
+
+    if(mShadowControl)
+    {
+    control.GetParent().Remove(mShadowControl);
+    }
+    mPointDown = false;
+  }
+  return true;
+}
+
+const std::string& DragAndDropDetector::GetContent() const
+{
+  return mContent;
+}
+
+const Vector2& DragAndDropDetector::GetCurrentScreenPosition() const
+{
+  return mScreenPosition;
+}
+
+void DragAndDropDetector::SetContent( const std::string& content )
+{
+  mContent = content;
+}
+
+void DragAndDropDetector::ClearContent()
+{
+  mContent.clear();
+}
+
+void DragAndDropDetector::SetPosition( const Vector2& screenPosition )
+{
+  mScreenPosition = screenPosition;
+}
+
+void DragAndDropDetector::EmitStartedSignal(Dali::Toolkit::Control& control)
+{
+  if( !mStartedSignal.Empty() )
+  {
+    Dali::Toolkit::DragAndDropDetector handle( this );
+    mStartedSignal.Emit( control, handle );
+  }
+}
+void DragAndDropDetector::EmitEnteredSignal(Dali::Toolkit::Control& control)
+{
+  if ( !mEnteredSignal.Empty() )
+  {
+    Dali::Toolkit::DragAndDropDetector handle( this );
+    mEnteredSignal.Emit( control, handle );
+  }
+}
+
+void DragAndDropDetector::EmitExitedSignal(Dali::Toolkit::Control& control)
+{
+  if ( !mExitedSignal.Empty() )
+  {
+    Dali::Toolkit::DragAndDropDetector handle( this );
+    mExitedSignal.Emit( control, handle );
+  }
+}
+
+void DragAndDropDetector::EmitMovedSignal(Dali::Toolkit::Control& control)
+{
+  if ( !mMovedSignal.Empty() )
+  {
+    Dali::Toolkit::DragAndDropDetector handle( this );
+    mMovedSignal.Emit( control, handle );
+  }
+}
+
+void DragAndDropDetector::EmitDroppedSignal(Dali::Toolkit::Control& control)
+{
+  if ( !mDroppedSignal.Empty() )
+  {
+    Dali::Toolkit::DragAndDropDetector handle( this );
+    mDroppedSignal.Emit( control, handle );
+  }
+}
+
+void DragAndDropDetector::EmitEndedSignal(Dali::Toolkit::Control& control)
+{
+  if( !mEndedSignal.Empty() )
+  {
+    Dali::Toolkit::DragAndDropDetector handle( this );
+    mEndedSignal.Emit( control, handle );
+  }
+}
+
+DragAndDropDetector::DragAndDropDetector()
+: mContent(),
+  mScreenPosition()
+{
+  mPanGestureDetector = Dali::PanGestureDetector::New();
+  mPointDown = false;
+}
+
+DragAndDropDetector::~DragAndDropDetector()
+{
+}
+
+} // namespace Internal
+
+} //namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/drag-drop-detector/drag-and-drop-detector-impl.h b/dali-toolkit/internal/drag-drop-detector/drag-and-drop-detector-impl.h
new file mode 100755 (executable)
index 0000000..e2e1c47
--- /dev/null
@@ -0,0 +1,269 @@
+#ifndef __DALI_INTERNAL_DRAG_AND_DROP_DETECTOR_H__
+#define __DALI_INTERNAL_DRAG_AND_DROP_DETECTOR_H__
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <string>
+#include <vector>
+#include <algorithm>
+
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/math/vector2.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/drag-drop-detector/drag-and-drop-detector.h>
+#include <dali/public-api/events/pan-gesture-detector.h>
+#include <dali/public-api/events/pan-gesture.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+using DragAndDropDetectorPtr = IntrusivePtr< DragAndDropDetector >;
+
+/**
+ * This class listens to Drag & Drop events.
+ */
+class DragAndDropDetector : public Dali::BaseObject, public ConnectionTracker
+{
+public:
+
+  using DragAndDropSignal = Dali::Toolkit::DragAndDropDetector::DragAndDropSignal;
+
+  // Creation
+
+  /**
+   * @copydoc Toolkit::DragAndDropDetector::New()
+   */
+  static Dali::Toolkit::DragAndDropDetector New();
+
+  // Public API
+
+  /**
+   * @copydoc Dali::DragAndDropDetector::GetContent() const
+   */
+  const std::string& GetContent() const;
+
+  /**
+   * @copydoc Dali::DragAndDropDetector::GetCurrentScreenPosition() const
+   */
+  const Vector2& GetCurrentScreenPosition() const;
+
+  /**
+   * Attaches control to DragAndDropDetector.
+   * @param[in] control  control that will be attached to DragAndDropDetector.
+   */
+  void Attach(Dali::Toolkit::Control& control);
+
+  /**
+   * Detaches control to DragAndDropDetector.
+   * @param[in] control  control that will be Detached from DragAndDropDetector.
+   */
+  void Detach(Dali::Toolkit::Control& control);
+
+  /**
+   * Detaches all control attached to DragAndDropDetector.
+   */
+  void DetachAll();
+
+  /**
+   * Returns the number of controls attached to the DragAndDropDetector.
+   */
+  uint32_t GetAttachedControlCount() const;
+
+  /**
+   * Returns a control by index. An empty handle if the index is not valid.
+   */
+  Dali::Toolkit::Control GetAttachedControl(uint32_t index) const;
+
+  /**
+   * Sets the dragged content.
+   * @param[in] content  A string that represents the content that has been dropped.
+   */
+  void SetContent( const std::string& content );
+
+  /**
+   * Clears the stored content.
+   */
+  void ClearContent();
+
+  /**
+   * Sets the position the drop occurred.
+   */
+  void SetPosition( const Vector2& screenPosition );
+
+  /**
+   * Called when a draggable object start drag.
+   */
+  void EmitStartedSignal(Dali::Toolkit::Control& control);
+
+  /**
+   * Called when a draggable object enters other object.
+   */
+  void EmitEnteredSignal(Dali::Toolkit::Control& control);
+
+  /**
+   * Called when a draggable object leaves other object.
+   */
+  void EmitExitedSignal(Dali::Toolkit::Control& control);
+
+  /**
+   * Called when a draggable object leaves other object.
+   */
+  void EmitMovedSignal(Dali::Toolkit::Control& control);
+
+  /**
+   * Is called when a drop actually occurs.
+   */
+  void EmitDroppedSignal(Dali::Toolkit::Control& control);
+
+  /**
+   * Called when a draggable object drag ended.
+   */
+  void EmitEndedSignal(Dali::Toolkit::Control& control);
+
+public: // Signals
+
+  /**
+   * @copydoc Dali::Toolkit::DragAndDropDetector::StartedSignal
+   */
+  DragAndDropSignal& StartedSignal()
+  {
+    return mStartedSignal;
+  }
+
+  /**
+   * @copydoc Dali::Toolkit::DragAndDropDetector::EnteredSignal
+   */
+  DragAndDropSignal& EnteredSignal()
+  {
+    return mEnteredSignal;
+  }
+
+  /**
+   * @copydoc Dali::Toolkit::DragAndDropDetector::ExitedSignal
+   */
+  DragAndDropSignal& ExitedSignal()
+  {
+    return mExitedSignal;
+  }
+
+  /**
+   * @copydoc Dali::Toolkit::DragAndDropDetector::MovedSignal
+   */
+  DragAndDropSignal& MovedSignal()
+  {
+    return mMovedSignal;
+  }
+
+  /**
+   * @copydoc Dali::Toolkit::DragAndDropDetector::DroppedSignal
+   */
+  DragAndDropSignal& DroppedSignal()
+  {
+    return mDroppedSignal;
+  }
+
+  /**
+   * @copydoc Dali::Toolkit::DragAndDropDetector::DroppedSignal
+   */
+  DragAndDropSignal& EndedSignal()
+  {
+    return mEndedSignal;
+  }
+
+public:
+  bool OnDrag(Dali::Actor actor, const Dali::TouchData& data);
+  void OnPan(Dali::Actor actor, const PanGesture& gesture);
+
+private:
+
+  // Construction & Destruction
+
+  /**
+   * Constructor.
+   */
+  DragAndDropDetector();
+
+  /**
+   * Destructor.
+   */
+  virtual ~DragAndDropDetector();
+
+  // Undefined
+  DragAndDropDetector( const DragAndDropDetector& ) = delete;
+  DragAndDropDetector& operator=( DragAndDropDetector& );
+
+private:
+
+  std::string mContent;    ///< The current Drag & drop content.
+
+  DragAndDropSignal mStartedSignal;
+  DragAndDropSignal mEnteredSignal;
+  DragAndDropSignal mExitedSignal;
+  DragAndDropSignal mMovedSignal;
+  DragAndDropSignal mDroppedSignal;
+  DragAndDropSignal mEndedSignal;
+
+  std::vector<Dali::Toolkit::Control> mControls;      //controls attached by Attach interface for drag&drop
+  Dali::Toolkit::Control mDragControl;                //the current drag control
+  Dali::Toolkit::Control mShadowControl;              //a shadow control for indicating where the control is, same size as the dragged control
+  std::vector<uint32_t> mFirstEnter;                  //control id indicating if the cursor is enter
+  Dali::PanGestureDetector mPanGestureDetector;       //pangesture for calculating the shadow actor position
+
+  Vector2 mLocalPosition;
+  Vector2 mDragLocalPosition;
+  Vector2 mScreenPosition; ///< The screen position of the drop location.
+
+  bool mPointDown; //bool flag to indicate if PointState::DOWN have been processed
+};
+
+} // namespace Internal
+
+
+// Helpers for public-api forwarding methods
+
+inline Internal::DragAndDropDetector& GetImplementation(Dali::Toolkit::DragAndDropDetector& detector)
+{
+  DALI_ASSERT_ALWAYS( detector && "DragAndDropDetector handle is empty" );
+
+  BaseObject& handle = detector.GetBaseObject();
+
+  return static_cast<Internal::DragAndDropDetector&>(handle);
+}
+
+inline const Internal::DragAndDropDetector& GetImplementation(const Dali::Toolkit::DragAndDropDetector& detector)
+{
+  DALI_ASSERT_ALWAYS( detector && "DragAndDropDetector handle is empty" );
+
+  const BaseObject& handle = detector.GetBaseObject();
+
+  return static_cast<const Internal::DragAndDropDetector&>(handle);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_DRAG_AND_DROP_DETECTOR_H__
index 8fab9fd..1799a2a 100755 (executable)
@@ -173,4 +173,5 @@ toolkit_src_files = \
    $(toolkit_src_dir)/transition-effects/cube-transition-wave-effect-impl.cpp \
    $(toolkit_src_dir)/scripting/script-impl.cpp \
    $(toolkit_src_dir)/scripting/script-plugin-proxy.cpp \
    $(toolkit_src_dir)/transition-effects/cube-transition-wave-effect-impl.cpp \
    $(toolkit_src_dir)/scripting/script-impl.cpp \
    $(toolkit_src_dir)/scripting/script-plugin-proxy.cpp \
-   $(toolkit_src_dir)/text/xhtml-entities.cpp
+   $(toolkit_src_dir)/text/xhtml-entities.cpp \
+   $(toolkit_src_dir)/drag-drop-detector/drag-and-drop-detector-impl.cpp