[gnome-music] added headerbar and selection toolbar.



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">&lt;Primary&gt;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]