From de6fd9f832154ff6e711326e8cc1bf4095ba5655 Mon Sep 17 00:00:00 2001 From: Kai Huuhko Date: Wed, 24 Apr 2013 18:44:19 +0000 Subject: [PATCH] Elementary: Use genlist_item_class functions to manage the class struct, improve item handling by using class attributes instead of the params tuple. --- doc/elementary/module-genlist.rst | 5 +- efl/elementary/genlist.pxd | 11 +- efl/elementary/genlist.pyx | 72 ++++++------ efl/elementary/genlist_item.pxi | 152 ++++++++++++++------------ efl/elementary/genlist_item_class.pxi | 38 ++++--- 5 files changed, 157 insertions(+), 121 deletions(-) diff --git a/doc/elementary/module-genlist.rst b/doc/elementary/module-genlist.rst index 9f143b4..e4d1de3 100644 --- a/doc/elementary/module-genlist.rst +++ b/doc/elementary/module-genlist.rst @@ -1,8 +1,11 @@ :mod:`genlist` Module ------------------------- +--------------------- .. automodule:: efl.elementary.genlist + Reference + --------- + .. inheritance-diagram:: efl.elementary.genlist :parts: 2 diff --git a/efl/elementary/genlist.pxd b/efl/elementary/genlist.pxd index 178cc1c..e67bc15 100644 --- a/efl/elementary/genlist.pxd +++ b/efl/elementary/genlist.pxd @@ -55,6 +55,12 @@ cdef extern from "Elementary.h": int elm_genlist_item_index_get(Elm_Object_Item *it) void elm_genlist_realized_items_update(Evas_Object *obj) unsigned int elm_genlist_items_count(Evas_Object *obj) + + Elm_Genlist_Item_Class *elm_genlist_item_class_new() + void elm_genlist_item_class_free(Elm_Genlist_Item_Class *itc) + void elm_genlist_item_class_ref(Elm_Genlist_Item_Class *itc) + void elm_genlist_item_class_unref(Elm_Genlist_Item_Class *itc) + void elm_genlist_item_tooltip_text_set(Elm_Object_Item *item, const_char *text) void elm_genlist_item_tooltip_content_cb_set(Elm_Object_Item *item, Elm_Tooltip_Item_Content_Cb func, void *data, Evas_Smart_Cb del_cb) void elm_genlist_item_tooltip_unset(Elm_Object_Item *item) @@ -69,6 +75,7 @@ cdef extern from "Elementary.h": const_char * elm_genlist_item_cursor_style_get(Elm_Object_Item *item) void elm_genlist_item_cursor_engine_only_set(Elm_Object_Item *item, Eina_Bool engine_only) Eina_Bool elm_genlist_item_cursor_engine_only_get(Elm_Object_Item *item) + void elm_genlist_homogeneous_set(Evas_Object *obj, Eina_Bool homogeneous) Eina_Bool elm_genlist_homogeneous_get(Evas_Object *obj) void elm_genlist_block_count_set(Evas_Object *obj, int n) @@ -76,6 +83,7 @@ cdef extern from "Elementary.h": void elm_genlist_longpress_timeout_set(Evas_Object *obj, double timeout) double elm_genlist_longpress_timeout_get(Evas_Object *obj) Elm_Object_Item * elm_genlist_at_xy_item_get(Evas_Object *obj, Evas_Coord x, Evas_Coord y, int *posret) + Elm_Object_Item * elm_genlist_item_parent_get(Elm_Object_Item *it) void elm_genlist_item_subitems_clear(Elm_Object_Item *item) void elm_genlist_item_expanded_set(Elm_Object_Item *item, Eina_Bool expanded) @@ -87,6 +95,7 @@ cdef extern from "Elementary.h": void elm_genlist_item_fields_update(Elm_Object_Item *item, const_char *parts, Elm_Genlist_Item_Field_Type itf) void elm_genlist_item_decorate_mode_set(Elm_Object_Item *it, const_char *decorate_it_type, Eina_Bool decorate_it_set) const_char * elm_genlist_item_decorate_mode_get(Elm_Object_Item *it) + Elm_Object_Item * elm_genlist_decorated_item_get(Evas_Object *obj) void elm_genlist_reorder_mode_set(Evas_Object *obj, Eina_Bool reorder_mode) Eina_Bool elm_genlist_reorder_mode_get(Evas_Object *obj) @@ -106,7 +115,7 @@ cdef extern from "Elementary.h": cdef class GenlistItemClass(object): cdef: - Elm_Genlist_Item_Class cls + Elm_Genlist_Item_Class *cls object _text_get_func object _content_get_func object _state_get_func diff --git a/efl/elementary/genlist.pyx b/efl/elementary/genlist.pyx index 2081ef2..cc172a0 100644 --- a/efl/elementary/genlist.pyx +++ b/efl/elementary/genlist.pyx @@ -549,18 +549,17 @@ ELM_SCROLLER_POLICY_OFF = enums.ELM_SCROLLER_POLICY_OFF cdef char *_py_elm_genlist_item_text_get(void *data, Evas_Object *obj, const_char *part) with gil: cdef: - GenlistItem item = data - GenlistItemClass itc = item.params[0] + GenlistItem item = data unicode u = _ctouni(part) - func = itc._text_get_func + func = item.itc._text_get_func if func is None: return NULL try: o = object_from_instance(obj) - ret = func(o, u, item.params[1]) - except Exception as e: + ret = func(o, u, item.item_data) + except: traceback.print_exc() return NULL @@ -572,27 +571,26 @@ cdef char *_py_elm_genlist_item_text_get(void *data, Evas_Object *obj, const_cha cdef Evas_Object *_py_elm_genlist_item_content_get(void *data, Evas_Object *obj, const_char *part) with gil: cdef: - GenlistItem item = data - GenlistItemClass itc = item.params[0] + GenlistItem item = data unicode u = _ctouni(part) evasObject icon - func = itc._content_get_func + func = item.itc._content_get_func if func is None: return NULL + o = object_from_instance(obj) + try: - o = object_from_instance(obj) - ret = func(o, u, item.params[1]) - except Exception as e: + icon = func(o, u, item.item_data) + except: traceback.print_exc() return NULL - if ret is not None: + if icon is not None: try: - icon = ret return icon.obj - except Exception as e: + except: traceback.print_exc() return NULL else: @@ -600,18 +598,17 @@ cdef Evas_Object *_py_elm_genlist_item_content_get(void *data, Evas_Object *obj, cdef Eina_Bool _py_elm_genlist_item_state_get(void *data, Evas_Object *obj, const_char *part) with gil: cdef: - GenlistItem item = data - GenlistItemClass itc = item.params[0] + GenlistItem item = data unicode u = _ctouni(part) - func = itc._state_get_func + func = item.itc._state_get_func if func is None: return 0 try: o = object_from_instance(obj) - ret = func(o, u, item.params[1]) - except Exception as e: + ret = func(o, u, item.item_data) + except: traceback.print_exc() return 0 @@ -619,52 +616,53 @@ cdef Eina_Bool _py_elm_genlist_item_state_get(void *data, Evas_Object *obj, cons cdef void _py_elm_genlist_object_item_del(void *data, Evas_Object *obj) with gil: cdef GenlistItem item = data - cdef GenlistItemClass itc if item is None: return - itc = item.params[0] + func = item.itc._del_func - func = itc._del_func if func is not None: try: o = object_from_instance(obj) - func(o, item.params[1]) - except Exception as e: + func(o, item.item_data) + except: traceback.print_exc() + item._unset_obj() Py_DECREF(item) cdef void _py_elm_genlist_item_func(void *data, Evas_Object *obj, void *event_info) with gil: cdef GenlistItem item = data - cdef object func = item.params[2] + cdef object func = item.cb_func if func is not None: try: o = object_from_instance(obj) - func(item, o, item.params[3]) - except Exception as e: + func(item, o, item.func_data) + except: traceback.print_exc() cdef int _py_elm_genlist_compare_func(const_void *data1, const_void *data2) with gil: - cdef Elm_Object_Item *citem1 = data1 - cdef Elm_Object_Item *citem2 = data2 - cdef object func + cdef: + Elm_Object_Item *citem1 = data1 + Elm_Object_Item *citem2 = data2 + GenlistItem item1 = elm_object_item_data_get(citem1) + GenlistItem item2 = elm_object_item_data_get(citem2) + object func - item1 = elm_object_item_data_get(citem1) - item2 = elm_object_item_data_get(citem2) - - func = item1.comparison_func - - if func is None: + if item1.comparison_func is not None: + func = item1.comparison_func + elif item2.comparison_func is not None: + func = item2.comparison_func + else: return 0 ret = func(item1, item2) if ret is not None: try: return ret - except Exception as e: + except: traceback.print_exc() return 0 else: diff --git a/efl/elementary/genlist_item.pxi b/efl/elementary/genlist_item.pxi index 04b8433..27a5988 100644 --- a/efl/elementary/genlist_item.pxi +++ b/efl/elementary/genlist_item.pxi @@ -3,19 +3,16 @@ cdef class GenlistItem(ObjectItem): """An item for the :py:class:`Genlist` widget.""" cdef: - Elm_Genlist_Item_Class *item_class + GenlistItemClass itc Elm_Object_Item *parent_item int flags - Evas_Smart_Cb cb - object comparison_func + object comparison_func, item_data, func_data - def __init__( self, - GenlistItemClass item_class not None, - item_data=None, - GenlistItem parent_item=None, - Elm_Genlist_Item_Type flags=enums.ELM_GENLIST_ITEM_NONE, - func=None, - func_data=None): + def __init__(self, + GenlistItemClass item_class not None, item_data=None, + GenlistItem parent_item=None, + Elm_Genlist_Item_Type flags=enums.ELM_GENLIST_ITEM_NONE, + func=None, func_data=None): """Create a new GenlistItem. :param item_data: Data that defines the model of this row. @@ -49,7 +46,7 @@ cdef class GenlistItem(ObjectItem): """ - self.item_class = &item_class.cls + self.itc = item_class self.parent_item = _object_item_from_python(parent_item) if parent_item is not None else NULL @@ -58,11 +55,15 @@ cdef class GenlistItem(ObjectItem): if func is not None: if not callable(func): raise TypeError("func is not None or callable") - self.cb = _py_elm_genlist_item_func - self.params = (item_class, item_data, func, func_data) + self.item_data = item_data + self.cb_func = func + self.func_data = func_data - cdef int _set_obj(self, Elm_Object_Item *item, params=None) except 0: + def __dealloc__(self): + self.parent_item = NULL + + cdef int _set_obj(self, Elm_Object_Item *item) except 0: assert self.item == NULL, "Object must be clean" self.item = item Py_INCREF(self) @@ -74,21 +75,21 @@ cdef class GenlistItem(ObjectItem): def __str__(self): return "%s(item_class=%s, func=%s, item_data=%s)" % \ - (self.__class__.__name__, - self.params[0].__class__.__name__, - self.params[2], - self.params[1]) + (type(self).__name__, + type(self.itc).__name__, + self.cb_func, + self.item_data) def __repr__(self): return ("%s(%#x, refcount=%d, Elm_Object_Item=%#x, " "item_class=%s, func=%s, item_data=%r)") % \ - (self.__class__.__name__, + (type(self).__name__, self, PY_REFCOUNT(self), self.item, - self.params[0].__class__.__name__, - self.params[2], - self.params[1]) + type(self.itc).__name__, + self.cb_func, + self.item_data) def append_to(self, GenlistWidget genlist not None): """append_to(Genlist genlist) -> GenlistItem @@ -100,15 +101,18 @@ cdef class GenlistItem(ObjectItem): :rtype: :py:class:`GenlistItem` """ - cdef Elm_Object_Item *item + cdef: + Elm_Object_Item *item + Evas_Smart_Cb cb = NULL - item = elm_genlist_item_append( genlist.obj, - self.item_class, - self, - self.parent_item, - self.flags, - self.cb, - self) + if self.cb_func is not None: + cb = _py_elm_genlist_item_func + + item = elm_genlist_item_append(genlist.obj, + self.itc.cls, self, + self.parent_item, + self.flags, + cb, self) if item is not NULL: self._set_obj(item) @@ -127,15 +131,18 @@ cdef class GenlistItem(ObjectItem): :rtype: :py:class:`GenlistItem` """ - cdef Elm_Object_Item *item + cdef: + Elm_Object_Item *item + Evas_Smart_Cb cb = NULL + + if self.cb_func is not None: + cb = _py_elm_genlist_item_func item = elm_genlist_item_prepend(genlist.obj, - self.item_class, - self, - self.parent_item, - self.flags, - self.cb, - self) + self.itc.cls, self, + self.parent_item, + self.flags, + cb, self) if item is not NULL: self._set_obj(item) @@ -155,19 +162,21 @@ cdef class GenlistItem(ObjectItem): :rtype: :py:class:`GenlistItem` """ - cdef Elm_Object_Item *item, *before + cdef: + Elm_Object_Item *item, *before + GenlistWidget genlist = before_item.widget + Evas_Smart_Cb cb = NULL + + if self.cb_func is not None: + cb = _py_elm_genlist_item_func - genlist = before_item.widget before = _object_item_from_python(before_item) - item = elm_genlist_item_insert_before( genlist.obj, - self.item_class, - self, - self.parent_item, - before, - self.flags, - self.cb, - self) + item = elm_genlist_item_insert_before(genlist.obj, + self.itc.cls, self, + self.parent_item, before, + self.flags, + cb, self) if item is not NULL: self._set_obj(item) @@ -187,19 +196,21 @@ cdef class GenlistItem(ObjectItem): :rtype: :py:class:`GenlistItem` """ - cdef Elm_Object_Item *item, *after + cdef: + Elm_Object_Item *item, *after + GenlistWidget genlist = after_item.widget + Evas_Smart_Cb cb = NULL + + if self.cb_func is not None: + cb = _py_elm_genlist_item_func - genlist = after_item.widget after = _object_item_from_python(after_item) - item = elm_genlist_item_insert_after( genlist.obj, - self.item_class, - self, - self.parent_item, - after, - self.flags, - self.cb, - self) + item = elm_genlist_item_insert_after(genlist.obj, + self.itc.cls, self, + self.parent_item, after, + self.flags, + cb, self) if item is not NULL: self._set_obj(item) @@ -232,21 +243,24 @@ cdef class GenlistItem(ObjectItem): to compare. """ - cdef Elm_Object_Item *item + cdef: + Elm_Object_Item *item + Evas_Smart_Cb cb = NULL + + if self.cb_func is not None: + cb = _py_elm_genlist_item_func if comparison_func is not None: if not callable(comparison_func): raise TypeError("func is not None or callable") self.comparison_func = comparison_func - item = elm_genlist_item_sorted_insert( genlist.obj, - self.item_class, - self, - self.parent_item, - self.flags, - _py_elm_genlist_compare_func, - self.cb, - self) + item = elm_genlist_item_sorted_insert(genlist.obj, + self.itc.cls, self, + self.parent_item, + self.flags, + _py_elm_genlist_compare_func, + cb, self) if item is not NULL: self._set_obj(item) @@ -258,10 +272,10 @@ cdef class GenlistItem(ObjectItem): property data: """User data for the item.""" def __get__(self): - return self.params[1] + return self.item_data def data_get(self): - return self.params[1] + return self.item_data property next: """This returns the item placed after the ``item``, on the container @@ -365,7 +379,7 @@ cdef class GenlistItem(ObjectItem): :type itc: :py:class:`GenlistItemClass` """ - elm_genlist_item_item_class_update(self.item, &itc.cls) + elm_genlist_item_item_class_update(self.item, itc.cls) #TODO: def item_class_get(self): """This returns the Genlist_Item_Class for the given item. It can be diff --git a/efl/elementary/genlist_item_class.pxi b/efl/elementary/genlist_item_class.pxi index 18a0d68..797b8d8 100644 --- a/efl/elementary/genlist_item_class.pxi +++ b/efl/elementary/genlist_item_class.pxi @@ -14,25 +14,26 @@ cdef class GenlistItemClass(object): """ # In pxd: - # Elm_Genlist_Item_Class cls - # object _text_get_func - # object _content_get_func - # object _state_get_func - # object _del_func - # object _item_style - # object _decorate_item_style - # object _decorate_all_item_style + # Elm_Genlist_Item_Class *cls + # object _text_get_func, _content_get_func, _state_get_func, _del_func + # object _item_style, _decorate_item_style, _decorate_all_item_style def __cinit__(self): + self.cls = elm_genlist_item_class_new() self.cls.func.text_get = _py_elm_genlist_item_text_get self.cls.func.content_get = _py_elm_genlist_item_content_get self.cls.func.state_get = _py_elm_genlist_item_state_get - # TODO: Check if the struct member is named del_ + # In C the struct member is del but we rename it to del_ in pxd self.cls.func.del_ = _py_elm_genlist_object_item_del + def __dealloc__(self): + elm_genlist_item_class_free(self.cls) + self.cls = NULL + def __init__(self, item_style=None, text_get_func=None, content_get_func=None, state_get_func=None, del_func=None, - decorate_item_style=None, decorate_all_item_style=None): + decorate_item_style=None, decorate_all_item_style=None, + *args, **kwargs): """GenlistItemClass constructor. @@ -45,7 +46,7 @@ cdef class GenlistItemClass(object): purpose is to return the label string to be used by a given part and row. This function should have the signature: - ``func(obj, part, item_data) -> str`` + ``func(obj, part, item_data) -> string`` :param content_get_func: if provided will override the behavior defined by :py:func:`content_get()` in this class. Its purpose is @@ -65,13 +66,12 @@ cdef class GenlistItemClass(object): defined by ``delete()`` in this class. Its purpose is to be called when row is deleted, thus finalizing resouces and similar. This function should have the signature: - ``func(obj, part, item_data) -> str`` + ``func(obj, part, item_data)`` .. note:: In all these signatures, 'obj' means Genlist and 'item_data' is the value given to Genlist item append/prepend methods, it should represent your row model as you want. """ - # # Use argument if found, else a function that was defined by child # class, or finally the fallback function defined in this class. @@ -151,6 +151,18 @@ cdef class GenlistItemClass(object): self._state_get_func, self._del_func) + def ref(self): + """Increase the C level reference count.""" + elm_genlist_item_class_ref(self.cls) + + def unref(self): + """Decrease the C level reference count.""" + elm_genlist_item_class_unref(self.cls) + + def free(self): + """Free the C level struct.""" + elm_genlist_item_class_free(self.cls) + property item_style: """The style of this item class.""" def __get__(self):