diff cagou/core/utils.py @ 196:519b3a29743c

utils, plugin file sharing: new utils module, with a FilterBehavior: FilterBehavior do a smooth animation for filtering out children of a layout according to a text content.
author Goffi <goffi@goffi.org>
date Wed, 23 May 2018 21:25:08 +0200
parents
children 9faccd140119
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cagou/core/utils.py	Wed May 23 21:25:08 2018 +0200
@@ -0,0 +1,73 @@
+#!/usr//bin/env python2
+# -*- coding: utf-8 -*-
+
+# Cagou: desktop/mobile frontend for Salut à Toi XMPP client
+# Copyright (C) 2016-2018 Jérôme Poisson (goffi@goffi.org)
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""misc utils/behaviors"""
+
+
+from kivy.animation import Animation
+
+
+class FilterBehavior(object):
+    """class to handle items filtering with animation"""
+
+    def __init__(self, *args, **kwargs):
+        super(FilterBehavior, self).__init__(*args, **kwargs)
+        self._filter_last = u''
+        self._filter_anim = Animation(width = 0,
+                                      height = 0,
+                                      opacity = 0,
+                                      d = 0.5)
+
+    def do_filter(self, children, text, get_child_text, width_cb, height_cb, continue_tests=None):
+        """filter the children
+
+        filtered children will have a animation to set width, height and opacity to 0
+        @param children(kivy.uix.widget.Widget): widgets to filter
+        @param text(unicode): filter text (if this text is not present in a child,
+            the child is filtered out)
+        @param get_child_text(callable): must retrieve child text
+            child is used as sole argument
+        @param width_cb(callable, int, None): method to retrieve width when opened
+            child is used as sole argument, int can be used instead of callable
+        @param height_cb(callable, int, None): method to retrieve height when opened
+            child is used as sole argument, int can be used instead of callable
+        @param continue_tests(list[callable]): list of test to skip the item
+            all callables take child as sole argument.
+            if any of the callable return True, the child is skipped (i.e. not filtered)
+        """
+        text = text.strip().lower()
+        filtering = len(text)>len(self._filter_last)
+        self._filter_last = text
+        for child in self.layout.children:
+            if continue_tests is not None and any([t(child) for t in continue_tests]):
+                continue
+            if text in get_child_text(child).lower():
+                self._filter_anim.cancel(child)
+                for key, method in (('width', width_cb),
+                                    ('height', height_cb),
+                                    ('opacity', lambda c: 1)):
+                    try:
+                        setattr(child, key, method(child))
+                    except TypeError:
+                        # method is not a callable, must be an int
+                        setattr(child, key, method)
+            elif (filtering
+                  and child.opacity > 0
+                  and not self._filter_anim.have_properties_to_animate(child)):
+                self._filter_anim.start(child)