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