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:
|
else:
|
||||||
return NULL
|
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 Eina_Bool _py_elm_genlist_item_state_get(void *data, Evas_Object *obj, const char *part) with gil:
|
||||||
cdef:
|
cdef:
|
||||||
GenlistItem item = <GenlistItem>data
|
GenlistItem item = <GenlistItem>data
|
||||||
|
|
|
@ -64,6 +64,7 @@ cdef extern from "Elementary.h":
|
||||||
|
|
||||||
ctypedef char *(*GenlistItemLabelGetFunc) (void *data, Evas_Object *obj, const char *part)
|
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 *(*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 (*GenlistItemStateGetFunc) (void *data, Evas_Object *obj, const char *part)
|
||||||
ctypedef Eina_Bool (*GenlistItemFilterGetFunc) (void *data, Evas_Object *obj, void *key)
|
ctypedef Eina_Bool (*GenlistItemFilterGetFunc) (void *data, Evas_Object *obj, void *key)
|
||||||
ctypedef void (*GenlistItemDelFunc) (void *data, Evas_Object *obj)
|
ctypedef void (*GenlistItemDelFunc) (void *data, Evas_Object *obj)
|
||||||
|
@ -71,6 +72,7 @@ cdef extern from "Elementary.h":
|
||||||
ctypedef struct Elm_Genlist_Item_Class_Func:
|
ctypedef struct Elm_Genlist_Item_Class_Func:
|
||||||
GenlistItemLabelGetFunc text_get
|
GenlistItemLabelGetFunc text_get
|
||||||
GenlistItemIconGetFunc content_get
|
GenlistItemIconGetFunc content_get
|
||||||
|
GenlistItemReusableIconGetFunc reusable_content_get
|
||||||
GenlistItemStateGetFunc state_get
|
GenlistItemStateGetFunc state_get
|
||||||
GenlistItemFilterGetFunc filter_get
|
GenlistItemFilterGetFunc filter_get
|
||||||
GenlistItemDelFunc del_ "del"
|
GenlistItemDelFunc del_ "del"
|
||||||
|
|
|
@ -18,6 +18,7 @@ cdef class GenlistItemClass(object):
|
||||||
Elm_Genlist_Item_Class *cls
|
Elm_Genlist_Item_Class *cls
|
||||||
object _text_get_func
|
object _text_get_func
|
||||||
object _content_get_func
|
object _content_get_func
|
||||||
|
object _reusable_content_get_func
|
||||||
object _state_get_func
|
object _state_get_func
|
||||||
object _filter_get_func
|
object _filter_get_func
|
||||||
object _del_func
|
object _del_func
|
||||||
|
@ -29,6 +30,7 @@ cdef class GenlistItemClass(object):
|
||||||
self.cls = elm_genlist_item_class_new()
|
self.cls = elm_genlist_item_class_new()
|
||||||
self.cls.func.text_get = _py_elm_genlist_item_text_get
|
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.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.state_get = _py_elm_genlist_item_state_get
|
||||||
self.cls.func.filter_get = _py_elm_genlist_item_filter_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
|
# 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,
|
def __init__(self, item_style=None, text_get_func=None,
|
||||||
content_get_func=None, state_get_func=None, del_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,
|
||||||
filter_get_func=None, *args, **kwargs):
|
filter_get_func=None, reusable_content_get_func=None,
|
||||||
|
*args, **kwargs):
|
||||||
|
|
||||||
"""GenlistItemClass constructor.
|
"""GenlistItemClass constructor.
|
||||||
|
|
||||||
|
@ -76,6 +79,14 @@ cdef class GenlistItemClass(object):
|
||||||
and similar. This function should have the signature:
|
and similar. This function should have the signature:
|
||||||
``func(obj, part, item_data)``
|
``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
|
.. note:: In all these signatures, 'obj' means Genlist and
|
||||||
'item_data' is the value given to Genlist item append/prepend
|
'item_data' is the value given to Genlist item append/prepend
|
||||||
methods, it should represent your row model as you want.
|
methods, it should represent your row model as you want.
|
||||||
|
@ -100,6 +111,14 @@ cdef class GenlistItemClass(object):
|
||||||
else:
|
else:
|
||||||
self._content_get_func = self.content_get
|
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 state_get_func is not None:
|
||||||
if callable(state_get_func):
|
if callable(state_get_func):
|
||||||
self._state_get_func = state_get_func
|
self._state_get_func = state_get_func
|
||||||
|
@ -236,6 +255,20 @@ cdef class GenlistItemClass(object):
|
||||||
"""
|
"""
|
||||||
return None
|
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):
|
def state_get(self, evasObject obj, part, item_data):
|
||||||
"""To be called by Genlist for each row to get its state.
|
"""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 Decorate All Mode", "test_genlist_decorate_all", "test_genlist_decorate_all"),
|
||||||
("Genlist Search by Text", "test_genlist_search", "test_genlist_search"),
|
("Genlist Search by Text", "test_genlist_search", "test_genlist_search"),
|
||||||
("Genlist Reorder Mode", "test_genlist_reorder", "test_genlist_reorder"),
|
("Genlist Reorder Mode", "test_genlist_reorder", "test_genlist_reorder"),
|
||||||
|
("Genlist Reusable Contents", "test_genlist_reusable", "test_genlist_reusable"),
|
||||||
]),
|
]),
|
||||||
("Lists - List", [
|
("Lists - List", [
|
||||||
("List", "test_list", "list_clicked"),
|
("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