kuuko pushed a commit to branch master. http://git.enlightenment.org/bindings/python/python-efl.git/commit/?id=3a26675680731a5f94f5790416f3236ab4bb454e
commit 3a26675680731a5f94f5790416f3236ab4bb454e Author: Kai Huuhko <kai.huu...@gmail.com> Date: Sat Nov 16 09:01:31 2013 +0200 Elementary: Convert more of the C DnD examples to Python. --- efl/elementary/cnp_callbacks.pxi | 11 +- efl/elementary/gengrid.pyx | 111 ++++++ efl/utils/conversions.pyx | 5 + examples/elementary/test_dnd.py | 804 +++++++++++++++++---------------------- 4 files changed, 467 insertions(+), 464 deletions(-) diff --git a/efl/elementary/cnp_callbacks.pxi b/efl/elementary/cnp_callbacks.pxi index 0683bdf..7e5c08f 100644 --- a/efl/elementary/cnp_callbacks.pxi +++ b/efl/elementary/cnp_callbacks.pxi @@ -193,7 +193,6 @@ cdef Evas_Object *py_elm_drag_icon_create_cb( :since: 1.8 """ - print("in drag_icon_create_cb") assert data != NULL, "data is NULL" cdef: @@ -248,7 +247,6 @@ cdef void py_elm_drag_done_cb(void *data, Evas_Object *obj, Eina_Bool accepted) :since: 1.8 """ - print("in drag_done_cb") assert data != NULL, "data is NULL" cdef: @@ -332,7 +330,6 @@ 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: @@ -416,21 +413,19 @@ cdef Eina_Bool py_elm_item_container_data_get_cb( :return: Returns EINA_TRUE, if successful, or EINA_FALSE if not. """ - print("in item_container_data_get_cb") - cdef: - DragUserInfo ret + DragUserInfo ret = DragUserInfo.__new__(DragUserInfo) 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) + func = o.data["item_container_data_get_cb"] + func(o, item, ret) 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) diff --git a/efl/elementary/gengrid.pyx b/efl/elementary/gengrid.pyx index 115e111..d6d7ad1 100644 --- a/efl/elementary/gengrid.pyx +++ b/efl/elementary/gengrid.pyx @@ -277,6 +277,7 @@ Items' scroll to types """ include "tooltips.pxi" +include "cnp_callbacks.pxi" from libc.string cimport strdup from cpython cimport Py_INCREF, Py_DECREF, PyUnicode_AsUTF8String @@ -1551,6 +1552,116 @@ cdef class Gengrid(Object): ret = elm_gengrid_at_xy_item_get(self.obj, x, y, &xposret, &yposret) return _object_item_to_python(ret), xposret, yposret + + # + # 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 + + self.data["item_container_data_get_cb"] = data_get + + 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 + + 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 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, func, *args, **kwargs) diff --git a/efl/utils/conversions.pyx b/efl/utils/conversions.pyx index b8d1d84..b62dc67 100644 --- a/efl/utils/conversions.pyx +++ b/efl/utils/conversions.pyx @@ -124,6 +124,11 @@ cdef Eina_List *python_list_objects_to_eina_list(list objects): cdef: Eina_List *lst = NULL Eo o + + if objects is None: + return NULL + for o in objects: lst = eina_list_append(lst, o.obj) + return lst diff --git a/examples/elementary/test_dnd.py b/examples/elementary/test_dnd.py index 00fd250..8545d2b 100644 --- a/examples/elementary/test_dnd.py +++ b/examples/elementary/test_dnd.py @@ -3,6 +3,8 @@ import os +from efl.ecore import Timer, ECORE_CALLBACK_CANCEL, ECORE_CALLBACK_RENEW, \ + AnimatorTimeline from efl.evas import EVAS_HINT_EXPAND, EVAS_HINT_FILL, \ EVAS_ASPECT_CONTROL_VERTICAL, EVAS_CALLBACK_MOUSE_MOVE, \ EVAS_CALLBACK_MOUSE_UP, EVAS_CALLBACK_MOUSE_DOWN, \ @@ -16,6 +18,9 @@ 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, DragUserInfo +from efl.elementary.gengrid import Gengrid, GengridItemClass +from efl.elementary.configuration import Configuration +conf = Configuration() EXPAND_BOTH = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND FILL_BOTH = EVAS_HINT_FILL, EVAS_HINT_FILL @@ -35,25 +40,25 @@ img = ( "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 +class AnimIconSt: + start_x = 0 + start_y = 0 + 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 DRAG_TIMEOUT = 0.3 ANIM_TIME = 0.5 -class DndItemClass(GenlistItemClass): +class DndGenlistItemClass(GenlistItemClass): def text_get(self, obj, part, data, *args): return data @@ -65,39 +70,48 @@ class DndItemClass(GenlistItemClass): return icon return None -itc1 = DndItemClass() +itc1 = DndGenlistItemClass() + +class DndGengridItemClass(GengridItemClass): + def text_get(self, obj, part, data, *args): + return data + + def content_get(self, obj, part, data, *args): + if part == "elm.swallow.icon": + icon = Icon(obj, file=os.path.join(img_path, data), + size_hint_aspect=(EVAS_ASPECT_CONTROL_VERTICAL, 1, 1)) + icon.show() + return icon + return None + +gic = DndGengridItemClass() def win_del(obj, data): print("will del <%s>" % 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 gli, yposret = gl.at_xy_item_get(x, y) if gli is not None: - print("over <%s>, gli=<%s> yposret %i" % (gli.part_text_get("elm.text"), gli, yposret)) + print("over <%s>, gli=%r yposret=%i" % ( + gli.part_text_get("elm.text"), gli, yposret)) else: - print("over none, yposret %i" % yposret) + print("over none, yposret=%i" % 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 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)) + else: + print("over none, xposret=%i yposret=%i", xposret, yposret) + return item, xposret, yposret def gl_dropcb(obj, it, ev, xposret, yposret, data): # This function is called when data is dropped on the genlist @@ -119,167 +133,135 @@ def gl_dropcb(obj, it, ev, xposret, yposret, data): 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) + 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) + obj.item_append(itc1, wh0rd, flags=ELM_GENLIST_ITEM_NONE) else: return False 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 grid_dropcb(obj, it, ev, xposret, yposret, data): + # This function is called when data is dropped on the gengrid + if ev.data is None: + return False + + p = ev.data + + wh0rdlist = p.split("#") + + wh0rdlist.pop(0) + wh0rdlist.pop() + + for wh0rd in wh0rdlist: + print("Item %s" % wh0rd) + + if not it: + it = obj.last_item + + if it: + it = obj.item_insert_after(gic, wh0rd, after_item=it) + else: + it = obj.item_append(gic, wh0rd) + + return True + +def anim_st_free(anim_st): + # Stops and free mem of ongoing animation + if anim_st is not None: + anim_st.gl.event_callback_del( + EVAS_CALLBACK_MOUSE_MOVE, gl_obj_mouse_move) + anim_st.gl.event_callback_del( + EVAS_CALLBACK_MOUSE_UP, gl_obj_mouse_up) + if anim_st.tm is not None: + anim_st.tm.delete() + anim_st.tm = None + + if anim_st.ea is not None: + anim_st.ea.delete() + anim_st.ea = None + + for st in anim_st.icons: + st.o.delete() + +def drag_anim_play(pos, anim_st): + # Impl of the animation of icons, called on frame time + + 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(anim_st): + # Start icons animation before actually drag-starts + yposret = 0 + + items = list(anim_st.gl.selected_items) + gli, yposret = anim_st.gl.at_xy_item_get(anim_st.mdx, anim_st.mdy) + 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) + + for gli in items: + # Now add icons to animation window + o = gli.part_content_get("elm.swallow.icon") + + if o is not None: + st = AnimIconSt() + ic = Icon(anim_st.gl, file=o.file, size_hint_align=FILL_BOTH, + size_hint_weight=EXPAND_BOTH, pos=o.pos, size=o.size) + st.start_x, st.start_y = o.pos + ic.show() + + st.o = ic + anim_st.icons.append(st) + + anim_st.tm = None + anim_st.ea = AnimatorTimeline(drag_anim_play, DRAG_TIMEOUT, + anim_st) + + return ECORE_CALLBACK_CANCEL + +def gl_obj_mouse_up(obj, event_info, data): + # Cancel any drag waiting to start on timeout + anim_st_free(data) + +def gl_obj_mouse_move(obj, event_info, data): + # Cancel any drag waiting to start on timeout + if event_info.event_flags & EVAS_EVENT_FLAG_ON_HOLD: + print("event on hold") + anim_st_free(data) + +def gl_obj_mouse_down(obj, event_info, data): + # Launch a timer to start drag animation + anim_st = DragAnimSt() + anim_st.e = obj.evas + anim_st.mdx = event_info.position.canvas.x + anim_st.mdy = event_info.position.canvas.y + anim_st.gl = data + anim_st.tm = Timer(DRAG_TIMEOUT, gl_anim_start, anim_st) + data.event_callback_add(EVAS_CALLBACK_MOUSE_UP, + gl_obj_mouse_up, anim_st) + data.event_callback_add(EVAS_CALLBACK_MOUSE_MOVE, + gl_obj_mouse_move, anim_st) + # END - Handling drag start animation def gl_dragdone(obj, doaccept, data): if doaccept: @@ -288,7 +270,6 @@ def gl_dragdone(obj, doaccept, data): it.delete() def gl_createicon(win, xoff, yoff, data): - #print("<%s> <%d>\n", __func__, __LINE__) it = data o = it.part_content_get("elm.swallow.icon") @@ -315,12 +296,10 @@ def gl_createicon(win, xoff, yoff, data): return icon, xoff, yoff -def gl_icons_get(data): +def gl_icons_get(gl): # Start icons animation before actually drag-starts - gl = data yposret = 0 - icons = [] xm, ym = gl.evas.pointer_canvas_xy @@ -374,54 +353,35 @@ def gl_get_drag_data(gl, it): return drag_data, items -# 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): +def grid_get_drag_data(gg, it): + # Construct a string of dragged info, user frees returned string + drag_data = None + + items = list(gg.selected_items) + if it is not None: + # Add the item mouse is over to the list if NOT seleced + if not it in items: + items.append(it) + + if items is not None: + # 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("Sending <%s>" % drag_data) + + return drag_data, items + +def gl_dnd_default_anim_data_getcb(gl, it, info): # This called before starting to drag, mouse-down was on it - info = DragUserInfo() info.format = ELM_SEL_FORMAT_TARGETS info.createicon = gl_createicon info.createdata = it @@ -439,85 +399,68 @@ def gl_dnd_default_anim_data_getcb(gl, it): else: return -# 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 gl_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 + 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, info.donecbdata = gl_get_drag_data(gl, it) + info.acceptdata = info.donecbdata + + if info.data is not None: + return True + else: + return False + +def grid_icons_get(grid): + # Start icons animation before actually drag-starts + + xposret, yposret = 0, 0 + icons = [] + + 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 + o = gli.part_content_get("elm.swallow.icon") + + if o is not None: + ic = Icon(grid, file=o.file, pos=o.pos, size=o.size, + size_hint_align=FILL_BOTH, size_hint_weight=EXPAND_BOTH) + ic.show() + icons.append(ic) + + return icons + +def grid_data_getcb(grid, it, 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(grid) + 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, info.donecbdata = grid_get_drag_data(grid, it) + info.acceptdata = info.donecbdata + + if info.data: + return True + else: + return False def dnd_genlist_default_anim_clicked(obj, item=None): win = StandardWindow("dnd-genlist-default-anim", @@ -533,11 +476,11 @@ def dnd_genlist_default_anim_clicked(obj, item=None): # 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.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) + 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 @@ -546,146 +489,93 @@ def dnd_genlist_default_anim_clicked(obj, item=None): bxx.pack_end(gl) gl.show() - #itc1 = DndItemClass() - for i in range (20): gl.item_append(itc1, img[i % 9], flags=ELM_GENLIST_ITEM_NONE) 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() +def dnd_genlist_user_anim_clicked(obj, item=None): + win = StandardWindow("dnd-genlist-user-anim", "DnD-Genlist-User-Anim", + autodel=True, size=(680,800)) + + bxx = Box(win, horizontal=True, size_hint_weight=EXPAND_BOTH) + win.resize_object_add(bxx) + bxx.show() + + for j in range(2): + 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) + + # 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) + bxx.pack_end(gl) + gl.show() + + for i in range(20): + gl.item_append(itc1, img[i % 9], flags=ELM_GENLIST_ITEM_NONE) + + win.show() + +def dnd_genlist_gengrid_clicked(obj, item=None): + win = StandardWindow("dnd-genlist-gengrid", "DnD-Genlist-Gengrid", + autodel=True, size=(680,800)) + + bxx = Box(win, horizontal=True, size_hint_weight=EXPAND_BOTH) + win.resize_object_add(bxx) + bxx.show() + + gl = Genlist(win, multi_select=True, + size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) + win.callback_delete_request_add(win_del, gl) + + # START Drag and Drop handling + 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) + # 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) + bxx.pack_end(gl) + gl.show() + + for i in range(20): + gl.item_append(itc1, img[i % 9], flags=ELM_GENLIST_ITEM_NONE) + + grid = Gengrid(win, item_size=(conf.scale * 150, conf.scale * 150), + horizontal=False, reorder_mode=False, multi_select=True, + size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) + win.callback_delete_request_add(win_del, grid) + + grid.drop_item_container_add(ELM_SEL_FORMAT_TARGETS, grid_item_getcb, + dropcb=grid_dropcb) + + grid.drag_item_container_add(ANIM_TIME, DRAG_TIMEOUT, grid_item_getcb, + grid_data_getcb) + + for i in range(20): + grid.item_append(gic, img[i % 9]) + + bxx.pack_end(grid) + grid.show() + + win.show() if __name__ == "__main__": @@ -710,6 +600,8 @@ if __name__ == "__main__": items = [ ("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), ] li = List(win, size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH) --