yakov pushed a commit to branch master.

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

commit 779f9bbba1fed11ddc7ceb39c22ba35c9b8902a3
Author: Yakov Goldberg <yako...@samsung.com>
Date:   Mon May 11 18:33:55 2015 +0300

    Implement DnD from factory/canvas to objtree.
    
    Objects can be dragged from factory/canvas to objtree.
---
 NEWS                 |   1 +
 src/bin/gui/dnd.c    |  19 +++-
 src/bin/gui/dnd.h    |   6 ++
 src/bin/gui/editor.c | 276 ++++++++++++++++++++++++++++++++++-----------------
 4 files changed, 211 insertions(+), 91 deletions(-)

diff --git a/NEWS b/NEWS
index 833a130..0ea01df 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ Changes since 1.0.0
 Features:
    * Add support for widgets: Hoversel
    * Add multicontext support: up to 15 contexts can be opened.
+   * Add DnD to objtree. Objects can be dragged from factory/canvas to objtree.
 
 Fixes:
   * Don't show empty hoversel in Property view when there is no resources.
diff --git a/src/bin/gui/dnd.c b/src/bin/gui/dnd.c
index cce2ad0..5ede42a 100644
--- a/src/bin/gui/dnd.c
+++ b/src/bin/gui/dnd.c
@@ -107,6 +107,8 @@ static void
 _dropenter(void *data, Evas_Object *obj)
 {
    _dnd_info.dnd_in_out++;
+   /* data is NULL when entering/leaving objtree. */
+   if (!data) return;
    Target_Info *ti = data;
    ti->drop_target = ti->wdg;
 
@@ -120,8 +122,10 @@ _dropenter(void *data, Evas_Object *obj)
 static void
 _dropleave(void *data, Evas_Object *obj)
 {
-   Target_Info *main_wdg_ti = data;
    _dnd_info.dnd_in_out--;
+   /* data is NULL when entering/leaving objtree. */
+   if (!data) return;
+   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.
@@ -610,6 +614,19 @@ drop_target_main_wdg_set(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)
+{
+   elm_drop_item_container_add(obj, ELM_SEL_FORMAT_TARGETS, itemgetcb,
+                               _dropenter, NULL, _dropleave, NULL, NULL, NULL, 
dropcb, dropdata);
+}
+
+void
+drop_item_container_del(Eo *obj)
+{
+   elm_drop_item_container_del(obj);
+}
+
+void
 drop_target_wdg_del(Gui_Widget *wdg, Eo *obj)
 {
    Target_Info *ti = NULL;
diff --git a/src/bin/gui/dnd.h b/src/bin/gui/dnd.h
index 185848c..f9e1d3c 100644
--- a/src/bin/gui/dnd.h
+++ b/src/bin/gui/dnd.h
@@ -28,6 +28,12 @@ drop_target_main_wdg_set(Gui_Widget *wdg, Eo *obj,
 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);
+
+void
+drop_item_container_del(Eo *obj);
+
 const char*
 dnd_drag_data_get();
 
diff --git a/src/bin/gui/editor.c b/src/bin/gui/editor.c
index 8197904..7755080 100644
--- a/src/bin/gui/editor.c
+++ b/src/bin/gui/editor.c
@@ -1638,15 +1638,29 @@ _drop_target_leave(void *data, Evas_Object *obj 
EINA_UNUSED)
      }
 }
 
+/* In the beginning of drop handler we want to determine,
+ * whenever drop can be successfull. */
+enum
+{
+   NO_DROP,
+   DROP_TO_CANVAS,
+   DROP_TO_WIN,
+   DROP_TO_BOX,
+   DROP_TO_TABLE,
+   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(void *data, Evas_Object *obj, Elm_Selection_Data *ev)
+_drop_target_drop(Gui_Widget *wdg, Eo *canvas_drop_target, const char 
*drag_data, Eina_Bool dropped_to_objtree)
 {
-   Gui_Widget *wdg = data;
-   Eo *canvas_drop_target = obj;
    DnD_Info *di = NULL;
+   const Gui_Widget *new_wdg = NULL;
+   int drop_to_wdg = NO_DROP;
+
    _wdg_border_draw(NULL, EINA_FALSE, BORDER_DROP_TARGET);
    if (wdg)
      {
@@ -1661,13 +1675,39 @@ _drop_target_drop(void *data, Evas_Object *obj, 
Elm_Selection_Data *ev)
         ERR("Drop target is wrong. If you see this message something is 
terribly wrong!");
      }
 
-   const char *drag_data = ev->data;
-   const Gui_Widget *new_wdg = NULL;
+   if (!wdg)
+     {
+        drop_to_wdg = DROP_TO_CANVAS;
+     }
+   else if (IS_WIN(wdg))
+     {
+        drop_to_wdg = DROP_TO_WIN;
+     }
+   else if (!strcmp(wdg_class_name_get(wdg), DB_DEF_BOX_CLASS))
+     {
+        drop_to_wdg = DROP_TO_BOX;
+     }
+   else if (!strcmp(wdg_class_name_get(wdg), DB_DEF_TABLE_CLASS))
+     {
+        drop_to_wdg = DROP_TO_TABLE;
+     }
+   else if (IS_MAIN(wdg))
+     {
+        drop_to_wdg = DROP_TO_MAIN;
+     }
+   if (drop_to_wdg == NO_DROP) goto end;
+
    const Gui_Context *ctx = _active_context_get();
    const Gui_Session *session = gui_context_editor_session_get(ctx);
    /* If drag_data != EDITOR_DRAG_DATA then new widget was dragged from the 
factory. */
    Eina_Bool drag_from_factory = !!strcmp(drag_data, EDITOR_DRAG_DATA);
    /* Drop when dragging from factory. */
+   int drop_x = di->pointer_x, drop_y = di->pointer_y;
+   if (dropped_to_objtree)
+     {
+        drop_x = drop_y = 0;
+     }
+
    if (drag_from_factory)
      {
         /* Don't allow to drop Window from factory into Main Obj*/
@@ -1675,7 +1715,7 @@ _drop_target_drop(void *data, Evas_Object *obj, 
Elm_Selection_Data *ev)
           {
              goto end;
           }
-        new_wdg = _editor_factory_wdg_create(drag_data, wdg, di->pointer_x, 
di->pointer_y);
+        new_wdg = _editor_factory_wdg_create(drag_data, wdg, drop_x, drop_y);
      }
    else
      {
@@ -1805,9 +1845,9 @@ _drop_target_drop(void *data, Evas_Object *obj, 
Elm_Selection_Data *ev)
                }
 
              val = prop_value_nth_get(prop, 0);
-             gui_value_int_set(val, di->pointer_x);
+             gui_value_int_set(val, drop_x);
              val = prop_value_nth_get(prop, 1);
-             gui_value_int_set(val, di->pointer_y);
+             gui_value_int_set(val, drop_y);
              propview_item_update(prop);
 
              Gui_Memento *memento = NULL;
@@ -1831,7 +1871,6 @@ _drop_target_drop(void *data, Evas_Object *obj, 
Elm_Selection_Data *ev)
           }
         goto end;
      }
-
    /* Dragging main wdg around canvas. */
    else if (!wdg_parent && !wdg)
      {
@@ -1878,7 +1917,7 @@ _drop_target_drop(void *data, Evas_Object *obj, 
Elm_Selection_Data *ev)
      }
 
    /* Where to drop. */
-   if (!wdg)
+   if (drop_to_wdg == DROP_TO_CANVAS)
      {
         Gui_Memento *memento_next = gui_memento_new(wdg_eid_get(new_wdg),
                                                     MEMENTO_WIDGET_PARENT,
@@ -1892,7 +1931,7 @@ _drop_target_drop(void *data, Evas_Object *obj, 
Elm_Selection_Data *ev)
           }
      }
    /* Dragging into win */
-   else if (wdg && IS_WIN(wdg))
+   else if (drop_to_wdg == DROP_TO_WIN)
      {
         Gui_Memento *memento_next = gui_memento_new(wdg_eid_get(new_wdg),
                                                     MEMENTO_WIDGET_PARENT,
@@ -1916,9 +1955,9 @@ _drop_target_drop(void *data, Evas_Object *obj, 
Elm_Selection_Data *ev)
                }
 
              val = prop_value_nth_get(prop, 0);
-             gui_value_int_set(val, di->pointer_x);
+             gui_value_int_set(val, drop_x);
              val = prop_value_nth_get(prop, 1);
-             gui_value_int_set(val, di->pointer_y);
+             gui_value_int_set(val, drop_y);
              propview_item_update(prop);
 
              memento_next = gui_memento_new(wdg_eid_get(new_wdg), 
MEMENTO_PROPERTY, old_prop, prop);
@@ -1931,87 +1970,93 @@ _drop_target_drop(void *data, Evas_Object *obj, 
Elm_Selection_Data *ev)
              wdg_prop_add((Gui_Widget *) new_wdg, prop);
           }
      }
-   else
+   else if (drop_to_wdg == DROP_TO_BOX)
      {
-        if (wdg && !strcmp(wdg_class_name_get(wdg), DB_DEF_BOX_CLASS))
-          {
-             /* Append content memento to the creation memento (which was 
created in _editor_factory_wdg_create())
-              * or to memento unpacking from previous container
-              * in order to correctly manage internals. */
-             Object_Container *_old_container, *_new_container;
-             _old_container = (Object_Container *) wdg_obj_container_get(wdg);
-             _new_container = obj_container_copy(_old_container);
-
-             Gui_Memento *memento_next = gui_memento_new(wdg_eid_get(wdg),
-                                                         
MEMENTO_OBJ_CONTAINER_ITEM,
-                                                         _old_container, 
_new_container);
-             /* Current memento is a memento created, during _factory 
_widget_create earlier in this func. */
-             gui_memento_append((Gui_Memento *) 
gui_context_current_memento_get(ctx), memento_next);
-             wdg_obj_container_unset(wdg);
-             wdg_obj_container_set(wdg, _new_container);
-
-             const Op_Desc *op_desc = 
db_container_desc_op_desc_get(db_container_desc_get(wdg_class_name_get(wdg)), 
CONTAINER_PACK);
-             Gui_Widget_Property *prop = prop_create_for_op(op_desc);
-             Gui_Value *val = prop_value_nth_get(prop, 0);
-             gui_value_name_id_set(val, GUI_TYPE_OBJECT, wdg_eid_get(new_wdg));
-
-             Object_Container_Item *ci = obj_container_item_new(prop, 
wdg_eid_get(new_wdg));
-             wdg_obj_container_item_add(wdg, ci, di->box_pack_idx);
-          }
-        else if (wdg && !strcmp(wdg_class_name_get(wdg), DB_DEF_TABLE_CLASS))
-          {
-             Eo *wdg_eo = session_eo_get(session, wdg);
-             Object_Container_Item *it;
+        /* Append content memento to the creation memento (which was created 
in _editor_factory_wdg_create())
+         * or to memento unpacking from previous container
+         * in order to correctly manage internals. */
+        Object_Container *_old_container, *_new_container;
+        _old_container = (Object_Container *) wdg_obj_container_get(wdg);
+        _new_container = obj_container_copy(_old_container);
 
-             Object_Container *_old_container, *_new_container;
-             _old_container = (Object_Container *) wdg_obj_container_get(wdg);
-             _new_container = obj_container_copy(_old_container);
+        Gui_Memento *memento_next = gui_memento_new(wdg_eid_get(wdg),
+                                                    MEMENTO_OBJ_CONTAINER_ITEM,
+                                                    _old_container, 
_new_container);
+        /* Current memento is a memento created, during _factory 
_widget_create earlier in this func. */
+        gui_memento_append((Gui_Memento *) 
gui_context_current_memento_get(ctx), memento_next);
+        wdg_obj_container_unset(wdg);
+        wdg_obj_container_set(wdg, _new_container);
 
-             Gui_Memento *memento_next = gui_memento_new(wdg_eid_get(wdg),
-                                                         
MEMENTO_OBJ_CONTAINER_ITEM,
-                                                         _old_container, 
_new_container);
-             /* Current memento is a memento created, during _factory 
_widget_create earlier in this func. */
-             gui_memento_append((Gui_Memento *) 
gui_context_current_memento_get(ctx), memento_next);
+        const Op_Desc *op_desc = 
db_container_desc_op_desc_get(db_container_desc_get(wdg_class_name_get(wdg)), 
CONTAINER_PACK);
+        Gui_Widget_Property *prop = prop_create_for_op(op_desc);
+        Gui_Value *val = prop_value_nth_get(prop, 0);
+        gui_value_name_id_set(val, GUI_TYPE_OBJECT, wdg_eid_get(new_wdg));
 
-             Eina_List *old_lst = wdg_obj_container_contents_list_get(wdg);
-             wdg_obj_container_unset(wdg);
-             wdg_obj_container_set(wdg, _new_container);
+        Object_Container_Item *ci = obj_container_item_new(prop, 
wdg_eid_get(new_wdg));
+        wdg_obj_container_item_add(wdg, ci, di->box_pack_idx);
+     }
+   else if (drop_to_wdg == DROP_TO_TABLE)
+     {
+        Eo *wdg_eo = session_eo_get(session, wdg);
+        Object_Container_Item *it;
 
-             /* Delete everything in new_container */
-             wdg_obj_container_item_remove_all(wdg);
+        Object_Container *_old_container, *_new_container;
+        _old_container = (Object_Container *) wdg_obj_container_get(wdg);
+        _new_container = obj_container_copy(_old_container);
 
-             /* Iterate over old list and create new container items and 
properties.
-              * Also get packing coordinates from Eo object and put it into 
property. */
-             Eina_List *l;
-             EINA_LIST_FOREACH(old_lst, l, it)
-               {
-                  Gui_Widget_Property *prop = obj_container_item_prop_get(it);
-                  Gui_Widget_Property *new_prop = prop_copy(prop);
-                  int ix, iy, iw, ih;
-                  Eid *eid = obj_container_item_eid_get(it);
-                  Eo *c = session_eo_get(session, wdg_get(eid));
-                  eo_do(wdg_eo, elm_obj_table_pack_get(c, &ix, &iy, &iw, &ih));
+        Gui_Memento *memento_next = gui_memento_new(wdg_eid_get(wdg),
+                                                    MEMENTO_OBJ_CONTAINER_ITEM,
+                                                    _old_container, 
_new_container);
+        /* Current memento is a memento created, during _factory 
_widget_create earlier in this func. */
+        gui_memento_append((Gui_Memento *) 
gui_context_current_memento_get(ctx), memento_next);
 
-                  gui_value_int_set(prop_value_nth_get(new_prop, 1), ix);
-                  gui_value_int_set(prop_value_nth_get(new_prop, 2), iy);
+        Eina_List *old_lst = wdg_obj_container_contents_list_get(wdg);
+        wdg_obj_container_unset(wdg);
+        wdg_obj_container_set(wdg, _new_container);
 
-                  Object_Container_Item *ci = obj_container_item_new(new_prop, 
eid);
-                  wdg_obj_container_item_add((Gui_Widget *) wdg, ci, -1);
-               }
+        /* Delete everything in new_container */
+        wdg_obj_container_item_remove_all(wdg);
 
-             /* Add new element into the container */
-             const Op_Desc *op_desc = 
db_container_desc_op_desc_get(db_container_desc_get(wdg_class_name_get(wdg)), 
CONTAINER_PACK);
-             Gui_Widget_Property *prop = prop_create_for_op(op_desc);
+        /* Iterate over old list and create new container items and properties.
+         * Also get packing coordinates from Eo object and put it into 
property. */
+        Eina_List *l;
+        EINA_LIST_FOREACH(old_lst, l, it)
+          {
+             Gui_Widget_Property *prop = obj_container_item_prop_get(it);
+             Gui_Widget_Property *new_prop = prop_copy(prop);
+             int ix, iy, iw, ih;
+             Eid *eid = obj_container_item_eid_get(it);
+             Eo *c = session_eo_get(session, wdg_get(eid));
+             eo_do(wdg_eo, elm_obj_table_pack_get(c, &ix, &iy, &iw, &ih));
 
-             gui_value_name_id_set(prop_value_nth_get(prop, 0), 
GUI_TYPE_OBJECT, wdg_eid_get(new_wdg));
-             gui_value_int_set(prop_value_nth_get(prop, 1), di->table_pack_x);
-             gui_value_int_set(prop_value_nth_get(prop, 2), di->table_pack_y);
-             gui_value_int_set(prop_value_nth_get(prop, 3), 1);
-             gui_value_int_set(prop_value_nth_get(prop, 4), 1);
+             gui_value_int_set(prop_value_nth_get(new_prop, 1), ix);
+             gui_value_int_set(prop_value_nth_get(new_prop, 2), iy);
 
-             Object_Container_Item *ci = obj_container_item_new(prop, 
wdg_eid_get(new_wdg));
-             wdg_obj_container_item_add(wdg, ci, -1);
+             Object_Container_Item *ci = obj_container_item_new(new_prop, eid);
+             wdg_obj_container_item_add((Gui_Widget *) wdg, ci, -1);
           }
+
+        /* Add new element into the container */
+        const Op_Desc *op_desc = 
db_container_desc_op_desc_get(db_container_desc_get(wdg_class_name_get(wdg)), 
CONTAINER_PACK);
+        Gui_Widget_Property *prop = prop_create_for_op(op_desc);
+
+        gui_value_name_id_set(prop_value_nth_get(prop, 0), GUI_TYPE_OBJECT, 
wdg_eid_get(new_wdg));
+        gui_value_int_set(prop_value_nth_get(prop, 1), di->table_pack_x);
+        gui_value_int_set(prop_value_nth_get(prop, 2), di->table_pack_y);
+        gui_value_int_set(prop_value_nth_get(prop, 3), 1);
+        gui_value_int_set(prop_value_nth_get(prop, 4), 1);
+
+        Object_Container_Item *ci = obj_container_item_new(prop, 
wdg_eid_get(new_wdg));
+        wdg_obj_container_item_add(wdg, ci, -1);
+     }
+   /* When drop into main object which is not window, only update parent. */
+   else if (drop_to_wdg == DROP_TO_MAIN)
+     {
+        Gui_Memento *memento_next = gui_memento_new(wdg_eid_get(new_wdg),
+                                                    MEMENTO_WIDGET_PARENT,
+                                                    
wdg_parent_id_get(new_wdg), wdg_eid_get(wdg));
+        gui_memento_append((Gui_Memento *) 
gui_context_current_memento_get(ctx), memento_next);
+        wdg_parent_set((Gui_Widget *) new_wdg, wdg_name_get(wdg));
      }
 end:
 
@@ -2025,11 +2070,60 @@ end:
           }
      }
 
-   _wdg_parent_win_reload(new_wdg);
-   _editor_wdg_selected_set(new_wdg);
-   objtree_build(wdg_context_get(new_wdg));
-   objtree_item_selected_set(new_wdg);
+   if (new_wdg)
+     {
+        _wdg_parent_win_reload(new_wdg);
+        _editor_wdg_selected_set(new_wdg);
+        objtree_build(wdg_context_get(new_wdg));
+        objtree_item_selected_set(new_wdg);
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_drop_target_drop_cb(void *data, Evas_Object *obj, Elm_Selection_Data *ev)
+{
+   const char *drag_data = ev->data;
+   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)
+{
+   Elm_Object_Item *it;
+   eo_do(obj, it = elm_obj_genlist_at_xy_item_get(x, y, yposret));
+   return it;
+}
+
+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)
+{
+   /* This function is called when data is dropped on the genlist */
+   Eo *canvas = NULL;
+   Gui_Widget *wdg = NULL;
+   if (it)
+     {
+        wdg = elm_object_item_data_get(it);
 
+        /* if widget is a box or table, drop into it,
+         * othervise drop into parent. */
+        if (!strcmp(wdg_class_name_get(wdg), DB_DEF_BOX_CLASS) ||
+            !strcmp(wdg_class_name_get(wdg), DB_DEF_TABLE_CLASS))
+          {
+          }
+        else
+          {
+             /* If dropping to main obj, return main object itself.*/
+             wdg = wdg_parent_get(wdg) ? (Gui_Widget *) wdg_parent_get(wdg) : 
wdg;
+          }
+     }
+   else
+     {
+        canvas = g->main_win->canvas_bg;
+     }
+   const char *drag_data = ev->data;
+   _drop_target_drop(wdg, canvas, drag_data, EINA_TRUE);
    return EINA_TRUE;
 }
 
@@ -2381,7 +2475,7 @@ _widget_add(Gui_Session *session, const Gui_Widget *wdg, 
void *data)
                                       _drop_target_enter, (void *) wdg,
                                       _drop_target_leave, (void *) wdg,
                                       _drop_target_pos, (void *) wdg,
-                                      _drop_target_drop, (void *) wdg);
+                                      _drop_target_drop_cb, (void *) wdg);
           }
         else if (!strcmp(wdg_class_name_get(wdg), DB_DEF_TABLE_CLASS))
           {
@@ -2389,7 +2483,7 @@ _widget_add(Gui_Session *session, const Gui_Widget *wdg, 
void *data)
                                       _drop_target_enter, (void *) wdg,
                                       _drop_target_leave, (void *) wdg,
                                       _drop_target_pos, (void *) wdg,
-                                      _drop_target_drop, (void *) wdg);
+                                      _drop_target_drop_cb, (void *) wdg);
           }
      }
    else
@@ -2490,7 +2584,7 @@ _widget_add(Gui_Session *session, const Gui_Widget *wdg, 
void *data)
                                   _drop_target_main_wdg_enter, (void *) wdg,
                                   _drop_target_main_wdg_leave, (void *) wdg,
                                   _drop_target_pos, (void *) wdg,
-                                  _drop_target_drop, (void *) wdg);
+                                  _drop_target_drop_cb, (void *) wdg);
 
         eo_do(fr, efl_gfx_visible_set(EINA_TRUE));
         eo_do(win, eo_key_data_set("__editor_frame", fr, NULL));
@@ -4581,9 +4675,11 @@ editor_init(GuiLogicCbs *_guilogic_cbs)
                             _drop_target_main_wdg_enter, NULL,
                             _drop_target_main_wdg_leave, NULL,
                             _drop_target_pos, NULL,
-                            _drop_target_drop, NULL
+                            _drop_target_drop_cb, NULL
                             );
 
+   drop_item_container_set(g->main_win->objtree_list, _objtree_it_get_cb, 
_objtree_drop_cb, NULL);
+
    key_binding_new(_key_binding_undo_cb, NULL, "ctrl", "z", NULL);
    key_binding_new(_key_binding_redo_cb, NULL, "ctrl", "shift", "z", NULL);
    key_binding_new(_key_binding_wdg_del_cb, NULL, "delete", NULL);

-- 


Reply via email to