[gnome-music] Album and Artists View basic playback
- From: Vadim Rutkovsky <vrutkovsky src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music] Album and Artists View basic playback
- Date: Tue, 7 May 2013 13:07:24 +0000 (UTC)
commit 056b47441cc8c744dd033ac4b55a5ca997c56821
Author: Vadim Rutkovsky <vrutkovs redhat com>
Date: Mon May 6 14:05:49 2013 +0200
Album and Artists View basic playback
src/view.js | 6 +-
src/widgets.js | 9 ++-
tests/tests_albumArt.js | 145 ------------------------------------
tests/tests_albumPlayback.js | 158 ++++++++++++++++++++++++++++++++++++++++
tests/tests_artistsPlayback.js | 146 +++++++++++++++++++++++++++++++++++++
5 files changed, 315 insertions(+), 149 deletions(-)
---
diff --git a/src/view.js b/src/view.js
index 8d35d42..b3a007c 100644
--- a/src/view.js
+++ b/src/view.js
@@ -449,8 +449,8 @@ const Artists = new Lang.Class({
var iter = this._model.get_iter (path)[1];
var artist = this._model.get_value (iter, 0);
var albums = this._artists[artist.toLowerCase()]["albums"]
- var artistAlbums = new Widgets.ArtistAlbums(artist, albums, this.player);
- this._artistAlbumsWidget.add(artistAlbums);
+ this.artistAlbums = new Widgets.ArtistAlbums(artist, albums, this.player);
+ this._artistAlbumsWidget.add(this.artistAlbums);
//this._artistAlbumsWidget.update(artist, albums);
},
@@ -473,11 +473,13 @@ const Artists = new Lang.Class({
);
}
this._artists[artist.toLowerCase()]["albums"].push(item)
+ this.emit("artist-added");
},
populate: function () {
if(grilo.tracker != null) {
grilo.populateArtists(this._offset, Lang.bind(this, this._addItem, null));
+ //FIXME: We're emitting this too early, need to wait for all artists to be filled in
}
},
});
diff --git a/src/widgets.js b/src/widgets.js
index 4a4ee35..8bfc4ec 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -241,7 +241,7 @@ const ArtistAlbums = new Lang.Class({
this.ui.add_from_resource('/org/gnome/music/ArtistAlbumsWidget.ui');
this.set_border_width(0);
this.ui.get_object("artist").set_label(this.artist);
- var widgets = [];
+ this.widgets = [];
this.model = Gtk.ListStore.new([
GObject.TYPE_STRING, /*title*/
@@ -258,10 +258,11 @@ const ArtistAlbums = new Lang.Class({
for (var i=0; i < albums.length; i++) {
let widget = new ArtistAlbumWidget(artist, albums[i], this.player, this.model)
this.pack_start(widget, false, false, 32);
- widgets.push(widget);
+ this.widgets.push(widget);
}
this.show_all();
this.player.connect('playlist-item-changed', Lang.bind(this, this.updateModel));
+ this.emit("albums-loaded");
},
updateModel: function(player, playlist, currentIter){
@@ -296,6 +297,7 @@ const ArtistAlbums = new Lang.Class({
},
});
+Signals.addSignalMethods(ArtistAlbums.prototype);
const ArtistAlbumWidget = new Lang.Class({
Name: "ArtistAlbumWidget",
@@ -360,11 +362,13 @@ const ArtistAlbumWidget = new Lang.Class({
songWidget.nowPlayingSign.set_no_show_all("true");
}
this.ui.get_object("grid1").show_all();
+ this.emit("tracks-loaded");
}
}));
this.pack_start(this.ui.get_object("ArtistAlbumWidget"), true, true, 0);
this.show_all();
+ this.emit("artist-album-loaded");
},
trackSelected: function(widget, iter) {
this.player.stop();
@@ -373,3 +377,4 @@ const ArtistAlbumWidget = new Lang.Class({
},
});
+Signals.addSignalMethods(ArtistAlbumWidget.prototype);
diff --git a/tests/tests_albumArt.js b/tests/tests_albumArt.js
index 9740f48..224a115 100755
--- a/tests/tests_albumArt.js
+++ b/tests/tests_albumArt.js
@@ -10,9 +10,6 @@ imports.searchPath.unshift('../libgd');
imports.searchPath.unshift('../data');
const AlbumArtCache = imports.src.albumArtCache.AlbumArtCache
const GLib = imports.gi.GLib;
-const Gio = imports.gi.Gio;
-const Gtk = imports.gi.Gtk;
-const Gdk = imports.gi.Gdk;
const Lang = imports.lang;
@@ -79,146 +76,4 @@ function testStripInvalidEntries_Spaces() {
assertEquals('Unknown Artist', albumArtCache.stripInvalidEntities("Unknown^^@(* ) Artist"))
}
-function registerResources() {
- let resource = Gio.Resource.load('../data/gnome-music.gresource');
- resource._register();
-
- let cssFile = Gio.File.new_for_uri('resource:///org/gnome/music/application.css');
- let provider = new Gtk.CssProvider();
- provider.load_from_file(cssFile);
- Gtk.init(null, 0);
- Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
- provider,
- Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
-}
-
-function getAlbumView() {
- registerResources();
-
- const AlbumView = imports.view.Albums;
- const Toolbar = imports.toolbar;
- const Player = imports.player;
- let toolbar = new Toolbar.Toolbar();
- let player = new Player.Player();
- return new AlbumView(toolbar, player);
-}
-
-function testAlbumViewCountIsNotEmpty() {
- var Mainloop = imports.mainloop;
- const View = imports.view;
- const Widgets = imports.widgets;
- let albumView = getAlbumView();
- // Wait for albums to load, run mainloop
- albumView.connect("album-art-updated", Lang.bind(this, function(){
- //FIXME: Here we try to quit the mainloop for each album
- //this causes exceptions and should be handled correctly
- try {
- Mainloop.quit('testMainloop');
- } catch(Exception) {}
- }));
- Mainloop.run('testMainloop');
- // Loaded, ready to go
-
- // Check that no more than 50 and no less than 0 albums were loaded
- if (!(albumView._offset > 0 && albumView._offset < 51))
- fail('albumView._offset="'+albumView._offset +'"')
-
- // The album has title and artist displayed (not null values)
- let firstAlbumIter = albumView._model.get_iter_first()[1];
- let firstAlbumPath = albumView._model.get_path(firstAlbumIter);
- let album = albumView._model.get_value(firstAlbumIter, 2);
- let artist = albumView._model.get_value(firstAlbumIter, 3);
- log(" First album is '"+album+"' by '"+artist+"'")
- assertNotNull(album)
- assertNotNull(artist)
-
- // Select first album
- let albumWidget = albumView._albumWidget;
- albumWidget.connect("loaded", Lang.bind(this, function(){
- Mainloop.quit('testMainloop');
- }));
- Mainloop.idle_add(function() {
- albumView.view.emit('item-activated', "0", firstAlbumPath);
- })
- Mainloop.run('testMainloop');
- // Album view loaded
-
- // Make sure that the same artist and album are displayed
- let artist2 = albumWidget.ui.get_object("artist_label").label;
- assertEquals(artist, artist2)
- let album2 = albumWidget.ui.get_object("title_label").label;
- assertEquals(album, album2)
-
- // Make sure that year is either ---- or more that 1000 (at least)
- let year = albumWidget.ui.get_object("released_label_info").label;
- if (year != '----')
- assertTrue(year > 1000)
-
- // Wait for tracks to be added
- albumWidget.connect('track-added', Lang.bind(this, function(){
- Mainloop.quit('testMainloop');
- }))
- Mainloop.run('testMainloop');
-
- // FIXME: wait for all tracks to be added, for now operate on the first one
- let model = albumWidget.model;
- let iter = model.get_iter_first()[1];
- let title = model.get_value(iter, 0);
- assertNotNull(title)
- assertEquals(title, model.get_value(iter, 5).get_title())
- log(" First track is '"+title+"'")
-
- // Buttons are disabled
- let player = albumWidget.player;
- assertFalse(player.prevBtn.get_sensitive())
- assertFalse(player.playBtn.get_sensitive())
- assertFalse(player.nextBtn.get_sensitive())
-
- // Artist and track labels are empty
- assertEquals(player.artistLabel.get_label(), "")
- assertEquals(player.titleLabel.get_label(), "")
-
- // Progress scale is not initialized (undefined range)
- assertEquals(player.progressScale.range, undefined)
-
- // Duration labels are set to "00:00"
- assertEquals(player.songTotalTimeLabel.get_label(), "00:00")
- assertEquals(player.songPlaybackTimeLabel.get_label(), "00:00")
-
- // Select the first song and remember its markup
- let firstTrackIter = albumWidget.model.get_iter_first()[1];
- let firstTrackMarkup = albumWidget.model.get_value(firstTrackIter, 0);
- let firstTrackPath = albumWidget.model.get_path(firstTrackIter);
- albumWidget.view.emit("item-activated", "0", firstTrackPath);
-
- // Buttons become enabled
- assertTrue(player.prevBtn.get_sensitive())
- assertTrue(player.playBtn.get_sensitive())
- assertTrue(player.nextBtn.get_sensitive())
-
- // Scale value is set to 0
- assertEquals(player.progressScale.get_value(), 0)
-
- // Track markup is updated
- let newTrackMarkup = albumWidget.model.get_value(firstTrackIter, 0);
- assertEquals(newTrackMarkup, "<b>" + firstTrackMarkup + "</b>");
-
- // Nowplaying icon is displayed for this track
- assertTrue(albumWidget.model.get_value(firstTrackIter, 3))
-
- // Artist and track labels are updated
- assertEquals(player.artistLabel.get_label(), artist)
- assertEquals(player.titleLabel.get_label(), title)
-
- // Other tracks don't contain <b> or <span> and don't display now playing icon
- let tracksIter = firstTrackIter.copy();
- while(albumWidget.model.iter_next(tracksIter)) {
- let trackMarkup = albumWidget.model.get_value(tracksIter, 0);
- assertTrue(trackMarkup.indexOf("<b>") == -1)
- assertTrue(trackMarkup.indexOf("<span>") == -1)
- assertFalse(albumWidget.model.get_value(tracksIter, 3))
- }
-}
-
gjstestRun();
-
diff --git a/tests/tests_albumPlayback.js b/tests/tests_albumPlayback.js
new file mode 100644
index 0000000..5420b91
--- /dev/null
+++ b/tests/tests_albumPlayback.js
@@ -0,0 +1,158 @@
+// application/javascript;version=1.8
+if (!('assertEquals' in this)) { /* allow running this test standalone */
+ imports.lang.copyPublicProperties(imports.jsUnit, this);
+ gjstestRun = function() { return imports.jsUnit.gjstestRun(window); };
+}
+
+imports.searchPath.unshift('..');
+imports.searchPath.unshift('../src');
+imports.searchPath.unshift('../libgd');
+imports.searchPath.unshift('../data');
+const Gio = imports.gi.Gio;
+const Gtk = imports.gi.Gtk;
+const Gdk = imports.gi.Gdk;
+const Lang = imports.lang;
+
+
+function registerResources() {
+ let resource = Gio.Resource.load('../data/gnome-music.gresource');
+ resource._register();
+
+ let cssFile = Gio.File.new_for_uri('resource:///org/gnome/music/application.css');
+ let provider = new Gtk.CssProvider();
+ provider.load_from_file(cssFile);
+ Gtk.init(null, 0);
+ Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
+ provider,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+}
+
+function getAlbumView() {
+ registerResources();
+
+ const AlbumView = imports.view.Albums;
+ const Toolbar = imports.toolbar;
+ const Player = imports.player;
+ let toolbar = new Toolbar.Toolbar();
+ let player = new Player.Player();
+ return new AlbumView(toolbar, player);
+}
+
+function testAlbumViewPlayback() {
+ var Mainloop = imports.mainloop;
+ const View = imports.view;
+ const Widgets = imports.widgets;
+ let albumView = getAlbumView();
+ // Wait for albums to load, run mainloop
+ albumView.connect("album-art-updated", Lang.bind(this, function(){
+ //FIXME: Here we try to quit the mainloop for each album
+ //this causes exceptions and should be handled correctly
+ try {
+ Mainloop.quit('testMainloop');
+ } catch(Exception) {}
+ }));
+ Mainloop.run('testMainloop');
+ // Loaded, ready to go
+
+ // Check that no more than 50 and no less than 0 albums were loaded
+ if (!(albumView._offset > 0 && albumView._offset < 51))
+ fail('albumView._offset="'+albumView._offset +'"')
+
+ // The album has title and artist displayed (not null values)
+ let firstAlbumIter = albumView._model.get_iter_first()[1];
+ let firstAlbumPath = albumView._model.get_path(firstAlbumIter);
+ let album = albumView._model.get_value(firstAlbumIter, 2);
+ let artist = albumView._model.get_value(firstAlbumIter, 3);
+ log(" First album is '"+album+"' by '"+artist+"'")
+ assertNotNull(album)
+ assertNotNull(artist)
+
+ // Select first album
+ let albumWidget = albumView._albumWidget;
+ albumWidget.connect("loaded", Lang.bind(this, function(){
+ Mainloop.quit('testMainloop');
+ }));
+ Mainloop.idle_add(function() {
+ albumView.view.emit('item-activated', "0", firstAlbumPath);
+ })
+ Mainloop.run('testMainloop');
+ // Album view loaded
+
+ // Make sure that the same artist and album are displayed
+ let artist2 = albumWidget.ui.get_object("artist_label").label;
+ assertEquals(artist, artist2)
+ let album2 = albumWidget.ui.get_object("title_label").label;
+ assertEquals(album, album2)
+
+ // Make sure that year is either ---- or more that 1000 (at least)
+ let year = albumWidget.ui.get_object("released_label_info").label;
+ if (year != '----')
+ assertTrue(year > 1000)
+
+ // Wait for tracks to be added
+ albumWidget.connect('track-added', Lang.bind(this, function(){
+ Mainloop.quit('testMainloop');
+ }))
+ Mainloop.run('testMainloop');
+
+ // FIXME: wait for all tracks to be added, for now operate on the first one
+ let model = albumWidget.model;
+ let iter = model.get_iter_first()[1];
+ let title = model.get_value(iter, 0);
+ assertNotNull(title);
+ assertEquals(title, model.get_value(iter, 5).get_title())
+ log(" First track is '"+title+"'")
+
+ // Buttons are disabled
+ let player = albumWidget.player;
+ assertFalse(player.prevBtn.get_sensitive())
+ assertFalse(player.playBtn.get_sensitive())
+ assertFalse(player.nextBtn.get_sensitive())
+
+ // Artist and track labels are empty
+ assertEquals(player.artistLabel.get_label(), "")
+ assertEquals(player.titleLabel.get_label(), "")
+
+ // Progress scale is not initialized (undefined range)
+ assertEquals(player.progressScale.range, undefined)
+
+ // Duration labels are set to "00:00"
+ assertEquals(player.songTotalTimeLabel.get_label(), "00:00")
+ assertEquals(player.songPlaybackTimeLabel.get_label(), "00:00")
+
+ // Select the first song and remember its markup
+ let firstTrackIter = albumWidget.model.get_iter_first()[1];
+ let firstTrackMarkup = albumWidget.model.get_value(firstTrackIter, 0);
+ let firstTrackPath = albumWidget.model.get_path(firstTrackIter);
+ albumWidget.view.emit("item-activated", "0", firstTrackPath);
+
+ // Buttons become enabled
+ assertTrue(player.prevBtn.get_sensitive())
+ assertTrue(player.playBtn.get_sensitive())
+ assertTrue(player.nextBtn.get_sensitive())
+
+ // Scale value is set to 0
+ assertEquals(player.progressScale.get_value(), 0)
+
+ // Track markup is updated
+ let newTrackMarkup = albumWidget.model.get_value(firstTrackIter, 0);
+ assertEquals(newTrackMarkup, "<b>" + firstTrackMarkup + "</b>");
+
+ // Nowplaying icon is displayed for this track
+ assertTrue(albumWidget.model.get_value(firstTrackIter, 3))
+
+ // Artist and track labels are updated
+ assertEquals(player.artistLabel.get_label(), artist)
+ assertEquals(player.titleLabel.get_label(), title)
+
+ // Other tracks don't contain <b> or <span> and don't display now playing icon
+ let tracksIter = firstTrackIter.copy();
+ while(albumWidget.model.iter_next(tracksIter)) {
+ let trackMarkup = albumWidget.model.get_value(tracksIter, 0);
+ assertTrue(trackMarkup.indexOf("<b>") == -1)
+ assertTrue(trackMarkup.indexOf("<span>") == -1)
+ assertFalse(albumWidget.model.get_value(tracksIter, 3))
+ }
+}
+
+gjstestRun();
diff --git a/tests/tests_artistsPlayback.js b/tests/tests_artistsPlayback.js
new file mode 100644
index 0000000..4eebb71
--- /dev/null
+++ b/tests/tests_artistsPlayback.js
@@ -0,0 +1,146 @@
+// application/javascript;version=1.8
+if (!('assertEquals' in this)) { /* allow running this test standalone */
+ imports.lang.copyPublicProperties(imports.jsUnit, this);
+ gjstestRun = function() { return imports.jsUnit.gjstestRun(window); };
+}
+
+imports.searchPath.unshift('..');
+imports.searchPath.unshift('../src');
+imports.searchPath.unshift('../libgd');
+imports.searchPath.unshift('../data');
+const Gio = imports.gi.Gio;
+const Gtk = imports.gi.Gtk;
+const Gdk = imports.gi.Gdk;
+const Lang = imports.lang;
+
+
+function registerResources() {
+ let resource = Gio.Resource.load('../data/gnome-music.gresource');
+ resource._register();
+
+ let cssFile = Gio.File.new_for_uri('resource:///org/gnome/music/application.css');
+ let provider = new Gtk.CssProvider();
+ provider.load_from_file(cssFile);
+ Gtk.init(null, 0);
+ Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
+ provider,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+}
+
+function getArtistView() {
+ registerResources();
+
+ const ArtistView = imports.view.Artists;
+ const Toolbar = imports.toolbar;
+ const Player = imports.player;
+ let toolbar = new Toolbar.Toolbar();
+ let player = new Player.Player();
+ return new ArtistView(toolbar, player);
+}
+
+function testArtistsViewPlayback() {
+ var Mainloop = imports.mainloop;
+ const View = imports.view;
+ const Widgets = imports.widgets;
+ let artistView = getArtistView();
+
+ artistView.connect("artist-added", Lang.bind(this, function(){
+ //FIXME: Here we try to quit the mainloop for each album
+ //this causes exceptions and should be handled correctly
+ try {
+ Mainloop.quit('testMainloop');
+ } catch(Exception) {}
+ }));
+ Mainloop.run('testMainloop');
+ // Loaded, ready to go
+
+ // Check that no more than 50 and no less than 0 artists were loaded
+ if (!(artistView._offset > 0 && artistView._offset < 51))
+ fail('artistView._offset="'+artistView._offset +'"')
+
+ // The album has title and artist displayed (not null values)
+ let firstArtistIter = artistView._model.get_iter_first()[1];
+ let firstArtistPath = artistView._model.get_path(firstArtistIter);
+ let artist = artistView._model.get_value(firstArtistIter, 0);
+ log(" First artist is '"+artist+"'")
+ assertNotNull(artist)
+
+ // Select first artist
+ artistView.view.emit('item-activated', "0", firstArtistPath);
+ let artistAlbumsWidget = artistView.artistAlbums;
+ assertTrue(artistAlbumsWidget.widgets.length > 0);
+
+ // Verify album title
+ let artistAlbumWidget = artistAlbumsWidget.widgets[0];
+ let albumTitle = artistAlbumWidget.album.get_title();
+ assertNotNull(albumTitle);
+ log(" First album is '" + albumTitle + "'")
+ assertEquals(artistAlbumWidget.ui.get_object("title").get_label(), albumTitle);
+
+ // Wait for all tracks to be added
+ artistAlbumWidget.connect("tracks-loaded", Lang.bind(this, function(){
+ Mainloop.quit('testMainloop1');
+ }));
+ Mainloop.run('testMainloop1');
+ assertTrue(artistAlbumWidget.tracks.length > 0);
+ let firstTrack = artistAlbumWidget.tracks[0];
+ let trackTitle = firstTrack.get_title();
+ log(" First track is '"+trackTitle+"'")
+
+ let player = artistAlbumWidget.player;
+ assertFalse(player.prevBtn.get_sensitive())
+ assertFalse(player.playBtn.get_sensitive())
+ assertFalse(player.nextBtn.get_sensitive())
+
+ // Artist and track labels are empty
+ assertEquals(player.artistLabel.get_label(), "")
+ assertEquals(player.titleLabel.get_label(), "")
+
+ // Progress scale is not initialized (undefined range)
+ assertEquals(player.progressScale.range, undefined)
+
+ // Duration labels are set to "00:00"
+ assertEquals(player.songTotalTimeLabel.get_label(), "00:00")
+ assertEquals(player.songPlaybackTimeLabel.get_label(), "00:00")
+
+ // Select the first song and remember its markup
+ let model = artistAlbumWidget.model;
+ let firstTrackIter = firstTrack.songWidget.iter;
+ let firstTrackMarkup = model.get_value(firstTrackIter, 0);
+ // Get songwidget and click on title
+ firstTrack.songWidget.emit("button-release-event", null)
+
+ // Wait for track to be played
+
+
+ // Buttons become enabled
+ assertTrue(player.prevBtn.get_sensitive())
+ assertTrue(player.playBtn.get_sensitive())
+ assertTrue(player.nextBtn.get_sensitive())
+
+ // Scale value is set to 0
+ assertEquals(player.progressScale.get_value(), 0)
+
+ // Track markup is updated
+ let newTrackMarkup = firstTrack.songWidget.title.get_label();
+ assertEquals(newTrackMarkup, "<b>" + firstTrackMarkup + "</b>");
+
+ // Nowplaying icon is displayed for this track
+ assertTrue(firstTrack.songWidget.nowPlayingSign.get_visible())
+
+ // Artist and track labels are updated
+ assertEquals(player.artistLabel.get_label(), artist)
+ assertEquals(player.titleLabel.get_label(), trackTitle)
+
+ // Other tracks don't contain <b> or <span> and don't display now playing icon
+ let tracksIter = firstTrackIter.copy();
+ while(model.iter_next(tracksIter)) {
+ let track = model.get_value(tracksIter, 5);
+ let trackMarkup = track.songWidget.title.get_label();
+ assertTrue(trackMarkup.indexOf("<b>") == -1)
+ assertTrue(trackMarkup.indexOf("grey") == -1)
+ assertFalse(track.songWidget.nowPlayingSign.get_visible())
+ }
+}
+
+gjstestRun();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]