[banshee/better-now-playing] [NowPlaying] Add BaseContextiew and port ContextPane to use it.



commit 532702ad2a53241ceb63ecfb525633ac63814136
Author: Alex Launi <alex launi gmail com>
Date:   Thu Jun 3 20:51:19 2010 -0400

    [NowPlaying] Add BaseContextiew and port ContextPane to use it.
    
    Added base class that abstracts some of the context page display
    logic so that Now Playing can do a better job of displaying context
    page information, and ported ContextPane to use it.

 .../Banshee.ContextPane/BaseContextView.cs         |  132 ++++++++++++++++++++
 .../Banshee.ContextPane/ContextPageManager.cs      |   40 +++++--
 .../Banshee.ContextPane/ContextPane.cs             |  109 +++--------------
 .../Banshee.ThickClient/Banshee.ThickClient.csproj |    1 +
 src/Core/Banshee.ThickClient/Makefile.am           |    1 +
 .../Banshee.NowPlaying/Actions.cs                  |   63 ++++++----
 6 files changed, 223 insertions(+), 123 deletions(-)
---
diff --git a/src/Core/Banshee.ThickClient/Banshee.ContextPane/BaseContextView.cs b/src/Core/Banshee.ThickClient/Banshee.ContextPane/BaseContextView.cs
new file mode 100644
index 0000000..b9be806
--- /dev/null
+++ b/src/Core/Banshee.ThickClient/Banshee.ContextPane/BaseContextView.cs
@@ -0,0 +1,132 @@
+// 
+// BaseContextView.cs
+// 
+// Author:
+//   Alex Launi <alex launi gmail com>
+// 
+// Copyright (c) 2010 Alex Launi
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+
+using Gtk;
+using Mono.Unix;
+
+using Banshee.Collection;
+using Banshee.Configuration;
+using Banshee.MediaEngine;
+using Banshee.ServiceStack;
+
+using Hyena.Gui;
+using Hyena.Widgets;
+
+namespace Banshee.ContextPane
+{
+    public abstract class BaseContextView : HBox
+    {
+        protected Gtk.Notebook notebook;
+
+        protected RoundedFrame loading;
+        protected RoundedFrame no_active;
+        protected BaseContextPage active_page;
+
+        protected Dictionary<BaseContextPage, Widget> pane_pages;
+
+        public BaseContextView ()
+        {
+            pane_pages = new Dictionary<BaseContextPage, Widget> ();
+            ServiceManager.PlayerEngine.ConnectEvent (OnPlayerEvent, PlayerEvent.StartOfStream | PlayerEvent.TrackInfoUpdated);
+        }
+
+        public ContextPageManager Manager { get; protected set; }
+
+        protected void CreateContextNotebook ()
+        {
+            notebook = new Notebook () {
+                ShowBorder = false,
+                ShowTabs = false
+            };
+
+            // 'No active track' and 'Loading' widgets
+            no_active = new RoundedFrame ();
+            no_active.Add (new Label () {
+                Markup = String.Format ("<b>{0}</b>", Catalog.GetString ("Waiting for playback to begin..."))
+            });
+            no_active.ShowAll ();
+            notebook.Add (no_active);
+
+            loading = new RoundedFrame ();
+            loading.Add (new Label () { Markup = String.Format ("<b>{0}</b>", Catalog.GetString ("Loading...")) });
+            loading.ShowAll ();
+            notebook.Add (loading);
+
+            PackStart (notebook, true, true, 0);
+            notebook.Show ();
+        }
+
+        public virtual void SetActivePage (BaseContextPage page)
+        {
+            if (page == null || page == active_page) {
+                return;
+            }
+
+            if (active_page != null) {
+                active_page.StateChanged -= OnActivePageStateChanged;
+            }
+
+            active_page = page;
+            active_page.StateChanged += OnActivePageStateChanged;
+            OnActivePageStateChanged (active_page.State);
+            SetCurrentTrackForActivePage ();
+        }
+
+        protected abstract bool Enabled { get; set; }
+
+        protected virtual void OnActivePageStateChanged (ContextState state)
+        {
+            if (active_page == null) {
+                return;
+            }
+
+            if (state == ContextState.NotLoaded)
+                notebook.CurrentPage = notebook.PageNum (no_active);
+            else if (state == ContextState.Loading)
+                notebook.CurrentPage = notebook.PageNum (loading);
+            else if (state == ContextState.Loaded)
+                notebook.CurrentPage = notebook.PageNum (pane_pages[active_page]);
+        }
+
+        protected virtual void OnPlayerEvent (PlayerEventArgs args)
+        {
+            if (Enabled) {
+                SetCurrentTrackForActivePage ();
+            }
+        }
+
+        protected void SetCurrentTrackForActivePage ()
+        {
+            TrackInfo track = ServiceManager.PlayerEngine.CurrentTrack;
+            if (track != null && active_page != null) {
+                active_page.SetTrack (track);
+            }
+        }
+    }
+}
diff --git a/src/Core/Banshee.ThickClient/Banshee.ContextPane/ContextPageManager.cs b/src/Core/Banshee.ThickClient/Banshee.ContextPane/ContextPageManager.cs
index 8f33b75..dffaaf6 100644
--- a/src/Core/Banshee.ThickClient/Banshee.ContextPane/ContextPageManager.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.ContextPane/ContextPageManager.cs
@@ -36,30 +36,50 @@ namespace Banshee.ContextPane
 {
     public class ContextPageManager
     {
-        private ContextPane pane;
         private Dictionary<string, BaseContextPage> pages = new Dictionary<string, BaseContextPage> ();
 
-        public ContextPageManager (ContextPane pane)
+        public event Action<BaseContextPage> PageAdded;
+        public event Action<BaseContextPage> PageRemoved;
+
+        public ContextPageManager ()
+        {
+        }
+
+        public void Init ()
         {
-            this.pane = pane;
             Mono.Addins.AddinManager.AddExtensionNodeHandler ("/Banshee/ThickClient/ContextPane", OnExtensionChanged);
         }
 
+        public IEnumerable<BaseContextPage> Pages {
+            get {
+                return pages.Values;
+            }
+        }
+
         private void OnExtensionChanged (object o, ExtensionNodeEventArgs args)
         {
-            TypeExtensionNode node = (TypeExtensionNode)args.ExtensionNode;
+            TypeExtensionNode node = (TypeExtensionNode) args.ExtensionNode;
 
             if (args.Change == ExtensionChange.Add) {
                 var page = (BaseContextPage) node.CreateInstance ();
-                pane.AddPage (page);
                 pages.Add (node.Id, page);
+                var handler = PageAdded;
+                if (handler != null) {
+                    handler (page);
+                }
             } else {
-                if (pages.ContainsKey (node.Id)) {
-                    var page = pages[node.Id];
-                    pane.RemovePage (page);
-                    page.Dispose ();
-                    pages.Remove (node.Id);
+                if (!pages.ContainsKey (node.Id)) {
+                    return;
                 }
+
+                var page = pages[node.Id];
+                var handler = PageRemoved;
+                if (handler != null) {
+                    PageRemoved (page);
+                }
+
+                page.Dispose ();
+                pages.Remove (node.Id);
             }
         }
     }
diff --git a/src/Core/Banshee.ThickClient/Banshee.ContextPane/ContextPane.cs b/src/Core/Banshee.ThickClient/Banshee.ContextPane/ContextPane.cs
index 5f11b1a..dfc30b9 100644
--- a/src/Core/Banshee.ThickClient/Banshee.ContextPane/ContextPane.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.ContextPane/ContextPane.cs
@@ -46,54 +46,45 @@ using Banshee.Gui;
 
 namespace Banshee.ContextPane
 {
-    public class ContextPane : Gtk.HBox
+    public class ContextPane : BaseContextView
     {
         private object tooltip_host = TooltipSetter.CreateHost ();
 
-        private Gtk.Notebook notebook;
         private VBox vbox;
         private bool large = false;
         private bool initialized = false;
 
-        private RoundedFrame no_active;
-        private RoundedFrame loading;
-
         private RadioButton radio_group = new RadioButton (null, "");
 
         private Dictionary<BaseContextPage, RadioButton> pane_tabs = new Dictionary<BaseContextPage, RadioButton> ();
-        private Dictionary<BaseContextPage, Widget> pane_pages = new Dictionary<BaseContextPage, Widget> ();
-        private List<BaseContextPage> pages = new List<BaseContextPage> ();
-        private BaseContextPage active_page;
 
         private Action<bool> expand_handler;
         public Action<bool> ExpandHandler {
             set { expand_handler = value; }
         }
 
-        public List<BaseContextPage> Pages {
-            get { return pages; }
-        }
-
         public bool Large {
             get { return large; }
         }
 
-        public ContextPane ()
+        public ContextPane () : base ()
         {
             HeightRequest = 200;
 
             CreateContextNotebook ();
             CreateTabButtonBox ();
 
-            new ContextPageManager (this);
+            Manager = new ContextPageManager ();
+            Manager.PageAdded += OnPageAdded;
+            Manager.PageRemoved += OnPageRemoved;
+            Manager.Init ();
+
             initialized = true;
 
             RestoreLastActivePage ();
 
             Enabled = ShowSchema.Get ();
             ShowAction.Activated += OnShowContextPane;
-
-            ServiceManager.PlayerEngine.ConnectEvent (OnPlayerEvent, PlayerEvent.StartOfStream | PlayerEvent.TrackInfoUpdated);
         }
 
         private void RestoreLastActivePage ()
@@ -101,7 +92,7 @@ namespace Banshee.ContextPane
             // TODO restore the last page
             string last_id = LastContextPageSchema.Get ();
             if (!String.IsNullOrEmpty (last_id)) {
-                var page = pages.FirstOrDefault (p => p.Id == last_id);
+                var page = Manager.Pages.FirstOrDefault (p => p.Id == last_id);
                 if (page != null) {
                     SetActivePage (page);
                     pane_tabs[page].Active = true;
@@ -135,58 +126,13 @@ namespace Banshee.ContextPane
             vbox.ShowAll ();
         }
 
-        private void CreateContextNotebook ()
-        {
-            notebook = new Notebook () {
-                ShowBorder = false,
-                ShowTabs = false
-            };
-
-            // 'No active track' and 'Loading' widgets
-            no_active = new RoundedFrame ();
-            no_active.Add (new Label () {
-                Markup = String.Format ("<b>{0}</b>", Catalog.GetString ("Waiting for playback to begin..."))
-            });
-            no_active.ShowAll ();
-            notebook.Add (no_active);
-
-            loading = new RoundedFrame ();
-            loading.Add (new Label () { Markup = String.Format ("<b>{0}</b>", Catalog.GetString ("Loading...")) });
-            loading.ShowAll ();
-            notebook.Add (loading);
-
-            PackStart (notebook, true, true, 0);
-            notebook.Show ();
-
-        }
-
-        private void OnPlayerEvent (PlayerEventArgs args)
-        {
-            if (Enabled) {
-                SetCurrentTrackForActivePage ();
-            }
-        }
-
-        private void SetCurrentTrackForActivePage ()
-        {
-            TrackInfo track = ServiceManager.PlayerEngine.CurrentTrack;
-            if (track != null && active_page != null) {
-                active_page.SetTrack (track);
-            }
-        }
-
-        private void OnActivePageStateChanged (ContextState state)
+        protected override void OnActivePageStateChanged (ContextState state)
         {
-            if (active_page == null || !pane_pages.ContainsKey (active_page)) {
+            if (!pane_pages.ContainsKey (active_page)) {
                 return;
             }
 
-            if (state == ContextState.NotLoaded)
-                notebook.CurrentPage = notebook.PageNum (no_active);
-            else if (state == ContextState.Loading)
-                notebook.CurrentPage = notebook.PageNum (loading);
-            else if (state == ContextState.Loaded)
-                notebook.CurrentPage = notebook.PageNum (pane_pages[active_page]);
+            base.OnActivePageStateChanged (state);
         }
 
         private Gtk.ToggleAction ShowAction {
@@ -198,7 +144,7 @@ namespace Banshee.ContextPane
             Enabled = ShowAction.Active;
         }
 
-        private bool Enabled {
+        protected override bool Enabled {
             get { return ShowSchema.Get (); }
             set {
                 ShowSchema.Set (value);
@@ -209,7 +155,7 @@ namespace Banshee.ContextPane
 
         private void UpdateVisibility ()
         {
-            int npages = pages.Count;
+            int npages = Manager.Pages.Count ();
             bool enabled = Enabled;
 
             ShowAction.Sensitive = npages > 0;
@@ -227,22 +173,7 @@ namespace Banshee.ContextPane
             vbox.Visible = true;//enabled && npages > 1;
         }
 
-        public void SetActivePage (BaseContextPage page)
-        {
-            if (page == null || page == active_page)
-                return;
-
-            if (active_page != null)
-                active_page.StateChanged -= OnActivePageStateChanged;
-
-            active_page = page;
-            active_page.StateChanged += OnActivePageStateChanged;
-            LastContextPageSchema.Set (page.Id);
-            OnActivePageStateChanged (active_page.State);
-            SetCurrentTrackForActivePage ();
-        }
-
-        public void AddPage (BaseContextPage page)
+        private void OnPageAdded (BaseContextPage page)
         {
             Hyena.Log.DebugFormat ("Adding context page {0}", page.Id);
 
@@ -285,9 +216,7 @@ namespace Banshee.ContextPane
             vbox.PackStart (toggle_button, false, false, 0);
             pane_tabs[page] = toggle_button;
 
-            pages.Add (page);
-
-            if (initialized && pages.Count == 1) {
+            if (initialized && Manager.Pages.Count () == 1) {
                 SetActivePage (page);
                 toggle_button.Active = true;
             }
@@ -295,7 +224,7 @@ namespace Banshee.ContextPane
             UpdateVisibility ();
         }
 
-        public void RemovePage (BaseContextPage page)
+        private void OnPageRemoved (BaseContextPage page)
         {
             Hyena.Log.DebugFormat ("Removing context page {0}", page.Id);
             // Remove the notebook page
@@ -307,8 +236,6 @@ namespace Banshee.ContextPane
             vbox.Remove (pane_tabs[page]);
             pane_tabs.Remove (page);
 
-            pages.Remove (page);
-
             // Set a new page as the default
             if (was_active) {
                 ActivateFirstPage ();
@@ -319,8 +246,8 @@ namespace Banshee.ContextPane
 
         private void ActivateFirstPage ()
         {
-            if (pages.Count > 0) {
-                SetActivePage (pages[0]);
+            if (Manager.Pages.Count () > 0) {
+                SetActivePage (Manager.Pages.First ());
                 pane_tabs[active_page].Active = true;
             }
         }
diff --git a/src/Core/Banshee.ThickClient/Banshee.ThickClient.csproj b/src/Core/Banshee.ThickClient/Banshee.ThickClient.csproj
index b389433..18dac92 100644
--- a/src/Core/Banshee.ThickClient/Banshee.ThickClient.csproj
+++ b/src/Core/Banshee.ThickClient/Banshee.ThickClient.csproj
@@ -310,6 +310,7 @@
     <Compile Include="Banshee.Gui.Widgets\CoverArtDisplay.cs" />
     <Compile Include="Banshee.CairoGlyphs\BansheeLineLogo.cs" />
     <Compile Include="Banshee.Gui\IGlobalUIActions.cs" />
+    <Compile Include="Banshee.ContextPane\BaseContextView.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ProjectExtensions>
diff --git a/src/Core/Banshee.ThickClient/Makefile.am b/src/Core/Banshee.ThickClient/Makefile.am
index 1f1b999..d254178 100644
--- a/src/Core/Banshee.ThickClient/Makefile.am
+++ b/src/Core/Banshee.ThickClient/Makefile.am
@@ -39,6 +39,7 @@ SOURCES =  \
 	Banshee.Collection.Gui/TrackListView.cs \
 	Banshee.Collection.Gui/XmlColumnController.cs \
 	Banshee.ContextPane/BaseContextPage.cs \
+	Banshee.ContextPane/BaseContextView.cs \
 	Banshee.ContextPane/ContextPageManager.cs \
 	Banshee.ContextPane/ContextPane.cs \
 	Banshee.Equalizer.Gui/EqualizerBandScale.cs \
diff --git a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/Actions.cs b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/Actions.cs
index 8e8d47e..336e630 100644
--- a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/Actions.cs
+++ b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/Actions.cs
@@ -45,20 +45,47 @@ namespace Banshee.NowPlaying
     {
         public const string TrackInfoId = "StandardNpOpen";
 
-        private Dictionary<int, BaseContextPage> pages;
         private NowPlayingSource now_playing_source;
+        private Dictionary<int, BaseContextPage> pages;
 
         public Actions (NowPlayingSource nowPlayingSource) : base ("NowPlaying")
         {
-            int i = 0;
             now_playing_source = nowPlayingSource;
             pages = new Dictionary<int, BaseContextPage> ();
-            ContextPane = new ContextPane.ContextPane ();
-            List<RadioActionEntry> actions = new List<RadioActionEntry> ();
 
+            Manager = new ContextPageManager ();
+            Manager.Init ();
+            Manager.PageAdded += OnContextPagesChanged;
+            Manager.PageRemoved += OnContextPagesChanged;
+
+            LoadActions ();
+
+            Register ();
+        }
+
+        // We've got 1 hard coded action available and the rest come from the context pane.
+        // so we loop through our pages and get their ids and return an IEnumerable with them all.
+        public IEnumerable<string> PageIds {
+            get {
+                return new string [] { TrackInfoId }.Concat (pages.Values.Select (p => p.Id));
+            }
+        }
+
+        private ContextPageManager Manager { get; set; }
+
+        private void LoadActions ()
+        {
+            // remove all of the existing actions
+            foreach (Gtk.Action action in ListActions ()) {
+                Remove (action);
+            }
+
+            // then add them all.
+            int i = 0;
+            List<RadioActionEntry> actions = new List<RadioActionEntry> ();
             actions.Add (new RadioActionEntry (TrackInfoId, null, null, null, "Track Information", i));
 
-            foreach (BaseContextPage page in ContextPane.Pages) {
+            foreach (BaseContextPage page in Manager.Pages) {
                 i++;
                 actions.Add (new RadioActionEntry (page.Id, null, null, null, page.Name, i));
                 pages.Add (i, page);
@@ -67,7 +94,7 @@ namespace Banshee.NowPlaying
             Add (actions.ToArray (), 0, OnChanged);
 
             this[TrackInfoId].IconName = "applications-multimedia";
-            foreach (BaseContextPage page in ContextPane.Pages) {
+            foreach (BaseContextPage page in Manager.Pages) {
                 foreach (string icon in page.IconNames) {
                     if (IconThemeUtils.HasIcon (icon)) {
                         this[page.Id].IconName = icon;
@@ -75,30 +102,22 @@ namespace Banshee.NowPlaying
                     }
                 }
             }
-
-            Register ();
-        }
-
-        // We've got 1 hard coded action available and the rest come from the context pane.
-        // so we loop through our pages and get their ids and return an IEnumerable with them all.
-        public IEnumerable<string> PageIds {
-            get {
-                return new string [] { TrackInfoId }.Concat (pages.Values.Select (p => p.Id));
-            }
         }
 
-        public void OnChanged (System.Object o, ChangedArgs args)
+        private void OnChanged (System.Object o, ChangedArgs args)
         {
-            Log.DebugFormat ("There are {0} actions. {1} is current", this.ListActions().Count (), args.Current.CurrentValue);
-
             if (args.Current.CurrentValue == 0) {
                 now_playing_source.SetSubstituteAudioDisplay (null);
             } else {
-                ContextPane.SetActivePage (pages[args.Current.CurrentValue]);
-                now_playing_source.SetSubstituteAudioDisplay (ContextPane);
+                Widget widget = pages[args.Current.CurrentValue].Widget;
+                now_playing_source.SetSubstituteAudioDisplay (widget);
+                widget.Show ();
             }
         }
 
-        private ContextPane.ContextPane ContextPane { get; set; }
+        private void OnContextPagesChanged (BaseContextPage page)
+        {
+            LoadActions ();
+        }
     }
 }



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