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