yakov pushed a commit to branch master.

http://git.enlightenment.org/tools/erigo.git/commit/?id=eb675d1d24d5debb7f572a2c71dc47b49fa75b76

commit eb675d1d24d5debb7f572a2c71dc47b49fa75b76
Author: Yakov Goldberg <yako...@samsung.com>
Date:   Sun Oct 11 14:06:10 2015 +0300

    Refactoring DnD
    
    - separate drag from drop: it is posible now to drag/drop from/to exteranal 
apps
    - DnD use memento to handle cases when Drag was started but not accepted
---
 src/bin/gui/dnd.c        | 457 +++++++++++++++++++----------
 src/bin/gui/dnd.h        |  29 +-
 src/bin/gui/editor.c     | 742 ++++++++++++++++-------------------------------
 src/bin/gui/egui_logic.c |   1 -
 src/lib/gui_parser.c     |  16 +-
 src/lib/gui_parser.h     |   2 +-
 src/lib/gui_widget.c     |   1 -
 7 files changed, 587 insertions(+), 661 deletions(-)

diff --git a/src/bin/gui/dnd.c b/src/bin/gui/dnd.c
index 759c86a..1c4b4f1 100644
--- a/src/bin/gui/dnd.c
+++ b/src/bin/gui/dnd.c
@@ -13,25 +13,25 @@
 #include "elm_widget.h"
 #include "dnd.h"
 
+#define TIME_TO_DRAG 0.1
+#define DND_IMAGE_SIZE 15
+#define DROP_TARGET "__drop_target__"
+#define DRAG_ITEM_CONTAINER_INFO "__drag_item_container_info__"
+
+/* Information about dragged or draggable(factory) object*/
 typedef struct
 {
-   Eid *wdg_id; /*DnD data*/
+   Eid *wdg_id; /*Widget id*/
    char *image_path; /* image for DnD icon. */
-   Eo *obj; /*object, where drag starts */
+   Eo *obj; /*object, where drag starts. Used to call cb on delete.  */
    Eo *drag_window_obj_wref;
-   const Gui_Widget *wdg; /* Dragged widget only used during drag */
 
-   void (*_drag_start_post_cb)(const Gui_Widget *wdg, const Eo *obj);
-} Drag_Info;
+   Eina_Bool drag_accept;
+   void (*dragdone_post_cb)(Eina_Bool accept);
 
-static Ecore_Timer *_drag_factory_timer = NULL;
-typedef struct
-{
-   Drag_Info *drag_info;
-   int dnd_in_out; /* Main objects enter/leave counter*/
-   const Gui_Widget *wdg_src;
-} DnD_Info;
+} Drag_Info;
 
+/* Information about Drop Target*/
 typedef struct
 {
    const Gui_Widget *wdg;
@@ -46,31 +46,72 @@ typedef struct
 
    Eo *obj; /* This obj is used only to properly call elm_drop_target_del() */
    const Gui_Widget *drop_target;
-} Target_Info;
+} Drop_Target_Info;
 
-#define TIME_TO_DRAG 0.1
-#define DND_IMAGE_SIZE 15
-#define DROP_TARGET "__drop_target__"
+/* Structure to keed data about current Drop events. */
+typedef struct
+{
+   int _enter_leave_counter;
+   char *_drop_data;
+   Eina_Bool _drop_data_requested;
+} _Drop_Info_Global;
 
-static DnD_Info _dnd_info;
+static _Drop_Info_Global _drop_info_global = {0, NULL, EINA_FALSE};
 
-/* Determine if dragged object is inside droppable. */
-Eina_Bool
-dnd_is_in_drop_target()
+/* Structure to keed data about current Drag event. */
+typedef struct
 {
-   return !!_dnd_info.dnd_in_out;
+   Drag_Info *drag_info;
+   const Gui_Widget *wdg_src;
+   char *_drag_data; /*Allocated on drag_start and deleted in dragdone*/
+} _Drag_Info_Global;
+
+static _Drag_Info_Global _drag_info_global = {NULL, NULL, NULL};
+
+static Ecore_Timer *_drag_factory_timer = NULL;
+
+static void
+_drop_data_free()
+{
+   if (_drop_info_global._drop_data)
+     {
+        free(_drop_info_global._drop_data);
+        _drop_info_global._drop_data = NULL;
+     }
+   _drop_info_global._drop_data_requested = EINA_FALSE;
+}
+
+int dnd_counter_get()
+{
+   return _drop_info_global._enter_leave_counter;
 }
 
-char *
-dnd_drag_data_get()
+static void
+_drop_data_request()
+{
+   if (_drop_info_global._drop_data_requested) return;
+
+   if (!_drop_info_global._drop_data)
+     {
+        if (_drag_info_global._drag_data)
+          _drop_info_global._drop_data = strdup(_drag_info_global._drag_data);
+        /* Request data about dragged object*/
+     }
+   _drop_info_global._drop_data_requested = EINA_TRUE;
+}
+
+const char *
+dnd_drop_data_get()
 {
-   return json_widget_generate(_dnd_info.drag_info->wdg_id);
+   if (!_drop_info_global._drop_data)
+     _drop_data_request();
+   return _drop_info_global._drop_data;
 }
 
 void
 dnd_drag_window_object_visibility_set(Eina_Bool visibility)
 {
-   eo_do(_dnd_info.drag_info->drag_window_obj_wref, 
efl_gfx_visible_set(visibility));
+   eo_do(_drag_info_global.drag_info->drag_window_obj_wref, 
efl_gfx_visible_set(visibility));
 }
 
 Eina_Bool
@@ -79,41 +120,63 @@ dnd_is_source()
    return !!dnd_drag_wdg_get();
 }
 
+Eina_Bool
+dnd_is_destination()
+{
+   return !!_drop_info_global._enter_leave_counter;
+}
+
 const Gui_Widget *
 dnd_drag_wdg_get()
 {
-   return _dnd_info.wdg_src;
+   return _drag_info_global.wdg_src;
 }
 
 static void
 _dragpos(void *data EINA_UNUSED, Eo * obj EINA_UNUSED, Evas_Coord x 
EINA_UNUSED, Evas_Coord y EINA_UNUSED, Elm_Xdnd_Action action EINA_UNUSED)
 {
-   //ERR("%s: %d %d", (char *) data, x, y);
+//   ERR("%s: %d %d", (char *) data, x, y);
 }
 
 static void
-_dragaccept(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, Eina_Bool 
doaccept EINA_UNUSED)
+_dragaccept(void *data, Evas_Object *obj EINA_UNUSED, Eina_Bool doaccept 
EINA_UNUSED)
 {
-   //ERR("accept: %d", doaccept);
+//   ERR("accept: %d; %s", doaccept, (char *) data);
+     Drag_Info *di = data;
+     if (di)
+       di->drag_accept = doaccept;
 }
 
 static void
-_dragdone(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED)
+_dragdone(void *data, Evas_Object *obj EINA_UNUSED)
 {
-   ERR("In");
-//   _dnd_info.wdg_src = NULL;
+   if (_drag_info_global._drag_data) free(_drag_info_global._drag_data);
+   _drag_info_global._drag_data = NULL;
+
+   Drag_Info *di = data;
+   if (di)
+     {
+        if (di->dragdone_post_cb)
+          {
+             di->dragdone_post_cb(di->drag_accept);
+          }
+     }
+
+   /* if dropping outside, NULL this pointer*/
+   if (!dnd_is_destination())
+     _drag_info_global.wdg_src = NULL;
 }
 
 /* This callback is called only for a window object.
- * So Target_Info -> wdg is always Main Widget.
+ * So Drop_Target_Info -> wdg is always Main Widget.
  * Obj is not NULL only for Canvas, which can be also be a drop target. */
 static void
 _dropenter(void *data, Evas_Object *obj)
 {
-   _dnd_info.dnd_in_out++;
+   _drop_info_global._enter_leave_counter++;
    /* data is NULL when entering/leaving objtree. */
    if (!data) return;
-   Target_Info *ti = data;
+   Drop_Target_Info *ti = data;
    ti->drop_target = ti->wdg;
 
    if (ti->drop_target_enter)
@@ -121,15 +184,15 @@ _dropenter(void *data, Evas_Object *obj)
 }
 
 /* This callback is called only for a window object.
- * So Target_Info -> wdg is always Main Widget.
+ * So Drop_Target_Info -> wdg is always Main Widget.
  * Obj is not NULL only for Canvas, which can be also be a drop target. */
 static void
 _dropleave(void *data, Evas_Object *obj)
 {
-   _dnd_info.dnd_in_out--;
+   _drop_info_global._enter_leave_counter--;
    /* data is NULL when entering/leaving objtree. */
    if (!data) return;
-   Target_Info *main_wdg_ti = data;
+   Drop_Target_Info *main_wdg_ti = data;
 
    /* if ti->drop_target is not current main widget, then it means,
     * that prev drop target, box for example wasn't leaved properly.
@@ -138,7 +201,7 @@ _dropleave(void *data, Evas_Object *obj)
     * */
    if (main_wdg_ti->drop_target != main_wdg_ti->wdg)
      {
-        Target_Info *ti = wdg_data_get(main_wdg_ti->drop_target, DROP_TARGET);
+        Drop_Target_Info *ti = wdg_data_get(main_wdg_ti->drop_target, 
DROP_TARGET);
         if (ti->drop_target_leave)
           ti->drop_target_leave(ti->leavedata, obj);
      }
@@ -146,13 +209,19 @@ _dropleave(void *data, Evas_Object *obj)
 
    if (main_wdg_ti->drop_target_leave)
      main_wdg_ti->drop_target_leave(main_wdg_ti->leavedata, obj);
+
+   if (!_drop_info_global._enter_leave_counter)
+     {
+        _drop_data_free();
+     }
 }
 
 static Eina_Bool
-_dropcb(void *data EINA_UNUSED, Evas_Object *obj, Elm_Selection_Data *ev)
+_dropcb(void *data, Evas_Object *obj, Elm_Selection_Data *ev)
 {
-   Target_Info *main_wdg_ti = data;
-   Target_Info *ti;
+   Drop_Target_Info *main_wdg_ti = data;
+   Drop_Target_Info *ti;
+
    /* if drop_target == NULL, then we drop on MAIN CANVAS*/
    if (main_wdg_ti->drop_target)
      {
@@ -165,7 +234,10 @@ _dropcb(void *data EINA_UNUSED, Evas_Object *obj, 
Elm_Selection_Data *ev)
 
    if (ti->drop_target_drop)
      ti->drop_target_drop(ti->dropdata, obj, ev);
-   _dnd_info.wdg_src = NULL;
+   _drag_info_global.wdg_src = NULL;
+
+   _drop_info_global._enter_leave_counter = 0;
+   _drop_data_free();
    return EINA_TRUE;
 }
 
@@ -236,11 +308,11 @@ _drop_target_iterate(Gui_Widget **drop_candidate, const 
Gui_Session *session, Ev
 }
 
 /* This callback is called every time for a window object.
- * So Target_Info -> wdg is always Main Widget*/
+ * So Drop_Target_Info -> wdg is always Main Widget*/
 static void
 _droppos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action 
action)
 {
-   Target_Info *main_wdg_ti = data;
+   Drop_Target_Info *main_wdg_ti = data;
    const Gui_Widget *wdg = main_wdg_ti->wdg;
 
    /* For canvas only*/
@@ -266,20 +338,19 @@ _droppos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, 
Elm_Xdnd_Action action
      {
         /* Call leave callback for previous target widget.
          * If prev wdg is MainWdg, don't call leave. */
-        if (main_wdg_ti->drop_target != wdg)
+        //if (main_wdg_ti->drop_target != wdg)
           {
-             Target_Info *ti = wdg_data_get(main_wdg_ti->drop_target, 
DROP_TARGET);
+             Drop_Target_Info *ti = wdg_data_get(main_wdg_ti->drop_target, 
DROP_TARGET);
              if (ti->drop_target_leave)
                {
                   ti->drop_target_leave(ti->leavedata, NULL);
                }
           }
-
         /* Call enter callback for new target widget.
          * If new wdg is MainWdg, don't call enter. */
-        if (drop_candidate != wdg)
+        //if (drop_candidate != wdg)
           {
-             Target_Info *ti = wdg_data_get(drop_candidate, DROP_TARGET);
+             Drop_Target_Info *ti = wdg_data_get(drop_candidate, DROP_TARGET);
              if (ti->drop_target_enter)
                {
                   ti->drop_target_enter(ti->enterdata, NULL);
@@ -300,7 +371,7 @@ _droppos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, 
Elm_Xdnd_Action action
 
    /* Simulate poscb inside drop candidate.
     * Get callbacks from drop candidate and call. */
-   Target_Info *ti = wdg_data_get(drop_candidate, DROP_TARGET);
+   Drop_Target_Info *ti = wdg_data_get(drop_candidate, DROP_TARGET);
    if (ti->drop_target_pos)
      {
         ti->drop_target_pos(ti->posdata, NULL, x, y, action);
@@ -354,13 +425,20 @@ _iter_dragged_widget_create(Gui_Session *session, const 
Gui_Widget *wdg, Eo *par
    return o;
 }
 
+static void
+_dnd_session_population_zero_cb(Gui_Session *session, void *data EINA_UNUSED)
+{
+   session_del(session);
+}
+
 /* Creates Eo object for given widget and parent.
- * Func is used to greate Eo object in dragwin and in the windo when in/out. */
+ * Func is used to create Eo object in dragwin and in the window when in/out. 
*/
 Eo*
 dnd_drag_obj_create(const Gui_Widget *dragged_wdg, Eo *parent)
 {
    Eo *ret;
    Gui_Session *dnd_session = session_new(MODE_SIMULATOR);
+   session_population_zero_cb_set(dnd_session, 
_dnd_session_population_zero_cb, NULL);
    ret = _iter_dragged_widget_create(dnd_session, dragged_wdg, parent);
    return ret;
 }
@@ -380,60 +458,12 @@ _drag_widget_object_create(void *data, Evas_Object 
*parent, Evas_Coord *xoff, Ev
    if (xoff) *xoff = cur_x_global;
    if (yoff) *yoff = cur_y_global;
 
-   ic = dnd_drag_obj_create(di->wdg, parent);
+   ic = dnd_drag_obj_create(wdg_get(di->wdg_id), parent);
    eo_do(ic, eo_wref_add(&(di->drag_window_obj_wref)));
    return ic;
 }
 
 static Eina_Bool
-_drag_start(void *data)
-{
-   Drag_Info *di = data;
-   Eo *drag_object = di->obj;
-
-   /* We want to provide inline image as a drag object
-    * in order to properly calculate coords of evas. */
-   if (di->wdg)
-     {
-        Eo *main_wdg_eo;
-        const Gui_Widget *main_wdg = wdg_main_wdg_get(di->wdg);
-
-        Gui_Session *session = (Gui_Session *) 
gui_context_editor_session_get(wdg_context_get(di->wdg));
-        main_wdg_eo = session_eo_get(session, main_wdg);
-        /* Usually main_wdg is win.
-         * But when it is not, need to get image of Editor win */
-        if (IS_WIN(main_wdg))
-          {
-             drag_object = elm_win_inlined_image_object_get(main_wdg_eo);
-          }
-        else
-          {
-             Eo *main_obj_inlined_win_img = eo_do_ret(main_wdg_eo, 
main_obj_inlined_win_img, eo_key_data_get("__editor_win"));
-             drag_object = 
elm_win_inlined_image_object_get(main_obj_inlined_win_img);
-          }
-     }
-
-   _dnd_info.drag_info = di;
-   _dnd_info.dnd_in_out = 0;
-   _dnd_info.wdg_src = di->wdg;
-
-   char *wdg_data = dnd_drag_data_get();
-   elm_drag_start(drag_object, ELM_SEL_FORMAT_TEXT,
-                  wdg_data, ELM_XDND_ACTION_COPY,
-                  _drag_widget_object_create, di,
-                  _dragpos, NULL,
-                  _dragaccept, NULL,
-                  _dragdone, NULL);
-   free(wdg_data);
-
-   if (di->_drag_start_post_cb)
-     {
-        di->_drag_start_post_cb(di->wdg, di->obj);
-     }
-   return ECORE_CALLBACK_CANCEL;
-}
-
-static Eina_Bool
 _drag_start_from_factory(void *data)
 {
    Drag_Info *di = data;
@@ -442,18 +472,17 @@ _drag_start_from_factory(void *data)
    image_create_icon_f = (di->image_path) ? _drag_factory_image_icon_create : 
_drag_factory_real_object_create;
 
    _drag_factory_timer = NULL;
-   _dnd_info.drag_info = di;
-   _dnd_info.dnd_in_out = 0;
-   _dnd_info.wdg_src = NULL;
+   _drag_info_global.drag_info = di;
+   _drag_info_global.wdg_src = NULL;
 
-   char *wdg_data = dnd_drag_data_get();
+   char *wdg_data = json_widget_generate(di->wdg_id);
+   _drag_info_global._drag_data = wdg_data;
    elm_drag_start(di->obj, ELM_SEL_FORMAT_TEXT,
                   wdg_data, ELM_XDND_ACTION_COPY,
                   image_create_icon_f, di,
                   _dragpos, NULL,
                   _dragaccept, NULL,
                   _dragdone, NULL);
-   free(wdg_data);
    return ECORE_CALLBACK_CANCEL;
 }
 
@@ -486,7 +515,7 @@ _drag_data_free(void *data, Eo *obj EINA_UNUSED, const 
Eo_Event_Description *des
    Drag_Info *di = data;
    if (di->image_path) free(di->image_path);
    free(di);
-   _dnd_info.drag_info = NULL;
+   _drag_info_global.drag_info = NULL;
    return EO_CALLBACK_CONTINUE;
 }
 
@@ -499,7 +528,6 @@ drag_add(Eo *obj, const char *image_path, Eid *wdg_id)
    if (image_path)
      di->image_path = strdup(image_path);
    di->wdg_id = wdg_id;
-   di->wdg = wdg_get(wdg_id);
    di->obj = obj;
    eo_do(obj, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_DOWN, 
_factory_drag_mouse_down, di));
    eo_do(obj, eo_event_callback_add(EVAS_OBJECT_EVENT_DEL, _drag_data_free, 
di));
@@ -508,52 +536,65 @@ drag_add(Eo *obj, const char *image_path, Eid *wdg_id)
 /* Function to start dragging, when mouse down/up are handled outside.
  * Dragging widgets on canvas */
 void
-drag_start(Eo *obj, const char *data EINA_UNUSED, const Gui_Widget *wdg, void 
(*cb)(const Gui_Widget *, const Eo *))
+drag_start(Eo *obj, Eid *wdg_id, void (*_post_cb)(const Gui_Widget *, const Eo 
*), void (*_dragdone_post_cb)(Eina_Bool accept))
 {
    Drag_Info *di = calloc(1, sizeof(Drag_Info));
    di->image_path = NULL;
-   di->wdg_id = wdg_eid_get(wdg);
+   di->wdg_id = wdg_id;
    di->obj = obj;
-   di->wdg = wdg;
-   di->_drag_start_post_cb = cb;
-   _dnd_info.drag_info = di;
+   di->dragdone_post_cb = _dragdone_post_cb;
+
+   _drag_info_global.drag_info = di;
+   _drag_info_global.wdg_src = wdg_get(di->wdg_id);
    eo_do(obj, eo_event_callback_add(EVAS_OBJECT_EVENT_DEL, _drag_data_free, 
di));
 
-   _drag_start(di);
-}
+   Eo *drag_object = obj;
 
-/* Function to start dragging, when mouse down/up are handled outside.
- * Dragging widgets on canvas */
-void
-drag_item_start(const char *data EINA_UNUSED, const Gui_Widget *wdg)
-{
-   Drag_Info *di = calloc(1, sizeof(Drag_Info));
-   di->image_path = NULL;
-   di->wdg_id = wdg_eid_get(wdg);
-   di->wdg = wdg;
-   _dnd_info.drag_info = di;
-}
+   /* We want to provide inline image as a drag object
+    * in order to properly calculate coords of evas. */
+   Eo *main_wdg_eo;
+   const Gui_Widget *main_wdg = wdg_main_wdg_get(wdg_get(di->wdg_id));
+
+   Gui_Session *session = (Gui_Session *) 
gui_context_editor_session_get(wdg_context_get(wdg_get(di->wdg_id)));
+   main_wdg_eo = session_eo_get(session, main_wdg);
+   /* Usually main_wdg is win.
+    * But when it is not, need to get image of Editor win */
+   if (IS_WIN(main_wdg))
+     {
+        drag_object = elm_win_inlined_image_object_get(main_wdg_eo);
+     }
+   else
+     {
+        Eo *main_obj_inlined_win_img = eo_do_ret(main_wdg_eo, 
main_obj_inlined_win_img, eo_key_data_get("__editor_win"));
+        drag_object = 
elm_win_inlined_image_object_get(main_obj_inlined_win_img);
+     }
 
-/* Function to stop dragging, when mouse down/up are handled outside.
- * Dragging widgets. */
-void
-drag_stop()
-{
-   _dnd_info.drag_info = NULL;
-   _dnd_info.dnd_in_out = 0;
+   char *wdg_data = json_widget_generate(di->wdg_id);
+   elm_drag_start(drag_object, ELM_SEL_FORMAT_TEXT,
+                  wdg_data, ELM_XDND_ACTION_COPY,
+                  _drag_widget_object_create, di,
+                  _dragpos, NULL,
+                  _dragaccept, di,
+                  _dragdone, di);
+   free(wdg_data);
+
+   if (_post_cb)
+     {
+        _post_cb(wdg_get(di->wdg_id), di->obj);
+     }
 }
 
-static Target_Info*
+static Drop_Target_Info*
 _target_info_new(Gui_Widget *wdg, Eo *obj)
 {
-   Target_Info *ti = NULL;
+   Drop_Target_Info *ti = NULL;
 
    if (wdg)
      {
         ti = wdg_data_get(wdg, DROP_TARGET);
         if (!ti)
           {
-             ti = calloc(1, sizeof(Target_Info));
+             ti = calloc(1, sizeof(Drop_Target_Info));
              ti->wdg = wdg;
              wdg_data_set(wdg, DROP_TARGET, ti);
           }
@@ -563,7 +604,7 @@ _target_info_new(Gui_Widget *wdg, Eo *obj)
         eo_do(obj, ti = eo_key_data_get(DROP_TARGET));
         if (!ti)
           {
-             ti = calloc(1, sizeof(Target_Info));
+             ti = calloc(1, sizeof(Drop_Target_Info));
              eo_do(obj, eo_key_data_set(DROP_TARGET, ti));
           }
      }
@@ -577,7 +618,7 @@ drop_target_wdg_set(Gui_Widget *wdg, Eo *obj,
                          Elm_Drag_Pos drop_target_pos, void *posdata,
                          Elm_Drop_Cb drop_target_drop, void *dropdata)
 {
-   Target_Info *ti = _target_info_new(wdg, obj);
+   Drop_Target_Info *ti = _target_info_new(wdg, obj);
 
    ti->drop_target_enter = drop_target_enter;
    ti->enterdata = enterdata;
@@ -600,17 +641,139 @@ drop_target_wdg_set(Gui_Widget *wdg, Eo *obj,
      }
 }
 
+typedef void (*Elm_Drag_Item_Container_Pos) (void *data, Evas_Object *cont, 
Elm_Object_Item *it, Evas_Coord x, Evas_Coord y, int xposret, int yposret, 
Elm_Xdnd_Action action);
+
+static Elm_Object_Item *
+_it_get_cb(Evas_Object *obj, Evas_Coord x, Evas_Coord y, int *xposret 
EINA_UNUSED, int *yposret)
+{
+   Elm_Object_Item *it;
+   eo_do(obj, it = elm_obj_genlist_at_xy_item_get(x, y, yposret));
+   return it;
+}
+
 void
-drop_item_container_set(Eo *obj, Elm_Xy_Item_Get_Cb itemgetcb, 
Elm_Drop_Item_Container_Cb dropcb, void *dropdata)
+drop_item_container_set(Eo *obj, Elm_Drag_Item_Container_Pos poscb, 
Elm_Drop_Item_Container_Cb dropcb, void *dropdata)
 {
-   elm_drop_item_container_add(obj, ELM_SEL_FORMAT_TEXT, itemgetcb,
-                               _dropenter, NULL, _dropleave, NULL, NULL, NULL, 
dropcb, dropdata);
+   elm_drop_item_container_add(obj, ELM_SEL_FORMAT_TEXT, _it_get_cb,
+                               _dropenter, NULL, _dropleave, NULL, poscb, 
NULL, dropcb, dropdata);
+}
+
+static Evas_Object *
+_gl_createicon(void *data, Evas_Object *win, Evas_Coord *xoff, Evas_Coord 
*yoff)
+{
+   Evas_Object *icon = NULL;
+   Evas_Object *o = elm_object_item_part_content_get(data, "elm.swallow.icon");
+
+   if (o)
+     {
+        int xm, ym, w = 30, h = 30;
+        const char *f;
+        const char *gr;
+        elm_image_file_get(o, &f, &gr);
+        evas_pointer_canvas_xy_get(evas_object_evas_get(o), &xm, &ym);
+        if (xoff) *xoff = xm - (w/2);
+        if (yoff) *yoff = ym - (h/2);
+        icon = elm_icon_add(win);
+        elm_image_file_set(icon, f, gr);
+        evas_object_size_hint_align_set(icon,
+              EVAS_HINT_FILL, EVAS_HINT_FILL);
+        evas_object_size_hint_weight_set(icon,
+              EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+        if (xoff && yoff) evas_object_move(icon, *xoff, *yoff);
+        evas_object_resize(icon, w, h);
+     }
+
+   return icon;
+}
+
+/* Structo to hold info when dragging from item container */
+typedef struct
+{
+   //Elm_Sel_Format format;
+   //const char *data;
+   //Eina_List *icons;
+   //Elm_Xdnd_Action action;
+//   Elm_Drag_Icon_Create_Cb createicon;
+  // void *createdata;
+   Elm_Drag_Start dragstart;
+//   void *startcbdata;
+   //Elm_Drag_Pos dragpos;
+   //void *dragdata;
+   //Elm_Drag_Accept acceptcb;
+   //void *acceptdata;
+   Elm_Drag_Done dragdone;
+  // void *donecbdata;
+} _Drag_Item_Container_Info;
+
+static void
+_drag_item_container_dragstart_cb(void *data EINA_UNUSED, Evas_Object *obj 
EINA_UNUSED)
+{
+   _Drag_Item_Container_Info *_dici = NULL;
+   eo_do(obj, _dici = eo_key_data_get(DRAG_ITEM_CONTAINER_INFO));
+
+   Gui_Widget *wdg = data;
+
+   Drag_Info *di = calloc(1, sizeof(Drag_Info));
+   di->image_path = NULL;
+   di->wdg_id = wdg_eid_get(wdg);
+   _drag_info_global.drag_info = di;
+   _drag_info_global.wdg_src = wdg;
+
+   if (_dici && _dici->dragstart)
+     {
+        _dici->dragstart(data, obj);
+     }
+}
+
+static void
+_drag_item_container_dragdone_cb(void *data, Evas_Object *obj, Eina_Bool 
accepted)
+{
+   _Drag_Item_Container_Info *_dici = NULL;
+   eo_do(obj, _dici = eo_key_data_get(DRAG_ITEM_CONTAINER_INFO));
+   if (_dici && _dici->dragdone)
+     {
+        _dici->dragdone(data, obj, accepted);
+     }
+   /* if dropping outside, NULL this pointer*/
+   if (!dnd_is_destination())
+     _drag_info_global.wdg_src = NULL;
+}
+
+static Eina_Bool
+_data_get_cb(Evas_Object *obj EINA_UNUSED,  /* The genlist object */
+                 Elm_Object_Item *it,
+                 Elm_Drag_User_Info *info)
+{
+   /* This called before starting to drag, mouse-down was on it */
+   Gui_Widget *wdg = elm_object_item_data_get(it);
+
+   info->format = ELM_SEL_FORMAT_TEXT;
+   info->icons = NULL;
+   info->data = json_widget_generate(wdg_eid_get(wdg));
+
+   info->createicon = _gl_createicon;
+   info->createdata = it;
+
+   info->dragstart = _drag_item_container_dragstart_cb;
+   info->startcbdata = wdg;
+
+   info->dragdone = _drag_item_container_dragdone_cb;
+
+   /* Now, collect data to send for drop from ALL selected items */
+   /* Save list pointer to remove items after drop and free list on done */
+
+   if (info->data) return EINA_TRUE;
+   return EINA_FALSE;
 }
 
 void
-drag_item_container_set(Eo *obj, double anim_tm, double tm_to_drag, 
Elm_Xy_Item_Get_Cb itemgetcb, Elm_Item_Container_Data_Get_Cb data_get)
+drag_item_container_set(Eo *obj, double anim_tm, double tm_to_drag, 
Elm_Drag_Start dragstart, Elm_Drag_Done dragdone)
 {
-   elm_drag_item_container_add(obj, anim_tm, tm_to_drag, itemgetcb, data_get);
+   _Drag_Item_Container_Info *_dici = calloc(1, 
sizeof(_Drag_Item_Container_Info));
+   _dici->dragstart = dragstart;
+   _dici->dragdone = dragdone;
+   eo_do(obj, eo_key_data_set(DRAG_ITEM_CONTAINER_INFO, _dici));
+   elm_drag_item_container_add(obj, anim_tm, tm_to_drag, _it_get_cb, 
_data_get_cb);
 }
 
 void
@@ -622,13 +785,17 @@ drop_item_container_del(Eo *obj)
 void
 drag_item_container_del(Eo *obj)
 {
+   _Drag_Item_Container_Info *_dici = NULL;
+
+   eo_do(obj, _dici = eo_key_data_get(DRAG_ITEM_CONTAINER_INFO));
+   free(_dici);
    elm_drag_item_container_del(obj);
 }
 
 void
 drop_target_wdg_del(Gui_Widget *wdg, Eo *obj)
 {
-   Target_Info *ti = NULL;
+   Drop_Target_Info *ti = NULL;
 
    if (wdg)
      {
@@ -653,5 +820,3 @@ drop_target_wdg_del(Gui_Widget *wdg, Eo *obj)
      }
    free(ti);
 }
-
-
diff --git a/src/bin/gui/dnd.h b/src/bin/gui/dnd.h
index fb290a4..5aee0f8 100644
--- a/src/bin/gui/dnd.h
+++ b/src/bin/gui/dnd.h
@@ -1,4 +1,3 @@
-
 #ifndef _DND_H
 #define _DND_H
 
@@ -6,13 +5,7 @@ void
 drag_add(Eo *obj, const char *image_path, Eid *wdg_id);
 
 void
-drag_start(Eo *obj, const char *data, const Gui_Widget *wdg, void (*cb)(const 
Gui_Widget *, const Eo *));
-
-void
-drag_item_start(const char *data, const Gui_Widget *wdg);
-
-void
-drag_stop();
+drag_start(Eo *obj, Eid *wdg_id, void (*_post_cb)(const Gui_Widget *, const Eo 
*), void (*_dragdone_post_cb)(Eina_Bool accept));
 
 void
 drop_target_wdg_set(Gui_Widget *wdg, Eo *obj,
@@ -25,29 +18,29 @@ void
 drop_target_wdg_del(Gui_Widget *wdg, Eo *obj);
 
 void
-drop_item_container_set(Eo *obj, Elm_Xy_Item_Get_Cb itemgetcb, 
Elm_Drop_Item_Container_Cb dropcb, void *dropdata);
+drop_item_container_set(Eo *obj, Elm_Drag_Item_Container_Pos poscb, 
Elm_Drop_Item_Container_Cb dropcb, void *dropdata);
 
 void
 drop_item_container_del(Eo *obj);
 
 void
-drag_item_container_set(Eo *obj, double anim_tm, double tm_to_drag, 
Elm_Xy_Item_Get_Cb itemgetcb, Elm_Item_Container_Data_Get_Cb data_get);
-
-void
-drag_item_container_del(Eo *obj);
-
-char *
-dnd_drag_data_get();
+drag_item_container_set(Eo *obj, double anim_tm, double tm_to_drag, 
Elm_Drag_Start dragstart, Elm_Drag_Done dragdone);
 
 const Gui_Widget *
 dnd_drag_wdg_get();
 
-Eina_Bool
-dnd_is_in_drop_target();
+int
+dnd_counter_get();
+
+const char *
+dnd_drop_data_get();
 
 Eina_Bool
 dnd_is_source();
 
+Eina_Bool
+dnd_is_destination();
+
 /* Creates Eo object for given widget and parent.
  * Func is used to greate Eo object in dragwin and in the windo when in/out. */
 Eo*
diff --git a/src/bin/gui/editor.c b/src/bin/gui/editor.c
index a823deb..6dce6bd 100644
--- a/src/bin/gui/editor.c
+++ b/src/bin/gui/editor.c
@@ -34,12 +34,10 @@
 #define FRAME_DELTA_H "__frame_delta_h"
 
 #define EDITOR_DND_DATA "__EDITOR_DND_DATA__"
-#define EDITOR_DRAG_DATA "__EDITOR_DRAG_DATA__"
 
 typedef struct
 {
    Eo *eo_cur;
-   Gui_Widget *wdg_cur;
 
    Eina_Bool packed; /* Need this, because no API to check if object is packed 
into table
                         and unpack causes error message. */
@@ -333,7 +331,9 @@ enum
 static void
 _wdg_border_draw(const Gui_Widget *wdg, Eina_Bool visibility, int 
border_type_color)
 {
-   const Gui_Session *session = 
gui_context_editor_session_get(_active_context_get());
+   const Gui_Context *ctx = _active_context_get();
+   if (!ctx) return;
+   const Gui_Session *session = gui_context_editor_session_get(ctx);
    Eo *obj = NULL;
    Eo *base_obj = canvas_get();
    if (wdg)
@@ -581,6 +581,9 @@ _drag_widget_iterate(Gui_Widget **drag_candidate, const 
Gui_Session *session, Ev
 void
 _drag_start_post_cb(const Gui_Widget *wdg, const Eo *_wdg_eo);
 
+static void
+_dragdone_post_cb(Eina_Bool accept);
+
 static Ecore_Timer *_drag_timer_start = NULL;
 static Eina_Bool drag_started = EINA_FALSE;
 
@@ -609,7 +612,7 @@ _drag_widget_start(void *data)
    const Gui_Session *session = 
gui_context_editor_session_get(wdg_context_get(wdg));
    Eo *wdg_eo = session_eo_get(session, wdg);
 
-   drag_start(wdg_eo, EDITOR_DRAG_DATA, wdg, _drag_start_post_cb);
+   drag_start(wdg_eo, wdg_eid_get(wdg), _drag_start_post_cb, 
_dragdone_post_cb);
    drag_started = EINA_TRUE;
    _drag_timer_start = NULL;
    return ECORE_CALLBACK_CANCEL;
@@ -673,21 +676,6 @@ _mouse_up_main(void *data EINA_UNUSED, Eo *obj 
EINA_UNUSED, const Eo_Event_Descr
      }
    if (!drag_started) return EO_CALLBACK_CONTINUE;
 
-   if (!dnd_is_in_drop_target())
-     {
-        const Gui_Widget *drag_widget = NULL;
-        ERR("Take the data here");
-        if (!drag_widget) return EO_CALLBACK_CONTINUE;
-
-        drag_stop();
-        _wdg_border_draw(NULL, EINA_FALSE, BORDER_DROP_TARGET);
-
-        Gui_Widget *wdg_main = data;
-        _wdg_parent_win_reload(wdg_main);
-        _editor_wdg_selected_set(drag_widget);
-        objtree_build(wdg_context_get(drag_widget));
-        objtree_item_selected_set(drag_widget);
-     }
    return EO_CALLBACK_CONTINUE;
 }
 
@@ -1195,7 +1183,6 @@ _frame_mouse_down(void *data EINA_UNUSED, Eo *obj, const 
Eo_Event_Description *d
    /* Don't use dnd for dragging window around canvas. */
    if (IS_WIN(wdg))
      {
-        printf("%s %p\n", __FUNCTION__, wdg);
         eo_do(obj, eo_event_callback_add(EVAS_OBJECT_EVENT_MOUSE_MOVE, 
_frame_mouse_move, NULL));
      }
    else
@@ -1212,53 +1199,8 @@ _frame_mouse_up(void *data EINA_UNUSED, Eo *obj, const 
Eo_Event_Description *des
    /* Don't use dnd for dragging window around canvas. */
    if (IS_WIN(wdg))
      {
-        printf("%s %p\n", __FUNCTION__, wdg);
         eo_do(obj, eo_event_callback_del(EVAS_OBJECT_EVENT_MOUSE_MOVE, 
_frame_mouse_move, NULL));
      }
-#if 0
-   else
-     {
-        if (_drag_timer_start)
-          {
-             ecore_timer_del(_drag_timer_start);
-             _drag_timer_start = NULL;
-          }
-        if (!drag_started) return EO_CALLBACK_CONTINUE;
-
-        if (!dnd_is_in_drop_target())
-          {
-             /* Check if dragged object is visible.
-              * If not, means that _drag_start_post_cb was called, so need to 
reload main wdg. */
-             Eo *canvas = egui_layout_gui_get()->main_win->canvas_scroller;
-             DnD_Main_Obj_Info *di = eo_do_ret(canvas, di, 
eo_key_data_get(EDITOR_DND_DATA));
-
-             const Gui_Widget *drag_widget = dnd_drag_wdg_get();
-             if (!drag_widget) return EO_CALLBACK_CONTINUE;
-
-             drag_stop();
-             _wdg_border_draw(NULL, EINA_FALSE, BORDER_DROP_TARGET);
-
-             if (di->eo_cur)
-               {
-                  eo_del(di->eo_cur);
-                  di->eo_cur = NULL;
-               }
-             _wdg_parent_win_reload(drag_widget);
-             _editor_wdg_selected_set(drag_widget);
-             objtree_build(wdg_context_get(drag_widget));
-             objtree_item_selected_set(drag_widget);
-          }
-     }
-   _canvas_resize_cb(NULL, g->main_win->canvas_scroller, NULL, NULL);
-   _mmd.down_x = 0;
-   _mmd.down_y = 0;
-   _mmd.object_w = 0;
-   _mmd.object_h = 0;
-   _mmd.object_x = 0;
-   _mmd.object_y = 0;
-   _mmd.delta_x = 0;
-   _mmd.delta_y = 0;
-#endif
    return EO_CALLBACK_CONTINUE;
 }
 
@@ -1656,12 +1598,16 @@ static Gui_Widget *
 _editor_wdg_create(Gui_Context *ctx, const char *json_data, const Gui_Widget 
*parent)
 {
    Eina_List *lst = NULL;
-   if (!gui_parser_json_parse(ctx, json_data, EINA_TRUE, &lst) ||
-         eina_list_count(lst) != 1)
+   if (!gui_parser_json_parse(ctx, json_data, EINA_TRUE, EINA_TRUE, &lst))
      {
-        ERR("Number of main widgets in JSON data has to be 1 - \n%s", 
json_data);
+        ERR("Can not parse: \n%s", json_data);
         return NULL;
      }
+   if (eina_list_count(lst) != 1)
+     {
+        ERR("Number of main widgets in JSON data has to be 1, have: %d \n", 
eina_list_count(lst));
+        //return NULL;
+     }
    Eid *wdg_id = eina_list_data_get(lst);
    Gui_Widget *wdg = wdg_get(wdg_id);
    if (parent)
@@ -1669,36 +1615,32 @@ _editor_wdg_create(Gui_Context *ctx, const char 
*json_data, const Gui_Widget *pa
    return wdg;
 }
 
+static Gui_Widget *_dragged_wdg;
+
 static void
 _drop_target_enter(void *data, Evas_Object *obj)
 {
-   ERR("In");
    Eo *canvas_drop_target = obj;
-   Eo *eo_container = NULL;
-   Gui_Widget *container = data;
+   Gui_Widget *drop_target_wdg = data;
    DnD_Main_Obj_Info *di = NULL;
-   const Gui_Session *session = NULL;
    /* If container == NULL, then canvas is a drop target or we have a error.*/
-   if (container)
+   if (drop_target_wdg)
      {
-        session = gui_context_editor_session_get(wdg_context_get(container));
-        if (IS_MAIN(container))
+        if (IS_MAIN(drop_target_wdg))
           {
-             di = wdg_data_get(container, EDITOR_DND_DATA);
+             di = wdg_data_get(drop_target_wdg, EDITOR_DND_DATA);
           }
         else
           {
-             const Gui_Widget *main_wdg = wdg_main_wdg_get(container);
+             const Gui_Widget *main_wdg = wdg_main_wdg_get(drop_target_wdg);
              _wdg_border_draw(main_wdg, EINA_FALSE, BORDER_DROP_TARGET);
              di = wdg_data_get(main_wdg, EDITOR_DND_DATA);
           }
-        eo_container = session_eo_get(session, container);
-        _wdg_border_draw(container, EINA_TRUE, BORDER_DROP_TARGET);
+        _wdg_border_draw(drop_target_wdg, EINA_TRUE, BORDER_DROP_TARGET);
      }
    else if (canvas_drop_target != NULL)
      {
         eo_do(canvas_drop_target, di = eo_key_data_get(EDITOR_DND_DATA));
-        eo_container = canvas_drop_target;
         _wdg_border_draw(NULL, EINA_FALSE, BORDER_DROP_TARGET);
      }
    else
@@ -1707,31 +1649,10 @@ _drop_target_enter(void *data, Evas_Object *obj)
         return;
      }
 
-   /* We are in the Erigo instance that initiated the DnD */
-   if (dnd_is_source())
-     {
-        di->wdg_cur = (Gui_Widget *)dnd_drag_wdg_get();
-     }
-   else
-     {
-        char *drag_data = dnd_drag_data_get();
-        if (drag_data)
-          {
-             /* Creation of the wdg */
-             printf("Enter ZZZ%sZZZ\n", drag_data);
-             di->wdg_cur = _editor_wdg_create(_active_context_get(), 
drag_data, NULL);
-             free(drag_data);
-          }
-     }
-   if (!di->eo_cur)
-     {
-        di->eo_cur = dnd_drag_obj_create(di->wdg_cur, eo_container);
-     }
-
-   if (container && !strcmp(wdg_class_name_get(container), DB_DEF_TABLE_CLASS))
+   if (drop_target_wdg && !strcmp(wdg_class_name_get(drop_target_wdg), 
DB_DEF_TABLE_CLASS))
      {
         Object_Container_Item *it;
-        const Eina_List *lst = wdg_obj_container_contents_list_get(container), 
*l;
+        const Eina_List *lst = 
wdg_obj_container_contents_list_get(drop_target_wdg), *l;
         int maxw = 1, maxh = 1;
         EINA_LIST_FOREACH(lst, l, it)
           {
@@ -1755,19 +1676,22 @@ _drop_target_enter(void *data, Evas_Object *obj)
 static void
 _drop_target_leave(void *data, Evas_Object *obj)
 {
-   Gui_Widget *container = data;
-   Eo *canvas_drop_target = obj, *eo_container = NULL;
+   /* FIXME: this is temp check in order to avoid segfault. */
+   if (!dnd_is_source() && !dnd_drop_data_get()) return;
+
+   Gui_Widget *drop_target_wdg = data;
+   Eo *canvas_drop_target = obj, *drop_target_wdg_eo = NULL;
    DnD_Main_Obj_Info *di = NULL;
    const Gui_Session *session = NULL;
-   _wdg_border_draw(container, EINA_FALSE, BORDER_DROP_TARGET);
-   if (container)
+   _wdg_border_draw(drop_target_wdg, EINA_FALSE, BORDER_DROP_TARGET);
+   if (drop_target_wdg)
      {
-        session = gui_context_editor_session_get(wdg_context_get(container));
-        if (IS_MAIN(container))
-           di = wdg_data_get(container, EDITOR_DND_DATA);
+        session = 
gui_context_editor_session_get(wdg_context_get(drop_target_wdg));
+        if (IS_MAIN(drop_target_wdg))
+           di = wdg_data_get(drop_target_wdg, EDITOR_DND_DATA);
         else
-           di = wdg_data_get(wdg_main_wdg_get(container), EDITOR_DND_DATA);
-        eo_container = session_eo_get(session, container);
+           di = wdg_data_get(wdg_main_wdg_get(drop_target_wdg), 
EDITOR_DND_DATA);
+        drop_target_wdg_eo = session_eo_get(session, drop_target_wdg);
      }
    else if (canvas_drop_target != NULL)
      {
@@ -1779,28 +1703,28 @@ _drop_target_leave(void *data, Evas_Object *obj)
         return;
      }
 
-   if (eo_container && !strcmp(wdg_class_name_get(container), 
DB_DEF_BOX_CLASS))
+   if (drop_target_wdg_eo && !strcmp(wdg_class_name_get(drop_target_wdg), 
DB_DEF_BOX_CLASS))
      {
         if (di->packed)
           {
-             eo_do(eo_container, elm_obj_box_unpack(di->eo_cur));
+             eo_do(drop_target_wdg_eo, elm_obj_box_unpack(di->eo_cur));
              di->packed = EINA_FALSE;
           }
      }
-   else if (eo_container && !strcmp(wdg_class_name_get(container), 
DB_DEF_TABLE_CLASS))
+   else if (drop_target_wdg_eo && !strcmp(wdg_class_name_get(drop_target_wdg), 
DB_DEF_TABLE_CLASS))
      {
         if (di->packed)
           {
              Eo *o;
              EINA_LIST_FREE(di->table_borders, o)
                {
-                  eo_do(eo_container, elm_obj_table_unpack(o));
+                  eo_do(drop_target_wdg_eo, elm_obj_table_unpack(o));
                   eo_del(o);
                }
              di->table_borders = NULL;
-             eo_do(eo_container, elm_obj_table_unpack(di->eo_cur));
+             eo_do(drop_target_wdg_eo, elm_obj_table_unpack(di->eo_cur));
 
-             const Eina_List *lst = 
wdg_obj_container_contents_list_get(container), *l;
+             const Eina_List *lst = 
wdg_obj_container_contents_list_get(drop_target_wdg), *l;
              Object_Container_Item *it;
              EINA_LIST_FOREACH(lst, l, it)
                {
@@ -1820,18 +1744,27 @@ _drop_target_leave(void *data, Evas_Object *obj)
                   iw = INT_GET(prop_value_nth_get(prop, 3));
                   ih = INT_GET(prop_value_nth_get(prop, 4));
                   Eo *c = session_eo_get(session, wdg_get(eid));
-                  eo_do(eo_container, elm_obj_table_pack(c, ix, iy, iw, ih));
+                  eo_do(drop_target_wdg_eo, elm_obj_table_pack(c, ix, iy, iw, 
ih));
                }
              di->packed = EINA_FALSE;
           }
      }
-   if (di->eo_cur && IS_MAIN(container))
+   if (di->eo_cur && IS_MAIN(drop_target_wdg))
      {
         eo_del(di->eo_cur);
         di->eo_cur = NULL;
      }
-   if (!dnd_drag_wdg_get()) wdg_del(di->wdg_cur);
-   di->wdg_cur = NULL;
+
+   if (!dnd_counter_get())
+     {
+        /* If drag was started in factory or outside Erigo - delete widget */
+        if (!dnd_is_source() && _dragged_wdg)
+          {
+             wdg_del(_dragged_wdg);
+          }
+        /* ... if started on canvas - NULL pointer */
+        _dragged_wdg = NULL;
+     }
 }
 
 /* In the beginning of drop handler we want to determine,
@@ -1846,9 +1779,6 @@ enum
    DROP_TO_MAIN
 };
 
-static Gui_Widget*
-_editor_factory_wdg_create(const char *class_name, const Gui_Widget 
*focused_wdg, Evas_Coord main_wdg_x, Evas_Coord main_wdg_y);
-
 /* canvas_drop_target != NULL when dropping on canvas. */
 static Eina_Bool
 _drop_target_drop(Gui_Widget *wdg, Eo *canvas_drop_target, const char 
*drag_data EINA_UNUSED, Eina_Bool dropped_to_objtree)
@@ -1894,6 +1824,7 @@ _drop_target_drop(Gui_Widget *wdg, Eo 
*canvas_drop_target, const char *drag_data
    if (drop_to_wdg == NO_DROP) goto end;
 
    Gui_Context *ctx = _active_context_get();
+   if (!ctx) return EINA_FALSE;
    const Gui_Session *session = gui_context_editor_session_get(ctx);
    /* Drop when dragging from factory. */
    int drop_x = di->pointer_x, drop_y = di->pointer_y;
@@ -1902,167 +1833,15 @@ _drop_target_drop(Gui_Widget *wdg, Eo 
*canvas_drop_target, const char *drag_data
         drop_x = drop_y = 0;
      }
 
-   new_wdg = di->wdg_cur;
+   /* FIXME: delete this, as wdg_cur must be created in _drop_target_pos()*/
+   if (!_dragged_wdg)
+     _dragged_wdg = _editor_wdg_create(_active_context_get(), drag_data, NULL);
+
+   new_wdg = _dragged_wdg;
    if (!dnd_is_source())
       memento_command_add(wdg_eid_get(new_wdg), MEMENTO_WIDGET,
             (void *) (intptr_t) EINA_FALSE, (void *) (intptr_t) EINA_TRUE);
 
-   /* Check if new_widget was packed previously: take it's parent and check
-    * if widget is packed into it's parent.
-    * If so, we need to unpack widget and delete from contents*/
-   Gui_Widget *wdg_parent = (Gui_Widget *) wdg_parent_get(new_wdg), 
*prev_wdg_container = NULL;
-   if (wdg_parent && wdg_obj_container_item_get(wdg_parent, -1, 
wdg_name_get(new_wdg)))
-     prev_wdg_container = wdg_parent;
-
-   /* Dragging inside the same container. */
-   if (prev_wdg_container && (prev_wdg_container == wdg))
-     {
-        /* Dragging inside the same box, just reorder items. */
-        if (!strcmp(wdg_class_name_get(wdg), DB_DEF_BOX_CLASS))
-          {
-             /* Get current(previous) index of draggable wdg. */
-             int cur_visual_idx = wdg_obj_container_item_idx_get(wdg, 
wdg_eid_get(new_wdg), EINA_TRUE);
-             int reorder_delta = di->box_pack_idx - cur_visual_idx;
-
-             Object_Container *_old_container, *_new_container;
-             _old_container = (Object_Container *) 
wdg_obj_container_get((Gui_Widget *) wdg);
-             _new_container = obj_container_copy(_old_container);
-
-             obj_container_ref(_old_container);
-             wdg_obj_container_unset((Gui_Widget *) wdg);
-             wdg_obj_container_set((Gui_Widget *) wdg, _new_container);
-
-             /* If anything was reordered, need to reload content. */
-             if (wdg_obj_container_content_reorder(wdg, cur_visual_idx, 
reorder_delta))
-               {
-                  memento_command_add(wdg_eid_get(wdg), 
MEMENTO_OBJ_CONTAINER_ITEM, _old_container, _new_container);
-               }
-             obj_container_unref(_old_container);
-          }
-        else if (!strcmp(wdg_class_name_get(wdg), DB_DEF_TABLE_CLASS))
-          {
-             Object_Container_Item *ci = wdg_obj_container_item_get(wdg, -1, 
wdg_name_get(new_wdg));
-             Eid *ci_eid = obj_container_item_eid_get(ci);
-             const Gui_Widget_Property *ci_prop = 
obj_container_item_prop_get(ci);
-             if ((INT_GET(prop_value_nth_get(ci_prop, 1)) != di->table_pack_x) 
||
-                 (INT_GET(prop_value_nth_get(ci_prop, 2)) != di->table_pack_y))
-               {
-                  Object_Container *_old_container, *_new_container;
-                  _old_container = (Object_Container *) 
wdg_obj_container_get((Gui_Widget *) wdg);
-                  _new_container = obj_container_copy(_old_container);
-
-                  memento_command_add(wdg_eid_get(wdg), 
MEMENTO_OBJ_CONTAINER_ITEM, _old_container, _new_container);
-
-                  const Eina_List *old_lst = 
wdg_obj_container_contents_list_get(wdg);
-                  wdg_obj_container_unset((Gui_Widget *) wdg);
-                  wdg_obj_container_set((Gui_Widget *) wdg, _new_container);
-
-                  /* Delete everything in new_container */
-                  wdg_obj_container_item_remove_all(wdg);
-
-                  /* Iterate over old list and create new container items and 
properties.
-                   * Also get packing coordinates from Eo object and put it 
into property. */
-                  Eo *wdg_eo = session_eo_get(session, wdg);
-                  Object_Container_Item *it;
-                  const Eina_List *l;
-                  EINA_LIST_FOREACH(old_lst, l, it)
-                    {
-                       int ix, iy, iw, ih;
-                       Gui_Widget_Property *prop = 
obj_container_item_prop_get(it);
-                       Eid *eid = obj_container_item_eid_get(it);
-                       Gui_Widget_Property *new_prop = prop_copy(prop);
-                       Eo *c = session_eo_get(session, wdg_get(eid));
-                       eo_do(wdg_eo, elm_obj_table_pack_get(c, &ix, &iy, &iw, 
&ih));
-
-                       if (eid == ci_eid)
-                         {
-                            ix = di->table_pack_x;
-                            iy = di->table_pack_y;
-                         }
-                       gui_value_int_set(prop_value_nth_get(new_prop, 1), ix);
-                       gui_value_int_set(prop_value_nth_get(new_prop, 2), iy);
-
-                       ci = obj_container_item_new(new_prop, eid);
-                       wdg_obj_container_item_add((Gui_Widget *) wdg, ci, -1);
-                    }
-               }
-          }
-        goto end;
-     }
-   /* Dragging inside window - only change position. */
-   else if ((wdg_parent == wdg) && IS_WIN(wdg))
-     {
-        if (new_wdg)
-          {
-             Gui_Widget_Property *old_prop, *prop;
-             Gui_Value *val;
-             old_prop = wdg_prop_get(new_wdg, DB_DEF_EFL_GFX_BASE_CLASS, 
POSITION_SET);
-             if (!old_prop)
-               {
-                  Op_Desc *op = 
db_mro_op_desc_get(wdg_class_name_get(new_wdg), DB_DEF_EFL_GFX_BASE_CLASS, 
POSITION_SET);
-                  prop = prop_create_for_op(op);
-               }
-             else
-               {
-                  prop = prop_copy(old_prop);
-               }
-
-             val = prop_value_nth_get(prop, 0);
-             gui_value_int_set(val, drop_x);
-             val = prop_value_nth_get(prop, 1);
-             gui_value_int_set(val, drop_y);
-             propview_item_update(prop);
-
-             memento_command_add(wdg_eid_get(new_wdg), MEMENTO_PROPERTY, 
old_prop, prop);
-
-             /* If new widget was dragged from the factory, memento must be 
added to the previous one. */
-             if (old_prop)
-               {
-                  wdg_prop_remove((Gui_Widget *) new_wdg, old_prop);
-               }
-             wdg_prop_add((Gui_Widget *) new_wdg, prop);
-          }
-        goto end;
-     }
-   /* Dragging main wdg around canvas. */
-   else if (!wdg_parent && !wdg)
-     {
-        wdg_data_set(new_wdg, CURSOR_DROP_X, (void *) (intptr_t) 
di->pointer_x);
-        wdg_data_set(new_wdg, CURSOR_DROP_Y, (void *) (intptr_t) 
di->pointer_y);
-        goto end;
-     }
-
-   /* If dragging from one container to another, unpack from the first one*/
-   if (prev_wdg_container && (prev_wdg_container != wdg))
-     {
-        Object_Container *_old_prev_container, *_new_prev_container;
-        _old_prev_container = (Object_Container *) 
wdg_obj_container_get((Gui_Widget *) prev_wdg_container);
-        _new_prev_container = obj_container_copy(_old_prev_container);
-        memento_command_add(wdg_eid_get(prev_wdg_container),
-              MEMENTO_OBJ_CONTAINER_ITEM,
-              _old_prev_container, _new_prev_container);
-        wdg_obj_container_unset((Gui_Widget *) prev_wdg_container);
-        wdg_obj_container_set((Gui_Widget *) prev_wdg_container, 
_new_prev_container);
-
-        /* Take old container's class name from content-property. */
-        Object_Container_Item *_ci = 
wdg_obj_container_item_get(prev_wdg_container, -1, wdg_name_get(new_wdg));
-        wdg_obj_container_item_remove(prev_wdg_container, _ci);
-     }
-   /* If dragging from a widget(window), unset parent*/
-   else if (wdg_parent && (wdg_parent != wdg))
-     {
-        memento_command_add(wdg_eid_get(new_wdg),
-              MEMENTO_WIDGET_PARENT,
-              wdg_parent_id_get(new_wdg), NULL);
-        wdg_parent_set((Gui_Widget *) new_wdg, NULL);
-     }
-   else if (!wdg_parent)
-     {
-        memento_command_add(wdg_eid_get(new_wdg),
-              MEMENTO_WIDGET_PARENT,
-              NULL, NULL);
-     }
-
    /* Where to drop. */
    if (drop_to_wdg == DROP_TO_CANVAS)
      {
@@ -2196,19 +1975,14 @@ _drop_target_drop(Gui_Widget *wdg, Eo 
*canvas_drop_target, const char *drag_data
               wdg_parent_id_get(new_wdg), wdg_eid_get(wdg));
         wdg_parent_set((Gui_Widget *) new_wdg, wdg_name_get(wdg));
      }
+
 end:
 
    if (!dnd_is_source() && di->eo_cur)
      {
         eo_del(di->eo_cur);
-#if 0
-        if (dnd_drag_wdg_get())
-          {
-          }
-#endif
      }
    di->eo_cur = NULL;
-   drag_stop();
 
    if (new_wdg)
      {
@@ -2219,6 +1993,8 @@ end:
      }
 
    context_memento_finalize(ctx);
+   _dragged_wdg = NULL;
+
    return EINA_TRUE;
 }
 
@@ -2229,14 +2005,34 @@ _drop_target_drop_cb(void *data, Evas_Object *obj, 
Elm_Selection_Data *ev)
    return _drop_target_drop(data, obj, drag_data, EINA_FALSE);
 }
 
-static Elm_Object_Item *
-_objtree_it_get_cb(Evas_Object *obj, Evas_Coord x, Evas_Coord y, int *xposret 
EINA_UNUSED, int *yposret)
+/* Objtree drag pos callback */
+static void
+_objtree_pos_cb(void *data EINA_UNUSED, Evas_Object *cont EINA_UNUSED, 
Elm_Object_Item *it EINA_UNUSED, Evas_Coord x EINA_UNUSED, Evas_Coord y 
EINA_UNUSED, int xposret EINA_UNUSED, int yposret EINA_UNUSED, Elm_Xdnd_Action 
action EINA_UNUSED)
 {
-   Elm_Object_Item *it;
-   eo_do(obj, it = elm_obj_genlist_at_xy_item_get(x, y, yposret));
-   return it;
+   if (!_active_context_get()) return;
+   if (!_dragged_wdg)
+     {
+        /* We are in the Erigo instance that initiated the DnD */
+        if (dnd_is_source())
+          {
+             _dragged_wdg = (Gui_Widget *) dnd_drag_wdg_get();
+          }
+        else
+          {
+             const char *drop_data = dnd_drop_data_get();
+             if (!drop_data) return;
+
+             /* Creation of the wdg */
+             //printf("Enter ZZZ%sZZZ\n", _drop_data);
+             if (!_dragged_wdg)
+               {
+                  _dragged_wdg = _editor_wdg_create(_active_context_get(), 
drop_data, NULL);
+               }
+          }
+     }
 }
 
+/* Objtree drop callback */
 static Eina_Bool
 _objtree_drop_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, 
Elm_Object_Item *it, Elm_Selection_Data *ev, int xposret EINA_UNUSED, int 
yposret EINA_UNUSED)
 {
@@ -2268,61 +2064,19 @@ _objtree_drop_cb(void *data EINA_UNUSED, Evas_Object 
*obj EINA_UNUSED, Elm_Objec
    return EINA_TRUE;
 }
 
-static Evas_Object *
-_gl_createicon(void *data, Evas_Object *win, Evas_Coord *xoff, Evas_Coord 
*yoff)
+static void
+_objtree_drag_start_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED)
 {
-   Evas_Object *icon = NULL;
-   Evas_Object *o = elm_object_item_part_content_get(data, "elm.swallow.icon");
-
-   if (o)
-     {
-        int xm, ym, w = 30, h = 30;
-        const char *f;
-        const char *gr;
-        elm_image_file_get(o, &f, &gr);
-        evas_pointer_canvas_xy_get(evas_object_evas_get(o), &xm, &ym);
-        if (xoff) *xoff = xm - (w/2);
-        if (yoff) *yoff = ym - (h/2);
-        icon = elm_icon_add(win);
-        elm_image_file_set(icon, f, gr);
-        evas_object_size_hint_align_set(icon,
-              EVAS_HINT_FILL, EVAS_HINT_FILL);
-        evas_object_size_hint_weight_set(icon,
-              EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-        if (xoff && yoff) evas_object_move(icon, *xoff, *yoff);
-        evas_object_resize(icon, w, h);
-     }
-
-   return icon;
+   Gui_Widget *wdg = data;
+   _drag_start_post_cb(wdg, NULL);
 }
 
-static Eina_Bool
-_objtree_data_getcb(Evas_Object *obj EINA_UNUSED,  /* The genlist object */
-                 Elm_Object_Item *it,
-                 Elm_Drag_User_Info *info)
+static void
+_objtree_dragdone_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, 
Eina_Bool accepted)
 {
-   /* This called before starting to drag, mouse-down was on it */
-   info->format = ELM_SEL_FORMAT_TEXT;
-   info->createicon = _gl_createicon;
-   info->createdata = it;
-   info->dragstart = NULL;
-   info->icons = NULL;
-   info->dragdone = NULL;
-
-   /* Now, collect data to send for drop from ALL selected items */
-   /* Save list pointer to remove items after drop and free list on done */
-   info->data = strdup(EDITOR_DRAG_DATA);
-
-   Gui_Widget *wdg = elm_object_item_data_get(it);
-   drag_item_start(EDITOR_DRAG_DATA, wdg);
-
-   if (info->data)
-     return EINA_TRUE;
-   else
-     return EINA_FALSE;
+   _dragdone_post_cb(accepted);
 }
 
-
 static void
 _table_cell_segment_get(int x, int y, int cell_w, int cell_h, int *_part_x, 
int *_part_y)
 {
@@ -2344,25 +2098,27 @@ static void
 _drop_target_pos(void *data, Eo *obj, Evas_Coord x, Evas_Coord y, 
Elm_Xdnd_Action action EINA_UNUSED)
 {
    Eo *canvas_drop_target = obj;
-   Gui_Widget *container = data;
+   Gui_Widget *drop_target_wdg = data;
    DnD_Main_Obj_Info *di = NULL;
-   Eo *eo_container = NULL;
+   Eo *drop_target_wdg_eo = NULL;
+
    Gui_Context *ctx = _active_context_get();
    if (!ctx) return;
    double scale = gui_context_scale_get(ctx);
    /* If wdg == NULL, then canvas is a drop target or we have a error.*/
-   if (container)
+   if (drop_target_wdg)
      {
         const Gui_Session *session = gui_context_editor_session_get(ctx);
-        di = wdg_data_get(wdg_main_wdg_get(container), EDITOR_DND_DATA);
-        eo_container = session_eo_get(session, container);
-        _wdg_border_draw(container, EINA_TRUE, BORDER_DROP_TARGET);
+        di = wdg_data_get(wdg_main_wdg_get(drop_target_wdg), EDITOR_DND_DATA);
+        drop_target_wdg_eo = session_eo_get(session, drop_target_wdg);
+        _wdg_border_draw(drop_target_wdg, EINA_TRUE, BORDER_DROP_TARGET);
         x = x / scale;
         y = y / scale;
      }
    else if (canvas_drop_target != NULL)
      {
         eo_do(canvas_drop_target, di = eo_key_data_get(EDITOR_DND_DATA));
+        drop_target_wdg_eo = canvas_drop_target;
         x = x / scale;
         y = y / scale;
      }
@@ -2372,6 +2128,31 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, 
Evas_Coord y, Elm_Xdnd_Actio
         return;
      }
 
+   if (!_dragged_wdg)
+     {
+        /* We are in the Erigo instance that initiated the DnD */
+        if (dnd_is_source())
+          {
+             _dragged_wdg = (Gui_Widget *) dnd_drag_wdg_get();
+          }
+        else
+          {
+             const char *drop_data = dnd_drop_data_get();
+             if (!drop_data) return;
+
+             /* Creation of the wdg */
+             if (!_dragged_wdg)
+               {
+                  _dragged_wdg = _editor_wdg_create(_active_context_get(), 
drop_data, NULL);
+               }
+          }
+     }
+
+   if (_dragged_wdg && !di->eo_cur && (!IS_WIN(_dragged_wdg)))
+     {
+        di->eo_cur = dnd_drag_obj_create(_dragged_wdg, drop_target_wdg_eo);
+     }
+
    di->pointer_x = x;
    di->pointer_y = y;
 
@@ -2389,13 +2170,13 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, 
Evas_Coord y, Elm_Xdnd_Actio
         dnd_drag_window_object_visibility_set(EINA_FALSE);
      }
 
-   if (container && !strcmp(wdg_class_name_get(container), DB_DEF_BOX_CLASS))
+   if (drop_target_wdg && !strcmp(wdg_class_name_get(drop_target_wdg), 
DB_DEF_BOX_CLASS))
      {
         Eo *child, *candidate = NULL;
         int idx = 0;
         //if (di->packed)
-        eo_do(eo_container, elm_obj_box_unpack(di->eo_cur));
-        Eina_List *box_chld = eo_do_ret(eo_container, box_chld, 
elm_obj_box_children_get()), *l;
+        eo_do(drop_target_wdg_eo, elm_obj_box_unpack(di->eo_cur));
+        Eina_List *box_chld = eo_do_ret(drop_target_wdg_eo, box_chld, 
elm_obj_box_children_get()), *l;
         di->box_pack_idx = 0;
         EINA_LIST_FOREACH(box_chld, l, child)
           {
@@ -2403,7 +2184,7 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, 
Evas_Coord y, Elm_Xdnd_Actio
              eo_do(child, efl_gfx_position_get(&child_x, &child_y));
              eo_do(child, efl_gfx_size_get(&child_w, &child_h));
 
-             Eina_Bool hor_box = eo_do_ret(eo_container, hor_box, 
elm_obj_box_horizontal_get());
+             Eina_Bool hor_box = eo_do_ret(drop_target_wdg_eo, hor_box, 
elm_obj_box_horizontal_get());
 
              /* Check box layout, cursor position and elements inside the box 
and
               * determine where to pack new object. */
@@ -2418,23 +2199,23 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, 
Evas_Coord y, Elm_Xdnd_Actio
         eina_list_free(box_chld);
         if (!candidate)
           {
-             eo_do(eo_container, elm_obj_box_pack_start(di->eo_cur));
+             eo_do(drop_target_wdg_eo, elm_obj_box_pack_start(di->eo_cur));
           }
         else
           {
-             eo_do(eo_container, elm_obj_box_pack_after(di->eo_cur, 
candidate));
+             eo_do(drop_target_wdg_eo, elm_obj_box_pack_after(di->eo_cur, 
candidate));
           }
         di->packed = EINA_TRUE;
      }
-   if (container && !strcmp(wdg_class_name_get(container), DB_DEF_TABLE_CLASS))
+   if (drop_target_wdg && !strcmp(wdg_class_name_get(drop_target_wdg), 
DB_DEF_TABLE_CLASS))
      {
-        const Eina_List *lst = wdg_obj_container_contents_list_get(container), 
*l;
+        const Eina_List *lst = 
wdg_obj_container_contents_list_get(drop_target_wdg), *l;
         Object_Container_Item *it;
         int cell_w = 0, cell_h = 0;
         int table_w = 0, table_h = 0;
         int pack_x = 0, pack_y = 0;
         int pointer_x_cell = 0, pointer_y_cell = 0;
-        eo_do(eo_container, efl_gfx_size_get(&table_w, &table_h));
+        eo_do(drop_target_wdg_eo, efl_gfx_size_get(&table_w, &table_h));
 
         cell_w = table_w / di->table_w;
         cell_h = table_h / di->table_h;
@@ -2531,7 +2312,7 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, 
Evas_Coord y, Elm_Xdnd_Actio
              /* Put objects to default places */
              if (di->packed)
                {
-                  eo_do(eo_container, elm_obj_table_unpack(di->eo_cur));
+                  eo_do(drop_target_wdg_eo, elm_obj_table_unpack(di->eo_cur));
                   EINA_LIST_FOREACH(lst, l, it)
                     {
                        Gui_Widget_Property *prop = 
obj_container_item_prop_get(it);
@@ -2545,9 +2326,9 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, 
Evas_Coord y, Elm_Xdnd_Actio
                        /* Don't pack widget which is currently dragged. */
                        if (dnd_drag_wdg_get() == wdg_get(eid))
                          continue;
-                       const Gui_Session *session = 
gui_context_editor_session_get(wdg_context_get(container));
+                       const Gui_Session *session = 
gui_context_editor_session_get(wdg_context_get(drop_target_wdg));
                        Eo *c = session_eo_get(session, wdg_get(eid));
-                       eo_do(eo_container, elm_obj_table_pack_set(c, ix, iy, 
iw, ih));
+                       eo_do(drop_target_wdg_eo, elm_obj_table_pack_set(c, ix, 
iy, iw, ih));
                     }
                }
 
@@ -2557,10 +2338,10 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, 
Evas_Coord y, Elm_Xdnd_Actio
                   Gui_Widget_Property *prop = obj_container_item_prop_get(it);
                   int ix, iy, iw, ih;
                   Eid *eid = EID_ID_GET(prop_value_nth_get(prop, 0));
-                  const Gui_Session *session = 
gui_context_editor_session_get(wdg_context_get(container));
+                  const Gui_Session *session = 
gui_context_editor_session_get(wdg_context_get(drop_target_wdg));
                   Eo *c = session_eo_get(session, wdg_get(eid));
 
-                  eo_do(eo_container, elm_obj_table_pack_get(c, &ix, &iy, &iw, 
&ih));
+                  eo_do(drop_target_wdg_eo, elm_obj_table_pack_get(c, &ix, 
&iy, &iw, &ih));
                   max_pack_x = (max_pack_x < ix) ? ix : max_pack_x;
                   max_pack_y = (max_pack_y < iy) ? iy : max_pack_y;
 
@@ -2569,25 +2350,25 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, 
Evas_Coord y, Elm_Xdnd_Actio
                   if ((new_column && (ix >= pack_x)) ||
                       (new_cell_x && (ix >= pack_x) && (iy == pack_y)))
                     {
-                       eo_do(eo_container, elm_obj_table_pack_set(c, ix + 1, 
iy, iw, ih));
+                       eo_do(drop_target_wdg_eo, elm_obj_table_pack_set(c, ix 
+ 1, iy, iw, ih));
                        max_pack_x = (max_pack_x < ix + 1) ? ix + 1 : 
max_pack_x;
                     }
 
                   /* If need to add a row, move all elements which are lower 
then new row,
                    * if need to add a cell, move elements which are lower in 
current column. */
-                  eo_do(eo_container, elm_obj_table_pack_get(c, &ix, NULL, 
NULL, NULL));
+                  eo_do(drop_target_wdg_eo, elm_obj_table_pack_get(c, &ix, 
NULL, NULL, NULL));
                   if ((new_line && (iy >= pack_y)) ||
                       (new_cell_y && (iy >= pack_y) && (ix == pack_x)))
                     {
-                       eo_do(eo_container, elm_obj_table_pack_set(c, ix, iy + 
1, iw, ih));
+                       eo_do(drop_target_wdg_eo, elm_obj_table_pack_set(c, ix, 
iy + 1, iw, ih));
                        max_pack_y = (max_pack_y < iy + 1) ? iy + 1 : 
max_pack_y;
                     }
                }
 
              /* Draw borders of the table. */
-            _table_borders_draw(eo_container, max_pack_x, max_pack_y, 
&(di->table_borders));
+            _table_borders_draw(drop_target_wdg_eo, max_pack_x, max_pack_y, 
&(di->table_borders));
 
-             eo_do(eo_container, elm_obj_table_pack(di->eo_cur, pack_x, 
pack_y, 1, 1));
+             eo_do(drop_target_wdg_eo, elm_obj_table_pack(di->eo_cur, pack_x, 
pack_y, 1, 1));
              di->table_pack_x = pack_x;
              di->table_pack_y = pack_y;
              di->packed = EINA_TRUE;
@@ -2603,7 +2384,9 @@ void
 _drag_start_post_cb(const Gui_Widget *wdg, const Eo *_wdg_eo)
 {
    Eo *wdg_eo = (Eo *) _wdg_eo;
-   eo_do(wdg_eo, efl_gfx_visible_set(EINA_FALSE));
+   /* FIXME: wdg_eo is NULL when dragging from objtree. It can be changed but 
should be?*/
+   if (wdg_eo) eo_do(wdg_eo, efl_gfx_visible_set(EINA_FALSE));
+
    Gui_Widget *wdg_container = NULL;
    Gui_Widget *wdg_parent = (Gui_Widget *) wdg_parent_get(wdg);
 
@@ -2615,7 +2398,6 @@ _drag_start_post_cb(const Gui_Widget *wdg, const Eo 
*_wdg_eo)
      wdg_container = wdg_parent;
 
    /* Explicitly call enter cb in order to create object, which will be 
dragged. */
-   Evas_Coord x = 0, y = 0;
    if (IS_MAIN(wdg))
      {
         _drop_target_enter(NULL, 
egui_layout_gui_get()->main_win->canvas_scroller);
@@ -2623,34 +2405,101 @@ _drag_start_post_cb(const Gui_Widget *wdg, const Eo 
*_wdg_eo)
         if (wi)
           {
              Eo *fr = main_wdg_info_frame_get(wi);
-             elm_grid_pack_get(fr, &x, &y, NULL, NULL);
              eo_do(fr, efl_gfx_visible_set(EINA_FALSE));
           }
-        _drop_target_pos(NULL, 
egui_layout_gui_get()->main_win->canvas_scroller, x, y, 
ELM_XDND_ACTION_UNKNOWN);
-     }
-   else
-     {
-        _drop_target_enter((Gui_Widget *) wdg_main_wdg_get(wdg), NULL);
-        eo_do(wdg_eo, efl_gfx_position_get(&x, &y));
      }
    /* Unpack Eo object if dragging from container. */
    if (wdg_container)
      {
         Eo *wdg_cont_eo = session_eo_get(session, wdg_container);
 
-        if (!strcmp(wdg_class_name_get(wdg_container), DB_DEF_BOX_CLASS))
+        Object_Container *_old_prev_container, *_new_prev_container;
+        _old_prev_container = (Object_Container *) 
wdg_obj_container_get((Gui_Widget *) wdg_container);
+        _new_prev_container = obj_container_copy(_old_prev_container);
+        memento_command_add(wdg_eid_get(wdg_container),
+                            MEMENTO_OBJ_CONTAINER_ITEM,
+                            _old_prev_container, _new_prev_container);
+
+        wdg_obj_container_unset((Gui_Widget *) wdg_container);
+        wdg_obj_container_set((Gui_Widget *) wdg_container, 
_new_prev_container);
+
+        /* Take old container's class name from content-property. */
+        Object_Container_Item *_ci = wdg_obj_container_item_get(wdg_container, 
-1, wdg_name_get(wdg));
+        wdg_obj_container_item_remove(wdg_container, _ci);
+
+        /* FIXME: wdg_eo is NULL when dragging from objtree. It can be changed 
but should be?*/
+        if (wdg_eo)
           {
-             eo_do(wdg_cont_eo, elm_obj_box_unpack(wdg_eo));
+             if (!strcmp(wdg_class_name_get(wdg_container), DB_DEF_BOX_CLASS))
+               {
+                  eo_do(wdg_cont_eo, elm_obj_box_unpack(wdg_eo));
+               }
+             else if (!strcmp(wdg_class_name_get(wdg_container), 
DB_DEF_TABLE_CLASS))
+               {
+                  eo_do(wdg_cont_eo, elm_obj_table_unpack(wdg_eo));
+                  /* Object will be deleted automatically by evas*/
+                  session_wdg_existence_set((Gui_Session *) session, wdg, 
EINA_FALSE);
+               }
           }
-        else if (!strcmp(wdg_class_name_get(wdg_container), 
DB_DEF_TABLE_CLASS))
+     }
+   /* If dragging from a widget(window), unset parent*/
+   else if (wdg_parent)
+     {
+        memento_command_add(wdg_eid_get(wdg),
+              MEMENTO_WIDGET_PARENT,
+              wdg_parent_id_get(wdg), NULL);
+        wdg_parent_set((Gui_Widget *) wdg, NULL);
+     }
+   else if (!wdg_parent)
+     {
+        memento_command_add(wdg_eid_get(wdg),
+              MEMENTO_WIDGET_PARENT,
+              NULL, NULL);
+     }
+}
+
+static Eina_Bool
+__undo_no_update(const Gui_Context *ctx);
+
+/* This callback is added only for dragging of objects on canvas. */
+static void
+_dragdone_post_cb(Eina_Bool accept)
+{
+   const Gui_Widget *wdg = dnd_drag_wdg_get();
+   if (!wdg) return;
+   Gui_Context *ctx = (Gui_Context *) wdg_context_get(wdg);
+
+   /* If dragged object was not accepted, or was accepted outside Erigo,
+    * drop memento created on drag start. */
+   if (!accept ||
+       (accept && !dnd_is_destination()))
+     {
+        __undo_no_update(ctx);
+        context_memento_move_to_prev(ctx);
+        context_memento_discard(ctx);
+
+        eo_do(g->main_win->toolbar_redo_it, 
elm_wdg_item_disabled_set(context_can_redo(ctx) ? EINA_FALSE : EINA_TRUE));
+        eo_do(g->main_win->toolbar_undo_it, 
elm_wdg_item_disabled_set(context_can_undo(ctx) ? EINA_FALSE : EINA_TRUE));
+
+        _wdg_parent_win_reload(wdg);
+        _editor_wdg_selected_set(wdg);
+        objtree_build(wdg_context_get(wdg));
+        objtree_item_selected_set(wdg);
+
+        /* If dropping memento, make obj visible */
+        const Gui_Session *session = gui_context_editor_session_get(ctx);
+        Eo *wdg_eo = session_eo_get(session, wdg);
+
+        eo_do(wdg_eo, efl_gfx_visible_set(EINA_TRUE));
+
+        Main_Wdg_Info *wi = wdg_data_get(wdg, MAIN_WDG_INFO);
+        if (wi)
           {
-             eo_do(wdg_cont_eo, elm_obj_table_unpack(wdg_eo));
-             /* Object will be deleted automatically by evas*/
-             session_wdg_existence_set((Gui_Session *) session, wdg, 
EINA_FALSE);
+             Eo *fr = main_wdg_info_frame_get(wi);
+             eo_do(fr, efl_gfx_visible_set(EINA_TRUE));
           }
-        /* Explicitly call target enter/pos cb, in order to calculate packing 
coords. */
-        _drop_target_enter(wdg_container, NULL);
-        _drop_target_pos(wdg_container, NULL, x, y, ELM_XDND_ACTION_UNKNOWN);
+
+        _dragged_wdg = NULL;
      }
 }
 
@@ -2816,7 +2665,6 @@ _widget_add(Gui_Session *session, const Gui_Widget *wdg, 
void *data)
              eo_do(iwin, efl_gfx_size_set(ow, oh));
              elm_grid_pack_set(fr, ox, oy, ow + dw, oh + dh);
           }
-
         elm_theme_free(theme);
      }
 
@@ -2873,7 +2721,6 @@ _editor_widget_clear(Gui_Widget *wdg)
 static void
 _wdg_parent_win_reload(const Gui_Widget *wdg)
 {
-   ERR("%p", wdg);
    if (!wdg) return;
    Gui_Widget *pwin = (Gui_Widget *) wdg_main_wdg_get(wdg);
    if (!pwin) return;
@@ -2908,13 +2755,13 @@ _update_widget_on_undoredo(Eid *wdg_id, Eina_Bool state)
 
 /* Undo last action */
 static Eina_Bool
-_editor_undo(const Gui_Context *ctx)
+__undo_no_update(const Gui_Context *ctx)
 {
    EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
-   const Memento *memento, *head_memento;
+   const Memento *memento;
    const Memento_Command *cmd;
    /* Save head memento for post function. */
-   head_memento = memento = context_current_memento_get(ctx);
+   memento = context_current_memento_get(ctx);
    if (!memento) return EINA_FALSE;
 
    const Eina_List *cmds_list = memento_commands_get(memento), *itr;
@@ -3047,6 +2894,7 @@ _editor_undo(const Gui_Context *ctx)
            case MEMENTO_WIDGET_PARENT:
                 {
                    Gui_Widget *wdg = wdg_get(eid);
+                   _wdg_border_draw(wdg, EINA_FALSE, BORDER_SELECTION);
                    /* According to current scenario, widget can be dragged 
from another and dropped to canvas.
                     * Thus here can be only main_wdg which is going to be 
undoed.
                     * So it's frame and editor window must be deleted and 
Main_Wdg_Info data must be freed. */
@@ -3108,7 +2956,19 @@ _editor_undo(const Gui_Context *ctx)
               ERR("case - default");
           }
      }
+   return EINA_TRUE;
+}
+
+/* Undo last action */
+static Eina_Bool
+_editor_undo(const Gui_Context *ctx)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
+   const Memento *head_memento;
+   /* Save head memento for post function. */
+   head_memento = context_current_memento_get(ctx);
 
+  if (! __undo_no_update(ctx)) return EINA_FALSE;
    /* Update propview. */
    _editor_undo_redo_post(head_memento);
 
@@ -3261,6 +3121,7 @@ _editor_redo(const Gui_Context *ctx)
            case MEMENTO_WIDGET_PARENT:
                 {
                    Gui_Widget *wdg = wdg_get(eid);
+                   _wdg_border_draw(wdg, EINA_FALSE, BORDER_SELECTION);
                    /* According to current scenario, widget can be dragged 
from canvas and dropped into object.
                     * Thus here can be only main_wdg which is going to be 
redoed.
                     * So it's frame and editor window must be deleted and 
Main_Wdg_Info data must be freed. */
@@ -3459,103 +3320,6 @@ _editor_selected_wdg_del_cb()
    context_memento_finalize(ctx);
 }
 
-static Gui_Widget *
-_editor_factory_wdg_create(const char *drag_data, const Gui_Widget 
*focused_wdg, Evas_Coord main_wdg_x, Evas_Coord main_wdg_y)
-{
-   const Gui_Widget *parent_win = NULL;
-   const char *parent_name = NULL;
-   Gui_Widget *wdg;
-   Gui_Context *ctx = _active_context_get();
-
-   if (!ctx)
-     {
-        ERR("No active context");
-        return NULL;
-     }
-
-   wdg = _editor_wdg_create(ctx, drag_data, focused_wdg);
-
-   /* If a widget is selected during creation */
-   if (focused_wdg)
-     {
-        parent_win = wdg_main_wdg_get(focused_wdg);
-        /* FIXME: We have to check the parent validity. This is not fully 
operational.
-         * What happens is that button, check... can be containers and so be 
considered
-         * as parents. We need to find a way to forbid that.
-         */
-        if (IS_WIN(wdg) || (!IS_WIN(parent_win) && !IS_CONTAINER(parent_win))) 
parent_win = NULL;
-        else parent_name = wdg_name_get(parent_win);
-     }
-
-   wdg_parent_set(wdg, parent_name);
-
-   memento_command_add(wdg_eid_get(wdg), MEMENTO_WIDGET,  (void *) (intptr_t) 
EINA_FALSE, (void *) (intptr_t) EINA_TRUE);
-
-   /*Add default visibility property*/
-   Gui_Widget_Property *prop;
-   Gui_Value *val;
-   Op_Desc *op;
-
-   if (IS_WIN(wdg))
-     {
-        op = db_mro_op_desc_get(DB_DEF_WIN_CLASS, DB_DEF_WIN_CLASS, TITLE_SET);
-        prop = prop_create_for_op(op);
-        val = prop_value_nth_get(prop, 0);
-        gui_value_string_set(val, eid_name_get(wdg_eid_get(wdg)));
-        wdg_prop_add(wdg, prop);
-     }
-
-   /* Save drop coordinates in internal data of widget, in order to set 
position of the frame */
-   if (IS_MAIN(wdg))
-     {
-        wdg_data_set(wdg, CURSOR_DROP_X, (void *) (intptr_t) main_wdg_x);
-        wdg_data_set(wdg, CURSOR_DROP_Y, (void *) (intptr_t) main_wdg_y);
-     }
-
-#if 0
-   // Set default property values
-   Eina_List *kl_list = eo_class_mro_get(class_name), *itr;
-   const char *kl_name;
-
-   EINA_LIST_REVERSE_FOREACH(kl_list, itr, kl_name)
-     {
-        const Eina_List *defaults = db_default_prop_values_get(kl_name);
-        const Eina_List  *l = NULL;
-        Gui_Widget_Property *defprop = NULL;
-        EINA_LIST_FOREACH(defaults, l, defprop)
-          {
-             Gui_Widget_Property *newprop = prop_copy(defprop);
-             wdg_prop_add(wdg, newprop);
-          }
-     }
-   eina_list_free(kl_list);
-#endif
-
-   Eo *pw = NULL;
-   if (!parent_win) pw = (Eo *)canvas_get();
-   _iter_widget_create(wdg, pw);
-
-   _editor_wdg_selected_set(wdg);
-   objtree_item_selected_set(wdg);
-
-   /* PoC: add main menu to each window. */
-#if 0
-   if (IS_WIN(wdg))
-     {
-        char menu_name[20] = {'\0'};
-        sprintf(menu_name, "%s_%s", wdg_name_get(wdg), "main_menu");
-        Eid *eid = eid_new(ctx, menu_name, EID_TYPE_WIDGET);
-
-        Gui_Widget *mmenu = wdg_new((Gui_Context *) ctx, DB_DEF_MENU_CLASS, 
eid);
-        wdg_parent_set(mmenu, wdg_name_get(wdg));
-
-        manager_widget_create(session, mmenu, MODE_EDITOR, NULL);
-        manager_widget_configure(session, mmenu, MODE_EDITOR, NULL);
-     }
-#endif
-   return wdg;
-}
-
 void
 editor_shutdown()
 {
@@ -5014,8 +4778,8 @@ editor_init(GuiLogicCbs *_guilogic_cbs)
                        _drop_target_drop_cb, NULL
                        );
 
-   drop_item_container_set(g->main_win->objtree_list, _objtree_it_get_cb, 
_objtree_drop_cb, NULL);
-   drag_item_container_set(g->main_win->objtree_list, 0.5, 0.3, 
_objtree_it_get_cb, _objtree_data_getcb);
+   drop_item_container_set(g->main_win->objtree_list, _objtree_pos_cb, 
_objtree_drop_cb, NULL);
+   drag_item_container_set(g->main_win->objtree_list, 0.5, 0.3, 
_objtree_drag_start_cb, _objtree_dragdone_cb);
 
    key_binding_new(_key_binding_undo_cb, NULL, "ctrl", "z", NULL);
    key_binding_new(_key_binding_redo_cb, NULL, "ctrl", "shift", "z", NULL);
diff --git a/src/bin/gui/egui_logic.c b/src/bin/gui/egui_logic.c
index e074015..12bfa74 100644
--- a/src/bin/gui/egui_logic.c
+++ b/src/bin/gui/egui_logic.c
@@ -398,7 +398,6 @@ _fs_mode_open(int fs_mode)
 void
 _toolbar_item_sel_cb
 (void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
-//(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const 
Eo_Event_Description *desc EINA_UNUSED, void *event_info)
 {
    const Gui_Context *ctx = _active_context_get();
    Elm_Object_Item *item = event_info;
diff --git a/src/lib/gui_parser.c b/src/lib/gui_parser.c
index bdfc0f8..a79df07 100644
--- a/src/lib/gui_parser.c
+++ b/src/lib/gui_parser.c
@@ -467,8 +467,9 @@ _read_items_section(const Gui_Context *gui_ctx, Gui_Widget 
*wdg, Item_Container_
    eina_iterator_free(it);
 }
 
+/* if null_parent is EINA_TRUE, set parent to NULL*/
 static Eina_Bool
-_widget_parse(Gui_Context *gui_ctx, Eid *eid, Eina_Json_Value *widget_js, 
const char *json_version EINA_UNUSED)
+_widget_parse(Gui_Context *gui_ctx, Eid *eid, Eina_Json_Value *widget_js, 
Eina_Bool null_parent, const char *json_version EINA_UNUSED)
 {
    /* Creation of widget */
    const char *class_name = NULL, *parent_name = NULL;
@@ -493,6 +494,7 @@ _widget_parse(Gui_Context *gui_ctx, Eid *eid, 
Eina_Json_Value *widget_js, const
    if ((j) && (eina_json_type_get(j) == EINA_JSON_TYPE_STRING))
       parent_name = eina_json_string_get(j);
 
+   if (null_parent) parent_name = NULL;
    if (!wdg_parent_set(wdg, parent_name))
      {
         goto bad_end;
@@ -991,9 +993,12 @@ _erigo_settings_parse(Gui_Context *gui_ctx, 
Eina_Json_Value *res_js)
    return ret;
 }
 
-/* Register name and save JSON in list. */
+/* Register name and save JSON in list.
+ *
+ * if null_parent is EINA_TRUE, set only first parent to NULL,
+ * this is used to null parent, when generating DnD widget from widget */
 Eina_Bool
-gui_parser_json_parse(Gui_Context *gui_ctx, const char *_data, Eina_Bool 
rename, Eina_List **mains)
+gui_parser_json_parse(Gui_Context *gui_ctx, const char *_data, Eina_Bool 
rename, Eina_Bool null_parent, Eina_List **mains)
 {
    Eina_Json_Context *ctx = eina_json_context_dom_new();
    Eina_Json_Type type;
@@ -1099,7 +1104,8 @@ gui_parser_json_parse(Gui_Context *gui_ctx, const char 
*_data, Eina_Bool rename,
                   parse_ret = EINA_FALSE;
                   break;
                }
-             parse_ret = _widget_parse(gui_ctx, name_id, c, json_version);
+             parse_ret = _widget_parse(gui_ctx, name_id, c, null_parent, 
json_version);
+             null_parent = EINA_FALSE;
              if (!parse_ret)
                {
                   ERR("Can not parse widget: \"%s\"", name);
@@ -1146,7 +1152,7 @@ gui_parser_json_file_read(Gui_Context *ctx, const char 
*in_path)
 
    if (file_data)
      {
-        ret = gui_parser_json_parse(ctx, file_data, EINA_FALSE, NULL);
+        ret = gui_parser_json_parse(ctx, file_data, EINA_FALSE, EINA_FALSE, 
NULL);
         free(file_data);
      }
    return ret;
diff --git a/src/lib/gui_parser.h b/src/lib/gui_parser.h
index 31bf4ea..0c0cb36 100644
--- a/src/lib/gui_parser.h
+++ b/src/lib/gui_parser.h
@@ -45,6 +45,6 @@ gui_parser_json_file_read(Gui_Context *ctx, const char 
*filename);
  * and create all widgets. Returns a list of the main widgets.
  * If new_name is true, widgets whose name is already reserved will receive a 
new name */
 Eina_Bool
-gui_parser_json_parse(Gui_Context *ctx, const char *data, Eina_Bool new_name, 
Eina_List **mains);
+gui_parser_json_parse(Gui_Context *ctx, const char *data, Eina_Bool new_name, 
Eina_Bool null_parent, Eina_List **mains);
 
 # endif
diff --git a/src/lib/gui_widget.c b/src/lib/gui_widget.c
index 3c62c8c..6c40ec0 100644
--- a/src/lib/gui_widget.c
+++ b/src/lib/gui_widget.c
@@ -3464,7 +3464,6 @@ void
 session_del(Gui_Session *session)
 {
    if (!session) return;
-   ERR("%p", session);
    eina_hash_foreach(session->eo_hash, _eo_hash_clean, session);
    eina_hash_free(session->delayed_props_lists_hash);
    eina_hash_free(session->eo_hash);

-- 


Reply via email to