kuuko pushed a commit to branch master.

http://git.enlightenment.org/bindings/python/python-efl.git/commit/?id=453c2a123c61c91d4af37c66e212ded6437e7796

commit 453c2a123c61c91d4af37c66e212ded6437e7796
Author: Kai Huuhko <kai.huu...@gmail.com>
Date:   Wed Dec 9 20:54:07 2015 +0200

    Elementary: Implement drag and drop
    
    Has some issues which we can work on later, should be API stable now.
---
 efl/elementary/cnp_callbacks.pxi  | 176 +++++++++++---------
 efl/elementary/gengrid_widget.pxi | 162 +++++++++---------
 efl/elementary/genlist_widget.pxi | 169 ++++++++++---------
 efl/elementary/object.pxi         | 336 ++++++++++++++++++--------------------
 examples/elementary/test_dnd.py   | 255 +++++++++++++++++++++++------
 5 files changed, 626 insertions(+), 472 deletions(-)

diff --git a/efl/elementary/cnp_callbacks.pxi b/efl/elementary/cnp_callbacks.pxi
index 2e56c95..83b4646 100644
--- a/efl/elementary/cnp_callbacks.pxi
+++ b/efl/elementary/cnp_callbacks.pxi
@@ -18,6 +18,7 @@ cdef extern from "Elementary.h":
     ctypedef void            (*Elm_Drag_Done)               (void *data, 
Evas_Object *obj, Eina_Bool accepted)
     ctypedef void            (*Elm_Drag_Accept)             (void *data, 
Evas_Object *obj, Eina_Bool doaccept)
     ctypedef void            (*Elm_Drag_Pos)                (void *data, 
Evas_Object *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action)
+    ctypedef void            (*Elm_Drag_Start)              (void *data, 
Evas_Object *obj)
     ctypedef 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)
     ctypedef Eina_Bool       (*Elm_Drop_Item_Container_Cb)  (void *data, 
Evas_Object *obj, Elm_Object_Item *it, Elm_Selection_Data *ev, int xposret, int 
yposret)
 
@@ -37,30 +38,22 @@ cdef extern from "Elementary.h":
 
     ctypedef _Elm_Drag_User_Info Elm_Drag_User_Info
 
-    ctypedef Eina_Bool      (*Elm_Item_Container_Data_Get_Cb)(
-        Evas_Object *obj,
-        Elm_Object_Item *it,
-        Elm_Drag_User_Info *info)
-
-    Eina_Bool elm_drag_item_container_add(Evas_Object *obj, double tm_to_anim, 
double tm_to_drag, Elm_Xy_Item_Get_Cb itemgetcb, Elm_Item_Container_Data_Get_Cb 
data_get)
-    Eina_Bool elm_drag_item_container_del(Evas_Object *obj)
-    Eina_Bool elm_drop_item_container_add(Evas_Object *obj,
-      Elm_Sel_Format format,
-      Elm_Xy_Item_Get_Cb itemgetcb,
-      Elm_Drag_State entercb, void *enterdata,
-      Elm_Drag_State leavecb, void *leavedata,
-      Elm_Drag_Item_Container_Pos poscb, void *posdata,
-      Elm_Drop_Item_Container_Cb dropcb, void *cbdata)
-    Eina_Bool elm_drop_item_container_del(Evas_Object *obj)
+    ctypedef Eina_Bool       (*Elm_Item_Container_Data_Get_Cb)(Evas_Object 
*obj, Elm_Object_Item *it, Elm_Drag_User_Info *info)
 
     Eina_Bool               elm_cnp_selection_set(Evas_Object *obj, 
Elm_Sel_Type selection, Elm_Sel_Format format, const void *buf, size_t buflen)
     Eina_Bool               elm_cnp_selection_get(Evas_Object *obj, 
Elm_Sel_Type selection, Elm_Sel_Format format, Elm_Drop_Cb datacb, void *udata)
     Eina_Bool               elm_object_cnp_selection_clear(Evas_Object *obj, 
Elm_Sel_Type selection)
     void                    elm_cnp_selection_loss_callback_set(Evas_Object 
*obj, Elm_Sel_Type selection, Elm_Selection_Loss_Cb func, const void *data)
-    # Eina_Bool               elm_drop_target_add(Evas_Object *obj, 
Elm_Sel_Format format, Elm_Drag_State entercb, void *enterdata, Elm_Drag_State 
leavecb, void *leavedata, Elm_Drag_Pos poscb, void *posdata, Elm_Drop_Cb 
dropcb, void *cbdata)
-    # Eina_Bool               elm_drop_target_del(Evas_Object *obj)
-    # Eina_Bool               elm_drag_start(Evas_Object *obj, Elm_Sel_Format 
format, const char *data, Elm_Xdnd_Action action, Elm_Drag_Icon_Create_Cb 
createicon, void *createdata, Elm_Drag_Pos dragpos, void *dragdata, 
Elm_Drag_Accept acceptcb, void *acceptdata, Elm_Drag_State dragdone, void 
*donecbdata)
-    # Eina_Bool               elm_drag_action_set(Evas_Object *obj, 
Elm_Xdnd_Action action)
+    Eina_Bool               elm_drop_target_add(Evas_Object *obj, 
Elm_Sel_Format format, Elm_Drag_State entercb, void *enterdata, Elm_Drag_State 
leavecb, void *leavedata, Elm_Drag_Pos poscb, void *posdata, Elm_Drop_Cb 
dropcb, void *dropdata)
+    Eina_Bool               elm_drop_target_del(Evas_Object *obj, 
Elm_Sel_Format format, Elm_Drag_State entercb, void *enterdata, Elm_Drag_State 
leavecb, void *leavedata, Elm_Drag_Pos poscb, void *posdata, Elm_Drop_Cb 
dropcb, void *dropdata)
+    Eina_Bool               elm_drag_start(Evas_Object *obj, Elm_Sel_Format 
format, const char *data, Elm_Xdnd_Action action, Elm_Drag_Icon_Create_Cb 
createicon, void *createdata, Elm_Drag_Pos dragpos, void *dragdata, 
Elm_Drag_Accept acceptcb, void *acceptdata, Elm_Drag_State dragdone, void 
*donecbdata)
+    Eina_Bool               elm_drag_cancel(Evas_Object *obj)
+    Eina_Bool               elm_drag_action_set(Evas_Object *obj, 
Elm_Xdnd_Action action)
+    Eina_Bool               elm_drag_item_container_add(Evas_Object *obj, 
double tm_to_anim, double tm_to_drag, Elm_Xy_Item_Get_Cb itemgetcb, 
Elm_Item_Container_Data_Get_Cb data_get)
+    Eina_Bool               elm_drag_item_container_del(Evas_Object *obj)
+    Eina_Bool               elm_drop_item_container_add(Evas_Object *obj, 
Elm_Sel_Format format, Elm_Xy_Item_Get_Cb itemgetcb, Elm_Drag_State entercb, 
void *enterdata, Elm_Drag_State leavecb, void *leavedata, 
Elm_Drag_Item_Container_Pos poscb, void *posdata, Elm_Drop_Item_Container_Cb 
dropcb, void *dropdata)
+    Eina_Bool               elm_drop_item_container_del(Evas_Object *obj)
+
 
 cdef class SelectionData(object):
 
@@ -85,8 +78,8 @@ cdef class SelectionData(object):
 
     property data:
         def __get__(self):
-            # TODO: void *
-            return <const char *>self.sel_data.data
+            # TODO: check if this can have anything other than text data
+            return _ctouni(<const char *>self.sel_data.data)
 
     property len:
         """:type: size_t"""
@@ -104,6 +97,7 @@ cdef class SelectionData(object):
         def __get__(self):
             return self.sel_data.action
 
+
 cdef Eina_Bool py_elm_drop_cb(void *data, Evas_Object *obj, Elm_Selection_Data 
*ev) with gil:
     """Callback invoked when the selected data is 'dropped' at its destination.
 
@@ -117,16 +111,18 @@ cdef Eina_Bool py_elm_drop_cb(void *data, Evas_Object 
*obj, Elm_Selection_Data *
     cdef:
         SelectionData sd = SelectionData.__new__(SelectionData)
         bint ret
+        evasObject o = object_from_instance(obj)
     sd.sel_data = ev
 
-    o = <object>data
-    cb_func = o.cnp_drop_cb
-    cb_data = o.cnp_drop_data
+    cb_func, cb_data = <object>data
 
-    ret = cb_func(o, sd, cb_data)
+    try:
+        ret = cb_func(o, sd, cb_data)
+    except Exception:
+        traceback.print_exc()
+        return 0
 
     sd.sel_data = NULL
-
     return ret
 
 cdef Elm_Object_Item *py_elm_xy_item_get_cb(Evas_Object *obj, Evas_Coord x, 
Evas_Coord y, int *xposret, int *yposret) with gil:
@@ -140,12 +136,12 @@ cdef Elm_Object_Item *py_elm_xy_item_get_cb(Evas_Object 
*obj, Evas_Coord x, Evas
     :return: object under x,y cords or NULL if not found.
 
     """
+    print("in xy_item_get_cb")
     assert obj != NULL, "obj is NULL"
 
     cdef:
         evasObject o = object_from_instance(obj)
         object xpos1, ypos1
-        int xpos2, ypos2
         ObjectItem it
 
     try:
@@ -156,13 +152,14 @@ cdef Elm_Object_Item *py_elm_xy_item_get_cb(Evas_Object 
*obj, Evas_Coord x, Evas
         return NULL
 
     if xpos1 is not None:
-        xpos2 = xpos1
-        xposret[0] = xpos2
+        xposret[0] = <int>xpos1
     if ypos1 is not None:
-        ypos2 = ypos1
-        yposret[0] = ypos2
+        yposret[0] = <int>ypos1
 
-    return it.item
+    if it:
+        return it.item
+    else:
+        return NULL
 
 cdef void py_elm_selection_loss_cb(void *data, Elm_Sel_Type selection) with 
gil:
     """Callback invoked when the selection ownership for a given selection is 
lost.
@@ -189,16 +186,14 @@ cdef Evas_Object *py_elm_drag_icon_create_cb(
         the drag icon object relative to the source drag object
     :return: An object to fill the drag window with or NULL if not needed
 
-    .. versionadded:: 1.8
-
     """
+    print("in drag_icon_create_cb")
     assert data != NULL, "data is NULL"
 
     cdef:
         evasObject win1 = object_from_instance(win)
         evasObject icon
         object xoff1 = None, yoff1 = None
-        Evas_Coord xoff2, yoff2
 
     createicon, createdata = <object>data
 
@@ -219,11 +214,9 @@ cdef Evas_Object *py_elm_drag_icon_create_cb(
     icon, xoff1, yoff1 = ret
 
     if xoff1 is not None:
-        xoff2 = xoff1
-        xoff[0] = xoff2
+        xoff[0] = <Evas_Coord>xoff1
     if yoff1 is not None:
-        yoff2 = yoff1
-        yoff[0] = yoff2
+        yoff[0] = <Evas_Coord>yoff1
 
     return icon.obj
 
@@ -233,10 +226,19 @@ cdef void py_elm_drag_state_cb(void *data, Evas_Object 
*obj) with gil:
     :param data: Application specific data
     :param obj: The object where the drag started
 
-    .. versionadded:: 1.8
-
     """
     print("in drag_state_cb")
+    assert data != NULL, "data is NULL"
+
+    cdef:
+        evasObject o = object_from_instance(obj)
+
+    statecb, statedata = <object>data
+
+    try:
+        statecb(o, statedata)
+    except Exception:
+        traceback.print_exc()
 
 cdef void py_elm_drag_done_cb(void *data, Evas_Object *obj, Eina_Bool 
accepted) with gil:
     """Callback called when a drag is finished.
@@ -245,9 +247,8 @@ cdef void py_elm_drag_done_cb(void *data, Evas_Object *obj, 
Eina_Bool accepted)
     :param obj: The object where the drag started
     :param accepted: TRUE if the dropped-data is accepted on drop
 
-    .. versionadded:: 1.8
-
     """
+    print("in drag_done_cb")
     assert data != NULL, "data is NULL"
 
     cdef:
@@ -267,10 +268,19 @@ cdef void py_elm_drag_accept_cb(void *data, Evas_Object 
*obj, Eina_Bool doaccept
     :param obj: The object where the drag started
     :param doaccept: A boolean as to if the target accepts the drag or not
 
-    .. versionadded:: 1.8
-
     """
     print("in drag_accept_cb")
+    assert data != NULL, "data is NULL"
+
+    cdef:
+        evasObject o = object_from_instance(obj)
+
+    acceptcb, acceptdata = <object>data
+
+    try:
+        acceptcb(o, <bint>doaccept, acceptdata)
+    except Exception:
+        traceback.print_exc()
 
 cdef void py_elm_drag_pos_cb(void *data, Evas_Object *obj,
     Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action) with gil:
@@ -281,8 +291,6 @@ cdef void py_elm_drag_pos_cb(void *data, Evas_Object *obj,
     :param x: The X coordinate relative to the top-left of the object
     :param y: The Y coordinate relative to the top-left of the object
 
-    .. versionadded:: 1.8
-
     """
     print("in drag_pos_cb")
     assert data != NULL, "data is NULL"
@@ -314,11 +322,18 @@ cdef void py_elm_drag_item_container_pos(
     :param yposret: Position relative to item (upper (-1), middle (0), bottom 
(1)
     :param action: The drag action to be done
 
-    .. versionadded:: 1.8
-
     """
     print("in drag_item_container_pos")
 
+    cdef:
+        evasObject o = object_from_instance(cont)
+        ObjectItem item = _object_item_to_python(it)
+
+    try:
+        o.data["drag_item_container_pos"](o, item, x, y, xposret, yposret, 
action, <object>data if data is not NULL else None)
+    except Exception:
+        traceback.print_exc()
+
 cdef Eina_Bool py_elm_drop_item_container_cb(
     void *data, Evas_Object *obj, Elm_Object_Item *it,
     Elm_Selection_Data *ev, int xposret, int yposret) with gil:
@@ -334,14 +349,17 @@ cdef Eina_Bool py_elm_drop_item_container_cb(
     :param yposret: Position relative to item (upper (-1), middle (0), bottom 
(1)
 
     """
+    print("in drop_item_container_cb")
     assert obj != NULL, "obj is NULL"
 
     cdef:
         evasObject o = object_from_instance(obj)
-        ObjectItem item = _object_item_to_python(it)
+        ObjectItem item
         SelectionData evdata = SelectionData.__new__(SelectionData)
         object cbdata = None
 
+    item = _object_item_to_python(it)
+
     evdata.sel_data = ev
 
     cb = o.data["drop_item_container_cb"]
@@ -355,6 +373,9 @@ cdef Eina_Bool py_elm_drop_item_container_cb(
         traceback.print_exc()
         return 0
 
+    return ret
+
+
 cdef class DragUserInfo(object):
     """
 
@@ -376,6 +397,18 @@ cdef class DragUserInfo(object):
     :param donecbdata: Application data to pass to @p dragdone (output)
 
     """
+    # Elm_Sel_Format format;
+    # const char *data;
+    # Eina_List *icons;
+    # Elm_Xdnd_Action action;
+    # Elm_Drag_Icon_Create_Cb createicon;
+    # void *createdata;
+    # Elm_Drag_Pos dragpos;
+    # void *dragdata;
+    # Elm_Drag_Accept acceptcb;
+    # void *acceptdata;
+    # Elm_Drag_Done dragdone;
+    # void *donecbdata;
     cdef:
         public Elm_Sel_Format format
         public Elm_Xdnd_Action action
@@ -392,19 +425,6 @@ cdef class DragUserInfo(object):
             if isinstance(value, unicode): value = 
PyUnicode_AsUTF8String(value)
             self._data = value
 
-    # Elm_Sel_Format format;
-    # const char *data;
-    # Eina_List *icons;
-    # Elm_Xdnd_Action action;
-    # Elm_Drag_Icon_Create_Cb createicon;
-    # void *createdata;
-    # Elm_Drag_Pos dragpos;
-    # void *dragdata;
-    # Elm_Drag_Accept acceptcb;
-    # void *acceptdata;
-    # Elm_Drag_Done dragdone;
-    # void *donecbdata;
-
 
 cdef Eina_Bool py_elm_item_container_data_get_cb(
     Evas_Object *obj, Elm_Object_Item *it, Elm_Drag_User_Info *info) with gil:
@@ -418,42 +438,42 @@ cdef Eina_Bool py_elm_item_container_data_get_cb(
 
     """
     cdef:
-        DragUserInfo ret = DragUserInfo.__new__(DragUserInfo)
+        DragUserInfo pyinfo = DragUserInfo.__new__(DragUserInfo)
         evasObject o = object_from_instance(obj)
         ObjectItem item = _object_item_to_python(it)
+        bint ret
 
     try:
         func = o.data["item_container_data_get_cb"]
-        func(o, item, ret)
+        ret = func(o, item, pyinfo)
     except Exception:
         traceback.print_exc()
         return 0
 
-    if ret is not None:
-        info.format = ret.format
-        info.data = ret._data
-        info.icons = python_list_objects_to_eina_list(ret.icons)
-        if ret.createicon is not None:
+    if ret:
+        info.format = pyinfo.format
+        info.data = strdup(pyinfo._data)
+        info.icons = python_list_objects_to_eina_list(pyinfo.icons)
+        if pyinfo.createicon is not None:
             info.createicon = py_elm_drag_icon_create_cb
-            createdata = (ret.createicon, ret.createdata)
+            createdata = (pyinfo.createicon, pyinfo.createdata)
             Py_INCREF(createdata)
             info.createdata = <void *>createdata
-        if ret.dragpos is not None:
+        if pyinfo.dragpos is not None:
             info.dragpos = py_elm_drag_pos_cb
-            dragdata = (ret.dragpos, ret.dragdata)
+            dragdata = (pyinfo.dragpos, pyinfo.dragdata)
             Py_INCREF(dragdata)
             info.dragdata = <void *>dragdata
-        if ret.acceptcb is not None:
+        if pyinfo.acceptcb is not None:
             info.acceptcb = py_elm_drag_accept_cb
-            acceptdata = (ret.acceptcb, ret.acceptdata)
+            acceptdata = (pyinfo.acceptcb, pyinfo.acceptdata)
             Py_INCREF(acceptdata)
             info.acceptdata = <void *>acceptdata
-        if ret.dragdone is not None:
+        if pyinfo.dragdone is not None:
             info.dragdone =py_elm_drag_done_cb
-            donecbdata = (ret.dragdone, ret.donecbdata)
+            donecbdata = (pyinfo.dragdone, pyinfo.donecbdata)
             Py_INCREF(donecbdata)
             info.donecbdata = <void *>donecbdata
         return 1
     else:
-        print("ret is None")
         return 0
diff --git a/efl/elementary/gengrid_widget.pxi 
b/efl/elementary/gengrid_widget.pxi
index 1d6b502..e27c737 100644
--- a/efl/elementary/gengrid_widget.pxi
+++ b/efl/elementary/gengrid_widget.pxi
@@ -627,111 +627,111 @@ cdef class Gengrid(Object):
                     flags))
 
     #
-    # TODO: Drag and Drop
+    # Drag and Drop
     # =============
 
-    # def drag_item_container_add(self,
-    #     double tm_to_anim, double tm_to_drag,
-    #     itemgetcb = None,
-    #     data_get = None):
-    #     """
-
-    #     Set a item container (list, genlist, grid) as source of drag
-
-    #     :param tm_to_anim: Time period to wait before start animation.
-    #     :param tm_to_drag: Time period to wait before start dragging.
-    #     :param itemgetcb: Callback to get Evas object for item at (x,y)
-    #     :param data_get:  Callback to get drag info
-
-    #     :raise RuntimeError: if setting drag source failed.
+    def drag_item_container_add(self,
+        double tm_to_anim, double tm_to_drag,
+        itemgetcb = None,
+        data_get = None):
+        """
 
-    #     :since: 1.8
+        Set a item container (list, genlist, grid) as source of drag
 
-    #     """
-    #     if itemgetcb is not None:
-    #         if not callable(itemgetcb):
-    #             raise TypeError("itemgetcb must be callable.")
-    #         self.data["xy_item_get_cb"] = itemgetcb
+        :param tm_to_anim: Time period to wait before start animation.
+        :param tm_to_drag: Time period to wait before start dragging.
+        :param itemgetcb: Callback to get Evas object for item at (x,y)
+        :param data_get:  Callback to get drag info
 
-    #     self.data["item_container_data_get_cb"] = data_get
+        :raise RuntimeError: if setting drag source failed.
 
-    #     if not elm_drag_item_container_add(self.obj,
-    #         tm_to_anim,
-    #         tm_to_drag,
-    #         <Elm_Xy_Item_Get_Cb>py_elm_xy_item_get_cb if itemgetcb is not 
None else NULL,
-    #         
<Elm_Item_Container_Data_Get_Cb>py_elm_item_container_data_get_cb if data_get 
is not None else NULL):
-    #         raise RuntimeError
+        .. versionadded:: 1.17
 
-    # def drag_item_container_del(self):
-    #     """
+        """
+        if itemgetcb is not None:
+            if not callable(itemgetcb):
+                raise TypeError("itemgetcb must be callable.")
+            self.data["xy_item_get_cb"] = itemgetcb
 
-    #     Deletes a item container from drag-source list
+        self.data["item_container_data_get_cb"] = data_get
 
-    #     :raise RuntimeError: if deleting drag source failed.
+        if not elm_drag_item_container_add(self.obj,
+            tm_to_anim,
+            tm_to_drag,
+            <Elm_Xy_Item_Get_Cb>py_elm_xy_item_get_cb if itemgetcb is not None 
else NULL,
+            <Elm_Item_Container_Data_Get_Cb>py_elm_item_container_data_get_cb 
if data_get is not None else NULL):
+            raise RuntimeError
 
-    #     :since: 1.8
+    def drag_item_container_del(self):
+        """
 
-    #     """
-    #     if not elm_drag_item_container_del(self.obj):
-    #         raise RuntimeError
+        Deletes a item container from drag-source list
 
-    # def drop_item_container_add(self, Elm_Sel_Format format,
-    #     itemgetcb = None, entercb = None, enterdata = None,
-    #     leavecb = None, leavedata = None,
-    #     poscb = None, posdata = None, dropcb = None, cbdata = None):
-    #     """
+        :raise RuntimeError: if deleting drag source failed.
 
-    #     Set a item container (list, genlist, grid) as target for drop.
+        .. versionadded:: 1.17
 
-    #     :param format: The formats supported for dropping
-    #     :param itemgetcb: Callback to get Evas object for item at (x,y)
-    #     :param entercb: The function to call when the object is entered with 
a drag
-    #     :param enterdata: The application data to pass to enterdata
-    #     :param leavecb: The function to call when the object is left with a 
drag
-    #     :param leavedata: The application data to pass to leavedata
-    #     :param poscb: The function to call when the object has a drag over it
-    #     :param posdata: The application data to pass to posdata
-    #     :param dropcb: The function to call when a drop has occurred
-    #     :param cbdata: The application data to pass to dropcb
+        """
+        if not elm_drag_item_container_del(self.obj):
+            raise RuntimeError
 
-    #     :raise RuntimeError: if setting drop target failed.
+    def drop_item_container_add(self, Elm_Sel_Format format,
+        itemgetcb = None, entercb = None, enterdata = None,
+        leavecb = None, leavedata = None,
+        poscb = None, posdata = None, dropcb = None, cbdata = None):
+        """
 
-    #     :since: 1.8
+        Set a item container (list, genlist, grid) as target for drop.
 
-    #     """
-    #     if itemgetcb is not None:
-    #         if not callable(itemgetcb):
-    #             raise TypeError("itemgetcb must be callable.")
-    #         self.data["xy_item_get_cb"] = itemgetcb
+        :param format: The formats supported for dropping
+        :param itemgetcb: Callback to get Evas object for item at (x,y)
+        :param entercb: The function to call when the object is entered with a 
drag
+        :param enterdata: The application data to pass to enterdata
+        :param leavecb: The function to call when the object is left with a 
drag
+        :param leavedata: The application data to pass to leavedata
+        :param poscb: The function to call when the object has a drag over it
+        :param posdata: The application data to pass to posdata
+        :param dropcb: The function to call when a drop has occurred
+        :param cbdata: The application data to pass to dropcb
 
-    #     self.data["drag_item_container_pos"] = poscb
-    #     self.data["drop_item_container_cb"] = dropcb
+        :raise RuntimeError: if setting drop target failed.
 
-    #     if not elm_drop_item_container_add(self.obj,
-    #         format,
-    #         <Elm_Xy_Item_Get_Cb>py_elm_xy_item_get_cb if itemgetcb is not 
None else NULL,
-    #         <Elm_Drag_State>py_elm_drag_state_cb if entercb is not None else 
NULL,
-    #         <void *>enterdata if enterdata is not None else NULL,
-    #         <Elm_Drag_State>py_elm_drag_state_cb if leavecb is not None else 
NULL,
-    #         <void *>leavedata if leavedata is not None else NULL,
-    #         <Elm_Drag_Item_Container_Pos>py_elm_drag_item_container_pos if 
poscb is not None else NULL,
-    #         <void *>posdata if posdata is not None else NULL,
-    #         <Elm_Drop_Item_Container_Cb>py_elm_drop_item_container_cb if 
dropcb is not None else NULL,
-    #         <void *>cbdata if cbdata is not None else NULL):
-    #         raise RuntimeError
+        .. versionadded:: 1.17
 
-    # def drop_item_container_del(self):
-    #     """
+        """
+        if itemgetcb is not None:
+            if not callable(itemgetcb):
+                raise TypeError("itemgetcb must be callable.")
+            self.data["xy_item_get_cb"] = itemgetcb
+
+        self.data["drag_item_container_pos"] = poscb
+        self.data["drop_item_container_cb"] = dropcb
+
+        if not elm_drop_item_container_add(self.obj,
+            format,
+            <Elm_Xy_Item_Get_Cb>py_elm_xy_item_get_cb if itemgetcb is not None 
else NULL,
+            <Elm_Drag_State>py_elm_drag_state_cb if entercb is not None else 
NULL,
+            <void *>enterdata if enterdata is not None else NULL,
+            <Elm_Drag_State>py_elm_drag_state_cb if leavecb is not None else 
NULL,
+            <void *>leavedata if leavedata is not None else NULL,
+            <Elm_Drag_Item_Container_Pos>py_elm_drag_item_container_pos if 
poscb is not None else NULL,
+            <void *>posdata if posdata is not None else NULL,
+            <Elm_Drop_Item_Container_Cb>py_elm_drop_item_container_cb if 
dropcb is not None else NULL,
+            <void *>cbdata if cbdata is not None else NULL):
+            raise RuntimeError
+
+    def drop_item_container_del(self):
+        """
 
-    #     Removes a container from list of drop targets.
+        Removes a container from list of drop targets.
 
-    #     :raise RuntimeError: if deleting drop target failed.
+        :raise RuntimeError: if deleting drop target failed.
 
-    #     :since: 1.8
+        .. versionadded:: 1.17
 
-    #     """
-    #     if not elm_drop_item_container_del(self.obj):
-    #         raise RuntimeError
+        """
+        if not elm_drop_item_container_del(self.obj):
+            raise RuntimeError
 
 
 
diff --git a/efl/elementary/genlist_widget.pxi 
b/efl/elementary/genlist_widget.pxi
index 6b77072..9c86788 100644
--- a/efl/elementary/genlist_widget.pxi
+++ b/efl/elementary/genlist_widget.pxi
@@ -104,7 +104,7 @@ cdef class Genlist(Object):
     def item_append(self,
                     GenlistItemClass item_class not None,
                     item_data,
-                    GenlistItem parent_item=None,
+                    ObjectItem parent_item=None,
                     int flags=ELM_GENLIST_ITEM_NONE,
                     func=None):
         """Append a new item (add as last row) to this genlist.
@@ -142,7 +142,7 @@ cdef class Genlist(Object):
     def item_prepend(   self,
                         GenlistItemClass item_class not None,
                         item_data,
-                        GenlistItem parent_item=None,
+                        ObjectItem parent_item=None,
                         int flags=ELM_GENLIST_ITEM_NONE,
                         func=None):
         """Prepend a new item (add as first row) to this genlist.
@@ -180,7 +180,7 @@ cdef class Genlist(Object):
     def item_insert_before( self,
                             GenlistItemClass item_class not None,
                             item_data,
-                            GenlistItem before_item=None,
+                            ObjectItem before_item=None,
                             int flags=ELM_GENLIST_ITEM_NONE,
                             func=None
                             ):
@@ -216,7 +216,7 @@ cdef class Genlist(Object):
     def item_insert_after(  self,
                             GenlistItemClass item_class not None,
                             item_data,
-                            GenlistItem after_item=None,
+                            ObjectItem after_item=None,
                             int flags=ELM_GENLIST_ITEM_NONE,
                             func=None
                             ):
@@ -253,7 +253,7 @@ cdef class Genlist(Object):
                             GenlistItemClass item_class not None,
                             item_data,
                             comparison_func not None,
-                            GenlistItem parent_item=None,
+                            ObjectItem parent_item=None,
                             int flags=ELM_GENLIST_ITEM_NONE,
                             func=None
                             #API XXX: *args, **kwargs
@@ -710,111 +710,108 @@ cdef class Genlist(Object):
             return bool(elm_genlist_focus_on_selection_get(self.obj))
 
     #
-    # TODO: Drag and Drop
+    # Drag and Drop
     # =============
 
-    # def drag_item_container_add(self,
-    #     double tm_to_anim, double tm_to_drag,
-    #     itemgetcb = None,
-    #     data_get = None):
-    #     """
-
-    #     Set a item container (list, genlist, grid) as source of drag
-
-    #     :param tm_to_anim: Time period to wait before start animation.
-    #     :param tm_to_drag: Time period to wait before start dragging.
-    #     :param itemgetcb: Callback to get Evas object for item at (x,y)
-    #     :param data_get:  Callback to get drag info
-
-    #     :raise RuntimeError: if setting drag source failed.
+    def drag_item_container_add(self, double tm_to_anim, double tm_to_drag, 
itemgetcb = None, data_get = None):
+        """
 
-    #     :since: 1.8
+        Set a item container (list, genlist, grid) as source of drag
 
-    #     """
-    #     if itemgetcb is not None:
-    #         if not callable(itemgetcb):
-    #             raise TypeError("itemgetcb must be callable.")
-    #         self.data["xy_item_get_cb"] = itemgetcb
+        :param tm_to_anim: Time period to wait before start animation.
+        :param tm_to_drag: Time period to wait before start dragging.
+        :param itemgetcb: Callback to get Evas object for item at (x,y)
+        :param data_get:  Callback to get drag info
 
-    #     self.data["item_container_data_get_cb"] = data_get
+        :raise RuntimeError: if setting drag source failed.
 
-    #     if not elm_drag_item_container_add(self.obj,
-    #         tm_to_anim,
-    #         tm_to_drag,
-    #         <Elm_Xy_Item_Get_Cb>py_elm_xy_item_get_cb if itemgetcb is not 
None else NULL,
-    #         
<Elm_Item_Container_Data_Get_Cb>py_elm_item_container_data_get_cb if data_get 
is not None else NULL):
-    #         raise RuntimeError
+        .. versionadded:: 1.17
 
-    # def drag_item_container_del(self):
-    #     """
+        """
+        if itemgetcb is not None:
+            if not callable(itemgetcb):
+                raise TypeError("itemgetcb must be callable.")
+            self.data["xy_item_get_cb"] = itemgetcb
 
-    #     Deletes a item container from drag-source list
+        self.data["item_container_data_get_cb"] = data_get
 
-    #     :raise RuntimeError: if deleting drag source failed.
+        if not elm_drag_item_container_add(self.obj,
+            tm_to_anim,
+            tm_to_drag,
+            <Elm_Xy_Item_Get_Cb>py_elm_xy_item_get_cb if itemgetcb is not None 
else NULL,
+            <Elm_Item_Container_Data_Get_Cb>py_elm_item_container_data_get_cb 
if data_get is not None else NULL):
+            raise RuntimeError
 
-    #     :since: 1.8
+    def drag_item_container_del(self):
+        """
 
-    #     """
-    #     if not elm_drag_item_container_del(self.obj):
-    #         raise RuntimeError
+        Deletes a item container from drag-source list
 
-    # def drop_item_container_add(self, Elm_Sel_Format format,
-    #     itemgetcb = None, entercb = None, enterdata = None,
-    #     leavecb = None, leavedata = None,
-    #     poscb = None, posdata = None, dropcb = None, cbdata = None):
-    #     """
+        :raise RuntimeError: if deleting drag source failed.
 
-    #     Set a item container (list, genlist, grid) as target for drop.
+        .. versionadded:: 1.17
 
-    #     :param format: The formats supported for dropping
-    #     :param itemgetcb: Callback to get Evas object for item at (x,y)
-    #     :param entercb: The function to call when the object is entered with 
a drag
-    #     :param enterdata: The application data to pass to enterdata
-    #     :param leavecb: The function to call when the object is left with a 
drag
-    #     :param leavedata: The application data to pass to leavedata
-    #     :param poscb: The function to call when the object has a drag over it
-    #     :param posdata: The application data to pass to posdata
-    #     :param dropcb: The function to call when a drop has occurred
-    #     :param cbdata: The application data to pass to dropcb
+        """
+        if not elm_drag_item_container_del(self.obj):
+            raise RuntimeError
 
-    #     :raise RuntimeError: if setting drop target failed.
+    def drop_item_container_add(self, Elm_Sel_Format format,
+        itemgetcb = None, entercb = None, enterdata = None,
+        leavecb = None, leavedata = None,
+        poscb = None, posdata = None, dropcb = None, cbdata = None):
+        """
 
-    #     :since: 1.8
+        Set a item container (list, genlist, grid) as target for drop.
 
-    #     """
-    #     if itemgetcb is not None:
-    #         if not callable(itemgetcb):
-    #             raise TypeError("itemgetcb must be callable.")
-    #         self.data["xy_item_get_cb"] = itemgetcb
+        :param format: The formats supported for dropping
+        :param itemgetcb: Callback to get Evas object for item at (x,y)
+        :param entercb: The function to call when the object is entered with a 
drag
+        :param enterdata: The application data to pass to enterdata
+        :param leavecb: The function to call when the object is left with a 
drag
+        :param leavedata: The application data to pass to leavedata
+        :param poscb: The function to call when the object has a drag over it
+        :param posdata: The application data to pass to posdata
+        :param dropcb: The function to call when a drop has occurred
+        :param cbdata: The application data to pass to dropcb
 
-    #     self.data["drag_item_container_pos"] = poscb
-    #     self.data["drop_item_container_cb"] = dropcb
+        :raise RuntimeError: if setting drop target failed.
 
-    #     if not elm_drop_item_container_add(self.obj,
-    #         format,
-    #         <Elm_Xy_Item_Get_Cb>py_elm_xy_item_get_cb if itemgetcb is not 
None else NULL,
-    #         <Elm_Drag_State>py_elm_drag_state_cb if entercb is not None else 
NULL,
-    #         <void *>enterdata if enterdata is not None else NULL,
-    #         <Elm_Drag_State>py_elm_drag_state_cb if leavecb is not None else 
NULL,
-    #         <void *>leavedata if leavedata is not None else NULL,
-    #         <Elm_Drag_Item_Container_Pos>py_elm_drag_item_container_pos if 
poscb is not None else NULL,
-    #         <void *>posdata if posdata is not None else NULL,
-    #         <Elm_Drop_Item_Container_Cb>py_elm_drop_item_container_cb if 
dropcb is not None else NULL,
-    #         <void *>cbdata if cbdata is not None else NULL):
-    #         raise RuntimeError
+        .. versionadded:: 1.17
 
-    # def drop_item_container_del(self):
-    #     """
+        """
+        if itemgetcb is not None:
+            if not callable(itemgetcb):
+                raise TypeError("itemgetcb must be callable.")
+            self.data["xy_item_get_cb"] = itemgetcb
+
+        self.data["drag_item_container_pos"] = poscb
+        self.data["drop_item_container_cb"] = dropcb
+
+        if not elm_drop_item_container_add(self.obj,
+            format,
+            <Elm_Xy_Item_Get_Cb>py_elm_xy_item_get_cb if itemgetcb is not None 
else NULL,
+            <Elm_Drag_State>py_elm_drag_state_cb if entercb is not None else 
NULL,
+            <void *>enterdata if enterdata is not None else NULL,
+            <Elm_Drag_State>py_elm_drag_state_cb if leavecb is not None else 
NULL,
+            <void *>leavedata if leavedata is not None else NULL,
+            <Elm_Drag_Item_Container_Pos>py_elm_drag_item_container_pos if 
poscb is not None else NULL,
+            <void *>posdata if posdata is not None else NULL,
+            <Elm_Drop_Item_Container_Cb>py_elm_drop_item_container_cb if 
dropcb is not None else NULL,
+            <void *>cbdata if cbdata is not None else NULL):
+            raise RuntimeError
+
+    def drop_item_container_del(self):
+        """
 
-    #     Removes a container from list of drop targets.
+        Removes a container from list of drop targets.
 
-    #     :raise RuntimeError: if deleting drop target failed.
+        :raise RuntimeError: if deleting drop target failed.
 
-    #     :since: 1.8
+        .. versionadded:: 1.17
 
-    #     """
-    #     if not elm_drop_item_container_del(self.obj):
-    #         raise RuntimeError
+        """
+        if not elm_drop_item_container_del(self.obj):
+            raise RuntimeError
 
 
     def callback_activated_add(self, func, *args, **kwargs):
diff --git a/efl/elementary/object.pxi b/efl/elementary/object.pxi
index 68dc40f..27c91fb 100644
--- a/efl/elementary/object.pxi
+++ b/efl/elementary/object.pxi
@@ -895,7 +895,7 @@ cdef class Object(SmartObject):
 
         """
         elm_object_focus_next_item_set(self.obj, next.item, direction)
-        
+
     property focused_item:
         """The focused object item in an object tree.
 
@@ -964,9 +964,9 @@ cdef class Object(SmartObject):
 
     property focus_move_policy:
         """The focus movement policy for the object.
-        
+
         :type: :ref:`Elm_Focus_Move_Policy`
-        
+
         .. versionadded:: 1.15
 
         """
@@ -990,7 +990,7 @@ cdef class Object(SmartObject):
         be scrolled as an item.
 
         :type: :ref:`Elm_Focus_Region_Show_Mode`
-        
+
         .. versionadded:: 1.16
 
         """
@@ -1324,12 +1324,12 @@ cdef class Object(SmartObject):
             return elm_object_tooltip_orient_get(self.obj)
         def __set__(self, Elm_Tooltip_Orient orient):
             elm_object_tooltip_orient_set(self.obj, orient)
-    
+
     def tooltip_orient_set(self, Elm_Tooltip_Orient orient):
         elm_object_tooltip_orient_set(self.obj, orient)
     def tooltip_orient_get(self):
         return elm_object_tooltip_orient_get(self.obj)
-    
+
     property tooltip_window_mode:
         def __get__(self):
             return bool(elm_object_tooltip_window_mode_get(self.obj))
@@ -1619,177 +1619,161 @@ cdef class Object(SmartObject):
     # Drag n Drop
     # ===========
 
-    # def drop_target_add(self, Elm_Sel_Format format,
-    #     entercb, enterdata, leavecb, leavedata, poscb, posdata, dropcb, 
dropdata):
-    #     """Set the given object as a target for drops for drag-and-drop
-
-    #     :param format: The formats supported for dropping
-    #     :param entercb: The function to call when the object is entered with 
a drag
-    #     :param enterdata: The application data to pass to enterdata
-    #     :param leavecb: The function to call when the object is left with a 
drag
-    #     :param leavedata: The application data to pass to leavecb
-    #     :param poscb: The function to call when the object has a drag over it
-    #     :param posdata: The application data to pass to poscb
-    #     :param dropcb: The function to call when a drop has occurred
-    #     :param cbdata: The application data to pass to dropcb
-    #     :raise RuntimeError: if adding as drop target fails.
-
-    #     :since: 1.8
-
-    #     """
-    #     if not callable(entercb) \
-    #     or not callable(leavecb) \
-    #     or not callable(poscb) \
-    #     or not callable(dropcb):
-    #         raise TypeError("A callback passed is not callable.")
-
-    #     enter = (entercb, enterdata)
-    #     leave = (leavecb, leavedata)
-    #     pos = (poscb, posdata)
-    #     drop = (dropcb, dropdata)
-
-    #     if not elm_drop_target_add(
-    #         self.obj, format,
-    #         py_elm_drag_state_cb, <void *>enter,
-    #         py_elm_drag_state_cb, <void *>leave,
-    #         py_elm_drag_pos_cb, <void *>pos,
-    #         py_elm_drop_cb, <void *>drop
-    #         ):
-    #         raise RuntimeError("Could not add drop target.")
-
-    # def drop_target_del(self):
-    #     """Deletes the drop target status of an object
-
-    #     :raise RuntimeError: if removing drop status fails.
-
-    #     :since: 1.8
-
-    #     """
-    #     if not elm_drop_target_del(self.obj):
-    #         raise RuntimeError("Could not delete drop target status.")
-
-    # def drag_start(self, Elm_Sel_Format format,
-    #     data, Elm_Xdnd_Action action, createicon, createdata,
-    #     dragpos, dragdata, acceptcb, acceptdata, dragdone, donecbdata):
-    #     """Begins a drag given a source object
-
-    #     :param format: The drag formats supported by the data
-    #     :param data: The drag data itself (a string)
-    #     :param action: The drag action to be done
-    #     :param createicon: Function to call to create a drag object,
-    #         or NULL if not wanted
-    #     :param createdata: Application data passed to ``createicon``
-    #     :param dragpos: Function called with each position of the drag,
-    #         x, y being screen coordinates if possible, and action being
-    #         the current action.
-    #     :param dragdata: Application data passed to ``dragpos``
-    #     :param acceptcb: Function called indicating if drop target accepts
-    #         (or does not) the drop data while dragging
-
-    #     :param acceptdata: Application data passed to ``acceptcb``
-    #     :param dragdone: Function to call when drag is done
-    #     :param donecbdata: Application data to pass to ``dragdone``
-    #     :raise RuntimeError: if starting drag fails.
-
-    #     :since: 1.8
-
-    #     """
-    #     if not elm_drag_start(Evas_Object *obj, format,
-    #         <const char *>data, action,
-    #         Elm_Drag_Icon_Create_Cb createicon, void *createdata,
-    #         Elm_Drag_Pos dragpos, void *dragdata,
-    #         Elm_Drag_Accept acceptcb, void *acceptdata,
-    #         Elm_Drag_State dragdone, void *donecbdata):
-    #         raise RuntimeError("Could not start drag.")
-
-    # def drag_action_set(self, Elm_Xdnd_Action action):
-    #     """Changes the current drag action
-
-    #     :param action: The drag action to be done
-    #     :raise RuntimeError: if changing drag action fails.
-
-    #     :since: 1.8
-
-    #     """
-    #     if not elm_drag_action_set(Evas_Object *obj, action):
-    #         raise RuntimeError("Could not set cnp xdnd action.")
-
-    # def drag_item_container_add(self, double tm_to_anim, double tm_to_drag,
-    # itemgetcb, data_get):
-    #     """
-
-    #     Set a item container (list, genlist, grid) as source of drag
-
-    #     :param tm_to_anim: Time period to wait before start animation.
-    #     :param tm_to_drag: Time period to wait before start dragging.
-    #     :param itemgetcb: Callback to get Evas_Object pointer for item at 
(x,y)
-    #     :param data_get:  Callback to get drag info
-    #     :return: Returns EINA_TRUE, if successful, or EINA_FALSE if not.
+    def drop_target_add(self, Elm_Sel_Format fmt,
+        entercb=None, enterdata=None, leavecb=None, leavedata=None,
+        poscb=None, posdata=None, dropcb=None, dropdata=None):
+        """Set the given object as a target for drops for drag-and-drop
+
+        :param format: The formats supported for dropping
+        :param entercb: The function to call when the object is entered with a 
drag
+        :param enterdata: The application data to pass to enterdata
+        :param leavecb: The function to call when the object is left with a 
drag
+        :param leavedata: The application data to pass to leavecb
+        :param poscb: The function to call when the object has a drag over it
+        :param posdata: The application data to pass to poscb
+        :param dropcb: The function to call when a drop has occurred
+        :param cbdata: The application data to pass to dropcb
+        :raise RuntimeError: if adding as drop target fails.
+
+        .. versionadded:: 1.17
+
+        """
+        if entercb:
+            if not callable(entercb):
+                raise TypeError("A callback passed is not callable.")
+            enter = (entercb, enterdata)
+            Py_INCREF(enter)
+        if leavecb:
+            if not callable(leavecb):
+                raise TypeError("A callback passed is not callable.")
+            leave = (leavecb, leavedata)
+            Py_INCREF(leave)
+        if poscb:
+            if not callable(poscb):
+                raise TypeError("A callback passed is not callable.")
+            pos = (poscb, posdata)
+            Py_INCREF(pos)
+        if dropcb:
+            if not callable(dropcb):
+                raise TypeError("A callback passed is not callable.")
+            drop = (dropcb, dropdata)
+            Py_INCREF(drop)
+
+        if not elm_drop_target_add(
+            self.obj, fmt,
+            <Elm_Drag_State>py_elm_drag_state_cb if entercb else NULL, <void 
*>enter if entercb else NULL,
+            <Elm_Drag_State>py_elm_drag_state_cb if leavecb else NULL, <void 
*>leave if leavecb else NULL,
+            <Elm_Drag_Pos>py_elm_drag_pos_cb if poscb else NULL, <void *>pos 
if poscb else NULL,
+            <Elm_Drop_Cb>py_elm_drop_cb if dropcb else NULL, <void *>drop if 
dropcb else NULL
+            ):
+            raise RuntimeError("Could not add drop target.")
+
+    def drop_target_del(self, Elm_Sel_Format fmt,
+        entercb, enterdata, leavecb, leavedata, poscb, posdata, dropcb, 
dropdata):
+        """Deletes the drop target status of an object
+
+        @param format The formats supported for dropping
+        @param entercb The function to call when the object is entered with a 
drag
+        @param enterdata The application data to pass to enterdata
+        @param leavecb The function to call when the object is left with a drag
+        @param leavedata The application data to pass to leavedata
+        @param poscb The function to call when the object has a drag over it
+        @param posdata The application data to pass to posdata
+        @param dropcb The function to call when a drop has occurred
+        @param dropdata The application data to pass to dropcb
+        @return Returns @c EINA_TRUE, if successful, or @c EINA_FALSE if not.
+
+        .. versionadded:: 1.17
+
+        """
+        if entercb:
+            if not callable(entercb):
+                raise TypeError("A callback passed is not callable.")
+            enter = (entercb, enterdata)
+            Py_INCREF(enter)
+        if leavecb:
+            if not callable(leavecb):
+                raise TypeError("A callback passed is not callable.")
+            leave = (leavecb, leavedata)
+            Py_INCREF(leave)
+        if poscb:
+            if not callable(poscb):
+                raise TypeError("A callback passed is not callable.")
+            pos = (poscb, posdata)
+            Py_INCREF(pos)
+        if dropcb:
+            if not callable(dropcb):
+                raise TypeError("A callback passed is not callable.")
+            drop = (dropcb, dropdata)
+            Py_INCREF(drop)
+
+        if not elm_drop_target_del(
+            self.obj, fmt,
+            <Elm_Drag_State>py_elm_drag_state_cb if entercb else NULL, <void 
*>enter if entercb else NULL,
+            <Elm_Drag_State>py_elm_drag_state_cb if leavecb else NULL, <void 
*>leave if leavecb else NULL,
+            <Elm_Drag_Pos>py_elm_drag_pos_cb if poscb else NULL, <void *>pos 
if poscb else NULL,
+            <Elm_Drop_Cb>py_elm_drop_cb if dropcb else NULL, <void *>drop if 
dropcb else NULL
+            ):
+            raise RuntimeError("Could not del drop target.")
+
+    def drag_start(self, Elm_Sel_Format format,
+        data, Elm_Xdnd_Action action, createicon, createdata,
+        dragpos, dragdata, acceptcb, acceptdata, dragdone, donecbdata):
+        """Begins a drag given a source object
+
+        :param format: The drag formats supported by the data
+        :param data: The drag data itself (a string)
+        :param action: The drag action to be done
+        :param createicon: Function to call to create a drag object,
+            or NULL if not wanted
+        :param createdata: Application data passed to ``createicon``
+        :param dragpos: Function called with each position of the drag,
+            x, y being screen coordinates if possible, and action being
+            the current action.
+        :param dragdata: Application data passed to ``dragpos``
+        :param acceptcb: Function called indicating if drop target accepts
+            (or does not) the drop data while dragging
+
+        :param acceptdata: Application data passed to ``acceptcb``
+        :param dragdone: Function to call when drag is done
+        :param donecbdata: Application data to pass to ``dragdone``
+        :raise RuntimeError: if starting drag fails.
+
+        .. versionadded:: 1.17
+
+        """
+        if not callable(createicon) \
+        or not callable(dragpos) \
+        or not callable(acceptcb) \
+        or not callable(dragdone):
+            raise TypeError("A callback passed is not callable.")
+
+        create = (createicon, createdata)
+        pos = (dragpos, dragdata)
+        accept = (acceptcb, acceptdata)
+        done = (dragdone, donecbdata)
+
+        if not elm_drag_start(self.obj, format,
+            <const char *>data, action,
+            py_elm_drag_icon_create_cb, <void *>create,
+            py_elm_drag_pos_cb, <void *>pos,
+            py_elm_drag_accept_cb, <void *>accept,
+            py_elm_drag_state_cb, <void *>done
+            ):
+            raise RuntimeError("Could not start drag.")
+
+    def drag_action_set(self, Elm_Xdnd_Action action):
+        """Changes the current drag action
+
+        :param action: The drag action to be done
+        :raise RuntimeError: if changing drag action fails.
+
+        .. versionadded:: 1.17
+
+        """
+        if not elm_drag_action_set(self.obj, action):
+            raise RuntimeError("Could not set cnp xdnd action.")
 
-    #     :since: 1.8
-
-    #     """
-    #     if not elm_drag_item_container_add(self.obj, tm_to_anim, tm_to_drag,
-        #     Elm_Xy_Item_Get_Cb itemgetcb, Elm_Item_Container_Data_Get_Cb 
data_get):
-    #         raise RuntimeError
-
-    # def drag_item_container_del(self):
-    #     """
-
-    #     Deletes a item container from drag-source list
-
-    #     :return: Returns EINA_TRUE, if successful, or EINA_FALSE if not.
-
-    #     :since: 1.8
-
-    #     """
-    #     if not elm_drag_item_container_del(self.obj):
-    #         raise RuntimeError
-
-    # def drop_item_container_add(self, format, itemgetcb, entercb, enterdata,
-    # leavecb, leavedata, poscb, posdata, dropcb, cbdata):
-    #     """
-
-    #     Set a item container (list, genlist, grid) as target for drop.
-
-    #     :param format: The formats supported for dropping
-    #     :param itemgetcb: Callback to get Evas_Object pointer for item at 
(x,y)
-    #     :param entercb: The function to call when the object is entered with 
a drag
-    #     :param enterdata: The application data to pass to enterdata
-    #     :param leavecb: The function to call when the object is left with a 
drag
-    #     :param leavedata: The application data to pass to leavedata
-    #     :param poscb: The function to call when the object has a drag over it
-    #     :param posdata: The application data to pass to posdata
-    #     :param dropcb: The function to call when a drop has occurred
-    #     :param cbdata: The application data to pass to dropcb
-    #     :return: Returns EINA_TRUE, if successful, or EINA_FALSE if not.
-
-    #     :since: 1.8
-
-    #     """
-    #     if not elm_drop_item_container_add(self.obj,
-    #           Elm_Sel_Format format,
-    #           Elm_Xy_Item_Get_Cb itemgetcb,
-    #           Elm_Drag_State entercb, void *enterdata,
-    #           Elm_Drag_State leavecb, void *leavedata,
-    #           Elm_Drag_Item_Container_Pos poscb, void *posdata,
-    #           Elm_Drop_Item_Container_Cb dropcb, void *cbdata):
-    #         raise RuntimeError
-
-    # def drop_item_container_del(self):
-    #     """
-
-    #     Removes a container from list of drop targets.
-
-    #     :param obj: The container object
-    #     :return: Returns EINA_TRUE, if successful, or EINA_FALSE if not.
-
-
-    #     :since: 1.8
-
-    #     """
-    #     if not elm_drop_item_container_del(self.obj):
-    #         raise RuntimeError
 
     #
     # Access (TODO)
diff --git a/examples/elementary/test_dnd.py b/examples/elementary/test_dnd.py
index c495be2..31bdea6 100644
--- a/examples/elementary/test_dnd.py
+++ b/examples/elementary/test_dnd.py
@@ -2,6 +2,15 @@
 # encoding: utf-8
 
 import os
+import logging
+
+efllog = logging.getLogger("efl")
+efllog.setLevel(logging.DEBUG)
+efllog.addHandler(logging.StreamHandler())
+elmlog = logging.getLogger("efl.elementary")
+elmlog.setLevel(logging.DEBUG)
+elmlog.propagate = False
+elmlog.addHandler(logging.StreamHandler())
 
 from efl.ecore import Timer, ECORE_CALLBACK_CANCEL, ECORE_CALLBACK_RENEW, \
     AnimatorTimeline
@@ -10,17 +19,21 @@ from efl.evas import EVAS_HINT_EXPAND, EVAS_HINT_FILL, 
EXPAND_BOTH, FILL_BOTH, \
     EVAS_CALLBACK_MOUSE_UP, EVAS_CALLBACK_MOUSE_DOWN, \
     EVAS_EVENT_FLAG_ON_HOLD
 from efl import elementary
-from efl.elementary.label import Label
-from efl.elementary.frame import Frame
-from efl.elementary.list import List
-from efl.elementary.box import Box
-from efl.elementary.window import StandardWindow
-from efl.elementary.icon import Icon
-from efl.elementary.genlist import Genlist, GenlistItemClass, \
+from efl.elementary import Label
+from efl.elementary import Frame
+from efl.elementary import List, ELM_LIST_LIMIT
+from efl.elementary import Box
+from efl.elementary import StandardWindow
+from efl.elementary import Icon
+from efl.elementary import Genlist, GenlistItem, GenlistItemClass, \
     ELM_SEL_FORMAT_TARGETS, ELM_GENLIST_ITEM_NONE, DragUserInfo
-from efl.elementary.gengrid import Gengrid, GengridItemClass
-from efl.elementary.configuration import Configuration
+from efl.elementary import Gengrid, GengridItemClass
+from efl.elementary import Background
+from efl.elementary import Check
+from efl.elementary import Button
+from efl.elementary import Configuration
 conf = Configuration()
+SCALE = conf.scale
 
 
 script_path = os.path.dirname(os.path.abspath(__file__))
@@ -39,19 +52,21 @@ img = (
     )
 
 class AnimIconSt:
-    start_x = 0
-    start_y = 0
-    o = None
+    def __init__(self):
+        self.start_x = 0
+        self.start_y = 0
+        self.o = None
 
 class DragAnimSt:
-    icwin = None
-    e = None
-    mdx = 0     # Mouse-down x
-    mdy = 0     # Mouse-down y
-    icons = []   # List of icons to animate (anim_icon_st)
-    tm = None
-    ea = None
-    gl = None
+    def __init__(self):
+        self.icwin = None
+        self.e = None
+        self.mdx = 0     # Mouse-down x
+        self.mdy = 0     # Mouse-down y
+        self.icons = []   # List of icons to animate (anim_icon_st)
+        self.tm = None
+        self.ea = None
+        self.gl = None
 
 DRAG_TIMEOUT = 0.3
 ANIM_TIME = 0.5
@@ -85,32 +100,31 @@ class DndGengridItemClass(GengridItemClass):
 gic = DndGengridItemClass()
 
 def win_del(obj, data):
-    print("will del <%s>" % data)
     data.drop_item_container_del()
     data.drag_item_container_del()
 
-    #elementary.exit()
-
 def gl_item_getcb(gl, x, y):
     # This function returns pointer to item under (x,y) coords
     gli, yposret = gl.at_xy_item_get(x, y)
     if gli is not None:
-        print("over <%s>, gli=%r yposret=%i" % (
-            gli.part_text_get("elm.text"), gli, yposret))
+        print("over %r yposret=%d" % (gli, yposret))
     else:
-        print("over none, yposret=%i" % yposret)
+        print("over none, yposret=%d" % yposret)
     return gli, None, yposret
 
 def grid_item_getcb(grid, x, y):
     # This function returns pointer to item under (x,y) coords
     item, xposret, yposret = grid.at_xy_item_get(x, y)
     if item is not None:
-        print("over <%s>, item=%r xposret=%i yposret=%i" % (
-            item.part_text_get("elm.text"), item, xposret, yposret))
+        print("over %r xposret=%d yposret=%d" % (item, xposret, yposret))
     else:
-        print("over none, xposret=%i yposret=%i", xposret, yposret)
+        print("over none, xposret=%d yposret=%d", xposret, yposret)
     return item, xposret, yposret
 
+def gl_poscb(obj, it, x, y, xposret, yposret, action, data):
+    print("obj: %r, item: %r, x y: %d %d, posret: %d %d" %
+          (obj, it, x, y, xposret, yposret))
+
 def gl_dropcb(obj, it, ev, xposret, yposret, data):
     # This function is called when data is dropped on the genlist
     if ev.data is None:
@@ -148,7 +162,6 @@ def grid_dropcb(obj, it, ev, xposret, yposret, data):
     p = ev.data
 
     wh0rdlist = p.split("#")
-
     wh0rdlist.pop(0)
     wh0rdlist.pop()
 
@@ -268,6 +281,7 @@ def gl_dragdone(obj, doaccept, data):
             it.delete()
 
 def gl_createicon(win, xoff, yoff, data):
+    print("in gl_createicon")
     it = data
     o = it.part_content_get("elm.swallow.icon")
 
@@ -297,7 +311,6 @@ def gl_createicon(win, xoff, yoff, data):
 def gl_icons_get(gl):
     # Start icons animation before actually drag-starts
 
-    yposret = 0
     icons = []
 
     xm, ym = gl.evas.pointer_canvas_xy
@@ -389,15 +402,14 @@ def gl_dnd_default_anim_data_getcb(gl, it, info):
     # 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, info.donecbdata = gl_get_drag_data(gl, it)
-
     info.acceptdata = info.donecbdata
 
     if info.data is not None:
-        return info
+        return True
     else:
-        return
+        return False
 
-def gl_data_getcb(gl, it, info):
+def gl_dnd_user_anim_data_getcb(gl, it, info):
     # This called before starting to drag, mouse-down was on it
     info.format = ELM_SEL_FORMAT_TARGETS
     info.createicon = gl_createicon
@@ -422,13 +434,12 @@ def grid_icons_get(grid):
 
     xm, ym = grid.evas.pointer_canvas_xy
     items = list(grid.selected_items)
-    print(items)
+
     gli, xposret, yposret = grid.at_xy_item_get(xm, ym)
     if gli is not None:
         # Add the item mouse is over to the list if NOT seleced
         if not gli in items:
             items.append(gli)
-    print(items)
 
     for gli in items:
         # Now add icons to animation window
@@ -472,18 +483,15 @@ def dnd_genlist_default_anim_clicked(obj, item=None):
         gl = Genlist(win, multi_select=True, size_hint_weight=EXPAND_BOTH,
             size_hint_align=FILL_BOTH)
 
-        # START Drag and Drop handling
         win.callback_delete_request_add(win_del, gl)
         gl.drop_item_container_add(ELM_SEL_FORMAT_TARGETS, gl_item_getcb,
+            #poscb=gl_poscb,
             dropcb=gl_dropcb)
 
         gl.drag_item_container_add(ANIM_TIME, DRAG_TIMEOUT, gl_item_getcb,
             gl_dnd_default_anim_data_getcb)
 
-        # FIXME:    This causes genlist to resize the horiz axis very slowly :(
-        #           Reenable this and resize the window horizontally, then try
-        #           to resize it back.
-        #elm_genlist_mode_set(gl, ELM_LIST_LIMIT)
+        gl.mode = ELM_LIST_LIMIT
         bxx.pack_end(gl)
         gl.show()
 
@@ -504,21 +512,17 @@ def dnd_genlist_user_anim_clicked(obj, item=None):
         gl = Genlist(win, multi_select=True, size_hint_weight=EXPAND_BOTH,
             size_hint_align=FILL_BOTH)
 
-        # START Drag and Drop handling
         win.callback_delete_request_add(win_del, gl)
         gl.drop_item_container_add(ELM_SEL_FORMAT_TARGETS, gl_item_getcb,
             dropcb=gl_dropcb)
 
         gl.drag_item_container_add(ANIM_TIME, DRAG_TIMEOUT, gl_item_getcb,
-            gl_data_getcb)
+            gl_dnd_user_anim_data_getcb)
 
         # We add mouse-down, up callbacks to start/stop drag animation
         gl.event_callback_add(EVAS_CALLBACK_MOUSE_DOWN, gl_obj_mouse_down, gl)
-        # END Drag and Drop handling
 
-        # FIXME: This causes genlist to resize the horiz axis very slowly :(
-        # Reenable this and resize the window horizontally, then try to resize 
it back
-        #elm_genlist_mode_set(gl, ELM_LIST_LIMIT)
+        gl.mode = ELM_LIST_LIMIT
         bxx.pack_end(gl)
         gl.show()
 
@@ -547,9 +551,7 @@ def dnd_genlist_gengrid_clicked(obj, item=None):
         gl_dnd_default_anim_data_getcb)
     # END Drag and Drop handling
 
-    # FIXME: This causes genlist to resize the horiz axis very slowly :(
-    # Reenable this and resize the window horizontally, then try to resize it 
back
-    #elm_genlist_mode_set(gl, ELM_LIST_LIMIT)
+    gl.mode = ELM_LIST_LIMIT
     bxx.pack_end(gl)
     gl.show()
 
@@ -576,6 +578,156 @@ def dnd_genlist_gengrid_clicked(obj, item=None):
     win.show()
 
 
+def _drop_box_button_new_cb(obj, ev, data):
+    win = data
+    if ev.data is None:
+        return False
+    if ev.len <= 0:
+        return False
+
+    p = ev.data
+
+    wh0rdlist = p.split("#")
+    wh0rdlist.pop(0)
+    wh0rdlist.pop()
+
+    for wh0rd in wh0rdlist:
+        ic = Icon(
+            win, file=os.path.join(img_path, wh0rd),
+            size_hint_aspect=(EVAS_ASPECT_CONTROL_VERTICAL, 1, 1))
+        bt = Button(win, text="Dropped button")
+        bt.part_content_set("icon", ic)
+        obj.pack_end(bt)
+        bt.show()
+        ic.show()
+
+    return True
+
+def _enter_but_cb(obj, data):
+    print("Entered _enter_but_cb - drop it here and I will never print this 
line anymore.")
+
+def _drop_but_icon_change_cb(obj, ev, data):
+    win = data
+    if ev.data is None:
+        return False
+    if ev.len <= 0:
+        return False
+
+    p = ev.data
+
+    wh0rdlist = p.split("#")
+    wh0rdlist.pop(0)
+    wh0rdlist.pop()
+
+    ic = Icon(
+        win, file=os.path.join(img_path, wh0rdlist[0]),
+        size_hint_aspect=(EVAS_ASPECT_CONTROL_VERTICAL, 1, 1))
+    obj.part_content_get("icon").delete()
+    obj.part_content_set("icon", ic)
+    ic.show()
+
+    return True
+
+# Callback used to test multi-callbacks feature */
+def _drop_but_cb_remove_cb(obj, ev, data):
+    print("Second callback called - removing it")
+    obj.drop_target_del(ELM_SEL_FORMAT_TARGETS, _enter_but_cb, NULL, NULL, 
NULL, NULL, NULL, _drop_but_cb_remove_cb, NULL)
+    return True
+
+def _drop_bg_change_cb(obj, ev, data):
+    if ev.data is None:
+        return False
+    if ev.len <= 0:
+        return False
+
+    p = ev.data
+
+    wh0rdlist = p.split("#")
+    wh0rdlist.pop(0)
+    wh0rdlist.pop()
+
+    obj.file = os.path.join(img_path, wh0rdlist[0])
+
+    return True
+
+def _5s_cancel_ck_changed(obj, ev, data):
+    _5s_cancel = obj.state
+
+
+def dnd_multi_features_clicked(obj, item=None):
+    win = StandardWindow("dnd-multi-features", "DnD-Multi Features",
+        autodel=True, size=(680,800))
+
+    bg = Background(win, size_hint_weight=EXPAND_BOTH)
+    bg.drop_target_add(ELM_SEL_FORMAT_TARGETS, dropcb=_drop_bg_change_cb)
+    win.resize_object_add(bg)
+    bg.show()
+
+    bxx = Box(win, horizontal=True, size_hint_weight=EXPAND_BOTH)
+    win.resize_object_add(bxx)
+    bxx.show()
+
+    grid = Gengrid(
+        bxx, horizontal=True, reorder_mode=False, multi_select=True,
+        size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH,
+        item_size=(SCALE * 100, SCALE * 100))
+    win.callback_delete_request_add(win_del, grid)
+
+    gic = DndGengridItemClass()
+
+    grid.drag_item_container_add(ANIM_TIME, DRAG_TIMEOUT, grid_item_getcb, 
grid_data_getcb)
+    for i in range(10):
+         grid.item_append(gic, img[i % 9])
+    bxx.pack_end(grid)
+    grid.show()
+
+
+
+    vert_box = Box(bxx, size_hint_weight=EXPAND_BOTH)
+    bxx.pack_end(vert_box)
+    vert_box.show()
+    vert_box.drop_target_add(ELM_SEL_FORMAT_TARGETS, 
dropcb=_drop_box_button_new_cb, dropdata=win)
+
+    _5s_cancel = False
+    ck = Check(vert_box, style="toggle", text="Cancel after 5s:", 
state=_5s_cancel)
+    ck.callback_changed_add(_5s_cancel_ck_changed)
+    vert_box.pack_end(ck)
+    ck.show()
+
+    ic = Icon(
+        win, file=os.path.join(img_path, "logo_small.png"),
+        size_hint_aspect=(EVAS_ASPECT_CONTROL_VERTICAL, 1, 1))
+    bt = Button(win, text="Multi-callbacks check")
+    bt.drop_target_add(ELM_SEL_FORMAT_TARGETS, 
dropcb=_drop_but_icon_change_cb, dropdata=win)
+    bt.drop_target_add(ELM_SEL_FORMAT_TARGETS, _enter_but_cb, 
dropcb=_drop_but_cb_remove_cb)
+    bt.part_content_set("icon", ic)
+    vert_box.pack_end(bt)
+    bt.show()
+    ic.show()
+
+    ic = Icon(
+        win, file=os.path.join(img_path, "logo_small.png"),
+        size_hint_aspect=(EVAS_ASPECT_CONTROL_VERTICAL, 1, 1))
+    bt = Button(win, text="Drop into me to change my icon")
+    bt.drop_target_add(ELM_SEL_FORMAT_TARGETS, 
dropcb=_drop_but_icon_change_cb, dropdata=win)
+    bt.part_content_set("icon", ic)
+    vert_box.pack_end(bt)
+    bt.show()
+    ic.show()
+
+    ic = Icon(
+        win, file=os.path.join(img_path, "logo_small.png"),
+        size_hint_aspect=(EVAS_ASPECT_CONTROL_VERTICAL, 1, 1))
+    bt = Button(win, text="No action on drop")
+    bt.part_content_set("icon", ic)
+    vert_box.pack_end(bt)
+    bt.show()
+    ic.show()
+
+    win.show()
+
+
+
 if __name__ == "__main__":
     win = StandardWindow("test", "python-elementary test application",
         size=(320,520))
@@ -599,6 +751,7 @@ if __name__ == "__main__":
         ("DnD Genlist Default Anim", dnd_genlist_default_anim_clicked),
         ("DnD Genlist User Anim", dnd_genlist_user_anim_clicked),
         ("DnD Genlist+Gengrid", dnd_genlist_gengrid_clicked),
+        ("DnD-Multi Features", dnd_multi_features_clicked),
         ]
 
     li = List(win, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)

-- 


Reply via email to