davemds pushed a commit to branch master.

http://git.enlightenment.org/bindings/python/python-efl.git/commit/?id=c11a7cf227d6f07ef8ca166f11fc649037708e1c

commit c11a7cf227d6f07ef8ca166f11fc649037708e1c
Author: Dave Andreoli <[email protected]>
Date:   Tue Aug 9 15:39:35 2016 +0200

    New 1.18 API: elm Genlist reusable content functionality
    
    with a FAILING test (failing also in C)
    
    (I love to implement broken stuff)
---
 efl/elementary/genlist.pxi                   | 24 +++++++++
 efl/elementary/genlist_cdef.pxi              | 12 +++--
 efl/elementary/genlist_item_class.pxi        | 35 ++++++++++++-
 examples/elementary/test.py                  |  1 +
 examples/elementary/test_genlist_reusable.py | 76 ++++++++++++++++++++++++++++
 5 files changed, 142 insertions(+), 6 deletions(-)

diff --git a/efl/elementary/genlist.pxi b/efl/elementary/genlist.pxi
index 2a2d78f..5ba857d 100644
--- a/efl/elementary/genlist.pxi
+++ b/efl/elementary/genlist.pxi
@@ -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
diff --git a/efl/elementary/genlist_cdef.pxi b/efl/elementary/genlist_cdef.pxi
index 0476ffb..d76fd05 100644
--- a/efl/elementary/genlist_cdef.pxi
+++ b/efl/elementary/genlist_cdef.pxi
@@ -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"
diff --git a/efl/elementary/genlist_item_class.pxi 
b/efl/elementary/genlist_item_class.pxi
index 68875d3..950f219 100644
--- a/efl/elementary/genlist_item_class.pxi
+++ b/efl/elementary/genlist_item_class.pxi
@@ -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.
 
diff --git a/examples/elementary/test.py b/examples/elementary/test.py
index f2e984d..f66f0d3 100755
--- a/examples/elementary/test.py
+++ b/examples/elementary/test.py
@@ -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"),
diff --git a/examples/elementary/test_genlist_reusable.py 
b/examples/elementary/test_genlist_reusable.py
new file mode 100644
index 0000000..8d83904
--- /dev/null
+++ b/examples/elementary/test_genlist_reusable.py
@@ -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()

-- 


Reply via email to