[gnome-music/playlists: 1/2] basic layout for SongsList widget
- From: Eslam Mostafa <cseslam src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/playlists: 1/2] basic layout for SongsList widget
- Date: Thu, 27 Jun 2013 23:17:30 +0000 (UTC)
commit 5ba68c551c9d75f6d33e4bb7861744d4caecacbf
Author: Eslam Mostafa <me eslammostafa com>
Date: Wed Jun 26 19:11:02 2013 +0200
basic layout for SongsList widget
data/PlaylistControls.ui | 40 ++++++++
data/PlaylistSongs.ui | 180 ++++++++++++++++++++++++++++++++++++
data/application.css | 21 ++++
data/gnome-music.gresource.xml | 2 +
src/view.js | 200 +++++++++++++++++----------------------
src/widgets.js | 130 ++++++++++++++++++++++++++
6 files changed, 460 insertions(+), 113 deletions(-)
---
diff --git a/data/PlaylistControls.ui b/data/PlaylistControls.ui
new file mode 100644
index 0000000..fb77c05
--- /dev/null
+++ b/data/PlaylistControls.ui
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.10 -->
+ <object class="GtkToolbar" id="container">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="toolbar_style">icons</property>
+ <property name="show_arrow">False</property>
+ <style>
+ <class name="inline-toolbar"/>
+ </style>
+ <property name="icon_size">2</property>
+ <child>
+ <object class="GtkToolButton" id="addPlaylist">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">toolbutton1</property>
+ <property name="use_underline">True</property>
+ <property name="icon_name">list-add-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="removePlaylist">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">toolbutton1</property>
+ <property name="use_underline">True</property>
+ <property name="icon_name">list-remove-symbolic</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/data/PlaylistSongs.ui b/data/PlaylistSongs.ui
new file mode 100644
index 0000000..b3697a6
--- /dev/null
+++ b/data/PlaylistSongs.ui
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.10 -->
+ <object class="GtkBox" id="container">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">24</property>
+ <property name="margin_top">18</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="playlist">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label">label</property>
+ <property name="ellipsize">middle</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="spacer">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="playlistEditButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="focus_on_click">False</property>
+ <style>
+ <class name="circle-button"/>
+ </style>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">applications-system-symbolic</property>
+ <property name="use_fallback">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="width_request">24</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="songsCount">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">00</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="songs">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Songs,</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="songsSize">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">size</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="songsDuration">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">duration</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <child>
+ <object class="GtkViewport" id="viewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/data/application.css b/data/application.css
index 0642bcd..c827b4f 100644
--- a/data/application.css
+++ b/data/application.css
@@ -25,6 +25,19 @@
background-color: #77757A;
}
+.playlist-controls-white{
+ background-color: #d7dad7;
+}
+.playlist-controls-white:selected{
+ background-color: #888A85;
+}
+.playlist-controls-dark{
+ background-color: #282528;
+}
+.playlist-controls-dark:selected{
+ background-color: #77757A;
+}
+
.songs-list {
box-shadow: inset 0 -1px shade(@borders, 1.30);
background-color: @theme_bg_color;
@@ -122,3 +135,11 @@
color: mix (@theme_fg_color, @theme_bg_color, 0.50);
}
+.circle-button {
+ border-radius: 15px;
+ border-width: 2px;
+}
+
+.circle-button image {
+ border-radius: 15px;
+}
diff --git a/data/gnome-music.gresource.xml b/data/gnome-music.gresource.xml
index 6e6b91f..cd4259f 100644
--- a/data/gnome-music.gresource.xml
+++ b/data/gnome-music.gresource.xml
@@ -9,5 +9,7 @@
<file preprocess="xml-stripblanks">PlayerToolbar.ui</file>
<file preprocess="xml-stripblanks">TrackWidget.ui</file>
<file preprocess="xml-stripblanks">NoMusic.ui</file>
+ <file preprocess="xml-stripblanks">PlaylistControls.ui</file>
+ <file preprocess="xml-stripblanks">PlaylistSongs.ui</file>
</gresource>
</gresources>
diff --git a/src/view.js b/src/view.js
index 5c26220..9ede6a8 100644
--- a/src/view.js
+++ b/src/view.js
@@ -319,33 +319,11 @@ const Songs = new Lang.Class({
this.countQuery = Query.songs_count;
this._items = {};
this.isStarred = null;
- this.view.set_view_type(Gd.MainViewType.LIST);
- this.view.get_generic_view().get_style_context().add_class("songs-list")
+ this.view = new Widgets.SongsList(player);
this._iconHeight = 32;
this._iconWidth = 32;
this._symbolicIcon = albumArtCache.makeDefaultIcon(this._iconHeight, this._iconWidth)
- this._addListRenderers();
this.player = player;
- this.player.connect('playlist-item-changed', Lang.bind(this, this.updateModel));
- },
-
- _onItemActivated: function (widget, id, path) {
- var iter = this._model.get_iter(path)[1]
- if (this._model.get_value(iter, 8) != errorIconName) {
- this.player.setPlaylist("Songs", null, this._model, iter, 5);
- this.player.setPlaying(true);
- }
- },
-
- updateModel: function(player, playlist, currentIter){
- if (playlist != this._model){
- return false;}
- if (this.iterToClean){
- this._model.set_value(this.iterToClean, 10, false);
- }
- this._model.set_value(currentIter, 10, true);
- this.iterToClean = currentIter.copy();
- return false;
},
_addItem: function(source, param, item) {
@@ -375,87 +353,6 @@ const Songs = new Lang.Class({
}
},
- _addListRenderers: function() {
- let listWidget = this.view.get_generic_view();
- let cols = listWidget.get_columns();
- let cells = cols[0].get_cells();
- cells[2].visible = false;
- let nowPlayingSymbolRenderer = new Gtk.CellRendererPixbuf();
- var columnNowPlaying = new Gtk.TreeViewColumn();
- nowPlayingSymbolRenderer.xalign = 1.0;
- columnNowPlaying.pack_start(nowPlayingSymbolRenderer, false);
- columnNowPlaying.fixed_width = 24;
- columnNowPlaying.add_attribute(nowPlayingSymbolRenderer, "visible", 10);
- columnNowPlaying.add_attribute(nowPlayingSymbolRenderer, "icon_name", 8);
- listWidget.insert_column(columnNowPlaying, 0);
-
- let titleRenderer = new Gtk.CellRendererText({ xpad: 0 });
- listWidget.add_renderer(titleRenderer,Lang.bind(this,function (col,cell,model,iter) {
- let item = model.get_value(iter,5);
- titleRenderer.xalign = 0.0;
- titleRenderer.yalign = 0.5;
- titleRenderer.height = 48;
- titleRenderer.ellipsize = Pango.EllipsizeMode.END;
- titleRenderer.text = item.get_title();
- }))
- let starRenderer = new Gtk.CellRendererPixbuf({xpad: 32});
- listWidget.add_renderer(starRenderer,Lang.bind(this,function (col,cell,model,iter) {
- let showstar = model.get_value(iter, 9);
- if(showstar){
- starRenderer.icon_name = starIconName;
-
- }
- else
- starRenderer.pixbuf = null;
- }))
-
- let durationRenderer =
- new Gd.StyledTextRenderer({ xpad: 32 });
- durationRenderer.add_class('dim-label');
- listWidget.add_renderer(durationRenderer, Lang.bind(this,
- function(col, cell, model, iter) {
- let item = model.get_value(iter, 5);
- if (item) {
- let duration = item.get_duration ();
- var minutes = parseInt(duration / 60);
- var seconds = duration % 60;
- var time = null
- if (seconds < 10)
- time = minutes + ":0" + seconds;
- else
- time = minutes + ":" + seconds;
- durationRenderer.xalign = 1.0;
- durationRenderer.text = time;
- }
- }));
-
- let artistRenderer =
- new Gd.StyledTextRenderer({ xpad: 32});
- artistRenderer.add_class('dim-label');
- artistRenderer.ellipsize = Pango.EllipsizeMode.END;
- listWidget.add_renderer(artistRenderer, Lang.bind(this,
- function(col, cell, model, iter) {
- let item = model.get_value(iter, 5);
- if (item) {
- artistRenderer.ellipsize = Pango.EllipsizeMode.END;
- artistRenderer.text = item.get_string(Grl.METADATA_KEY_ARTIST);
- }
- }));
- let typeRenderer =
- new Gd.StyledTextRenderer({ xpad: 32});
- typeRenderer.add_class('dim-label');
- typeRenderer.ellipsize = Pango.EllipsizeMode.END;
- listWidget.add_renderer(typeRenderer, Lang.bind(this,
- function(col, cell, model, iter) {
- let item = model.get_value(iter, 5);
- if (item) {
- typeRenderer.ellipsize = Pango.EllipsizeMode.END;
- typeRenderer.text = item.get_string(Grl.METADATA_KEY_ALBUM);
- }
- }));
-
- },
-
populate: function() {
if (grilo.tracker != null)
grilo.populateSongs (this._offset, Lang.bind(this, this._addItem, null));
@@ -463,15 +360,6 @@ const Songs = new Lang.Class({
});
-const Playlists = new Lang.Class({
- Name: "PlaylistsView",
- Extends: ViewContainer,
-
- _init: function(header_bar, player) {
- this.parent("Playlists", header_bar);
- },
-});
-
const Artists = new Lang.Class({
Name: "ArtistsView",
Extends: ViewContainer,
@@ -579,4 +467,90 @@ const Artists = new Lang.Class({
//FIXME: We're emitting this too early, need to wait for all artists to be filled in
}
},
+
+});
+
+const Playlists = new Lang.Class({
+ Name: "PlaylistsView",
+ Extends: ViewContainer,
+
+ _init: function(header_bar, player) {
+ this.parent("Playlists", header_bar, true);
+ this.player= player;
+ this.view.set_view_type(Gd.MainViewType.LIST);
+ this.view.set_hexpand(false);
+ this.view.get_style_context().add_class("artist-panel");
+ this.view.get_generic_view().get_selection().set_mode(Gtk.SelectionMode.SINGLE);
+ this._songsListWidget = new Widgets.SongsList(this.player);
+ /*let builder = new Gtk.Builder();
+ builder.add_from_resource('/org/gnome/music/PlaylistControls.ui');
+ let controls = builder.get_object('container');*/
+ this._grid.attach(new Gtk.Separator(), 0, 1, 1, 1);
+ //this._grid.attach(controls, 0, 2, 1, 1);
+ this._grid.attach(new Gtk.Separator({orientation: Gtk.Orientation.VERTICAL}), 1, 0, 1, 3);
+ this._grid.attach(this._songsListWidget, 2, 0, 2, 3);
+ 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");
+ //controls.get_style_context().add_class("playlist-controls-dark");
+ } else {
+ this.view.get_generic_view().get_style_context().add_class("artist-panel-white");
+ //controls.get_style_context().add_class("playlist-controls-white");
+ }
+ this.show_all();
+ },
+ _addListRenderers: function() {
+ let listWidget = this.view.get_generic_view();
+
+ var cols = listWidget.get_columns()
+ var cells = cols[0].get_cells()
+ cells[2].visible = false
+
+ let typeRenderer =
+ new Gd.StyledTextRenderer({ xpad: 0 });
+ typeRenderer.ellipsize = 3;
+ typeRenderer.xalign = 0.0;
+ typeRenderer.yalign = 0.5;
+ typeRenderer.height = 48;
+ typeRenderer.width = 220;
+ listWidget.add_renderer(typeRenderer, Lang.bind(this,
+ function(col, cell, model, iter) {
+ typeRenderer.text = model.get_value(iter, 0);
+ }));
+ },
+
+ _onItemActivated: function (widget, id, path) {
+ let iter = this._model.get_iter (path)[1];
+ let playlist = this._model.get_value (iter, 0);
+ //this._playlistLabel.set_text(playlist);
+ let url = this._playlists[playlist.toLowerCase()]['url'];
+ this._songsListWidget.update(playlist, this._playlists[playlist.toLowerCase()]);
+ },
+
+ _addItem: function (source, param, item) {
+ this._offset += 1;
+ if (item == null)
+ return
+ var playlist = "Unknown"
+ if (item.get_title() != null)
+ playlist = item.get_title();
+ if (item.get_string(Grl.METADATA_KEY_TITLE) != null)
+ playlist = item.get_string(Grl.METADATA_KEY_TITLE)
+ var url = item.get_string(Grl.METADATA_KEY_URL)
+ if (this._playlists[playlist.toLowerCase()] == undefined) {
+ var iter = this._model.append();
+ this._playlists[playlist.toLowerCase()] = {"iter": iter, "url": url}
+ this._model.set(
+ iter,
+ [0, 1, 2, 3],
+ [playlist, playlist, playlist, playlist]
+ );
+ }
+ },
+
+ populate: function () {
+ if(grilo.tracker != null) {
+ grilo.populatePlaylists(this._offset, Lang.bind(this, this._addItem, null));
+ }
+ },
});
diff --git a/src/widgets.js b/src/widgets.js
index 5c3b2ba..1806b43 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -632,3 +632,133 @@ const ArtistAlbumWidget = new Lang.Class({
});
Signals.addSignalMethods(ArtistAlbumWidget.prototype);
+
+const SongsList = new Lang.Class({
+ Name: "SongsList",
+ Extends: Gd.MainView,
+
+ _init: function(player){
+ this.parent();
+ this.set_shadow_type(Gtk.ShadowType.NONE);
+ this.player = player;
+ this.set_view_type(Gd.MainViewType.LIST);
+ this.get_generic_view().get_style_context().add_class("songs-list")
+ this._model = Gtk.ListStore.new([
+ GObject.TYPE_STRING,
+ GObject.TYPE_STRING,
+ GObject.TYPE_STRING,
+ GObject.TYPE_STRING,
+ GdkPixbuf.Pixbuf,
+ GObject.TYPE_OBJECT,
+ GObject.TYPE_BOOLEAN,
+ GObject.TYPE_STRING,
+ GObject.TYPE_BOOLEAN,
+ GObject.TYPE_BOOLEAN
+ ]);
+ this.set_model(this._model);
+ this._addListRenderers();
+ this.show_all();
+ this.connect('item-activated', Lang.bind(this, this._onItemActivated));
+ this.player.connect('playlist-item-changed', Lang.bind(this, this.updateModel));
+ },
+
+ updateModel: function(player, playlist, currentIter){
+ if (playlist != this._model){
+ return false;}
+ if (this.iterToClean){
+ this._model.set_value(this.iterToClean, 9, false);
+ }
+ this._model.set_value(currentIter, 9, true);
+ this.iterToClean = currentIter.copy();
+ return false;
+ },
+
+ _onItemActivated: function (widget, id, path) {
+ var iter = this._model.get_iter(path)[1]
+ if (this._model.get_value(iter, 7) != errorIconName) {
+ this.player.setPlaylist("Playlist", null, this._model, iter, 5);
+ this.player.setPlaying(true);
+ }
+ },
+
+ _addListRenderers: function() {
+ let listWidget = this.get_generic_view();
+ let cols = listWidget.get_columns();
+ let cells = cols[0].get_cells();
+ cells[2].visible = false;
+ let nowPlayingSymbolRenderer = new Gtk.CellRendererPixbuf();
+ var columnNowPlaying = new Gtk.TreeViewColumn();
+ nowPlayingSymbolRenderer.xalign = 1.0;
+ columnNowPlaying.pack_start(nowPlayingSymbolRenderer, false);
+ columnNowPlaying.fixed_width = 24;
+ columnNowPlaying.add_attribute(nowPlayingSymbolRenderer, "visible", 9);
+ columnNowPlaying.add_attribute(nowPlayingSymbolRenderer, "icon_name", 7);
+ listWidget.insert_column(columnNowPlaying, 0);
+
+ let titleRenderer = new Gtk.CellRendererText({ xpad: 0 });
+ listWidget.add_renderer(titleRenderer,Lang.bind(this,function (col,cell,model,iter) {
+ let item = model.get_value(iter,5);
+ titleRenderer.xalign = 0.0;
+ titleRenderer.yalign = 0.5;
+ titleRenderer.height = 48;
+ titleRenderer.ellipsize = Pango.EllipsizeMode.END;
+ titleRenderer.text = item.get_title();
+ }))
+ let starRenderer = new Gtk.CellRendererPixbuf({xpad: 32});
+ listWidget.add_renderer(starRenderer,Lang.bind(this,function (col,cell,model,iter) {
+ let showstar = model.get_value(iter,8);
+ if(showstar){
+ starRenderer.icon_name = starIconName;
+
+ }
+ else
+ starRenderer.pixbuf = null;
+ }))
+
+ let durationRenderer =
+ new Gd.StyledTextRenderer({ xpad: 32 });
+ durationRenderer.add_class('dim-label');
+ listWidget.add_renderer(durationRenderer, Lang.bind(this,
+ function(col, cell, model, iter) {
+ let item = model.get_value(iter, 5);
+ if (item) {
+ let duration = item.get_duration ();
+ var minutes = parseInt(duration / 60);
+ var seconds = duration % 60;
+ var time = null
+ if (seconds < 10)
+ time = minutes + ":0" + seconds;
+ else
+ time = minutes + ":" + seconds;
+ durationRenderer.xalign = 1.0;
+ durationRenderer.text = time;
+ }
+ }));
+
+ let artistRenderer =
+ new Gd.StyledTextRenderer({ xpad: 32});
+ artistRenderer.add_class('dim-label');
+ artistRenderer.ellipsize = Pango.EllipsizeMode.END;
+ listWidget.add_renderer(artistRenderer, Lang.bind(this,
+ function(col, cell, model, iter) {
+ let item = model.get_value(iter, 5);
+ if (item) {
+ artistRenderer.ellipsize = Pango.EllipsizeMode.END;
+ artistRenderer.text = item.get_string(Grl.METADATA_KEY_ARTIST);
+ }
+ }));
+ let typeRenderer =
+ new Gd.StyledTextRenderer({ xpad: 32});
+ typeRenderer.add_class('dim-label');
+ typeRenderer.ellipsize = Pango.EllipsizeMode.END;
+ listWidget.add_renderer(typeRenderer, Lang.bind(this,
+ function(col, cell, model, iter) {
+ let item = model.get_value(iter, 5);
+ if (item) {
+ typeRenderer.ellipsize = Pango.EllipsizeMode.END;
+ typeRenderer.text = item.get_string(Grl.METADATA_KEY_ALBUM);
+ }
+ }));
+
+ },
+});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]