kuuko pushed a commit to branch master.

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

commit 87ee22d55910144f13a0048c2ebfbfe7d07b1420
Author: Kai Huuhko <kai.huu...@gmail.com>
Date:   Thu Oct 10 05:42:39 2013 +0300

    Elementary: DnD work
    
     - Genlist default animation test functional
     - Some callbacks are still missing
---
 efl/elementary/cnp_callbacks.pxi  | 150 +++++++++++++++++++++++++++++++++++-
 efl/elementary/genlist_widget.pxi |  13 +++-
 examples/elementary/test_dnd.py   | 157 +++++++++++++++++---------------------
 3 files changed, 223 insertions(+), 97 deletions(-)

diff --git a/efl/elementary/cnp_callbacks.pxi b/efl/elementary/cnp_callbacks.pxi
index 958bbb6..c41c86e 100644
--- a/efl/elementary/cnp_callbacks.pxi
+++ b/efl/elementary/cnp_callbacks.pxi
@@ -1,5 +1,6 @@
 from efl.elementary.enums cimport Elm_Sel_Type, Elm_Sel_Format, \
     Elm_Xdnd_Action
+from efl.utils.conversions cimport python_list_objects_to_eina_list
 
 cdef extern from "Elementary.h":
     struct _Elm_Selection_Data:
@@ -78,7 +79,7 @@ cdef class SelectionData(object):
     property data:
         def __get__(self):
             # TODO: void *
-            return None
+            return <const_char *>self.sel_data.data
 
     property len:
         """:type: size_t"""
@@ -103,6 +104,8 @@ cdef Eina_Bool py_elm_drop_cb(void *data, Evas_Object *obj, 
Elm_Selection_Data *
     :param ev: struct holding information about selected data
 
     """
+    print("in drop_cb")
+    assert data != NULL, "data is NULL"
     cdef:
         SelectionData sd = SelectionData.__new__(SelectionData)
         bint ret
@@ -146,10 +149,10 @@ cdef Elm_Object_Item *py_elm_xy_item_get_cb(Evas_Object 
*obj, Evas_Coord x, Evas
 
     if xpos1 is not None:
         xpos2 = xpos1
-        xposret = &xpos2
+        xposret[0] = xpos2
     if ypos1 is not None:
         ypos2 = ypos1
-        yposret = &ypos2
+        yposret[0] = ypos2
 
     return it.item
 
@@ -181,6 +184,40 @@ cdef Evas_Object *py_elm_drag_icon_create_cb(
 
     """
     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
+
+    if xoff != NULL:
+        xoff1 = xoff[0]
+    if yoff != NULL:
+        yoff1 = yoff[0]
+
+    try:
+        ret = createicon(win1, xoff1, yoff1, createdata)
+    except:
+        traceback.print_exc()
+        return NULL
+
+    if ret is None:
+        return NULL
+
+    icon, xoff1, yoff1 = ret
+
+    if xoff1 is not None:
+        xoff2 = xoff1
+        xoff[0] = xoff2
+    if yoff1 is not None:
+        yoff2 = yoff1
+        yoff[0] = yoff2
+
+    return icon.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
@@ -192,6 +229,28 @@ cdef void py_elm_drag_state_cb(void *data, Evas_Object 
*obj) with gil:
     """
     print("in drag_state_cb")
 
+cdef void py_elm_drag_done_cb(void *data, Evas_Object *obj, Eina_Bool 
accepted) with gil:
+    """Callback called when a drag is finished.
+
+    @param data Application specific data
+    @param obj The object where the drag started
+    @param accepted TRUE if the droppped-data is accepted on drop
+    :since: 1.8
+
+    """
+    print("in drag_done_cb")
+    assert data != NULL, "data is NULL"
+
+    cdef:
+        evasObject o = object_from_instance(obj)
+
+    donecb, donedata = <object>data
+
+    try:
+        donecb(o, <bint>accepted, donedata)
+    except:
+        traceback.print_exc()
+
 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
 
@@ -215,7 +274,17 @@ cdef void py_elm_drag_pos_cb(void *data, Evas_Object *obj,
 
     """
     print("in drag_pos_cb")
+    assert data != NULL, "data is NULL"
 
+    cdef:
+        evasObject o = object_from_instance(obj)
+
+    dragpos, dragdata = <object>data
+
+    try:
+        dragpos(o, x, y, action, dragdata)
+    except:
+        traceback.print_exc()
 
 cdef void py_elm_drag_item_container_pos(
     void *data, Evas_Object *cont, Elm_Object_Item *it,
@@ -254,7 +323,26 @@ cdef Eina_Bool py_elm_drop_item_container_cb(
 
     """
     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)
+        SelectionData evdata = SelectionData.__new__(SelectionData)
+        object cbdata = None
+
+    evdata.sel_data = ev
+
+    cb = o.data["drop_item_container_cb"]
+
+    if data != NULL:
+        cbdata = <object>data
 
+    try:
+        ret = cb(o, item, evdata, xposret, yposret, cbdata)
+    except:
+        traceback.print_exc()
+        return 0
 
 cdef class DragUserInfo(object):
     """
@@ -277,8 +365,21 @@ cdef class DragUserInfo(object):
     @param donecbdata Application data to pass to @p dragdone (output)
 
     """
+    cdef:
+        public Elm_Sel_Format format
+        public Elm_Xdnd_Action action
+        public list icons
+        public object createicon, createdata, dragpos, dragdata
+        public object acceptcb, acceptdata, dragdone, donecbdata
+        const_char *_data
+
+    property data:
+        def __get__(self):
+            return _ctouni(self._data)
 
-    cdef Elm_Drag_User_Info *info
+        def __set__(self, value):
+            if isinstance(value, unicode): value = 
PyUnicode_AsUTF8String(value)
+            self._data = value
 
     # Elm_Sel_Format format;
     # const char *data;
@@ -306,3 +407,44 @@ cdef Eina_Bool py_elm_item_container_data_get_cb(
 
     """
     print("in item_container_data_get_cb")
+
+    cdef:
+        DragUserInfo ret
+        evasObject o = object_from_instance(obj)
+        ObjectItem item = _object_item_to_python(it)
+
+    try:
+        ret = <DragUserInfo?>o.data["item_container_data_get_cb"](o, item)
+    except:
+        traceback.print_exc()
+        return 0
+
+    if ret is not None:
+        print("populating info")
+        info.format = ret.format
+        info.data = ret._data
+        info.icons = python_list_objects_to_eina_list(ret.icons)
+        if ret.createicon is not None:
+            info.createicon = py_elm_drag_icon_create_cb
+            createdata = (ret.createicon, ret.createdata)
+            Py_INCREF(createdata)
+            info.createdata = <void *>createdata
+        if ret.dragpos is not None:
+            info.dragpos = py_elm_drag_pos_cb
+            dragdata = (ret.dragpos, ret.dragdata)
+            Py_INCREF(dragdata)
+            info.dragdata = <void *>dragdata
+        if ret.acceptcb is not None:
+            info.acceptcb = py_elm_drag_accept_cb
+            acceptdata = (ret.acceptcb, ret.acceptdata)
+            Py_INCREF(acceptdata)
+            info.acceptdata = <void *>acceptdata
+        if ret.dragdone is not None:
+            info.dragdone =py_elm_drag_done_cb
+            donecbdata = (ret.dragdone, ret.donecbdata)
+            Py_INCREF(donecbdata)
+            info.donecbdata = <void *>donecbdata
+        return 1
+    else:
+        print("ret is None")
+        return 0
diff --git a/efl/elementary/genlist_widget.pxi 
b/efl/elementary/genlist_widget.pxi
index d3fac26..1530a4f 100644
--- a/efl/elementary/genlist_widget.pxi
+++ b/efl/elementary/genlist_widget.pxi
@@ -694,6 +694,8 @@ cdef class Genlist(Object):
                 raise TypeError("itemgetcb must be callable.")
             self.data["xy_item_get_cb"] = itemgetcb
 
+        self.data["item_container_data_get_cb"] = data_get
+
         if not elm_drag_item_container_add(self.obj,
             tm_to_anim,
             tm_to_drag,
@@ -742,17 +744,20 @@ cdef class Genlist(Object):
                 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,
+            <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,
+            <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,
+            <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):
+            <void *>cbdata if cbdata is not None else NULL):
             raise RuntimeError
 
     def drop_item_container_del(self):
diff --git a/examples/elementary/test_dnd.py b/examples/elementary/test_dnd.py
index 9053b8f..f989aa5 100644
--- a/examples/elementary/test_dnd.py
+++ b/examples/elementary/test_dnd.py
@@ -7,7 +7,7 @@ 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
+    ELM_SEL_FORMAT_TARGETS, ELM_GENLIST_ITEM_NONE, DragUserInfo
 
 img = (
     "panel_01.jpg",
@@ -39,19 +39,12 @@ img = (
 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":
+        if part == "elm.swallow.icon":
             icon = Icon(obj)
             icon.file = data
             icon.size_hint_aspect = evas.EVAS_ASPECT_CONTROL_VERTICAL, 1, 1
@@ -59,8 +52,10 @@ class DndItemClass(GenlistItemClass):
             return icon
         return None
 
+itc1 = DndItemClass()
+
 def win_del(obj, data):
-    #print("<%s> <%d> will del <%p>\n", __func__, __LINE__, data)
+    print("will del <%s>" % data)
     data.drop_item_container_del()
     data.drag_item_container_del()
 
@@ -73,12 +68,11 @@ def win_del(obj, data):
 
 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))
+        print("over <%s>, gli=<%s> yposret %i" % 
(gli.part_text_get("elm.text"), gli, yposret))
     else:
-        print("over none, yposret %i\n", yposret)
+        print("over none, yposret %i" % yposret)
     return gli, None, yposret
 
 # def grid_item_getcb(obj, x, y, int *xposret, int *yposret):
@@ -92,42 +86,33 @@ def gl_item_getcb(gl, x, y):
 #         print("over none, xposret %i yposret %i\n", *xposret, *yposret)
 #     return item
 
-def gl_dropcb(data, obj, it,
-    ev, # Elm_Selection_Data *
-    xposret, yposret):
+def gl_dropcb(obj, it, ev, xposret, yposret, data):
     # 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
+    wh0rdlist = p.split("#")
+
+    wh0rdlist.pop(0)
+    wh0rdlist.pop()
+
+    for wh0rd in wh0rdlist:
+        print("Item %s" % wh0rd)
+
+        if yposret == -1:
+            obj.item_insert_before(itc1, wh0rd, before_item=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, wh0rd, after_item=it, 
flags=ELM_GENLIST_ITEM_NONE)
+            else:
+                it = obj.item_append(itc1, wh0rd, flags=ELM_GENLIST_ITEM_NONE)
         else:
-            p = None
+            return False
 
     return True
 
@@ -284,44 +269,43 @@ def gl_dropcb(data, obj, it,
 # # 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):
+def gl_createicon(win, xoff, yoff, data):
     #print("<%s> <%d>\n", __func__, __LINE__)
     it = data
     o = it.part_content_get("elm.swallow.icon")
 
-    if o is not None:
-        w = h = 30
+    if o is None:
+        return
 
-        f, g = o.file
+    w = h = 30
 
-        xm, ym = o.evas.pointer_canvas_xy
+    f, g = o.file
 
-        if xoff is not None:
-            xoff = xm - (w/2)
-        if yoff is not None:
-            yoff = ym - (h/2)
+    xm, ym = o.evas.pointer_canvas_xy
 
-        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:
+        xoff = xm - (w/2)
+    if yoff is not None:
+        yoff = ym - (h/2)
 
-        if xoff is not None and yoff is not None:
-            icon.move(xoff, yoff)
-        icon.resize(w, h)
+    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
 
-    return icon
+    if (xoff is not None) and (yoff is not None):
+        icon.move(xoff, yoff)
+    icon.resize(w, h)
+
+    return icon, xoff, yoff
 
 def gl_icons_get(data):
     # Start icons animation before actually drag-starts
-    #print("<%s> <%d>\n", __func__, __LINE__)
     gl = data
 
     yposret = 0
@@ -329,18 +313,17 @@ def gl_icons_get(data):
     icons = []
 
     xm, ym = gl.evas.pointer_canvas_xy
-    items = gl.selected_items
-    gli = gl.at_xy_item_get(xm, ym, yposret)
+    items = list(gl.selected_items)
+    gli, yposret = gl.at_xy_item_get(xm, ym)
 
     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)
+        if not gli in items:
+            items.append(gli)
 
-    for gli in items:
+    for it in items:
         # Now add icons to animation window
-        o = gli.part_content_get("elm.swallow.icon")
+        o = it.part_content_get("elm.swallow.icon")
 
         if o is not None:
             f, g = o.file
@@ -356,22 +339,19 @@ def gl_icons_get(data):
 
             icons.append(ic)
 
-    eina_list_free(items)
     return icons
 
-def gl_get_drag_data(gl, it, items):
+def gl_get_drag_data(gl, it):
     # Construct a string of dragged info, user frees returned string
     drag_data = None
-    #print("<%s> <%d>\n", __func__, __LINE__)
 
-    items = gl.selected_items
+    items = list(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 not it in items:
+            items.append(it)
 
-    if items:
+    if items is not None:
         # Now we can actually compose string to send and start dragging
         drag_data = "file://"
 
@@ -383,9 +363,9 @@ def gl_get_drag_data(gl, it, items):
 
         drag_data += "#"
 
-        #print("<%s> <%d> Sending <%s>\n", __func__, __LINE__, drag_data)
+        print("Sending <%s>" % drag_data)
 
-    return drag_data
+    return drag_data, items
 
 # def grid_get_drag_data(gg, it, Eina_List **items):
 #     # Construct a string of dragged info, user frees returned string
@@ -432,26 +412,25 @@ def gl_get_drag_data(gl, it, items):
 
 #     return drag_data
 
-def gl_dnd_default_anim_data_getcb(gl, it,
-        info # Elm_Drag_User_Info *
-    ):
+def gl_dnd_default_anim_data_getcb(gl, it):
     # This called before starting to drag, mouse-down was on it
+    info = DragUserInfo()
     info.format = ELM_SEL_FORMAT_TARGETS
-    info.createicon = _gl_createicon
+    info.createicon = gl_createicon
     info.createdata = it
-    info.icons = _gl_icons_get(obj)
-    info.dragdone = _gl_dragdone
+    info.icons = gl_icons_get(gl)
+    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.data, info.donecbdata = gl_get_drag_data(gl, it)
+
     info.acceptdata = info.donecbdata
 
     if info.data is not None:
-        return True
+        return info
     else:
-        return False
+        return
 
 # def gl_data_getcb(gl,  it,
 #         Elm_Drag_User_Info *info):
@@ -563,7 +542,7 @@ def dnd_genlist_default_anim_clicked(*args):
         bxx.pack_end(gl)
         gl.show()
 
-        itc1 = DndItemClass()
+        #itc1 = DndItemClass()
 
         for i in range (20):
             gl.item_append(itc1, "images/{0}".format(img[i % 9]), 
flags=ELM_GENLIST_ITEM_NONE)

-- 


Reply via email to