kuuko pushed a commit to branch master.

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

commit afe11df6365d156b2b2b09f011406a4071967968
Author: Kai Huuhko <kai.huu...@gmail.com>
Date:   Tue Oct 8 17:13:32 2013 +0300

    Elementary: Beginnings of Drag and Drop support, very much work in progress.
---
 efl/elementary/cnp_callbacks.pxi  | 210 ++++++++++-
 efl/elementary/genlist.pyx        |  17 +-
 efl/elementary/genlist_widget.pxi | 113 +++++-
 efl/elementary/object.pyx         | 180 ++++++++--
 examples/elementary/test_dnd.py   | 715 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 1184 insertions(+), 51 deletions(-)

diff --git a/efl/elementary/cnp_callbacks.pxi b/efl/elementary/cnp_callbacks.pxi
index 49e9750..958bbb6 100644
--- a/efl/elementary/cnp_callbacks.pxi
+++ b/efl/elementary/cnp_callbacks.pxi
@@ -1,3 +1,59 @@
+from efl.elementary.enums cimport Elm_Sel_Type, Elm_Sel_Format, \
+    Elm_Xdnd_Action
+
+cdef extern from "Elementary.h":
+    struct _Elm_Selection_Data:
+        Evas_Coord       x, y
+        Elm_Sel_Format   format
+        void            *data
+        size_t           len
+        Elm_Xdnd_Action  action
+
+    ctypedef _Elm_Selection_Data Elm_Selection_Data
+
+    ctypedef Eina_Bool       (*Elm_Drop_Cb)                 (void *data, 
Evas_Object *obj, Elm_Selection_Data *ev)
+    ctypedef Elm_Object_Item *(*Elm_Xy_Item_Get_Cb)         (Evas_Object *obj, 
Evas_Coord x, Evas_Coord y, int *xposret, int *yposret)
+    ctypedef void            (*Elm_Selection_Loss_Cb)       (void *data, 
Elm_Sel_Type selection)
+    ctypedef Evas_Object    *(*Elm_Drag_Icon_Create_Cb)     (void *data, 
Evas_Object *win, Evas_Coord *xoff, Evas_Coord *yoff)
+    ctypedef void            (*Elm_Drag_State)              (void *data, 
Evas_Object *obj)
+    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_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)
+
+    struct _Elm_Drag_User_Info:
+        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
+
+    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)
+
 cdef class SelectionData(object):
 
     """Structure holding the info about selected data."""
@@ -39,7 +95,7 @@ cdef class SelectionData(object):
         def __get__(self):
             return self.sel_data.action
 
-cdef Eina_Bool elm_drop_cb(void *data, Evas_Object *obj, Elm_Selection_Data 
*ev):
+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.
 
     :param data: Application specific data
@@ -62,7 +118,42 @@ cdef Eina_Bool elm_drop_cb(void *data, Evas_Object *obj, 
Elm_Selection_Data *ev)
 
     return ret
 
-cdef void elm_selection_loss_cb(void *data, Elm_Sel_Type selection):
+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:
+    """Callback invoked to find out what object is under (x,y) coords
+
+    :param obj: The container object
+    :param x: cord to check
+    :param y: cord to check
+    :param xposret: Position relative to item (left (-1), middle (0), right (1)
+    :param yposret: Position relative to item (upper (-1), middle (0), bottom 
(1)
+    :return: object under x,y cords or NULL if not found.
+
+    """
+    assert obj != NULL, "obj is NULL"
+
+    cdef:
+        evasObject o = object_from_instance(obj)
+        object xpos1, ypos1
+        int xpos2, ypos2
+        ObjectItem it
+
+    try:
+        ret = o.data["xy_item_get_cb"](o, x, y)
+        it, xpos1, ypos1 = ret
+    except:
+        traceback.print_exc()
+        return NULL
+
+    if xpos1 is not None:
+        xpos2 = xpos1
+        xposret = &xpos2
+    if ypos1 is not None:
+        ypos2 = ypos1
+        yposret = &ypos2
+
+    return it.item
+
+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.
 
     :param data: Application specific data
@@ -75,20 +166,23 @@ cdef void elm_selection_loss_cb(void *data, Elm_Sel_Type 
selection):
 
     cb_func(selection, cb_data)
 
-cdef Evas_Object *elm_drag_icon_create_cb(void *data, Evas_Object *win, 
Evas_Coord *xoff, Evas_Coord *yoff):
+cdef Evas_Object *py_elm_drag_icon_create_cb(
+    void *data, Evas_Object *win, Evas_Coord *xoff, Evas_Coord *yoff) with gil:
     """Callback called to create a drag icon object
 
     :param data: Application specific data
     :param win: The window to create the objects relative to
-    :param xoff: A return coordinate for the X offset at which to place the 
drag icon object relative to the source drag object
-    :param yoff: A return coordinate for the Y offset at which to place the 
drag icon object relative to the source drag object
+    :param xoff: A return coordinate for the X offset at which to place
+        the drag icon object relative to the source drag object
+    :param yoff: A return coordinate for the Y offset at which to place
+        the drag icon object relative to the source drag object
     :return: An object to fill the drag window with or NULL if not needed
     :since: 1.8
 
     """
-    pass
+    print("in drag_icon_create_cb")
 
-cdef void elm_drag_state(void *data, Evas_Object *obj):
+cdef void py_elm_drag_state_cb(void *data, Evas_Object *obj) with gil:
     """Callback called when a drag is finished, enters, or leaves an object
 
     :param data: Application specific data
@@ -96,9 +190,9 @@ cdef void elm_drag_state(void *data, Evas_Object *obj):
     :since: 1.8
 
     """
-    pass
+    print("in drag_state_cb")
 
-cdef void elm_drag_accept(void *data, Evas_Object *obj, Eina_Bool doaccept):
+cdef void py_elm_drag_accept_cb(void *data, Evas_Object *obj, Eina_Bool 
doaccept) with gil:
     """Callback called when a drag is responded to with an accept or deny
 
     :param data: Application specific data
@@ -107,9 +201,10 @@ cdef void elm_drag_accept(void *data, Evas_Object *obj, 
Eina_Bool doaccept):
     :since: 1.8
 
     """
-    pass
+    print("in drag_accept_cb")
 
-cdef void elm_drag_pos(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord 
y, Elm_Xdnd_Action action):
+cdef void py_elm_drag_pos_cb(void *data, Evas_Object *obj,
+    Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action) with gil:
     """Callback called when a drag is over an object, and gives 
object-relative coordinates
 
     :param data: Application specific data
@@ -119,4 +214,95 @@ cdef void elm_drag_pos(void *data, Evas_Object *obj, 
Evas_Coord x, Evas_Coord y,
     :since: 1.8
 
     """
-    pass
+    print("in drag_pos_cb")
+
+
+cdef void py_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) with gil:
+    """
+
+    Callback called when a drag is over an object
+
+    :param data: Application specific data
+    @param cont The container object where the drag started
+    @param it The object item in container where mouse-over
+    @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
+    @param xposret Position relative to item (left (-1), middle (0), right (1)
+    @param yposret Position relative to item (upper (-1), middle (0), bottom 
(1)
+    @param action The drag action to be done
+    @since 1.8
+
+    """
+    print("in drag_item_container_pos")
+
+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:
+    """
+
+    Callback invoked in when the selected data is 'dropped' on container.
+
+    @param data Application specific data
+    @param obj The evas object where selected data is 'dropped'.
+    @param it The item in container where drop-cords
+    @param ev struct holding information about selected data
+    @param xposret Position relative to item (left (-1), middle (0), right (1)
+    @param yposret Position relative to item (upper (-1), middle (0), bottom 
(1)
+
+    """
+    print("in drop_item_container_cb")
+
+
+cdef class DragUserInfo(object):
+    """
+
+    Structure describing user information for the drag process.
+
+    @param format The drag formats supported by the data (output)
+    @param data The drag data itself (a string) (output)
+    @param icons if value not NULL, play default anim (output)
+    @param action The drag action to be done (output)
+    @param createicon Function to call to create a drag object, or NULL if not 
wanted (output)
+    @param createdata Application data passed to @p createicon (output)
+    @param dragpos Function called with each position of the drag,
+        x, y being screen coordinates if possible, and action being the 
current action. (output)
+    @param dragdata Application data passed to @p dragpos (output)
+    @param acceptcb Function called indicating if drop target accepts
+        (or does not) the drop data while dragging (output)
+    @param acceptdata Application data passed to @p acceptcb (output)
+    @param dragdone Function to call when drag is done (output)
+    @param donecbdata Application data to pass to @p dragdone (output)
+
+    """
+
+    cdef Elm_Drag_User_Info *info
+
+    # 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:
+    """
+
+    Callback invoked when starting to drag for a container.
+
+    @param obj The container object
+    @param it The Elm_Object_Item pointer where drag-start
+    @return Returns EINA_TRUE, if successful, or EINA_FALSE if not.
+
+    """
+    print("in item_container_data_get_cb")
diff --git a/efl/elementary/genlist.pyx b/efl/elementary/genlist.pyx
index 1b4ebb0..d2d8166 100644
--- a/efl/elementary/genlist.pyx
+++ b/efl/elementary/genlist.pyx
@@ -654,7 +654,6 @@ cdef extern from "Elementary.h":
     void                    elm_genlist_focus_on_selection_set(Evas_Object 
*obj, Eina_Bool enabled)
     Eina_Bool               
elm_genlist_focus_on_selection_get(const_Evas_Object *obj)
 
-
 from cpython cimport PyUnicode_AsUTF8String
 
 from efl.utils.deprecated import DEPRECATED
@@ -694,9 +693,19 @@ ELM_OBJECT_SELECT_MODE_NONE = 
enums.ELM_OBJECT_SELECT_MODE_NONE
 ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY = enums.ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY
 ELM_OBJECT_SELECT_MODE_MAX = enums.ELM_OBJECT_SELECT_MODE_MAX
 
-ELM_SCROLLER_POLICY_AUTO = enums.ELM_SCROLLER_POLICY_AUTO
-ELM_SCROLLER_POLICY_ON = enums.ELM_SCROLLER_POLICY_ON
-ELM_SCROLLER_POLICY_OFF = enums.ELM_SCROLLER_POLICY_OFF
+ELM_SEL_FORMAT_TARGETS = enums.ELM_SEL_FORMAT_TARGETS
+ELM_SEL_FORMAT_NONE = enums.ELM_SEL_FORMAT_NONE
+ELM_SEL_FORMAT_TEXT = enums.ELM_SEL_FORMAT_TEXT
+ELM_SEL_FORMAT_MARKUP = enums.ELM_SEL_FORMAT_MARKUP
+ELM_SEL_FORMAT_IMAGE = enums.ELM_SEL_FORMAT_IMAGE
+ELM_SEL_FORMAT_VCARD = enums.ELM_SEL_FORMAT_VCARD
+ELM_SEL_FORMAT_HTML = enums.ELM_SEL_FORMAT_HTML
+
+ELM_SEL_TYPE_PRIMARY = enums.ELM_SEL_TYPE_PRIMARY
+ELM_SEL_TYPE_SECONDARY = enums.ELM_SEL_TYPE_SECONDARY
+ELM_SEL_TYPE_XDND = enums.ELM_SEL_TYPE_XDND
+ELM_SEL_TYPE_CLIPBOARD = enums.ELM_SEL_TYPE_CLIPBOARD
+
 
 cdef char *_py_elm_genlist_item_text_get(void *data, Evas_Object *obj, 
const_char *part) with gil:
     cdef:
diff --git a/efl/elementary/genlist_widget.pxi 
b/efl/elementary/genlist_widget.pxi
index e794d31..d3fac26 100644
--- a/efl/elementary/genlist_widget.pxi
+++ b/efl/elementary/genlist_widget.pxi
@@ -1,3 +1,5 @@
+include "cnp_callbacks.pxi"
+
 cdef class Genlist(Object):
 
     """This is the class that actually implements the widget."""
@@ -489,7 +491,7 @@ cdef class Genlist(Object):
         :param x: The input x coordinate
         :param y: The input y coordinate
         :param posret: The position relative to the item returned here
-        :return: The item at the coordinates or None if none
+        :return: 
(:py:class:`ObjectItem<efl.elementary.object_item.ObjectItem>` it, **int** 
posret)
 
         This returns the item at the given coordinates (which are canvas
         relative, not object-relative). If an item is at that coordinate,
@@ -502,7 +504,12 @@ cdef class Genlist(Object):
         the genlist.
 
         """
-        return _object_item_to_python(elm_genlist_at_xy_item_get(self.obj, x, 
y, NULL))
+        cdef:
+            int posret
+            Elm_Object_Item *ret
+
+        ret = elm_genlist_at_xy_item_get(self.obj, x, y, &posret)
+        return _object_item_to_python(ret), posret
 
     property decorated_item:
         """This function returns the item that was activated with a mode, by
@@ -661,6 +668,108 @@ cdef class Genlist(Object):
         def __get__(self):
             return bool(elm_genlist_focus_on_selection_get(self.obj))
 
+    #
+    # 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 draggind.
+        :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.
+
+        :since: 1.8
+
+        """
+        if itemgetcb is not None:
+            if not callable(itemgetcb):
+                raise TypeError("itemgetcb must be callable.")
+            self.data["xy_item_get_cb"] = itemgetcb
+
+        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
+
+    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, Elm_Sel_Format format,
+        itemgetcb = None, entercb = None, enterdata = None,
+        leavecb = None, leavedata = None,
+        poscb = None, posdata = None, dropcb = None, cbdata = None):
+        """
+
+        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 itemgetcb is not None:
+            if not callable(itemgetcb):
+                raise TypeError("itemgetcb must be callable.")
+            self.data["xy_item_get_cb"] = itemgetcb
+
+        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,
+            <Elm_Drag_State>py_elm_drag_state_cb if leavecb is not None else 
NULL,
+            <void *>leavedata,
+            <Elm_Drag_Item_Container_Pos>py_elm_drag_item_container_pos if 
poscb is not None else NULL,
+            <void *>posdata,
+            <Elm_Drop_Item_Container_Cb>py_elm_drop_item_container_cb if 
dropcb is not None else NULL,
+            <void *>cbdata):
+            raise RuntimeError
+
+    def drop_item_container_del(self):
+        """
+
+        Removes a container from list of drop tragets.
+
+        :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
+
 
     def callback_activated_add(self, func, *args, **kwargs):
         self._callback_add_full("activated", _cb_object_item_conv,
diff --git a/efl/elementary/object.pyx b/efl/elementary/object.pyx
index a7fb913..c4bde83 100644
--- a/efl/elementary/object.pyx
+++ b/efl/elementary/object.pyx
@@ -203,30 +203,18 @@ from enums cimport Elm_Focus_Direction, Elm_Sel_Format, 
Elm_Sel_Type, \
 from libc.string cimport const_char
 from libc.stdlib cimport const_void
 
+include "cnp_callbacks.pxi"
+
 cdef extern from "Edje.h":
     ctypedef void (*Edje_Signal_Cb)(void *data, Evas_Object *obj, const_char 
*emission, const_char *source)
 
 cdef extern from "Elementary.h":
     ctypedef struct Elm_Theme
 
-    ctypedef struct Elm_Selection_Data:
-        Evas_Coord       x, y
-        Elm_Sel_Format   format
-        void            *data
-        size_t           len
-        Elm_Xdnd_Action  action
-
     ctypedef Eina_Bool       (*Elm_Event_Cb)                (void *data, 
Evas_Object *obj, Evas_Object *src, Evas_Callback_Type t, void *event_info)
     ctypedef Evas_Object    *(*Elm_Tooltip_Content_Cb)      (void *data, 
Evas_Object *obj, Evas_Object *tooltip)
     ctypedef Evas_Object    *(*Elm_Tooltip_Item_Content_Cb) (void *data, 
Evas_Object *obj, Evas_Object *tooltip, void *item)
 
-    ctypedef Eina_Bool       (*Elm_Drop_Cb)                 (void *data, 
Evas_Object *obj, Elm_Selection_Data *ev)
-    ctypedef void            (*Elm_Selection_Loss_Cb)       (void *data, 
Elm_Sel_Type selection)
-    ctypedef Evas_Object    *(*Elm_Drag_Icon_Create_Cb)     (void *data, 
Evas_Object *win, Evas_Coord *xoff, Evas_Coord *yoff)
-    ctypedef void            (*Elm_Drag_State)              (void *data, 
Evas_Object *obj)
-    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)
-
     # Object handling       (py3: DONE)
     void                    elm_object_part_text_set(Evas_Object *obj, 
const_char *part, const_char *label)
     void                    elm_object_text_set(Evas_Object *obj, const_char 
*label)
@@ -422,12 +410,15 @@ cdef bint _event_dispatcher(Object obj, Object src, 
Evas_Callback_Type t, event_
             return ret
     return False
 
-cdef Eina_Bool _event_callback(void *data, Evas_Object *o, Evas_Object *src, 
Evas_Callback_Type t, void *event_info) with gil:
-    cdef Object obj = object_from_instance(o)
-    cdef Object src_obj = object_from_instance(src)
-    cdef bint ret = False
-    cdef EventKeyDown down_event
-    cdef EventKeyUp up_event
+cdef Eina_Bool _event_callback(void *data, Evas_Object *o, \
+    Evas_Object *src, Evas_Callback_Type t, void *event_info) with gil:
+
+    cdef:
+        Object obj = object_from_instance(o)
+        Object src_obj = object_from_instance(src)
+        bint ret = False
+        EventKeyDown down_event
+        EventKeyUp up_event
 
     if t == evasenums.EVAS_CALLBACK_KEY_DOWN:
         down_event = EventKeyDown()
@@ -459,7 +450,6 @@ cdef void signal_callback(void *data, Evas_Object *obj,
         except:
             traceback.print_exc()
 
-include "cnp_callbacks.pxi"
 
 # TODO: Is this handled in Eo now?
 cdef void _event_data_del_cb(void *data, Evas_Object *o, void *event_info) 
with gil:
@@ -970,7 +960,10 @@ cdef class Object(evasObject):
     cpdef bint orientation_mode_disabled_get(self):
         return elm_object_orientation_mode_disabled_get(self.obj)
 
+    #
     # Cursors
+    # =======
+
     property cursor:
         """The cursor to be shown when mouse is over the object
 
@@ -1028,7 +1021,10 @@ cdef class Object(evasObject):
     def cursor_theme_search_enabled_get(self):
         return elm_object_cursor_theme_search_enabled_get(self.obj)
 
+    #
     # Focus
+    # =====
+
     property focus:
         """Set/unset focus to a given Elementary object.
 
@@ -1237,7 +1233,10 @@ cdef class Object(evasObject):
     def tree_focus_allow_get(self):
         return bool(elm_object_tree_focus_allow_get(self.obj))
 
+    #
     # Mirroring
+    # =========
+
     property mirrored:
         """The widget's mirrored mode.
 
@@ -1271,7 +1270,10 @@ cdef class Object(evasObject):
     def mirrored_automatic_set(self, automatic):
         elm_object_mirrored_automatic_set(self.obj, automatic)
 
+    #
     # Scaling
+    # =======
+
     property scale:
         """The scaling factor for the Elementary object.
 
@@ -1289,7 +1291,10 @@ cdef class Object(evasObject):
     def scale_get(self):
         return elm_object_scale_get(self.obj)
 
+    #
     # Scrollhints
+    # ===========
+
     def scroll_hold_push(self):
         """scroll_hold_push()
 
@@ -1383,7 +1388,10 @@ cdef class Object(evasObject):
     def scroll_lock_y_get(self):
         return bool(elm_object_scroll_lock_y_get(self.obj))
 
+    #
     # Theme
+    # =====
+
     property theme:
         """A theme to be used for this object and its children.
 
@@ -1408,7 +1416,10 @@ cdef class Object(evasObject):
             th.th = elm_object_theme_get(self.obj)
             return th
 
+    #
     # Tooltips
+    # ========
+
     def tooltip_show(self):
         """tooltip_show()
 
@@ -1668,12 +1679,15 @@ cdef class Object(evasObject):
     def translatable_text_get(self):
         return _ctouni(elm_object_translatable_text_get(self.obj))
 
+    #
     # Callbacks
+    # =========
     #
     # TODO: Should these be internal only? (cdef)
     #       Or remove the individual widget callback_*_add/del methods and
     #       use just these.
     #
+
     def _callback_add_full(self, event, event_conv, func, *args, **kargs):
         """Add a callback for the smart event specified by event.
 
@@ -1795,7 +1809,10 @@ cdef class Object(evasObject):
         """
         return <long>self.obj
 
+    #
     # Copy and Paste
+    # ==============
+
     def cnp_selection_set(self, Elm_Sel_Type selection, Elm_Sel_Format format, 
buf):
         """Set copy data for a widget.
 
@@ -1841,7 +1858,7 @@ cdef class Object(evasObject):
             raise TypeError("datacb is not callable.")
         self.cnp_drop_cb = datacb
         self.cnp_drop_data = udata
-        if not elm_cnp_selection_get(self.obj, selection, format, elm_drop_cb, 
<void *>self):
+        if not elm_cnp_selection_get(self.obj, selection, format, 
py_elm_drop_cb, <void *>self):
             raise RuntimeError("Could not get cnp data from widget.")
 
     def cnp_selection_clear(self, Elm_Sel_Type selection):
@@ -1883,19 +1900,24 @@ cdef class Object(evasObject):
             raise TypeError("func is not callable.")
         self.cnp_selection_loss_cb = func
         self.cnp_selection_loss_data = data
-        elm_cnp_selection_loss_callback_set(self.obj, selection, 
elm_selection_loss_cb, <const_void *>data)
+        elm_cnp_selection_loss_callback_set(
+            self.obj, selection, py_elm_selection_loss_cb, <const_void *>data)
+
+    #
+    # Drag n Drop
+    # ===========
 
-    # TODO:
-    # def drop_target_add(self, Elm_Sel_Format format, entercb, enterdata, 
leavecb, leavedata, poscb, posdata, dropcb, dropdata):
+    # 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 leavedata
+    #     :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 posdata
+    #     :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.
@@ -1903,11 +1925,24 @@ cdef class Object(evasObject):
     #     :since: 1.8
 
     #     """
-    #     if not elm_drop_target_add(self.obj, 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):
+    #     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):
@@ -1921,7 +1956,9 @@ cdef class Object(evasObject):
     #     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):
+    # 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
@@ -1961,6 +1998,83 @@ cdef class Object(evasObject):
     #     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 draggind.
+    #     :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.
+
+    #     :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 tragets.
+
+    #     :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
+    # ======
 
     def unregister(self):
         """Unregister accessible object.
diff --git a/examples/elementary/test_dnd.py b/examples/elementary/test_dnd.py
new file mode 100644
index 0000000..9053b8f
--- /dev/null
+++ b/examples/elementary/test_dnd.py
@@ -0,0 +1,715 @@
+#!/usr/bin/env python
+# encoding: utf-8
+
+from efl import evas
+from efl import elementary
+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, \
+    ELM_SEL_FORMAT_TARGETS, ELM_GENLIST_ITEM_NONE
+
+img = (
+    "panel_01.jpg",
+    "plant_01.jpg",
+    "rock_01.jpg",
+    "rock_02.jpg",
+    "sky_01.jpg",
+    "sky_02.jpg",
+    "sky_03.jpg",
+    "sky_04.jpg",
+    "wood_01.jpg",
+    )
+
+# class anim_icon_st:
+#     int start_x
+#     int start_y
+#     Evas_Object *o
+
+# class drag_anim_st:
+#     Evas_Object *icwin
+#     Evas *e
+#     Evas_Coord mdx     # Mouse-down x
+#     Evas_Coord mdy     # Mouse-down y
+#     Eina_List *icons   # List of icons to animate (anim_icon_st)
+#     Ecore_Timer *tm
+#     Ecore_Animator *ea
+#     Evas_Object *gl
+
+DRAG_TIMEOUT = 0.3
+ANIM_TIME = 0.5
+
+def item_ptr_cmp(d1, d2):
+    return (d1 - d2)
+
+#static Elm_Genlist_Item_Class *itc1
+#static Elm_Gengrid_Item_Class *gic
+
+
+class DndItemClass(GenlistItemClass):
+    def text_get(self, obj, part, data, *args):
+        return data
+
+    def content_get(self, obj, part, data, *args):
+        if not part == "elm.swallow.icon":
+            icon = Icon(obj)
+            icon.file = data
+            icon.size_hint_aspect = evas.EVAS_ASPECT_CONTROL_VERTICAL, 1, 1
+            icon.show()
+            return icon
+        return None
+
+def win_del(obj, data):
+    #print("<%s> <%d> will del <%p>\n", __func__, __LINE__, data)
+    data.drop_item_container_del()
+    data.drag_item_container_del()
+
+    # FIXME Needed?: if (gic) elm_gengrid_item_class_free(gic)
+    #gic = NULL
+    # FIXME Needed?: if (itc1) elm_genlist_item_class_free(itc1)
+    #itc1 = NULL
+
+    elementary.exit()
+
+def gl_item_getcb(gl, x, y):
+    # This function returns pointer to item under (x,y) coords
+    #print("<%s> <%d> obj=<%p>\n", __func__, __LINE__, gl)
+    gli, yposret = gl.at_xy_item_get(x, y)
+    if gli is not None:
+        print("over <%s>, gli=<%s> yposret %i\n" % 
(gli.part_text_get("elm.text"), gli, yposret))
+    else:
+        print("over none, yposret %i\n", yposret)
+    return gli, None, yposret
+
+# def grid_item_getcb(obj, x, y, int *xposret, int *yposret):
+#     # This function returns pointer to item under (x,y) coords
+#     #print("<%s> <%d> obj=<%p>\n", __func__, __LINE__, obj)
+#     item = gl.at_xy_item_get(x, y, xposret, yposret)
+#     if item is not None:
+#         print("over <%s>, item=<%p> xposret %i yposret %i\n",
+#             elm_object_item_part_text_get(item, "elm.text"), item, *xposret, 
*yposret)
+#     else:
+#         print("over none, xposret %i yposret %i\n", *xposret, *yposret)
+#     return item
+
+def gl_dropcb(data, obj, it,
+    ev, # Elm_Selection_Data *
+    xposret, yposret):
+    # This function is called when data is dropped on the genlist
+    #print("<%s> <%d> str=<%s>\n", __func__, __LINE__, (char *) ev->data)
+    if ev.data is None:
+        return False
+
+    p = ev.data
+    p = strchr(p, '#')
+    while p is not None:
+        p += 1
+        p2 = strchr(p, '#')
+        if p2 is not None:
+            p2 = '\0'
+            print("Item %s\n", p)
+            if yposret == -1:
+                obj.item_insert_before(itc1, p, before=it,
+                        flags=ELM_GENLIST_ITEM_NONE)
+            elif yposret == 0 or yposret == 1:
+                if not it:
+                    it = obj.last_item
+
+                if it:
+                    it = obj.item_insert_after(itc1, p, None, it,
+                    ELM_GENLIST_ITEM_NONE)
+                else:
+                    it = obj.item_append(itc1, p, None,
+                    ELM_GENLIST_ITEM_NONE)
+            else:
+                return False
+
+            p = p2
+
+        else:
+            p = None
+
+    return True
+
+# def grid_dropcb(data, obj, it, Elm_Selection_Data *ev, int xposret, int 
yposret):
+#     # This function is called when data is dropped on the genlist
+#     #print("<%s> <%d> str=<%s>\n", __func__, __LINE__, (char *) ev->data)
+#     if not ev.data:
+#         return False
+
+#     p = ev->data
+#     p = strchr(p, '#')
+#     while(p)
+#       {
+#           p++
+#           char *p2 = strchr(p, '#')
+#           if (p2)
+#              {
+#                  *p2 = '\0'
+#                  print("Item %s\n", p)
+#                  if (!it) it = elm_gengrid_last_item_get(obj)
+#                  if (it) it = elm_gengrid_item_insert_after(obj, gic, 
strdup(p), it, NULL, NULL)
+#                  else it = elm_gengrid_item_append(obj, gic, strdup(p), 
NULL, NULL)
+#                  p = p2
+#              }
+#           else p = NULL
+#       }
+
+#     return True
+
+# static void _gl_obj_mouse_move( void *data, Evas *e, Evas_Object *obj, void 
*event_info)
+# static void _gl_obj_mouse_up( void *data, Evas *e, Evas_Object *obj, void 
*event_info)
+
+# def anim_st_free(drag_anim_st *anim_st):
+#     # Stops and free mem of ongoing animation
+#     #print("<%s> <%d>\n", __func__, __LINE__)
+#     if anim_st is not None:
+#         evas_object_event_callback_del_full
+#               (anim_st->gl, EVAS_CALLBACK_MOUSE_MOVE, _gl_obj_mouse_move, 
anim_st)
+#         evas_object_event_callback_del_full
+#               (anim_st->gl, EVAS_CALLBACK_MOUSE_UP, _gl_obj_mouse_up, 
anim_st)
+#         if anim_st.tm is not None:
+#             ecore_timer_del(anim_st->tm)
+#             anim_st->tm = NULL
+
+#         if anim_st.ea is not None:
+#             ecore_animator_del(anim_st->ea)
+#             anim_st->ea = NULL
+
+#         anim_icon_st *st
+
+#         EINA_LIST_FREE(anim_st->icons, st)
+#              {
+#                  evas_object_hide(st->o)
+#                  evas_object_del(st->o)
+#                  free(st)
+#              }
+
+#         free(anim_st)
+
+# def drag_anim_play(void *data, double pos):
+#     # Impl of the animation of icons, called on frame time
+#     drag_anim_st *anim_st = data
+#     #print("<%s> <%d>\n", __func__, __LINE__)
+#     anim_icon_st *st
+
+#     if anim_st is not None:
+#         if pos > 0.99:
+#             anim_st.ea = None  # Avoid deleting on mouse up
+
+#             for st in anim_st.icons:
+#                 st.o.hide()   # Hide animated icons
+#             anim_st_free(anim_st)
+#             return ECORE_CALLBACK_CANCEL
+
+#         for st in anim_st.icons:
+#             w, h = st.o.size
+#             xm, ym = anim_st.e.pointer_canvas_xy
+#             x = st.start_x + (pos * (xm - (st.start_x + (w/2))))
+#             y = st.start_y + (pos * (ym - (st.start_y + (h/2))))
+#             st.o.move(x, y)
+
+#         return ECORE_CALLBACK_RENEW
+
+#     return ECORE_CALLBACK_CANCEL
+
+# def gl_anim_start(void *data):
+#     # Start icons animation before actually drag-starts
+#     drag_anim_st *anim_st = data
+#     #print("<%s> <%d>\n", __func__, __LINE__)
+#     int yposret = 0
+
+#     Eina_List *l
+#     Eina_List *items = 
eina_list_clone(elm_genlist_selected_items_get(anim_st->gl))
+#     Elm_Object_Item *gli = elm_genlist_at_xy_item_get(anim_st->gl,
+#             anim_st->mdx, anim_st->mdy, &yposret)
+#     if gli is not None:
+#         # Add the item mouse is over to the list if NOT seleced
+#           void *p = eina_list_search_unsorted(items, _item_ptr_cmp, gli)
+#           if (!p)
+#              items = eina_list_append(items, gli)
+
+#     for gli in items:
+#         # Now add icons to animation window
+#         o = gli.part_content_get("elm.swallow.icon")
+
+#         if o is not None:
+#             st = []
+#             f, g = o.file
+#             ic = Icon(anim_st.gl)
+#             ic.file = f, g
+#             st.start_x, st.start_y, w, h = o.geometry
+#             ic.size_hint_align = EVAS_HINT_FILL, EVAS_HINT_FILL
+#             ic.size_hint_weight = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND
+
+#             ic.move(st.start_x, st.start_y)
+#             ic.resize(w, h)
+#             ic.show()
+
+#             st.o = ic
+#             anim_st.icons.append(st)
+
+#     eina_list_free(items)
+
+#     anim_st.tm = None
+#     anim_st.ea = ecore_animator_timeline_add(DRAG_TIMEOUT,
+#             _drag_anim_play, anim_st)
+
+#     return ECORE_CALLBACK_CANCEL
+
+# def gl_obj_mouse_up(e, obj, event_info, data):
+#     # Cancel any drag waiting to start on timeout
+#     drag_anim_st *anim_st = data
+#     anim_st_free(anim_st)
+
+# def gl_obj_mouse_move(e, obj, event_info, data):
+#     # Cancel any drag waiting to start on timeout
+#     if (((Evas_Event_Mouse_Move *)event_info)->event_flags & 
EVAS_EVENT_FLAG_ON_HOLD):
+#         drag_anim_st *anim_st = data
+#         anim_st_free(anim_st)
+
+# def gl_obj_mouse_down(e, obj, event_info, data):
+#     # Launch a timer to start drag animation
+#     Evas_Event_Mouse_Down *ev = event_info
+#     drag_anim_st *anim_st = calloc(1, sizeof(*anim_st))
+#     anim_st->e = e
+#     anim_st->mdx = ev->canvas.x
+#     anim_st->mdy = ev->canvas.y
+#     anim_st->gl = data
+#     anim_st->tm = ecore_timer_add(DRAG_TIMEOUT, _gl_anim_start, anim_st)
+#     evas_object_event_callback_add(data, EVAS_CALLBACK_MOUSE_UP,
+#             _gl_obj_mouse_up, anim_st)
+#     evas_object_event_callback_add(data, EVAS_CALLBACK_MOUSE_MOVE,
+#             _gl_obj_mouse_move, anim_st)
+# # END   - Handling drag start animation
+
+def gl_dragdone(obj, doaccept, data):
+    #print("<%s> <%d> data=<%p> doaccept=<%d>\n", __func__, __LINE__, data, 
doaccept)
+
+    if doaccept:
+        # Remove items dragged out (accepted by target)
+        for it in data:
+            it.delete()
+
+def gl_createicon(data, win, xoff, yoff):
+    #print("<%s> <%d>\n", __func__, __LINE__)
+    it = data
+    o = it.part_content_get("elm.swallow.icon")
+
+    if o is not None:
+        w = h = 30
+
+        f, g = o.file
+
+        xm, ym = o.evas.pointer_canvas_xy
+
+        if xoff is not None:
+            xoff = xm - (w/2)
+        if yoff is not None:
+            yoff = ym - (h/2)
+
+        icon = Icon(win)
+        icon.file = f, g
+        icon.size_hint_align = evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL
+        icon.size_hint_weight = evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND
+
+        if xoff is not None and yoff is not None:
+            icon.move(xoff, yoff)
+        icon.resize(w, h)
+
+    return icon
+
+def gl_icons_get(data):
+    # Start icons animation before actually drag-starts
+    #print("<%s> <%d>\n", __func__, __LINE__)
+    gl = data
+
+    yposret = 0
+
+    icons = []
+
+    xm, ym = gl.evas.pointer_canvas_xy
+    items = gl.selected_items
+    gli = gl.at_xy_item_get(xm, ym, yposret)
+
+    if gli is not None:
+        # Add the item mouse is over to the list if NOT seleced
+        p = eina_list_search_unsorted(items, _item_ptr_cmp, gli)
+        if p is not None:
+            items = eina_list_append(items, gli)
+
+    for gli in items:
+        # Now add icons to animation window
+        o = gli.part_content_get("elm.swallow.icon")
+
+        if o is not None:
+            f, g = o.file
+            ic = Icon(gl)
+            ic.file = f, g
+            x, y, w, h = o.geometry
+            ic.size_hint_align = evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL
+            ic.size_hint_weight = evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND
+
+            ic.move(x, y)
+            ic.resize(w, h)
+            ic.show()
+
+            icons.append(ic)
+
+    eina_list_free(items)
+    return icons
+
+def gl_get_drag_data(gl, it, items):
+    # Construct a string of dragged info, user frees returned string
+    drag_data = None
+    #print("<%s> <%d>\n", __func__, __LINE__)
+
+    items = gl.selected_items
+    if it is not None:
+        # Add the item mouse is over to the list if NOT seleced
+        p = eina_list_search_unsorted(items, _item_ptr_cmp, it)
+        if p is None:
+            items = eina_list_append(items, it)
+
+    if items:
+        # Now we can actually compose string to send and start dragging
+        drag_data = "file://"
+
+        for it in items:
+            t = it.part_text_get("elm.text")
+            if t is not None:
+                drag_data += "#"
+                drag_data += t
+
+        drag_data += "#"
+
+        #print("<%s> <%d> Sending <%s>\n", __func__, __LINE__, drag_data)
+
+    return drag_data
+
+# def grid_get_drag_data(gg, it, Eina_List **items):
+#     # Construct a string of dragged info, user frees returned string
+#     const char *drag_data = NULL
+#     #print("<%s> <%d>\n", __func__, __LINE__)
+
+#     *items = eina_list_clone(elm_gengrid_selected_items_get(obj))
+#     if (it)
+#       {  # Add the item mouse is over to the list if NOT seleced
+#           void *p = eina_list_search_unsorted(*items, _item_ptr_cmp, it)
+#           if (!p)
+#              *items = eina_list_append(*items, it)
+#       }
+
+#     if (*items)
+#       {  # Now we can actually compose string to send and start dragging
+#           Eina_List *l
+#           const char *t
+#           unsigned int len = 0
+
+#           EINA_LIST_FOREACH(*items, l, it)
+#              {
+#                  t = elm_object_item_part_text_get(it, "elm.text")
+#                  if (t)
+#                     len += strlen(t)
+#              }
+
+#           drag_data = malloc(len + eina_list_count(*items) * 2 + 8)
+#           strcpy((char *) drag_data, "file://")
+
+#           EINA_LIST_FOREACH(*items, l, it)
+#              {
+#                  t = elm_object_item_part_text_get(it, "elm.text")
+#                  if (t)
+#                     {
+#                         strcat((char *) drag_data, "#")
+#                         strcat((char *) drag_data, t)
+#                     }
+#              }
+#           strcat((char *) drag_data, "#")
+
+#           print("<%s> <%d> Sending <%s>\n", __func__, __LINE__, drag_data)
+#       }
+
+#     return drag_data
+
+def gl_dnd_default_anim_data_getcb(gl, it,
+        info # Elm_Drag_User_Info *
+    ):
+    # This called before starting to drag, mouse-down was on it
+    info.format = ELM_SEL_FORMAT_TARGETS
+    info.createicon = _gl_createicon
+    info.createdata = it
+    info.icons = _gl_icons_get(obj)
+    info.dragdone = _gl_dragdone
+
+    # 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 = _gl_get_drag_data(obj, it, info.donecbdata)
+    #print("%s - data = %s\n", __FUNCTION__, info->data)
+    info.acceptdata = info.donecbdata
+
+    if info.data is not None:
+        return True
+    else:
+        return False
+
+# def gl_data_getcb(gl,  it,
+#         Elm_Drag_User_Info *info):
+#     # This called before starting to drag, mouse-down was on it
+#     info->format = ELM_SEL_FORMAT_TARGETS
+#     info->createicon = _gl_createicon
+#     info->createdata = it
+#     info->dragdone = _gl_dragdone
+
+#     # 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 = _gl_get_drag_data(obj, it, (Eina_List **) &info->donecbdata)
+#     info->acceptdata = info->donecbdata
+
+#     if (info->data)
+#       return True
+#     else
+#       return False
+
+# def grid_icons_get(void *data):
+#     # Start icons animation before actually drag-starts
+#     #print("<%s> <%d>\n", __func__, __LINE__)
+
+#     Eina_List *l
+
+#     Eina_List *icons = NULL
+
+#     Evas_Coord xm, ym
+#     evas_pointer_canvas_xy_get(evas_object_evas_get(data), &xm, &ym)
+#     Eina_List *items = eina_list_clone(elm_gengrid_selected_items_get(data))
+#     Elm_Object_Item *gli = elm_gengrid_at_xy_item_get(data,
+#             xm, ym, NULL, NULL)
+#     if gli is not None:
+#         # Add the item mouse is over to the list if NOT seleced
+#         void *p = eina_list_search_unsorted(items, _item_ptr_cmp, gli)
+#         if p is None:
+#             items = eina_list_append(items, gli)
+
+#     for gli in items:
+#         # Now add icons to animation window
+#         o = gli.part_content_get("elm.swallow.icon")
+
+#         if o is not None:
+#             int x, y, w, h
+#             const char *f, *g
+#             elm_image_file_get(o, &f, &g)
+#             Evas_Object *ic = elm_icon_add(data)
+#             elm_image_file_set(ic, f, g)
+#             evas_object_geometry_get(o, &x, &y, &w, &h)
+#             ic.size_hint_align = EVAS_HINT_FILL, EVAS_HINT_FILL
+#             ic.size_hint_weight = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND
+
+#             ic.move(x, y)
+#             ic.resize(w, h)
+#             ic.show()
+
+#             icons =  eina_list_append(icons, ic)
+
+#     eina_list_free(items)
+#     return icons
+
+# def grid_data_getcb(gl, it,
+#         Elm_Drag_User_Info *info):
+#     # This called before starting to drag, mouse-down was on it
+#     info->format = ELM_SEL_FORMAT_TARGETS
+#     info->createicon = _gl_createicon
+#     info->createdata = it
+#     info->icons = _grid_icons_get(obj)
+#     info->dragdone = _gl_dragdone
+
+#     # 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 = _grid_get_drag_data(obj, it, (Eina_List **) 
&info->donecbdata)
+#     print("%s - data = %s\n", __FUNCTION__, info->data)
+#     info->acceptdata = info->donecbdata
+
+#     if (info->data)
+#       return True
+#     else
+#       return False
+
+def dnd_genlist_default_anim_clicked(*args):
+    win = StandardWindow("dnd-genlist-default-anim", 
"DnD-Genlist-Default-Anim")
+    win.autodel = True
+
+    bxx = Box(win)
+    bxx.horizontal = True
+    bxx.size_hint_weight = evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND
+    win.resize_object_add(bxx)
+    bxx.show()
+
+    for j in range(2):
+        gl = Genlist(win)
+
+        # START Drag and Drop handling
+        win.callback_delete_request_add(win_del, gl)
+        gl.multi_select = True # We allow multi drag
+        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_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.size_hint_weight = evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND
+        gl.size_hint_align = evas.EVAS_HINT_FILL, evas.EVAS_HINT_FILL
+        bxx.pack_end(gl)
+        gl.show()
+
+        itc1 = DndItemClass()
+
+        for i in range (20):
+            gl.item_append(itc1, "images/{0}".format(img[i % 9]), 
flags=ELM_GENLIST_ITEM_NONE)
+
+    win.resize(680, 800)
+    win.show()
+
+# def test_dnd_genlist_user_anim(obj, event_info, data):
+#     win = StandardWindow("dnd-genlist-user-anim", "DnD-Genlist-User-Anim")
+#     win.autodel = True
+
+#     bxx = Box(win)
+#     bxx.horizontal = True
+#     bxx.size_hint_weight = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND
+#     win.resize_object_add(bxx)
+#     bxx.show()
+
+#     itc1 = elm_genlist_item_class_new()
+#     itc1->item_style     = "default"
+#     itc1->func.text_get = gl_text_get
+#     itc1->func.content_get  = gl_content_get
+#     itc1->func.del       = NULL
+
+#     for (j = 0 j < 2 j++):
+#         gl = Genlist(win)
+
+#         # START Drag and Drop handling
+#         win.callback_delete_request_add(win_del, gl)
+#         elm_genlist_multi_select_set(gl, True) # We allow multi drag
+#         elm_drop_item_container_add(gl,
+#               ELM_SEL_FORMAT_TARGETS,
+#               _gl_item_getcb,
+#               NULL, NULL,
+#               NULL, NULL,
+#               NULL, NULL,
+#               _gl_dropcb, NULL)
+
+#         elm_drag_item_container_add(gl, ANIM_TIME, DRAG_TIMEOUT,
+#               _gl_item_getcb, _gl_data_getcb)
+
+#         # We add mouse-down, up callbacks to start/stop drag animation
+#         evas_object_event_callback_add(gl, 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.size_hint_weight = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND
+#         gl.size_hint_align = EVAS_HINT_FILL, EVAS_HINT_FILL
+#         elm_box_pack_end(bxx, gl)
+#         gl.show()
+
+#         for (i = 0 i < 20 i++)
+#             snprintf(buf, sizeof(buf), "%s/images/%s", 
elm_app_data_dir_get(), img[(i % 9)])
+#             const char *path = eina_stringshare_add(buf)
+#             elm_genlist_item_append(gl, itc1, path, NULL, 
ELM_GENLIST_ITEM_NONE, NULL, NULL)
+
+#     evas_object_resize(win, 680, 800)
+#     win.show()
+
+# def test_dnd_genlist_gengrid(void *data __UNUSED__, Evas_Object *obj 
__UNUSED__, void *event_info __UNUSED__):
+#     win = StandardWindow("dnd-genlist-gengrid", "DnD-Genlist-Gengrid")
+#     win.autodel = True
+
+#     bxx = elm_box_add(win)
+#     elm_box_horizontal_set(bxx, True)
+#     bxx.size_hint_weight = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND
+#     elm_win_resize_object_add(win, bxx)
+#     bxx.show()
+
+#       {
+#           itc1 = elm_genlist_item_class_new()
+#           itc1->item_style     = "default"
+#           itc1->func.text_get = gl_text_get
+#           itc1->func.content_get  = gl_content_get
+#           itc1->func.del       = NULL
+
+#           Evas_Object *gl = elm_genlist_add(win)
+#           evas_object_smart_callback_add(win, "delete,request", _win_del, gl)
+
+#           # START Drag and Drop handling
+#           elm_genlist_multi_select_set(gl, True) # We allow multi drag
+#           elm_drop_item_container_add(gl, ELM_SEL_FORMAT_TARGETS, 
_gl_item_getcb, NULL, NULL,
+#                   NULL, NULL, NULL, NULL, _gl_dropcb, NULL)
+
+#           elm_drag_item_container_add(gl, ANIM_TIME, DRAG_TIMEOUT,
+#                   _gl_item_getcb, _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.size_hint_weight = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND
+#           gl.size_hint_align = EVAS_HINT_FILL, EVAS_HINT_FILL
+#           elm_box_pack_end(bxx, gl)
+#           gl.show()
+
+#           for (i = 0 i < 20 i++)
+#              {
+#                  snprintf(buf, sizeof(buf), "%s/images/%s", 
elm_app_data_dir_get(), img[(i % 9)])
+#                  const char *path = eina_stringshare_add(buf)
+#                  elm_genlist_item_append(gl, itc1, path, NULL, 
ELM_GENLIST_ITEM_NONE, NULL, NULL)
+#              }
+#       }
+
+#       {
+#           Evas_Object *grid = elm_gengrid_add(win)
+#           evas_object_smart_callback_add(win, "delete,request", _win_del, 
grid)
+#           elm_gengrid_item_size_set(grid,
+#                   elm_config_scale_get() * 150,
+#                   elm_config_scale_get() * 150)
+#           elm_gengrid_horizontal_set(grid, False)
+#           elm_gengrid_reorder_mode_set(grid, False)
+#           elm_gengrid_multi_select_set(grid, True) # We allow multi drag
+#           grid.size_hint_weight = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND
+#           grid.size_hint_align = EVAS_HINT_FILL, EVAS_HINT_FILL
+
+#           gic = elm_gengrid_item_class_new()
+#           gic->item_style = "default"
+#           gic->func.text_get = gl_text_get
+#           gic->func.content_get = gl_content_get
+
+#           elm_drop_item_container_add(grid, ELM_SEL_FORMAT_TARGETS, 
_grid_item_getcb, NULL, NULL,
+#                   NULL, NULL, NULL, NULL, _grid_dropcb, NULL)
+
+#           elm_drag_item_container_add(grid, ANIM_TIME, DRAG_TIMEOUT,
+#                   _grid_item_getcb, _grid_data_getcb)
+#           for (i = 0 i < 20 i++)
+#              {
+#                  snprintf(buf, sizeof(buf), "%s/images/%s", 
elm_app_data_dir_get(), img[(i % 9)])
+#                  const char *path = eina_stringshare_add(buf)
+#                  elm_gengrid_item_append(grid, gic, path, NULL, NULL)
+#              }
+#           elm_box_pack_end(bxx, grid)
+#           grid.show()
+#       }
+
+#     evas_object_resize(win, 680, 800)
+#     win.show()
+
+
+if __name__ == "__main__":
+    elementary.init()
+
+    dnd_genlist_default_anim_clicked(None)
+
+    elementary.run()
+    elementary.shutdown()

-- 


Reply via email to