[gnome-music] added headerbar and selection toolbar.
- From: Vadim Rutkovsky <vrutkovsky src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music] added headerbar and selection toolbar.
- Date: Fri, 12 Jul 2013 10:01:10 +0000 (UTC)
commit 6b5bfe00602f4a02e37a87f074551aed591c7afc
Author: Vadim Rutkovsky <vrutkovs redhat com>
Date: Fri Jul 12 11:58:45 2013 +0200
added headerbar and selection toolbar.
added search button.
deleted: 0001-added-headerbar-and-selection-toolbar.patch
cancel button position fix.
Selection toolbar and Headerbar patch.
https://bugzilla.gnome.org/show_bug.cgi?id=703255
data/Headerbar.ui | 176 ++++++++++++++++++++++++++++++++++++++++
data/SelectionToolbar.ui | 41 +++++++++
data/gnome-music.gresource.xml | 2 +
src/player.js | 12 +++
src/toolbar.js | 51 ++++++++----
src/view.js | 37 ++++++---
src/widgets.js | 19 ++++-
src/window.js | 17 ++--
8 files changed, 316 insertions(+), 39 deletions(-)
---
diff --git a/data/Headerbar.ui b/data/Headerbar.ui
new file mode 100644
index 0000000..948a039
--- /dev/null
+++ b/data/Headerbar.ui
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface domain="gnome-music">
+ <!-- interface-requires gtk+ 3.10 -->
+ <menu id="selection-menu">
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">Select All</attribute>
+ <attribute name="accel"><Primary>a</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">Select None</attribute>
+ </item>
+ </section>
+ </menu>
+ <object class="GtkMenuButton" id="selection-menu-button">
+ <property name="menu-model">selection-menu</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="relief">none</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkBox" id="selection-menu-button-box">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="selection-menu-button-label">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="label" translatable="yes">Click on items to select them</property>
+ </object>
+ <packing>
+ <property name="pack-type">start</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkArrow" id="selection-menu-button-arrow">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="arrow-type">down</property>
+ <property name="shadow-type">none</property>
+ </object>
+ <packing>
+ <property name="pack-type">start</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <style>
+ <class name="selection-menu"/>
+ </style>
+ </object>
+ <object class="GtkHeaderBar" id="header-bar">
+ <property name="visible">True</property>
+ <property name="vexpand">False</property>
+ <child>
+ <object class="GtkButton" id="search-button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="sensitive">True</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage" id="search-button-image">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">edit-find-symbolic</property>
+ <property name="icon-size">1</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="select-button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="sensitive">True</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage" id="select-button-image">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">object-select-symbolic</property>
+ <property name="icon-size">1</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="done-button">
+ <property name="visible">False</property>
+ <property name="no_show_all">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Cancel</property>
+ <property name="valign">center</property>
+ <property name="sensitive">True</property>
+ <style>
+ <class name="text-button"/>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="back-button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="sensitive">True</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage" id="back-button-image">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">go-previous-symbolic</property>
+ <property name="icon-size">1</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack_type">start</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator" id="close-button-separator">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="valign">fill</property>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="close-button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ <property name="relief">none</property>
+ <property name="sensitive">True</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage" id="close-button-image">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">window-close-symbolic</property>
+ <property name="icon_size">1</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/data/SelectionToolbar.ui b/data/SelectionToolbar.ui
new file mode 100644
index 0000000..bb59e08
--- /dev/null
+++ b/data/SelectionToolbar.ui
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface domain="gnome-music">
+ <!-- interface-requires gtk+ 3.10 -->
+ <object class="GtkEventBox" id="eventbox1">
+ <property name="width_request">-1</property>
+ <property name="height_request">-1</property>
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">False</property>
+ <child>
+ <object class="GtkButtonBox" id="buttonbox1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="margin_left">10</property>
+ <property name="margin_top">10</property>
+ <property name="margin_bottom">10</property>
+ <property name="orientation">vertical</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="button1">
+ <property name="label" translatable="yes">Add to Playlist</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <style>
+ <class name="text-button"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/data/gnome-music.gresource.xml b/data/gnome-music.gresource.xml
index 6e6b91f..24a708c 100644
--- a/data/gnome-music.gresource.xml
+++ b/data/gnome-music.gresource.xml
@@ -7,6 +7,8 @@
<file preprocess="xml-stripblanks">ArtistAlbumWidget.ui</file>
<file preprocess="xml-stripblanks">ArtistAlbumsWidget.ui</file>
<file preprocess="xml-stripblanks">PlayerToolbar.ui</file>
+ <file preprocess="xml-stripblanks">SelectionToolbar.ui</file>
+ <file preprocess="xml-stripblanks">Headerbar.ui</file>
<file preprocess="xml-stripblanks">TrackWidget.ui</file>
<file preprocess="xml-stripblanks">NoMusic.ui</file>
</gresource>
diff --git a/src/player.js b/src/player.js
index 664ab47..b763c52 100644
--- a/src/player.js
+++ b/src/player.js
@@ -803,3 +803,15 @@ const Player = new Lang.Class({
});
Signals.addSignalMethods(Player.prototype);
+
+const SelectionToolbar = new Lang.Class({
+ Name: 'SelectionToolbar',
+ _init: function() {
+ this._ui = new Gtk.Builder();
+ this._ui.add_from_resource('/org/gnome/music/SelectionToolbar.ui');
+ this.eventbox = this._ui.get_object("eventbox1");
+ this._add_to_playlist_button = this._ui.get_object("button1");
+ this.eventbox.set_visible(false);
+ }
+});
+Signals.addSignalMethods(SelectionToolbar.prototype);
diff --git a/src/toolbar.js b/src/toolbar.js
index 14fd249..24e0e2f 100644
--- a/src/toolbar.js
+++ b/src/toolbar.js
@@ -42,16 +42,28 @@ const ToolbarState = {
const Toolbar = new Lang.Class({
Name: 'MainToolbar',
- Extends: Gtk.HeaderBar,
_init: function() {
- this.parent();
this._stack_switcher = new Gtk.StackSwitcher ();
- this.set_custom_title (null);
- this._addBackButton();
- this._addSearchButton();
- this._addSelectButton();
- this._addCloseButton();
+ this._ui = new Gtk.Builder();
+ this._ui.add_from_resource('/org/gnome/music/Headerbar.ui');
+ this.header_bar = this._ui.get_object("header-bar");
+ this._selectButton = this._ui.get_object("select-button");
+ this._cancelButton = this._ui.get_object("done-button");
+ this._backButton = this._ui.get_object("back-button");
+ this._closeSeparator = this._ui.get_object("close-button-separator");
+ this._closeButton = this._ui.get_object("close-button");
+ this._selectionMenu = this._ui.get_object("selection-menu");
+ this._selectionMenuButton = this._ui.get_object("selection-menu-button");
+ this._selectionMenuButton.set_relief(Gtk.ReliefStyle.NONE);
+ this.header_bar.custom_title = this._stack_switcher;
+ this._searchButton = this._ui.get_object("search-button");
+ this._backButton.connect('clicked', Lang.bind(this, this.setState));
+ this._closeButton.connect('clicked', Lang.bind(this, this._closeButtonClicked));
+ },
+
+ _closeButtonClicked: function() {
+ this._closeButton.get_toplevel().close();
},
set_stack: function(stack) {
@@ -65,10 +77,18 @@ const Toolbar = new Lang.Class({
setSelectionMode: function(selectionMode) {
this._selectionMode = selectionMode;
- if (selectionMode)
- this.get_style_context().add_class('selection-mode');
- else
- this.get_style_context().remove_class('selection-mode');
+ if (selectionMode){
+ this._selectButton.hide();
+ this._cancelButton.show();
+ this.header_bar.get_style_context().add_class('selection-mode');
+ this._cancelButton.get_style_context().remove_class('selection-mode');
+ }
+ else{
+ this.header_bar.get_style_context().remove_class('selection-mode');
+ this._selectButton.set_active(false);
+ this._selectButton.show();
+ this._cancelButton.hide();
+ }
this._update();
},
@@ -83,10 +103,10 @@ const Toolbar = new Lang.Class({
_update: function() {
if (this._state == ToolbarState.SINGLE ||
this._selectionMode) {
- this.custom_title = null;
+ this.header_bar.custom_title = null;
} else {
this.title = "";
- this.custom_title = this._stack_switcher;
+ this.header_bar.custom_title = this._stack_switcher;
}
if (this._state == ToolbarState.SINGLE &&
@@ -96,6 +116,7 @@ const Toolbar = new Lang.Class({
this._backButton.hide();
if (this._selectionMode) {
+ this.header_bar.custom_title = this._selectionMenuButton;
this._closeSeparator.hide();
this._closeButton.hide();
} else {
@@ -128,10 +149,6 @@ const Toolbar = new Lang.Class({
this._selectButton.show();
},
- _closeButtonClicked: function() {
- this._closeButton.get_toplevel().close();
- },
-
_addCloseButton: function() {
this._closeSeparator = new Gtk.Separator({ orientation: Gtk.Orientation.VERTICAL });
this.pack_end(this._closeSeparator);
diff --git a/src/view.js b/src/view.js
index 5c26220..7f766f6 100644
--- a/src/view.js
+++ b/src/view.js
@@ -57,7 +57,7 @@ const ViewContainer = new Lang.Class({
Name: "ViewContainer",
Extends: Gtk.Stack,
- _init: function(title, header_bar, use_stack) {
+ _init: function(title, header_bar, selection_toolbar, use_stack) {
this.parent({transition_type: Gtk.StackTransitionType.CROSSFADE});
this._grid = new Gtk.Grid({orientation: Gtk.Orientation.VERTICAL})
this._iconWidth = -1
@@ -84,7 +84,7 @@ const ViewContainer = new Lang.Class({
});
this.view.set_view_type(Gd.MainViewType.ICON);
this.view.set_model(this._model);
-
+ this.selection_toolbar = selection_toolbar;
let _box = new Gtk.Box({orientation: Gtk.Orientation.VERTICAL});
_box.pack_start(this.view, true, true, 0);
if (use_stack){
@@ -111,11 +111,18 @@ const ViewContainer = new Lang.Class({
if (button.get_active()) {
this.view.set_selection_mode(true);
this.header_bar.setSelectionMode(true);
+ this.selection_toolbar.eventbox.set_visible(true);
+ this.selection_toolbar._add_to_playlist_button.sensitive = false;
} else {
this.view.set_selection_mode(false);
this.header_bar.setSelectionMode(false);
+ this.selection_toolbar.eventbox.set_visible(false);
}
}));
+ header_bar._cancelButton.connect('clicked',Lang.bind(this,function(button){
+ this.view.set_selection_mode(false);
+ header_bar.setSelectionMode(false);
+ }));
this.title = title;
this.add(this._grid)
@@ -136,6 +143,10 @@ const ViewContainer = new Lang.Class({
}));
}));
this.header_bar.connect('state-changed', Lang.bind(this, this._onStateChanged))
+ this.view.connect('view-selection-changed',Lang.bind(this,function(){
+ let items = this.view.get_selection();
+ this.selection_toolbar._add_to_playlist_button.sensitive = items.length > 0
+ }));
},
_populate: function() {
@@ -276,8 +287,8 @@ const Albums = new Lang.Class({
Name: "AlbumsView",
Extends: ViewContainer,
- _init: function(header_bar, player){
- this.parent("Albums", header_bar);
+ _init: function(header_bar, selection_toolbar, player){
+ this.parent("Albums", header_bar,selection_toolbar);
this.view.set_view_type(Gd.MainViewType.ICON);
this.countQuery = Query.album_count;
this._albumWidget = new Widgets.AlbumWidget (player);
@@ -296,10 +307,10 @@ const Albums = new Lang.Class({
let title = this._model.get_value (iter, 2);
let artist = this._model.get_value (iter, 3);
let item = this._model.get_value (iter, 5);
- this._albumWidget.update (artist, title, item, this.header_bar);
+ this._albumWidget.update (artist, title, item, this.header_bar,this.selection_toolbar);
this.header_bar.setState (0);
- this.header_bar.title = title;
- this.header_bar.sub_title = artist;
+ this.header_bar.header_bar.title = title;
+ this.header_bar.header_bar.sub_title = artist;
this.visible_child = this._albumWidget;
},
@@ -314,8 +325,8 @@ const Songs = new Lang.Class({
Name: "SongsView",
Extends: ViewContainer,
- _init: function(header_bar, player) {
- this.parent("Songs", header_bar);
+ _init: function(header_bar, selection_toolbar, player) {
+ this.parent("Songs", header_bar, selection_toolbar);
this.countQuery = Query.songs_count;
this._items = {};
this.isStarred = null;
@@ -467,8 +478,8 @@ const Playlists = new Lang.Class({
Name: "PlaylistsView",
Extends: ViewContainer,
- _init: function(header_bar, player) {
- this.parent("Playlists", header_bar);
+ _init: function(header_bar, selection_toolbar, player) {
+ this.parent("Playlists", header_bar, selection_toolbar);
},
});
@@ -476,8 +487,8 @@ const Artists = new Lang.Class({
Name: "ArtistsView",
Extends: ViewContainer,
- _init: function(header_bar, player) {
- this.parent("Artists", header_bar, true);
+ _init: function(header_bar, selection_toolbar ,player) {
+ this.parent("Artists", header_bar, selection_toolbar, true);
this.player = player;
this._artists = {};
this.countQuery = Query.artist_count;
diff --git a/src/widgets.js b/src/widgets.js
index 36fd32a..0d3131d 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -201,7 +201,7 @@ const AlbumWidget = new Lang.Class({
}));
},
- update: function (artist, album, item, header_bar) {
+ update: function (artist, album, item, header_bar,selection_toolbar) {
let released_date = item.get_publication_date();
if (released_date != null) {
this.ui.get_object("released_label_info").set_text(
@@ -270,11 +270,28 @@ const AlbumWidget = new Lang.Class({
if(button.get_active()){
this.view.set_selection_mode(true);
header_bar.setSelectionMode(true);
+ this.player.eventBox.set_visible(false);
+ selection_toolbar.eventbox.set_visible(true);
+ selection_toolbar._add_to_playlist_button.sensitive = false;
}else{
this.view.set_selection_mode(false);
header_bar.setSelectionMode(false);
+ header_bar.title = this.album;
+ selection_toolbar.eventbox.set_visible(false);
+ if(this.player.PlaybackStatus != 'Stopped' ){
+ this.player.eventBox.set_visible(true);
+ }
}
}));
+ header_bar._cancelButton.connect('clicked',Lang.bind(this,function(button){
+ this.view.set_selection_mode(false);
+ header_bar.setSelectionMode(false);
+ header_bar.header_bar.title = this.album;
+ }));
+ this.view.connect('view-selection-changed',Lang.bind(this,function(){
+ let items = this.view.get_selection();
+ selection_toolbar._add_to_playlist_button.sensitive = items.length > 0
+ }));
this.view.set_model(this.model);
let escapedArtist = GLib.markup_escape_text(artist, -1);
let escapedAlbum = GLib.markup_escape_text(album, -1);
diff --git a/src/window.js b/src/window.js
index 5a24c5b..7752ed0 100644
--- a/src/window.js
+++ b/src/window.js
@@ -99,9 +99,9 @@ const MainWindow = new Lang.Class({
});
this.views = [];
this.player = new Player.Player();
-
+ this.selection_toolbar = new Player.SelectionToolbar();
this.toolbar = new Toolbar.Toolbar();
- this.set_titlebar(this.toolbar);
+ this.set_titlebar(this.toolbar.header_bar);
this._stack = new Gtk.Stack({
transition_type: Gtk.StackTransitionType.CROSSFADE,
transition_duration: 100,
@@ -111,6 +111,7 @@ const MainWindow = new Lang.Class({
this._box.pack_start(this._stack, true, true, 0);
this._box.pack_start(this.player.eventBox, false, false, 0);
+ this._box.pack_start(this.selection_toolbar.eventbox,false, false, 0);
this.add(this._box);
let count = -1;
let cursor = tracker.query(Query.songs_count, null)
@@ -118,10 +119,11 @@ const MainWindow = new Lang.Class({
count = cursor.get_integer(0);
if(count > 0)
{
- this.views[0] = new Views.Albums(this.toolbar, this.player);
- this.views[1] = new Views.Artists(this.toolbar, this.player);
- this.views[2] = new Views.Songs(this.toolbar, this.player);
- this.views[3] = new Views.Playlists(this.toolbar, this.player);
+ this.views[0] = new Views.Albums(this.toolbar, this.selection_toolbar, this.player);
+ this.views[1] = new Views.Artists(this.toolbar, this.selection_toolbar, this.player);
+ this.views[2] = new Views.Songs(this.toolbar, this.selection_toolbar, this.player);
+ this.views[3] = new Views.Playlists(this.toolbar, this.selection_toolbar, this.player);
+
for (let i in this.views) {
this._stack.add_titled(
@@ -143,8 +145,7 @@ const MainWindow = new Lang.Class({
this.views[0] = new Views.Empty(this.toolbar, this.player);
this._stack.add_titled(this.views[0],"Empty","Empty");
}
-
- this.toolbar.show();
+ this.toolbar.header_bar.show();
this.player.eventBox.show_all();
this._box.show();
this.show();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]