davemds pushed a commit to branch master.

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

commit 005dd26f73f0a634d16286362b80ce98e2e277a8
Author: Dave Andreoli <d...@gurumeditation.it>
Date:   Wed Jan 20 22:55:43 2016 +0100

    Implemented Genlist filter ability
    
    It is somehow not perfectly working, see TODO for more info
---
 TODO                                       |  4 +-
 doc/elementary/genlist.rst                 |  1 +
 efl/elementary/genlist.pxi                 | 18 +++++++
 efl/elementary/genlist_cdef.pxi            |  3 ++
 efl/elementary/genlist_item_class.pxi      | 27 +++++++++-
 efl/elementary/genlist_widget.pxi          | 38 +++++++++++++-
 examples/elementary/test_genlist_filter.py | 84 ++++++++++++++++++++++++++++++
 7 files changed, 170 insertions(+), 5 deletions(-)

diff --git a/TODO b/TODO
index 516d3c5..4e41a98 100644
--- a/TODO
+++ b/TODO
@@ -3,12 +3,14 @@ BUGS
 ====
 * EdjeEdit: PartState API does not work
 * Elm.Map: overlays_show segfaults, scrollers in examples are jumpy
+* Genlist: "filter,done" event is not always fired (see the genlist_filter.py 
test)
 * Elementary: when we use custom function callbacks we usually leak some
     reference around, some examples:
     - Fileselector.custom_filter_append()
     - Multibuttonentry.format_function_set()
     - Multibuttonentry.filter_append()
     - Multibuttonentry.filterprepend()
+   ... maybe do like is done in genlist filter_set() ??
 
 Failing unit tests
 ------------------
@@ -22,8 +24,6 @@ TODO
   http://www.freedesktop.org/wiki/Software/DBusBindings
   (requires fd.org shell account?)
 * Review the internal functions and name them consistently
-* Evas: SmartObject needs testing
-* Improve ethumb
 * edje: complete the unit tests
 * Initial Evas GL support (for Elm)
 * Add more documentation for callbacks, events, etc.
diff --git a/doc/elementary/genlist.rst b/doc/elementary/genlist.rst
index e6cb8d0..1d1b482 100644
--- a/doc/elementary/genlist.rst
+++ b/doc/elementary/genlist.rst
@@ -348,6 +348,7 @@ Emitted signals
 - ``item,unfocused`` - When the genlist item has lost focus. (since 1.10)
 - ``changed`` - Genlist is now changed their items and properties and all
   calculation is finished. (since 1.16)
+- ``filter,done`` - Genlist filter operation is completed.. (since 1.17)
 
 
 Enumerations
diff --git a/efl/elementary/genlist.pxi b/efl/elementary/genlist.pxi
index 71935a0..d395297 100644
--- a/efl/elementary/genlist.pxi
+++ b/efl/elementary/genlist.pxi
@@ -80,6 +80,24 @@ cdef Eina_Bool _py_elm_genlist_item_state_get(void *data, 
Evas_Object *obj, cons
 
     return ret if ret is not None else 0
 
+cdef Eina_Bool _py_elm_genlist_item_filter_get(void *data, Evas_Object *obj, 
void *key) with gil:
+    cdef:
+        GenlistItem item = <GenlistItem>data
+        object pykey = <object>key
+
+    func = item.item_class._filter_get_func
+    if func is None:
+        return 1
+
+    try:
+        o = object_from_instance(obj)
+        ret = func(o, pykey, item.item_data)
+    except Exception:
+        traceback.print_exc()
+        return 0
+
+    return 1 if ret else 0
+
 cdef void _py_elm_genlist_object_item_del(void *data, Evas_Object *obj) with 
gil:
     cdef GenlistItem item = <GenlistItem>data
 
diff --git a/efl/elementary/genlist_cdef.pxi b/efl/elementary/genlist_cdef.pxi
index c990620..89779d3 100644
--- a/efl/elementary/genlist_cdef.pxi
+++ b/efl/elementary/genlist_cdef.pxi
@@ -64,12 +64,14 @@ cdef extern from "Elementary.h":
     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 struct Elm_Genlist_Item_Class_Func:
         GenlistItemLabelGetFunc text_get
         GenlistItemIconGetFunc content_get
         GenlistItemStateGetFunc state_get
+        GenlistItemFilterGetFunc filter_get
         GenlistItemDelFunc del_ "del"
 
     ctypedef struct Elm_Genlist_Item_Class:
@@ -155,3 +157,4 @@ cdef extern from "Elementary.h":
     Elm_Object_Item *       elm_genlist_nth_item_get(const Evas_Object *obj, 
unsigned int nth)
     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)
+    void                    elm_genlist_filter_set(Evas_Object *obj, void *key)
diff --git a/efl/elementary/genlist_item_class.pxi 
b/efl/elementary/genlist_item_class.pxi
index 06546ba..68875d3 100644
--- a/efl/elementary/genlist_item_class.pxi
+++ b/efl/elementary/genlist_item_class.pxi
@@ -19,6 +19,7 @@ cdef class GenlistItemClass(object):
         object _text_get_func
         object _content_get_func
         object _state_get_func
+        object _filter_get_func
         object _del_func
         object _item_style
         object _decorate_item_style
@@ -29,6 +30,7 @@ cdef class GenlistItemClass(object):
         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
+        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
         self.cls.func.del_ = _py_elm_genlist_object_item_del
 
@@ -39,7 +41,7 @@ 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,
-                 *args, **kwargs):
+                 filter_get_func=None, *args, **kwargs):
 
         """GenlistItemClass constructor.
 
@@ -106,6 +108,14 @@ cdef class GenlistItemClass(object):
         else:
             self._state_get_func = self.state_get
 
+        if filter_get_func is not None:
+            if callable(filter_get_func):
+                self._filter_get_func = filter_get_func
+            else:
+                raise TypeError("filter_get_func is not callable!")
+        else:
+            self._filter_get_func = self.filter_get
+
         if del_func is not None:
             if callable(del_func):
                 self._del_func = del_func
@@ -136,7 +146,7 @@ cdef class GenlistItemClass(object):
     def __repr__(self):
         return ("<%s(%#x, refcount=%d, Elm_Genlist_Item_Class=%#x, "
                 "item_style=%r, text_get_func=%s, content_get_func=%s, "
-                "state_get_func=%s, del_func=%s)>") % \
+                "state_get_func=%s, filter_get_func=%s, del_func=%s)>") % \
                (type(self).__name__,
                 <uintptr_t><void *>self,
                 PY_REFCOUNT(self),
@@ -145,6 +155,7 @@ cdef class GenlistItemClass(object):
                 self._text_get_func,
                 self._content_get_func,
                 self._state_get_func,
+                self._filter_get_func,
                 self._del_func)
 
     def ref(self):
@@ -237,3 +248,15 @@ cdef class GenlistItemClass(object):
         """
         return False
 
+    def filter_get(self, evasObject obj, key, item_data):
+        """To be called by Genlist for each row when filter is enabled.
+
+        :param obj: the Genlist instance
+        :param key: the filter key given in the filter_set function
+        :param item_data: the value given to genlist append/prepend.
+
+        :return: Wheter the item should be visible or not
+        :rtype: bool
+        """
+        return True
+
diff --git a/efl/elementary/genlist_widget.pxi 
b/efl/elementary/genlist_widget.pxi
index 6961255..416678b 100644
--- a/efl/elementary/genlist_widget.pxi
+++ b/efl/elementary/genlist_widget.pxi
@@ -685,7 +685,6 @@ cdef class Genlist(Object):
                     <const char *>pattern if pattern is not None else NULL,
                     flags))
 
-
     property focus_on_selection:
         """
 
@@ -709,6 +708,33 @@ cdef class Genlist(Object):
         def __get__(self):
             return bool(elm_genlist_focus_on_selection_get(self.obj))
 
+    property filter:
+        """ Set filter mode with key.
+
+        This initiates the filter mode of genlist with user/application
+        provided key. If key is None, the filter mode is turned off.
+
+        The given key will be passed back in the filter_get function of
+        the GenlistItemClass
+
+        :type: any python object
+
+        .. versionadded:: 1.17
+
+        """
+        def __set__(self, object key):
+            self.data['__filterkeyref'] = key # keep a reference for key
+            elm_genlist_filter_set(self.obj, <void *>key if key is not None 
else NULL)
+
+        def __get__(self):
+            return self.data['__filterkeyref']
+
+    def filter_set(self, key):
+        self.data['__filterkeyref'] = key
+        elm_genlist_filter_set(self.obj, <void*>key if key is not None else 
NULL)
+    def filter_get(self):
+        return self.data['__filterkeyref']
+
     #
     # Drag and Drop
     # =============
@@ -1070,6 +1096,16 @@ cdef class Genlist(Object):
     def callback_changed_del(self, func):
         self._callback_del("changed", func)
 
+    def callback_filter_done_add(self, func, *args, **kwargs):
+        """Genlist filter operation is completed.
+
+        .. versionadded:: 1.17
+        """
+        self._callback_add("filter,done", func, args, kwargs)
+
+    def callback_filter_done_del(self, func):
+        self._callback_del("filter,done", func)
+
     property scroller_policy:
         """
 
diff --git a/examples/elementary/test_genlist_filter.py 
b/examples/elementary/test_genlist_filter.py
new file mode 100644
index 0000000..7b35491
--- /dev/null
+++ b/examples/elementary/test_genlist_filter.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+# encoding: utf-8
+
+import os
+
+from efl.evas import EXPAND_BOTH, FILL_BOTH, EXPAND_HORIZ, FILL_HORIZ
+
+from efl import elementary as elm
+from efl.elementary import StandardWindow, Box, Entry, Genlist, 
GenlistItemClass
+
+
+names = [
+   "Aaliyah", "Aamir", "Aaralyn", "Aaron", "Abagail",
+   "Babitha", "Bahuratna", "Bandana", "Bulbul", "Cade", "Caldwell",
+   "Chandan", "Caster", "Dagan", "Daulat", "Dag", "Earl", "Ebenzer",
+   "Ellison", "Elizabeth", "Filbert", "Fitzpatrick", "Florian", "Fulton",
+   "Frazer", "Gabriel", "Gage", "Galen", "Garland", "Gauhar", "Hadden",
+   "Hafiz", "Hakon", "Haleem", "Hank", "Hanuman", "Jabali", "Jaimini",
+   "Jayadev", "Jake", "Jayatsena", "Jonathan", "Kamaal", "Jeirk",
+   "Jasper", "Jack", "Mac", "Macy", "Marlon", "Milson"
+]
+
+
+# item class functions
+def gl_text_get(obj, part, item_data):
+    return item_data
+
+def gl_filter_get(obj, key, item_data):
+    print('"%s" -> "%s"' % (item_data, key))
+    if not key:
+        return True
+    if key.lower() in item_data.lower():
+        return True
+    return False
+
+
+def entry_changed_cb(en, gl):
+    gl.filter = en.text or None
+
+
+def test_genlist_filter(parent):
+    win = StandardWindow("genlist-filter", "Genlist Filter", autodel=True,
+                         size=(420, 600), focus_highlight_enabled=True)
+
+    # main vertical box
+    box = Box(win, size_hint_expand=EXPAND_BOTH)
+    win.resize_object_add(box)
+    box.show()
+
+    
+    # the Genlist widget
+    gl = Genlist(win, mode=elm.ELM_LIST_COMPRESS, homogeneous=True,
+                 select_mode=elm.ELM_OBJECT_SELECT_MODE_ALWAYS,
+                 size_hint_expand=EXPAND_BOTH, size_hint_fill=FILL_BOTH)
+    gl.callback_filter_done_add(lambda g: print("filter,done"))
+    gl.show()
+    box.pack_end(gl)
+
+    itc = GenlistItemClass(item_style="default",
+                           text_get_func=gl_text_get,
+                           filter_get_func=gl_filter_get)
+
+    for i in range(500):
+        gl.item_append(itc, names[i % len(names)])
+
+
+    # the entry
+    en = Entry(box, single_line=True,
+               size_hint_expand=EXPAND_HORIZ, size_hint_fill=FILL_HORIZ)
+    en.part_text_set('guide', 'Type here to filter items')
+    en.callback_changed_user_add(entry_changed_cb, gl)
+    box.pack_start(en)
+    en.show()
+
+
+    #
+    win.show()
+    en.focus = True
+
+
+if __name__ == "__main__":
+    elm.policy_set(elm.ELM_POLICY_QUIT, elm.ELM_POLICY_QUIT_LAST_WINDOW_CLOSED)
+    test_genlist_filter(None)
+    elm.run()

-- 


Reply via email to