[gnome-music] Make All Artist in Artist view work



commit c397c7ae02e5a3dd12bcc4d84861d1dbccc178c6
Author: Seif Lotfy <seif lotfy com>
Date:   Tue May 21 20:36:57 2013 +0200

    Make All Artist in Artist view work
    
    Signed-off-by: Seif Lotfy <seif lotfy com>

 src/albumArtCache.js |    2 +-
 src/grilo.js         |    8 +-
 src/view.js          |  108 ++++++++++-----------------------
 src/widgets.js       |  163 +++++++++++++++++++++++++++++++++++++++++++++++---
 src/window.js        |    4 +-
 5 files changed, 193 insertions(+), 92 deletions(-)
---
diff --git a/src/albumArtCache.js b/src/albumArtCache.js
index 9dff5a3..5390d61 100644
--- a/src/albumArtCache.js
+++ b/src/albumArtCache.js
@@ -195,7 +195,7 @@ const AlbumArtCache = new Lang.Class({
     },
 
     makeIconFrame: function (pixbuf) {
-        border = 1.5;
+        let border = 1.5;
         pixbuf = pixbuf.scale_simple(pixbuf.get_width() - border * 2,
                                      pixbuf.get_height() - border * 2,
                                      0);
diff --git a/src/grilo.js b/src/grilo.js
index d597715..e3b55fc 100644
--- a/src/grilo.js
+++ b/src/grilo.js
@@ -69,19 +69,19 @@ const Grilo = new Lang.Class({
         this.populateItems (Query.artist, offset, callback)
     },
 
-    populateAlbums: function (offset, callback) {
-        this.populateItems (Query.album, offset, callback)
+    populateAlbums: function (offset, callback, count=50) {
+        this.populateItems (Query.album, offset, callback, count)
     },
 
     populateSongs: function (offset, callback) {
         this.populateItems (Query.songs, offset, callback)
     },
 
-    populateItems: function (query, offset, callback) {
+    populateItems: function (query, offset, callback, count=50) {
         var options = Grl.OperationOptions.new(null);
         options.set_flags (Grl.ResolutionFlags.FULL | Grl.ResolutionFlags.IDLE_RELAY);
         options.set_skip (offset);
-        options.set_count(50);
+        options.set_count(count);
         grilo.tracker.query(
             query,
                 [Grl.METADATA_KEY_ID, Grl.METADATA_KEY_TITLE, Grl.METADATA_KEY_ARTIST, 
Grl.METADATA_KEY_CREATION_DATE],
diff --git a/src/view.js b/src/view.js
index ee7c68b..62fec62 100644
--- a/src/view.js
+++ b/src/view.js
@@ -53,60 +53,6 @@ function extractFileName(uri) {
 
 const grilo = Grilo.grilo;
 
-
-const LoadMoreButton = new Lang.Class({
-    Name: 'LoadMoreButton',
-    _init: function(counter) {
-        this._block = false;
-        this._counter = counter;
-        let child = new Gtk.Grid({ column_spacing: 10,
-                                   hexpand: false,
-                                   halign: Gtk.Align.CENTER,
-                                   visible: true });
-
-        this._spinner = new Gtk.Spinner({ halign: Gtk.Align.CENTER,
-                                          no_show_all: true });
-        this._spinner.set_size_request(16, 16);
-        child.add(this._spinner);
-
-        this._label = new Gtk.Label({ label: "Load More",
-                                      visible: true });
-        child.add(this._label);
-
-        this.widget = new Gtk.Button({ no_show_all: true,
-                                       child: child });
-        this.widget.get_style_context().add_class('documents-load-more');
-        this.widget.connect('clicked', Lang.bind(this,
-            function() {
-                this._label.label = "Loading...";
-                this._spinner.show();
-                this._spinner.start();
-            }));
-
-        this._onItemCountChanged();
-    },
-
-    _onItemCountChanged: function() {
-        let remainingDocs = this._counter();
-        let visible = !(remainingDocs <= 0 || this._block);
-        this.widget.set_visible(visible);
-
-        if (!visible) {
-            this._label.label = "Load More";
-            this._spinner.stop();
-            this._spinner.hide();
-        }
-    },
-
-    setBlock: function(block) {
-        if (this._block == block)
-            return;
-
-        this._block = block;
-        this._onItemCountChanged();
-    }
-});
-
 const ViewContainer = new Lang.Class({
     Name: "ViewContainer",
     Extends: Gtk.Stack,
@@ -136,21 +82,24 @@ const ViewContainer = new Lang.Class({
         });
         this.view.set_view_type(Gd.MainViewType.ICON);
         this.view.set_model(this._model);
+
+        let _box = new Gtk.Box({orientation: Gtk.Orientation.VERTICAL});
+        _box.pack_start(this.view, true, true, 0);
         if (use_stack){
             this.stack = new Gd.Stack({
                 transition_type: Gd.StackTransitionType.SLIDE_RIGHT,
             })
             var dummy = new Gtk.Frame({visible: false});
             this.stack.add_named(dummy, "dummy");
-            this.stack.add_named(this.view, "artists");
+            this.stack.add_named(_box, "artists");
             this.stack.set_visible_child_name("dummy");
             this._grid.add(this.stack);
         } else {
-            this._grid.add(this.view);
+            this._grid.add(_box);
         }
 
-        this._loadMore = new LoadMoreButton(this._getRemainingItemCount);
-        this._grid.add(this._loadMore.widget);
+        this._loadMore = new Widgets.LoadMoreButton(this._getRemainingItemCount);
+        _box.pack_end(this._loadMore.widget, false, false, 0);
         this._loadMore.widget.connect("clicked", Lang.bind(this, this.populate))
         this.view.connect('item-activated',
                             Lang.bind(this, this._onItemActivated));
@@ -538,13 +487,8 @@ const Artists = new Lang.Class({
         this._artistAlbumsWidget.set_hexpand(true);
         this.view.get_style_context().add_class("artist-panel");
         this.view.get_generic_view().get_selection().set_mode(Gtk.SelectionMode.SINGLE);
-        var scrolledWindow = new Gtk.ScrolledWindow();
-        scrolledWindow.set_policy(
-            Gtk.PolicyType.NEVER,
-            Gtk.PolicyType.AUTOMATIC);
-        scrolledWindow.add(this._artistAlbumsWidget);
         this._grid.attach(new Gtk.Separator({orientation: Gtk.Orientation.VERTICAL}), 1, 0, 1, 1)
-        this._grid.attach(scrolledWindow, 2, 0, 1, 1);
+        this._grid.attach(this._artistAlbumsWidget, 2, 0, 2, 2);
         this._addListRenderers();
         if(Gtk.Settings.get_default().gtk_application_prefer_dark_theme)
             this.view.get_generic_view().get_style_context().add_class("artist-panel-dark");
@@ -557,12 +501,21 @@ const Artists = new Lang.Class({
             [0, 1, 2, 3],
             ["All Artists", "All Artists", "All Artists", "All Artists"]
         );
-        let selection = this.view.get_generic_view().get_selection();
-        selection.select_path(this._model.get_path(this._allIter));
-        this.view.emit('item-activated', "0", this._model.get_path(this._allIter));
+        if (this.header_bar.get_stack() != null)
+            this.header_bar.get_stack().connect("notify::visible-child", Lang.bind(this, 
this._onNotifyMode));
         this.show_all();
     },
 
+    _onNotifyMode: function(widget, param) {
+        if (this != widget.get_visible_child())
+            return;
+        let selection = this.view.get_generic_view().get_selection();
+        if (!selection.get_selected()[0]) {
+            selection.select_path(this._model.get_path(this._allIter));
+            this.view.emit('item-activated', "0", this._model.get_path(this._allIter));
+        }
+    },
+
     _addListRenderers: function() {
         let listWidget = this.view.get_generic_view();
 
@@ -584,20 +537,23 @@ const Artists = new Lang.Class({
     },
 
     _onItemActivated: function (widget, id, path) {
-        var children = this._artistAlbumsWidget.get_children();
-        for (var i=0; i<children.length; i++)
-            this._artistAlbumsWidget.remove(children[i])
-        var iter = this._model.get_iter (path)[1];
-        var artist = this._model.get_value (iter, 0);
-        var albums = this._artists[artist.toLowerCase()]["albums"]
-        this.artistAlbums = new Widgets.ArtistAlbums(artist, albums, this.player);
+        let children = this._artistAlbumsWidget.get_children();
+        for (let i=0; i<children.length; i++)
+            this._artistAlbumsWidget.remove(children[i]);
+        let iter = this._model.get_iter (path)[1];
+        let artist = this._model.get_value (iter, 0);
+        let albums = this._artists[artist.toLowerCase()]["albums"];
+        this.artistAlbums = null;
+        if (this._model.get_string_from_iter(iter) == this._model.get_string_from_iter(this._allIter))
+            this.artistAlbums = new Widgets.AllArtistsAlbums(this.player);
+        else
+            this.artistAlbums = new Widgets.ArtistAlbums(artist, albums, this.player);
         this._artistAlbumsWidget.add(this.artistAlbums);
-        //this._artistAlbumsWidget.update(artist, albums);
     },
 
     _addItem: function (source, param, item) {
         this._offset += 1;
-        if( item == null )
+        if (item == null)
             return
         var artist = "Unknown"
         if (item.get_author() != null)
diff --git a/src/widgets.js b/src/widgets.js
index cdc4d6f..1baccaa 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -39,6 +39,59 @@ const albumArtCache = AlbumArtCache.AlbumArtCache.getDefault();
 const nowPlayingIconName = 'media-playback-start-symbolic';
 const errorIconName = 'dialog-error-symbolic';
 
+const LoadMoreButton = new Lang.Class({
+    Name: 'LoadMoreButton',
+    _init: function(counter) {
+        this._block = false;
+        this._counter = counter;
+        let child = new Gtk.Grid({ column_spacing: 10,
+                                   hexpand: false,
+                                   halign: Gtk.Align.CENTER,
+                                   visible: true });
+
+        this._spinner = new Gtk.Spinner({ halign: Gtk.Align.CENTER,
+                                          no_show_all: true });
+        this._spinner.set_size_request(16, 16);
+        child.add(this._spinner);
+
+        this._label = new Gtk.Label({ label: "Load More",
+                                      visible: true });
+        child.add(this._label);
+
+        this.widget = new Gtk.Button({ no_show_all: true,
+                                       child: child });
+        this.widget.get_style_context().add_class('documents-load-more');
+        this.widget.connect('clicked', Lang.bind(this,
+            function() {
+                this._label.label = "Loading...";
+                this._spinner.show();
+                this._spinner.start();
+            }));
+
+        this._onItemCountChanged();
+    },
+
+    _onItemCountChanged: function() {
+        let remainingDocs = this._counter();
+        let visible = !(remainingDocs <= 0 || this._block);
+        this.widget.set_visible(visible);
+
+        if (!visible) {
+            this._label.label = "Load More";
+            this._spinner.stop();
+            this._spinner.hide();
+        }
+    },
+
+    setBlock: function(block) {
+        if (this._block == block)
+            return;
+
+        this._block = block;
+        this._onItemCountChanged();
+    }
+});
+
 const AlbumWidget = new Lang.Class({
     Name: "AlbumWidget",
     Extends: Gtk.EventBox,
@@ -265,21 +318,31 @@ const ArtistAlbums = new Lang.Class({
                 GObject.TYPE_BOOLEAN
                 ]);
 
+        this._hbox = new Gtk.Box({orientation: Gtk.Orientation.VERTICAL});
+        this._albumBox = new Gtk.Box({orientation: Gtk.Orientation.VERTICAL, spacing: 48});
+        this._scrolledWindow = new Gtk.ScrolledWindow();
+        this._scrolledWindow.set_policy(
+            Gtk.PolicyType.NEVER,
+            Gtk.PolicyType.AUTOMATIC);
+        this._scrolledWindow.add(this._hbox);
+        this._hbox.pack_start(this.ui.get_object("ArtistAlbumsWidget"), false, false, 0);
+        this._hbox.pack_start(this._albumBox, false, false, 16);
+        this.pack_start(this._scrolledWindow, true, true, 0);
+
+        for (var i=0; i < albums.length; i++)
+            this.addAlbum(albums[i]);
 
-        this.pack_start(this.ui.get_object("ArtistAlbumsWidget"), false, false, 0);
-        var hbox = new Gtk.Box({orientation: Gtk.Orientation.VERTICAL});
-        hbox.set_spacing(48);
-        this.pack_start(hbox, false, false, 16);
-        for (var i=0; i < albums.length; i++) {
-            let widget = new ArtistAlbumWidget(artist, albums[i], this.player, this.model)
-            hbox.pack_start(widget, false, false, 0);
-            this.widgets.push(widget);
-        }
         this.show_all();
         this.player.connect('playlist-item-changed', Lang.bind(this, this.updateModel));
         this.emit("albums-loaded");
     },
 
+    addAlbum: function(album) {
+        let widget = new ArtistAlbumWidget(this.artist, album, this.player, this.model)
+        this._albumBox.pack_start(widget, false, false, 0);
+        this.widgets.push(widget);
+    },
+
     updateModel: function(player, playlist, currentIter){
         //this is not our playlist, return
         if (playlist != this.model){
@@ -334,6 +397,88 @@ const ArtistAlbums = new Lang.Class({
 });
 Signals.addSignalMethods(ArtistAlbums.prototype);
 
+
+const AllArtistsAlbums = new Lang.Class({
+    Name: "AllArtistsAlbums",
+    Extends: ArtistAlbums,
+
+    _init: function(player) {
+        this.parent("All Artists", [], player);
+        this._offset = 0;
+        this.countQuery = Query.album_count;
+        this._loadMore = new LoadMoreButton(Lang.bind(this, this._getRemainingItemCount));
+        this.pack_end(this._loadMore.widget, false, false, 0);
+        this._loadMore.widget.connect("clicked", Lang.bind(this, this._populate))
+        this._connectView();
+        this._populate();
+    },
+
+    _connectView: function() {
+        this._adjustmentValueId = this._scrolledWindow.vadjustment.connect(
+            'value-changed',
+            Lang.bind(this, this._onScrolledWinChange)
+        );
+        this._adjustmentChangedId = this._scrolledWindow.vadjustment.connect(
+            'changed',
+            Lang.bind(this, this._onScrolledWinChange)
+        );
+        this._scrollbarVisibleId = this._scrolledWindow.get_vscrollbar().connect(
+            'notify::visible',
+            Lang.bind(this, this._onScrolledWinChange)
+        );
+        this._onScrolledWinChange();
+    },
+
+    _onScrolledWinChange: function() {
+        let vScrollbar = this._scrolledWindow.get_vscrollbar();
+        let adjustment = this._scrolledWindow.vadjustment;
+        let revealAreaHeight = 32;
+
+        // if there's no vscrollbar, or if it's not visible, hide the button
+        if (!vScrollbar ||
+            !vScrollbar.get_visible()) {
+            this._loadMore.setBlock(true);
+            return;
+        }
+
+        let value = adjustment.value;
+        let upper = adjustment.upper;
+        let page_size = adjustment.page_size;
+
+        let end = false;
+        // special case this values which happen at construction
+        if ((value == 0) && (upper == 1) && (page_size == 1))
+            end = false;
+        else
+            end = !(value < (upper - page_size - revealAreaHeight));
+        if (this._getRemainingItemCount() <= 0)
+            end = false;
+        this._loadMore.setBlock(!end);
+    },
+
+
+    _populate: function () {
+        if (grilo.tracker != null)
+            grilo.populateAlbums (this._offset, Lang.bind(this,
+                function (source, param, item, remaining) {
+                    if (item != null) {
+                        this._offset += 1;
+                        this.addAlbum(item);
+                    }
+                }), 5);
+    },
+
+    _getRemainingItemCount: function () {let count = -1;
+        if (this.countQuery != null) {
+            let cursor = Grilo.tracker.query(this.countQuery, null)
+            if (cursor != null && cursor.next(null))
+                count = cursor.get_integer(0);
+        }
+        return ( count - this._offset);
+    },
+});
+
+
 const ArtistAlbumWidget = new Lang.Class({
     Name: "ArtistAlbumWidget",
     Extends: Gtk.HBox,
diff --git a/src/window.js b/src/window.js
index 4b859a1..1d7f25e 100644
--- a/src/window.js
+++ b/src/window.js
@@ -63,6 +63,7 @@ const MainWindow = new Lang.Class({
             transition_duration: 100,
             visible: true
         });
+        this.toolbar.set_stack(this._stack);
 
         this._box.pack_start(this.toolbar, false, false, 0);
         this._box.pack_start(this._stack, true, true, 0);
@@ -87,7 +88,7 @@ const MainWindow = new Lang.Class({
             );
         }
 
-        this._onNotifyModelId = this._stack.connect("notify::visible-child", this._onNotifyMode);
+        this._onNotifyModelId = this._stack.connect("notify::visible-child", Lang.bind(this, 
this._onNotifyMode));
         this.connect("destroy",Lang.bind(this, function(){
             this._stack.disconnect(this._onNotifyModelId);
         }));
@@ -100,7 +101,6 @@ const MainWindow = new Lang.Class({
             this._stack.add_titled(this.views[0],"Empty","Empty");
         }
 
-        this.toolbar.set_stack(this._stack);
         this.toolbar.show();
         this.player.eventBox.show_all();
         this._box.show();


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