yakov pushed a commit to branch master.

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

commit 1e88207ade4e4fce27f6449c7152d6506aba5e5f
Author: Yakov Goldberg <yako...@samsung.com>
Date:   Wed Nov 18 11:29:32 2015 +0200

    Implement DnD for layout with support of swallow objects
---
 src/bin/gui/editor.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 219 insertions(+), 6 deletions(-)

diff --git a/src/bin/gui/editor.c b/src/bin/gui/editor.c
index 2b167e5..8774555 100644
--- a/src/bin/gui/editor.c
+++ b/src/bin/gui/editor.c
@@ -63,6 +63,13 @@ typedef struct
              int table_pack_y;
              Eina_List *table_borders;
           };
+        /* Layout packing data. */
+        struct
+          {
+             Eid *drop_to_item;
+             const char *part;
+             Evas_Coord ox, ow, oy, oh;
+          };
      };
 
    int pointer_x;
@@ -1645,6 +1652,7 @@ enum
    DROP_TO_WIN,
    DROP_TO_BOX,
    DROP_TO_TABLE,
+   DROP_TO_LAYOUT,
    DROP_TO_MAIN
 };
 
@@ -1690,22 +1698,22 @@ _drop_target_drop(Gui_Widget *drop_target_wdg, Eo 
*canvas_drop_target, const cha
      {
         drop_to_wdg = DROP_TO_TABLE;
      }
+   else if (!strcmp(wdg_class_name_get(drop_target_wdg), DB_DEF_LAYOUT_CLASS))
+     {
+        drop_to_wdg = DROP_TO_LAYOUT;
+     }
    else if (IS_MAIN(drop_target_wdg))
      {
         drop_to_wdg = DROP_TO_MAIN;
      }
    if (drop_to_wdg == NO_DROP) goto end;
 
-   /* Commeting out positioning of dropped widget.
-    * This part makes sens when DnD inside window changes position. */
-#if 0
    /* 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;
      }
-#endif
 
    /* FIXME: delete this, as wdg_cur must be created in _drop_target_pos()*/
    if (!_dragged_wdg)
@@ -1803,6 +1811,81 @@ _drop_target_drop(Gui_Widget *drop_target_wdg, Eo 
*canvas_drop_target, const cha
 #endif
           }
      }
+   else if (drop_to_wdg == DROP_TO_LAYOUT)
+     {
+        if (new_wdg)
+          {
+             if (di->drop_to_item)
+               {
+                  const Eina_List *citems = 
wdg_obj_container_contents_list_get(drop_target_wdg), *itr;
+                  Object_Container_Item *cit = NULL;
+                  EINA_LIST_FOREACH(citems, itr, cit)
+                    {
+                       if (di->drop_to_item == 
obj_container_item_eid_get(cit)) break;
+                       cit = NULL;
+                    }
+
+                  if (cit)
+                    {
+                       Object_Container *_old_container, *_new_container;
+                       Gui_Widget_Property *i_prop, *new_prop;
+                       Gui_Value *val;
+
+                       _old_container = (Object_Container *) 
wdg_obj_container_get(drop_target_wdg);
+                       _new_container = obj_container_copy(_old_container);
+
+                       memento_command_add(wdg_eid_get(drop_target_wdg),
+                                           MEMENTO_OBJ_CONTAINER,
+                                           _old_container, _new_container);
+                       wdg_obj_container_unset(drop_target_wdg);
+                       wdg_obj_container_set(drop_target_wdg, _new_container);
+
+                       i_prop = obj_container_item_prop_get(cit);
+                       new_prop = prop_copy(i_prop);
+                       val = prop_value_nth_get(new_prop, 1);
+                       /* Assign new widget as container item. */
+                       gui_value_name_id_set(val, GUI_TYPE_OBJECT, 
wdg_eid_get(new_wdg));
+                       Object_Container_Item *ci = 
obj_container_item_new(new_prop, wdg_eid_get(new_wdg));
+
+                       /* Get index of old item. */
+                       int idx = 
wdg_obj_container_item_idx_get(drop_target_wdg, di->drop_to_item, EINA_FALSE);
+                       wdg_obj_container_item_remove(drop_target_wdg, cit);
+                       wdg_obj_container_item_add(drop_target_wdg, ci, idx);
+                       if (eid_is_dummy(di->drop_to_item))
+                         memento_command_add(di->drop_to_item, MEMENTO_WIDGET, 
 (void *) (intptr_t) EINA_TRUE, (void *) (intptr_t) EINA_FALSE);
+                    }
+               }
+             else
+               {
+                  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 (old_prop)
+                    {
+                       wdg_prop_remove((Gui_Widget *) new_wdg, old_prop);
+                    }
+                  wdg_prop_add((Gui_Widget *) new_wdg, prop);
+               }
+          }
+     }
    else if (drop_to_wdg == DROP_TO_BOX)
      {
         /* Append content memento to the creation memento (which was created 
in _editor_factory_wdg_create())
@@ -2284,6 +2367,89 @@ _drop_target_pos(void *data, Eo *obj, Evas_Coord x, 
Evas_Coord y, Elm_Xdnd_Actio
              di->packed = EINA_TRUE;
           }
      }
+   if (drop_target_wdg && !strcmp(wdg_class_name_get(drop_target_wdg), 
DB_DEF_LAYOUT_CLASS))
+     {
+        /* manually check for part's contents.
+         * FIXME: DUMMY objects can be changed to dummy widget: the same 
widget but with dummy_id,
+         * thus it can be iterated as a child.*/
+        Evas_Coord ox, ow, oy, oh;
+        Object_Container_Item *cit;
+        Eina_Bool repack = EINA_FALSE;
+        Eid *ieid = NULL;
+        const char *part = NULL;
+        Eo *o_container = session_eo_get(session, drop_target_wdg);
+        const Eina_List *citems = 
wdg_obj_container_contents_list_get(drop_target_wdg), *itr;
+
+        /* If dragged object is packed and cursor is in coords of swallow 
object,
+         * don't need to check anything*/
+        if (di->packed &&
+            ((x >= di->ox) && (x <= di->ox + di->ow)) &&
+            ((y >= di->oy) && (y <= di->oy + di->oh)))
+          {
+             return;
+          }
+
+        /* Detect if cursor is inside swallow object.*/
+        EINA_LIST_FOREACH(citems, itr, cit)
+          {
+             ieid = obj_container_item_eid_get(cit);
+             Gui_Widget_Property *i_prop = obj_container_item_prop_get(cit);
+             part = STRING_GET(prop_value_nth_get(i_prop, 0));
+             Gui_Widget *iw = wdg_get(ieid);
+             Eo *ieo = session_eo_get(session, iw);
+             eo_do(ieo, efl_gfx_position_get(&ox, &oy),
+                   efl_gfx_size_get(&ow, &oh));
+             if (((x >= ox) && (x <= ox + ow)) &&
+                 ((y >= oy) && (y <= oy + oh)))
+               {
+                  break;
+               }
+             ox = oy = ow =oh = 0;
+             ieid = NULL;
+          }
+
+        /* If previously found object changed. */
+        if (di->drop_to_item != ieid)
+          {
+             di->drop_to_item = ieid;
+             repack = EINA_TRUE;
+             di->ox = ox;
+             di->oy = oy;
+             di->ow = ow;
+             di->oh = oh;
+             if (di->packed)
+               {
+                  di->packed = EINA_FALSE;
+                  eo_do(o_container, 
elm_obj_container_content_unset(di->part));
+               }
+          }
+        /* If need to repack, iterate over all content, unset original object 
and set dragged.*/
+        if (repack)
+          {
+             EINA_LIST_FOREACH(citems, itr, cit)
+               {
+                  ieid = obj_container_item_eid_get(cit);
+                  Gui_Widget *iw = wdg_get(ieid);
+                  Eo *ieo = session_eo_get(session, iw);
+                  Gui_Widget_Property *i_prop = 
obj_container_item_prop_get(cit);
+                  part = STRING_GET(prop_value_nth_get(i_prop, 0));
+                  if (ieid == di->drop_to_item)
+                    {
+                       eo_do(o_container, 
elm_obj_container_content_unset(part));
+                       eo_do(ieo, efl_gfx_visible_set(EINA_FALSE));
+                       eo_do(o_container, elm_obj_container_content_set(part, 
di->eo_cur));
+                       di->packed = EINA_TRUE;
+                       di->part = part;
+                    }
+                  else
+                    {
+                       eo_do(ieo, efl_gfx_visible_set(EINA_TRUE));
+                       eo_do(o_container, elm_obj_container_content_set(part, 
ieo));
+                    }
+
+               }
+          }
+     }
 }
 
 /*********************************************************/
@@ -2299,11 +2465,12 @@ _drag_start_post(const Gui_Widget *wdg, const Eo 
*_wdg_eo)
 
    Gui_Widget *wdg_container = NULL;
    Gui_Widget *wdg_parent = (Gui_Widget *) wdg_parent_get(wdg);
+   const Gui_Context *ctx = wdg_context_get(wdg);
+   const Gui_Session *session = gui_context_editor_session_get(ctx);
 
    /* Unset selected widget. */
    _editor_wdg_selected_set(NULL);
 
-   const Gui_Session *session = 
gui_context_editor_session_get(wdg_context_get(wdg));
    if (wdg_parent && wdg_obj_container_item_get(wdg_parent, -1, 
wdg_name_get(wdg)))
      wdg_container = wdg_parent;
 
@@ -2329,6 +2496,19 @@ _drag_start_post(const Gui_Widget *wdg, const Eo 
*_wdg_eo)
    /* Unpack Eo object if dragging from container. */
    if (wdg_container)
      {
+        /* If container is layout, need to create new dummy instead of dragged 
widget. */
+        Eid *new_dummy_eid = NULL;
+        if (!strcmp(wdg_class_name_get(wdg_container), DB_DEF_LAYOUT_CLASS))
+          {
+             Gui_Widget *_dummy_wdg = 
wdg_get(gui_context_eid_get_by_name(NULL, "__dummy"));
+             char *new_dummy_name = gui_context_free_name_get(ctx, 
wdg_class_name_get(_dummy_wdg));
+             new_dummy_eid = eid_new((Gui_Context *)ctx, new_dummy_name, 
EID_TYPE_WIDGET);
+             Gui_Widget *new_dummy_wdg = wdg_copy(_dummy_wdg, new_dummy_eid, 
EINA_TRUE);
+             free(new_dummy_name);
+             wdg_parent_set(new_dummy_wdg, wdg_name_get(wdg_container));
+             memento_command_add(new_dummy_eid, MEMENTO_WIDGET,  (void *) 
(intptr_t) EINA_FALSE, (void *) (intptr_t) EINA_TRUE);
+          }
+
         Eo *wdg_cont_eo = session_eo_get(session, wdg_container);
 
         Object_Container *_old_prev_container, *_new_prev_container;
@@ -2341,9 +2521,34 @@ _drag_start_post(const Gui_Widget *wdg, const Eo 
*_wdg_eo)
         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. */
+        /* If container is layout, create, fill in property and create 
Container Item. */
         Object_Container_Item *_ci = wdg_obj_container_item_get(wdg_container, 
-1, wdg_name_get(wdg));
+        int idx = wdg_obj_container_item_idx_get(wdg_container, 
obj_container_item_eid_get(_ci), EINA_FALSE);
+        Object_Container_Item *dummy_ci = NULL;
+        const char *part = NULL;
+        if (!strcmp(wdg_class_name_get(wdg_container), DB_DEF_LAYOUT_CLASS))
+          {
+             Gui_Widget_Property *i_prop = obj_container_item_prop_get(_ci);
+             Gui_Widget_Property *new_prop = prop_copy(i_prop);
+
+             Gui_Value *val = prop_value_nth_get(new_prop, 1);
+             gui_value_name_id_set(val, GUI_TYPE_OBJECT, new_dummy_eid);
+             dummy_ci = obj_container_item_new(new_prop, new_dummy_eid);
+             val = prop_value_nth_get(new_prop, 0);
+             part = STRING_GET(val);
+          }
+
         wdg_obj_container_item_remove(wdg_container, _ci);
+        /* If dummy item was created, add it into container, create Eo and 
pack it. */
+        if (dummy_ci)
+          {
+             wdg_obj_container_item_add(wdg_container, dummy_ci, idx);
+             Gui_Widget *wi = wdg_get(new_dummy_eid);
+
+             manager_widget_create((Gui_Session *) session, wi, NULL);
+             Eo *dummy_eo = session_eo_get(session, wi);
+             eo_do(wdg_cont_eo, elm_obj_container_content_set(part, dummy_eo));
+          }
 
         /* FIXME: wdg_eo is NULL when dragging from objtree. It can be changed 
but should be?*/
         if (wdg_eo)
@@ -2512,6 +2717,14 @@ _widget_add(Gui_Session *session, const Gui_Widget *wdg, 
void *data EINA_UNUSED)
                                       _drop_target_pos, (void *) wdg,
                                       _drop_target_drop_cb, (void *) wdg);
           }
+        else if (!strcmp(wdg_class_name_get(wdg), DB_DEF_LAYOUT_CLASS))
+          {
+             drop_target_wdg_set((Gui_Widget *) wdg, o,
+                                 _drop_target_enter, (void *) wdg,
+                                 _drop_target_leave, (void *) wdg,
+                                 _drop_target_pos, (void *) wdg,
+                                 _drop_target_drop_cb, (void *) wdg);
+          }
      }
    else
      {

-- 


Reply via email to