New 1.18 API: elm Genlist reusable content functionality
with a FAILING test (failing also in C) (I love to implement broken stuff)
This commit is contained in:
parent
99113cd990
commit
c11a7cf227
|
@ -62,6 +62,30 @@ cdef Evas_Object *_py_elm_genlist_item_content_get(void *data, Evas_Object *obj,
|
|||
else:
|
||||
return NULL
|
||||
|
||||
cdef Evas_Object *_py_elm_genlist_item_reusable_content_get(void *data, Evas_Object *obj, const char *part, Evas_Object *old) with gil:
|
||||
cdef:
|
||||
GenlistItem item = <GenlistItem>data
|
||||
unicode u = _ctouni(part)
|
||||
evasObject icon
|
||||
|
||||
func = item.item_class._reusable_content_get_func
|
||||
if func is None:
|
||||
return NULL
|
||||
|
||||
o = object_from_instance(obj)
|
||||
old_content = object_from_instance(old)
|
||||
|
||||
try:
|
||||
icon = func(o, u, item.item_data, old_content)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
return NULL
|
||||
|
||||
if icon is not None:
|
||||
return icon.obj
|
||||
else:
|
||||
return NULL
|
||||
|
||||
cdef Eina_Bool _py_elm_genlist_item_state_get(void *data, Evas_Object *obj, const char *part) with gil:
|
||||
cdef:
|
||||
GenlistItem item = <GenlistItem>data
|
||||
|
|
|
@ -62,15 +62,17 @@ cdef extern from "Elementary.h":
|
|||
pass
|
||||
|
||||
|
||||
ctypedef char *(*GenlistItemLabelGetFunc) (void *data, Evas_Object *obj, const char *part)
|
||||
ctypedef Evas_Object *(*GenlistItemIconGetFunc) (void *data, Evas_Object *obj, const char *part)
|
||||
ctypedef Eina_Bool (*GenlistItemStateGetFunc) (void *data, Evas_Object *obj, const char *part)
|
||||
ctypedef Eina_Bool (*GenlistItemFilterGetFunc) (void *data, Evas_Object *obj, void *key)
|
||||
ctypedef void (*GenlistItemDelFunc) (void *data, Evas_Object *obj)
|
||||
ctypedef char *(*GenlistItemLabelGetFunc) (void *data, Evas_Object *obj, const char *part)
|
||||
ctypedef Evas_Object *(*GenlistItemIconGetFunc) (void *data, Evas_Object *obj, const char *part)
|
||||
ctypedef Evas_Object *(*GenlistItemReusableIconGetFunc)(void *data, Evas_Object *obj, const char *part, Evas_Object *old)
|
||||
ctypedef Eina_Bool (*GenlistItemStateGetFunc) (void *data, Evas_Object *obj, const char *part)
|
||||
ctypedef Eina_Bool (*GenlistItemFilterGetFunc) (void *data, Evas_Object *obj, void *key)
|
||||
ctypedef void (*GenlistItemDelFunc) (void *data, Evas_Object *obj)
|
||||
|
||||
ctypedef struct Elm_Genlist_Item_Class_Func:
|
||||
GenlistItemLabelGetFunc text_get
|
||||
GenlistItemIconGetFunc content_get
|
||||
GenlistItemReusableIconGetFunc reusable_content_get
|
||||
GenlistItemStateGetFunc state_get
|
||||
GenlistItemFilterGetFunc filter_get
|
||||
GenlistItemDelFunc del_ "del"
|
||||
|
|
|
@ -18,6 +18,7 @@ cdef class GenlistItemClass(object):
|
|||
Elm_Genlist_Item_Class *cls
|
||||
object _text_get_func
|
||||
object _content_get_func
|
||||
object _reusable_content_get_func
|
||||
object _state_get_func
|
||||
object _filter_get_func
|
||||
object _del_func
|
||||
|
@ -29,6 +30,7 @@ cdef class GenlistItemClass(object):
|
|||
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.reusable_content_get = _py_elm_genlist_item_reusable_content_get
|
||||
self.cls.func.state_get = _py_elm_genlist_item_state_get
|
||||
self.cls.func.filter_get = _py_elm_genlist_item_filter_get
|
||||
# In C the struct member is del but we rename it to del_ in pxd
|
||||
|
@ -41,7 +43,8 @@ cdef class GenlistItemClass(object):
|
|||
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,
|
||||
filter_get_func=None, *args, **kwargs):
|
||||
filter_get_func=None, reusable_content_get_func=None,
|
||||
*args, **kwargs):
|
||||
|
||||
"""GenlistItemClass constructor.
|
||||
|
||||
|
@ -76,6 +79,14 @@ cdef class GenlistItemClass(object):
|
|||
and similar. This function should have the signature:
|
||||
``func(obj, part, item_data)``
|
||||
|
||||
:param reusable_content_get_func: if provided will override the behavior
|
||||
defined by :py:func:`reusable_content_get()` in this class.
|
||||
Its purpose is to return the icon object to be used (swallowed) by a
|
||||
given part and row. This can be used to reuse (cache) contents
|
||||
(since 1.18)
|
||||
This function should have the signature:
|
||||
``func(obj, part, item_data, old_content) -> obj``
|
||||
|
||||
.. 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.
|
||||
|
@ -100,6 +111,14 @@ cdef class GenlistItemClass(object):
|
|||
else:
|
||||
self._content_get_func = self.content_get
|
||||
|
||||
if reusable_content_get_func is not None:
|
||||
if callable(reusable_content_get_func):
|
||||
self._reusable_content_get_func = reusable_content_get_func
|
||||
else:
|
||||
raise TypeError("reusable_content_get_func is not callable!")
|
||||
else:
|
||||
self._reusable_content_get_func = self.reusable_content_get
|
||||
|
||||
if state_get_func is not None:
|
||||
if callable(state_get_func):
|
||||
self._state_get_func = state_get_func
|
||||
|
@ -236,6 +255,20 @@ cdef class GenlistItemClass(object):
|
|||
"""
|
||||
return None
|
||||
|
||||
def reusable_content_get(self, evasObject obj, part, item_data, old_content):
|
||||
"""To be called by Genlist for each row to get its icon.
|
||||
|
||||
:param obj: the Genlist instance
|
||||
:param part: the part that is being handled.
|
||||
:param item_data: the value given to genlist append/prepend.
|
||||
:param old_content: the old (if available) content that can be used
|
||||
instead of creating a new object every time.
|
||||
|
||||
:return: icon object to be used and swallowed.
|
||||
:rtype: evas Object or None
|
||||
"""
|
||||
return None
|
||||
|
||||
def state_get(self, evasObject obj, part, item_data):
|
||||
"""To be called by Genlist for each row to get its state.
|
||||
|
||||
|
|
|
@ -181,6 +181,7 @@ items = [
|
|||
("Genlist Decorate All Mode", "test_genlist_decorate_all", "test_genlist_decorate_all"),
|
||||
("Genlist Search by Text", "test_genlist_search", "test_genlist_search"),
|
||||
("Genlist Reorder Mode", "test_genlist_reorder", "test_genlist_reorder"),
|
||||
("Genlist Reusable Contents", "test_genlist_reusable", "test_genlist_reusable"),
|
||||
]),
|
||||
("Lists - List", [
|
||||
("List", "test_list", "list_clicked"),
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
|
||||
from efl.evas import EXPAND_BOTH, EXPAND_HORIZ, FILL_BOTH
|
||||
from efl import elementary as elm
|
||||
|
||||
|
||||
class MyItemClass(elm.GenlistItemClass):
|
||||
def __init__(self):
|
||||
elm.GenlistItemClass.__init__(self, item_style='default')
|
||||
|
||||
def text_get(self, obj, part, item_data):
|
||||
return 'Item # %i' % item_data
|
||||
|
||||
def content_get(self, obj, part, item_data):
|
||||
if part == 'elm.swallow.icon':
|
||||
return elm.Icon(obj, standard='user-home')
|
||||
if part == 'elm.swallow.end':
|
||||
print('Creating NEW content for item #%d' % item_data)
|
||||
txt = '<warning>Content for item %i</warning>' % item_data
|
||||
return elm.Label(obj, text=txt)
|
||||
return None
|
||||
|
||||
def reusable_content_get(self, obj, part, item_data, old_content):
|
||||
if part == 'elm.swallow.end' and old_content:
|
||||
if obj.data['reusable_enabled'] == True:
|
||||
print('REUSING content for item # %i' % item_data)
|
||||
return old_content
|
||||
return None
|
||||
|
||||
itc = MyItemClass()
|
||||
|
||||
|
||||
def check_changed_cb(ck, gl):
|
||||
gl.data['reusable_enabled'] = ck.state
|
||||
gl.realized_items_update()
|
||||
|
||||
def test_genlist_reusable(parent):
|
||||
win = elm.StandardWindow('GenlistReusable', 'Genlist Reusable Contents',
|
||||
size=(400, 400), autodel=True)
|
||||
|
||||
# main vertical box
|
||||
box = elm.Box(win, size_hint_weight=EXPAND_BOTH)
|
||||
win.resize_object_add(box)
|
||||
box.show()
|
||||
|
||||
# info frame
|
||||
fr = elm.Frame(win, text='Information', size_hint_expand=EXPAND_HORIZ,
|
||||
size_hint_fill=FILL_BOTH)
|
||||
fr.content = elm.Label(fr, text='Numbers on the left should always match the one on the right')
|
||||
box.pack_end(fr)
|
||||
fr.show()
|
||||
|
||||
# genlist
|
||||
gl = elm.Genlist(win, homogeneous=True, mode=elm.ELM_LIST_COMPRESS,
|
||||
size_hint_expand=EXPAND_BOTH, size_hint_fill=FILL_BOTH)
|
||||
box.pack_end(gl)
|
||||
for i in range(0, 2000):
|
||||
gl.item_append(itc, i)
|
||||
gl.show()
|
||||
gl.data['reusable_enabled'] = True
|
||||
|
||||
# buttons
|
||||
ck = elm.Check(win, text='Enable reusable contents', state=True)
|
||||
ck.callback_changed_add(check_changed_cb, gl)
|
||||
box.pack_end(ck)
|
||||
ck.show()
|
||||
|
||||
win.show()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
elm.policy_set(elm.ELM_POLICY_QUIT, elm.ELM_POLICY_QUIT_LAST_WINDOW_CLOSED)
|
||||
test_genlist_reusable(None)
|
||||
elm.run()
|
Loading…
Reference in New Issue