[gnome-music/wip/jfelder/albumview-rubberband: 15/16] albumsview: Add rubberband selection



commit 9d0445640494031f43648868318b4f593cfc2194
Author: Jean Felder <jfelder src gnome org>
Date:   Wed Jan 8 18:15:41 2020 +0100

    albumsview: Add rubberband selection
    
    Rubberband selection is natively handled by the FlowBox. It only needs
    to be in SelectionMode multiple.
    There are two ways to activate rubberband selection:
    - Ctrl + long left button press, if not in selection mode
    - long left button press in selection mode
    
    Once an initial selection has been made, rubberband selection has the
    following behavior:
    * holding ctrl inverts the selection state
    * not holding ctrl creates a new selection
    
    AlbumCover does not need to listen to the "button-release-event" event
    anymore. It is now handled by the GtkGestureLongPress of the
    AlbumsView's flowbox.
    
    The cover labels style need to be updated to prevent a color change
    when an AlbumCover enters the selected state.
    
    Closes: #83
    Related: #146

 data/org.gnome.Music.css         |  5 +++++
 data/ui/AlbumCover.ui            |  1 -
 data/ui/AlbumsView.ui            |  7 +++++++
 gnomemusic/views/albumsview.py   | 41 +++++++++++++++++++++++++++++++++++++++-
 gnomemusic/widgets/albumcover.py | 15 +--------------
 5 files changed, 53 insertions(+), 16 deletions(-)
---
diff --git a/data/org.gnome.Music.css b/data/org.gnome.Music.css
index ea1c3cbe..ee821f79 100644
--- a/data/org.gnome.Music.css
+++ b/data/org.gnome.Music.css
@@ -3,8 +3,13 @@
 }
 
 /* AlbumCover */
+.albumcover-title-label {
+    color: @theme_fg_color;
+}
+
 .albumcover-artist-label {
     font-size: smaller;
+    color: @theme_fg_color;
 }
 
 /* By default in Adwaita dark this is not transparent */
diff --git a/data/ui/AlbumCover.ui b/data/ui/AlbumCover.ui
index 46d21b3c..b9ef7a27 100644
--- a/data/ui/AlbumCover.ui
+++ b/data/ui/AlbumCover.ui
@@ -19,7 +19,6 @@
               <object class="GtkEventBox" id="_events">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <signal name="button-release-event" handler="_on_album_event" swapped="no"/>
                 <child>
                   <object class="CoverStack" id="_cover_stack">
                     <property name="visible">True</property>
diff --git a/data/ui/AlbumsView.ui b/data/ui/AlbumsView.ui
index cb7828fc..031b3f90 100644
--- a/data/ui/AlbumsView.ui
+++ b/data/ui/AlbumsView.ui
@@ -18,6 +18,7 @@
             <property name="selection-mode">none</property>
             <property name="valign">start</property>
             <property name="visible">True</property>
+            <signal name="selected-children-changed" handler="_on_selected_children_changed" swapped="no"/>
             <style>
               <class name="content-view"/>
             </style>
@@ -26,4 +27,10 @@
       </object>
     </child>
   </template>
+  <object class="GtkGestureLongPress" id="_flowbox_long_press">
+    <property name="propagation-phase">capture</property>
+    <property name="widget">_flowbox</property>
+    <signal name="begin" handler="_on_flowbox_press_begin" swapped="no"/>
+    <signal name="cancel" handler="_on_flowbox_press_cancel" swapped="no"/>
+  </object>
 </interface>
diff --git a/gnomemusic/views/albumsview.py b/gnomemusic/views/albumsview.py
index 9f8bb095..e479fec5 100644
--- a/gnomemusic/views/albumsview.py
+++ b/gnomemusic/views/albumsview.py
@@ -25,7 +25,7 @@
 import math
 
 from gettext import gettext as _
-from gi.repository import GLib, GObject, Gtk
+from gi.repository import Gdk, GLib, GObject, Gtk
 
 from gnomemusic.widgets.headerbar import HeaderBar
 from gnomemusic.widgets.albumcover import AlbumCover
@@ -46,6 +46,7 @@ class AlbumsView(Gtk.Stack):
 
     _scrolled_window = Gtk.Template.Child()
     _flowbox = Gtk.Template.Child()
+    _flowbox_long_press = Gtk.Template.Child()
 
     def __init__(self, application, player=None):
         """Initialize AlbumsView
@@ -63,9 +64,12 @@ class AlbumsView(Gtk.Stack):
         self._adjustment_timeout_id = None
         self._viewport = self._scrolled_window.get_child()
         self._widget_counter = 1
+        self._ctrl_hold = False
 
         model = self._window._app.props.coremodel.props.albums_sort
         self._flowbox.bind_model(model, self._create_widget)
+        self._flowbox.set_hadjustment(self._scrolled_window.get_hadjustment())
+        self._flowbox.set_vadjustment(self._scrolled_window.get_vadjustment())
         self._flowbox.connect("child-activated", self._on_child_activated)
 
         self.bind_property(
@@ -201,6 +205,41 @@ class AlbumsView(Gtk.Stack):
         self._headerbar.props.title = corealbum.props.title
         self._headerbar.props.subtitle = corealbum.props.artist
 
+    @Gtk.Template.Callback()
+    def _on_flowbox_press_begin(self, gesture, sequence):
+        event = gesture.get_last_event(sequence)
+        ok, state = event.get_state()
+        if ((ok is True
+             and state == Gdk.ModifierType.CONTROL_MASK)
+                or self.props.selection_mode is True):
+            self._flowbox.props.selection_mode = Gtk.SelectionMode.MULTIPLE
+            if state == Gdk.ModifierType.CONTROL_MASK:
+                self._ctrl_hold = True
+
+    @Gtk.Template.Callback()
+    def _on_flowbox_press_cancel(self, gesture, sequence):
+        self._flowbox.props.selection_mode = Gtk.SelectionMode.NONE
+
+    @Gtk.Template.Callback()
+    def _on_selected_children_changed(self, flowbox):
+        if self._flowbox.props.selection_mode == Gtk.SelectionMode.NONE:
+            return
+
+        if self.props.selection_mode is False:
+            self.props.selection_mode = True
+
+        with self._window._app.props.coreselection.freeze_notify():
+            if self._ctrl_hold is False:
+                self.deselect_all()
+            for child in self._flowbox.get_selected_children():
+                if self._ctrl_hold is True:
+                    child.props.selected = not child.props.selected
+                else:
+                    child.props.selected = True
+
+        self._ctrl_hold = False
+        self._flowbox.props.selection_mode = Gtk.SelectionMode.NONE
+
     def _toggle_all_selection(self, selected):
         """
         Selects or deselects all items without sending the notify::active
diff --git a/gnomemusic/widgets/albumcover.py b/gnomemusic/widgets/albumcover.py
index 89e97798..efbc5b18 100644
--- a/gnomemusic/widgets/albumcover.py
+++ b/gnomemusic/widgets/albumcover.py
@@ -24,7 +24,7 @@
 
 import gi
 gi.require_version('Grl', '0.3')
-from gi.repository import Gdk, GObject, Gtk
+from gi.repository import GObject, Gtk
 
 from gnomemusic.albumartcache import Art
 from gnomemusic.corealbum import CoreAlbum
@@ -46,7 +46,6 @@ class AlbumCover(Gtk.FlowBoxChild):
     _check = Gtk.Template.Child()
     _title_label = Gtk.Template.Child()
     _artist_label = Gtk.Template.Child()
-    _events = Gtk.Template.Child()
 
     selected = GObject.Property(
         type=bool, default=False, flags=GObject.ParamFlags.READWRITE)
@@ -86,8 +85,6 @@ class AlbumCover(Gtk.FlowBoxChild):
 
         self.connect('query-tooltip', self._on_tooltip_query)
 
-        self._events.add_events(Gdk.EventMask.TOUCH_MASK)
-
         self._cover_stack.props.size = Art.Size.MEDIUM
 
         self.show()
@@ -116,16 +113,6 @@ class AlbumCover(Gtk.FlowBoxChild):
         """
         return self._corealbum
 
-    @Gtk.Template.Callback()
-    def _on_album_event(self, evbox, event, data=None):
-        modifiers = Gtk.accelerator_get_default_mod_mask()
-        if ((event.get_state() & modifiers) == Gdk.ModifierType.CONTROL_MASK
-                and not self.props.selection_mode):
-            self.props.selection_mode = True
-
-        if self.props.selection_mode:
-            self.props.selected = not self.props.selected
-
     @Gtk.Template.Callback()
     def _on_tooltip_query(self, widget, x, y, kb, tooltip, data=None):
         tooltip.set_custom(self._tooltip)


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