[gnome-music/wip/gbsneto/flowbox: 1/7] albums: optimize select/unselect all



commit e88ddd92e865b2ee30ab74ab6182656b8cfe1c11
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Wed Aug 10 22:51:22 2016 -0300

    albums: optimize select/unselect all
    
    Iterating over all the albums and changing the ::active
    property would send hundreds of notify::active signals,
    which in turn makes it go in and out of Python to C to
    Python in a way that makes the UI freeze for a second.
    
    Fix that by blocking all these signals and updating the
    list of selected items manually.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=760164

 gnomemusic/view.py |   22 +++++++++++++++++++++-
 1 files changed, 21 insertions(+), 1 deletions(-)
---
diff --git a/gnomemusic/view.py b/gnomemusic/view.py
index 865ba4f..6221b5e 100644
--- a/gnomemusic/view.py
+++ b/gnomemusic/view.py
@@ -368,6 +368,7 @@ class Albums(ViewContainer):
         self.player = player
         self.add(self._albumWidget)
         self.albums_selected = []
+        self.all_items = []
         self.items_selected = []
         self.items_selected_callback = None
         self._add_list_renderers()
@@ -466,6 +467,10 @@ class Albums(ViewContainer):
         self.window.notification.set_timeout(0)
 
         if item:
+            # Store all items to optimize 'Select All' action
+            self.all_items.append(item)
+
+            # Add to the flowbox
             child = self._create_album_item(item)
             self.view.add(child)
         elif remaining == 0:
@@ -494,7 +499,9 @@ class Albums(ViewContainer):
                                self._on_album_event_triggered,
                                child)
 
-        child.check.connect('notify::active', self._on_child_toggled, child)
+        child.check_handler_id = child.check.connect('notify::active',
+                                                     self._on_child_toggled,
+                                                     child)
 
         child.check.bind_property('visible', self, 'selection_mode',
                                   GObject.BindingFlags.BIDIRECTIONAL)
@@ -544,15 +551,28 @@ class Albums(ViewContainer):
                 self.items_selected_callback(self.items_selected)
 
     def _toggle_all_selection(self, selected):
+        """
+        Selects or unselects all items without sending the notify::active
+        signal for performance purposes.
+        """
         for child in self.view.get_children():
+            GObject.signal_handler_block(child.check, child.check_handler_id)
+
+            # Set the checkbutton state without emiting the signal
             child.check.set_active(selected)
 
+            GObject.signal_handler_unblock(child.check, child.check_handler_id)
+
+        self.update_header_from_selection(len(self.albums_selected))
+
     @log
     def select_all(self):
+        self.albums_selected = list(self.all_items)
         self._toggle_all_selection(True)
 
     @log
     def unselect_all(self):
+        self.albums_selected = []
         self._toggle_all_selection(False)
 
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]