[banshee/source-contents] 2009-03-04 Gabriel Burt <gabriel burt gmail com>
- From: Gabriel Burt <gburt src gnome org>
- To: svn-commits-list gnome org
- Subject: [banshee/source-contents] 2009-03-04 Gabriel Burt <gabriel burt gmail com>
- Date: Mon, 4 May 2009 20:40:41 -0400 (EDT)
commit d9ff21cca37ed96b850fe775ba48c72c999b6a76
Author: Gabriel Burt <gabriel burt gmail com>
Date: Mon Mar 2 17:19:12 2009 -0600
2009-03-04 Gabriel Burt <gabriel burt gmail com>
This patch lets extensions provide alternate views ("contents") for
sources, and lets users switch between them via a menu.
* src/Clients/Nereid/Nereid/PlayerInterface.cs: Delegate to the
ViewContainer to setup the content when the source changes.
* src/Clients/Nereid/Nereid/ViewContainer.cs: Add a title button that is
shown if there is more than one content extension available for a given
source (otherwise just a label is shown as before). Put all the sources'
contents into a SourceContentNotebook, and use update the content (and
content options) with the new SourceContentManager.
* src/Core/Banshee.ThickClient/Banshee.Gui/CommonServices.cs: Register the
SourceContentManager.
* src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs:
* src/Core/Banshee.ThickClient/Banshee.Sources.Gui/ObjectListSourceContents.cs:
Add a SourceContentProvider subclass/extension.
* src/Core/Banshee.ThickClient/Banshee.ThickClient.addin.xml: Declare the
new SourceContentProvider extension point, and the two above extensions.
* src/Core/Banshee.ThickClient/Banshee.Sources.Gui/ISourceContents.cs:
Update header.
* src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentManager.cs:
New service that loads /Banshee/ThickClient/SourceContentProvider
extensions, and has methods for getting the contents that support a given
source.
* src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentMenu.cs:
New Menu subclass that has one item per content that a source supports,
and when clicked it switches to that page in the associated Notebook.
* src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentNotebook.cs:
New Notebook subclass that knows how to Activate (create/switch to) the
hidden tab for a particular SourceContentProvider's content; also saves
the id of the last activated content provider.
* src/Core/Banshee.ThickClient/Makefile.am: Add the three new files above.
* src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying.addin.xml:
* src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingInterface.cs:
* src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs:
Intead of explicitly defining the content for the Now Playing source, just
declare a content extension that is compatible with it. This should make
it pretty easy to add other content, such as visualization.
---
ChangeLog | 50 +++++++
src/Clients/Nereid/Nereid/PlayerInterface.cs | 35 +-----
src/Clients/Nereid/Nereid/ViewContainer.cs | 127 ++++++++++++------
.../Banshee.Gui/CommonServices.cs | 1 +
.../CompositeTrackSourceContents.cs | 28 ++++
.../Banshee.Sources.Gui/ISourceContents.cs | 2 +-
.../ObjectListSourceContents.cs | 27 ++++
.../Banshee.Sources.Gui/SourceContentManager.cs | 136 ++++++++++++++++++++
.../Banshee.Sources.Gui/SourceContentMenu.cs | 81 ++++++++++++
.../Banshee.Sources.Gui/SourceContentNotebook.cs | 81 ++++++++++++
.../Banshee.ThickClient.addin.xml | 11 +-
src/Core/Banshee.ThickClient/Makefile.am | 3 +
.../Banshee.NowPlaying.addin.xml | 4 +
.../Banshee.NowPlaying/NowPlayingInterface.cs | 28 ++++
.../Banshee.NowPlaying/NowPlayingSource.cs | 19 +--
15 files changed, 543 insertions(+), 90 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index aca54cc..91850e7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -776,6 +776,56 @@
2009-03-04 Gabriel Burt <gabriel burt gmail com>
+ This patch lets extensions provide alternate views ("contents") for
+ sources, and lets users switch between them via a menu.
+
+ * src/Clients/Nereid/Nereid/PlayerInterface.cs: Delegate to the
+ ViewContainer to setup the content when the source changes.
+
+ * src/Clients/Nereid/Nereid/ViewContainer.cs: Add a title button that is
+ shown if there is more than one content extension available for a given
+ source (otherwise just a label is shown as before). Put all the sources'
+ contents into a SourceContentNotebook, and use update the content (and
+ content options) with the new SourceContentManager.
+
+ * src/Core/Banshee.ThickClient/Banshee.Gui/CommonServices.cs: Register the
+ SourceContentManager.
+
+ * src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs:
+ * src/Core/Banshee.ThickClient/Banshee.Sources.Gui/ObjectListSourceContents.cs:
+ Add a SourceContentProvider subclass/extension.
+
+ * src/Core/Banshee.ThickClient/Banshee.ThickClient.addin.xml: Declare the
+ new SourceContentProvider extension point, and the two above extensions.
+
+ * src/Core/Banshee.ThickClient/Banshee.Sources.Gui/ISourceContents.cs:
+ Update header.
+
+ * src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentManager.cs:
+ New service that loads /Banshee/ThickClient/SourceContentProvider
+ extensions, and has methods for getting the contents that support a given
+ source.
+
+ * src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentMenu.cs:
+ New Menu subclass that has one item per content that a source supports,
+ and when clicked it switches to that page in the associated Notebook.
+
+ * src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentNotebook.cs:
+ New Notebook subclass that knows how to Activate (create/switch to) the
+ hidden tab for a particular SourceContentProvider's content; also saves
+ the id of the last activated content provider.
+
+ * src/Core/Banshee.ThickClient/Makefile.am: Add the three new files above.
+
+ * src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying.addin.xml:
+ * src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingInterface.cs:
+ * src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs:
+ Intead of explicitly defining the content for the Now Playing source, just
+ declare a content extension that is compatible with it. This should make
+ it pretty easy to add other content, such as visualization.
+
+2009-03-04 Gabriel Burt <gabriel burt gmail com>
+
* src/Core/Banshee.Core/Resources/contributors.xml: Add a bunch of people
as developers and contributors, most of whom should have been in here for
some time.
diff --git a/src/Clients/Nereid/Nereid/PlayerInterface.cs b/src/Clients/Nereid/Nereid/PlayerInterface.cs
index 1b95574..f2fa914 100644
--- a/src/Clients/Nereid/Nereid/PlayerInterface.cs
+++ b/src/Clients/Nereid/Nereid/PlayerInterface.cs
@@ -65,8 +65,6 @@ namespace Nereid
// Major Interaction Components
private SourceView source_view;
- private CompositeTrackSourceContents composite_view;
- private ObjectListSourceContents object_view;
private Label status_label;
protected PlayerInterface (IntPtr ptr) : base (ptr)
@@ -84,8 +82,6 @@ namespace Nereid
ActionService.SourceActions.SourceView = this;
- composite_view.TrackView.HasFocus = true;
-
InitialShowPresent ();
}
@@ -161,14 +157,10 @@ namespace Nereid
view_container = new ViewContainer ();
source_view = new SourceView ();
- composite_view = new CompositeTrackSourceContents ();
Hyena.Widgets.ScrolledWindow source_scroll = new Hyena.Widgets.ScrolledWindow ();
source_scroll.AddWithFrame (source_view);
- composite_view.TrackView.HeaderVisible = false;
- view_container.Content = composite_view;
-
source_box.PackStart (source_scroll, true, true, 0);
source_box.PackStart (new UserJobTileHost (), false, false, 0);
@@ -341,34 +333,9 @@ namespace Nereid
if (source == null) {
return;
}
-
- // Connect the source models to the views if possible
- ISourceContents contents = source.GetProperty<ISourceContents> ("Nereid.SourceContents",
- source.GetInheritedProperty<bool> ("Nereid.SourceContentsPropagate"));
view_container.ClearFooter ();
-
- if (contents != null) {
- if (view_container.Content != contents) {
- view_container.Content = contents;
- }
- view_container.Content.SetSource (source);
- view_container.Show ();
- } else if (source is ITrackModelSource) {
- view_container.Content = composite_view;
- view_container.Content.SetSource (source);
- view_container.Show ();
- } else if (source is Hyena.Data.IObjectListModel) {
- if (object_view == null) {
- object_view = new ObjectListSourceContents ();
- }
-
- view_container.Content = object_view;
- view_container.Content.SetSource (source);
- view_container.Show ();
- } else {
- view_container.Hide ();
- }
+ view_container.SetSource (source);
// Associate the view with the model
if (view_container.Visible && view_container.Content is ITrackModelSourceContents) {
diff --git a/src/Clients/Nereid/Nereid/ViewContainer.cs b/src/Clients/Nereid/Nereid/ViewContainer.cs
index 41c51c3..b4c504d 100644
--- a/src/Clients/Nereid/Nereid/ViewContainer.cs
+++ b/src/Clients/Nereid/Nereid/ViewContainer.cs
@@ -31,6 +31,8 @@ using System.Collections.Generic;
using Gtk;
using Mono.Unix;
+using Hyena.Widgets;
+
using Banshee.Widgets;
using Banshee.Gui.Widgets;
using Banshee.Sources.Gui;
@@ -38,25 +40,37 @@ using Banshee.Collection;
using Banshee.Gui;
using Banshee.ServiceStack;
+using Banshee.Sources;
namespace Nereid
{
-
public class ViewContainer : VBox
{
private SearchEntry search_entry;
private HBox header;
+ private Label title_button_label;
private Label title_label;
+ private SourceContentMenu content_menu;
private Label search_label;
private VBox footer;
+ private MenuButton title_button;
private ISourceContents content;
+ private ISourceContents explicit_content;
+ private SourceContentNotebook notebook;
+
+ private SourceContentManager content_manager;
public ViewContainer ()
{
- BuildHeader ();
-
Spacing = 8;
+ content_manager = ServiceManager.Get<SourceContentManager> ();
+ notebook = new SourceContentNotebook ();
+
+ BuildHeader ();
+
+ PackStart (notebook, true, true, 0);
+
SearchSensitive = false;
}
@@ -65,32 +79,30 @@ namespace Nereid
header = new HBox ();
footer = new VBox ();
- EventBox title_box = new EventBox ();
+ content_menu = new SourceContentMenu (notebook);
+
title_label = new Label ();
title_label.Xalign = 0.0f;
- title_label.Ellipsize = Pango.EllipsizeMode.End;
+ title_label.Xpad = 6;
+ title_label.Ypad = 6;
+ title_label.NoShowAll = true;
- title_box.Add (title_label);
+ title_button_label = new Label ();
+ title_button_label.Xalign = 0.0f;
+ title_button_label.Xpad = 6;
+ title_button_label.Ypad = 6;
- // Show the source context menu when the title is right clicked
- title_box.PopupMenu += delegate {
- ServiceManager.Get<InterfaceActionService> ().SourceActions ["SourceContextMenuAction"].Activate ();
- };
+ title_button = new MenuButton (title_button_label, content_menu, true);
- title_box.ButtonPressEvent += delegate (object o, ButtonPressEventArgs press) {
- if (press.Event.Button == 3) {
- ServiceManager.Get<InterfaceActionService> ().SourceActions ["SourceContextMenuAction"].Activate ();
- }
- };
-
BuildSearchEntry ();
search_label = new Label (Catalog.GetString ("_Search:"));
search_label.MnemonicWidget = search_entry.InnerEntry;
- header.PackStart (title_box, true, true, 0);
- header.PackStart (search_label, false, false, 5);
- header.PackStart (search_entry, false, false, 0);
+ header.PackStart (title_label, false, false, 0);
+ header.PackStart (title_button, false, false, 0);
+ header.PackEnd (search_entry, false, false, 0);
+ header.PackEnd (search_label, false, false, 5);
InterfaceActionService uia = ServiceManager.Get<InterfaceActionService> ();
if (uia != null) {
@@ -201,36 +213,69 @@ namespace Nereid
public SearchEntry SearchEntry {
get { return search_entry; }
}
-
- public ISourceContents Content {
- get { return content; }
- set {
- if (content == value) {
- return;
- }
- // Hide the old content widget
- if (content != null && content.Widget != null) {
- content.Widget.Hide ();
- }
+ public void SetSource (Source source)
+ {
+ if (source == null) {
+ return;
+ }
+
+ bool show_menu = false;
+
+ if (explicit_content != null) {
+ explicit_content.Widget.Hide ();
+ }
+
+ // If the Source has an explicit view set in its Properties, then honor that, otherwise
+ // determine what content to show from the content extensions that are compatible
+ explicit_content = source.GetProperty<ISourceContents> ("Nereid.SourceContents",
+ source.GetInheritedProperty<bool> ("Nereid.SourceContentsPropagate"));
- // Add and show the new one
- if (value != null && value.Widget != null) {
- PackStart (value.Widget, true, true, 0);
- value.Widget.Show ();
+ if (explicit_content != null) {
+ Hyena.Log.DebugFormat ("Honoring explicit content request ({0}) from source ({1})", explicit_content, source);
+ explicit_content.SetSource (source);
+ notebook.Hide ();
+ if (explicit_content.Widget.Parent == null) {
+ PackStart (explicit_content.Widget, true, true, 0);
}
-
- // Remove the old one
- if (content != null && content.Widget != null) {
- Remove (content.Widget);
+ explicit_content.Widget.Show ();
+ } else {
+ List<SourceContentProvider> providers = new List<SourceContentProvider> (content_manager.GetProvidersFor (source));
+ SourceContentProvider default_provider = content_manager.GetLastOrDefaultProviderFor (source);
+ if (default_provider == null) {
+ Hyena.Log.ErrorFormat ("No default content provider found for source '{0}' (type {1})", source, source.GetType ());
+ source.SetStatus (Catalog.GetString ("Error: No view found for this source"), true);
+ notebook.Hide ();
+ return;
}
-
- content = value;
+
+ notebook.SetSource (source, default_provider);
+ content_menu.SetSource (source, providers, default_provider);
+
+ show_menu = (content_menu.Children.Length > 1);
+ notebook.Show ();
}
+
+ if (show_menu) {
+ title_label.Hide ();
+ content_menu.ShowAll ();
+ title_button.Show ();
+ } else {
+ title_button.Hide ();
+ title_label.Show ();
+ }
+
+ Show ();
+ }
+
+ public ISourceContents Content {
+ get { return content; }
}
public string Title {
- set { title_label.Markup = String.Format ("<b>{0}</b>", GLib.Markup.EscapeText (value)); }
+ set {
+ title_button_label.Markup = title_label.Markup = String.Format ("<b>{0}</b>", GLib.Markup.EscapeText (value));
+ }
}
public bool SearchSensitive {
diff --git a/src/Core/Banshee.ThickClient/Banshee.Gui/CommonServices.cs b/src/Core/Banshee.ThickClient/Banshee.Gui/CommonServices.cs
index 6f336b3..8961f4a 100644
--- a/src/Core/Banshee.ThickClient/Banshee.Gui/CommonServices.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.Gui/CommonServices.cs
@@ -38,6 +38,7 @@ namespace Banshee.Gui
{
ServiceManager.RegisterService <Banshee.Gui.GtkElementsService> ();
ServiceManager.RegisterService <Banshee.Gui.InterfaceActionService> ();
+ ServiceManager.RegisterService <Banshee.Sources.Gui.SourceContentManager> ();
ServiceManager.RegisterService <Banshee.Collection.Gui.ArtworkManager> ();
}
}
diff --git a/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs
index 8be3609..1374b4f 100644
--- a/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs
@@ -48,6 +48,34 @@ using Banshee.Collection.Gui;
namespace Banshee.Sources.Gui
{
+ public class CompositeTrackContentProvider : SourceContentProvider
+ {
+ CompositeTrackSourceContents contents;
+
+ public CompositeTrackContentProvider ()
+ {
+ Id = "composite-track-list";
+ Name = Catalog.GetString ("Standard Track List");
+ IsDefault = true;
+ }
+
+ public override bool Supports (Source source)
+ {
+ return source is ITrackModelSource;
+ }
+
+ public override ISourceContents CreateFor (Source source)
+ {
+ if (contents == null) {
+ contents = new CompositeTrackSourceContents ();
+ }
+
+ contents.ResetSource ();
+ contents.SetSource (source);
+ return contents;
+ }
+ }
+
public class CompositeTrackSourceContents : FilteredListSourceContents, ITrackModelSourceContents
{
// private QueryFilterView<string> genre_view;
diff --git a/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/ISourceContents.cs b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/ISourceContents.cs
index c93b8c4..b91d7c9 100644
--- a/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/ISourceContents.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/ISourceContents.cs
@@ -4,7 +4,7 @@
// Author:
// Gabriel Burt <gburt novell com>
//
-// Copyright (C) 2007 Novell, Inc.
+// Copyright (C) 2008 Novell, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
diff --git a/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/ObjectListSourceContents.cs b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/ObjectListSourceContents.cs
index 8c5cbfc..e61162b 100644
--- a/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/ObjectListSourceContents.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/ObjectListSourceContents.cs
@@ -45,6 +45,33 @@ using Banshee.Collection.Gui;
namespace Banshee.Sources.Gui
{
+ public class ObjectListContentProvider : SourceContentProvider
+ {
+ ObjectListSourceContents contents;
+
+ public ObjectListContentProvider ()
+ {
+ Id = "object-list";
+ Name = Catalog.GetString ("Object List");
+ }
+
+ public override bool Supports (Source source)
+ {
+ return source is Hyena.Data.IObjectListModel;
+ }
+
+ public override ISourceContents CreateFor (Source source)
+ {
+ if (contents == null) {
+ contents = new ObjectListSourceContents ();
+ }
+
+ contents.ResetSource ();
+ contents.SetSource (source);
+ return contents;
+ }
+ }
+
public class ObjectListSourceContents : ScrolledWindow, ISourceContents
{
private ObjectListView object_view;
diff --git a/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentManager.cs b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentManager.cs
new file mode 100644
index 0000000..a3223b7
--- /dev/null
+++ b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentManager.cs
@@ -0,0 +1,136 @@
+//
+// SourceContentManager.cs
+//
+// Author:
+// Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 2009 Novell, Inc.
+//
+// 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 Mono.Addins;
+using Hyena;
+
+using Banshee.ServiceStack;
+using Banshee.Configuration;
+using Banshee.Sources;
+
+namespace Banshee.Sources.Gui
+{
+ public abstract class SourceContentProvider
+ {
+ private string id;
+ public string Id {
+ get { return id; }
+ protected set { id = value; }
+ }
+
+ private string name;
+ public string Name {
+ get { return name; }
+ protected set { name = value; }
+ }
+
+ private bool is_default;
+ public bool IsDefault {
+ get { return is_default; }
+ protected set { is_default = value; }
+ }
+
+ // Inheritable?
+ // IconName?
+
+ public abstract bool Supports (Source source);
+ public abstract ISourceContents CreateFor (Source source);
+ }
+
+ // Responsible for loading ISourceContents and pairing them up with Sources
+ public class SourceContentManager : IRequiredService
+ {
+ private Dictionary<string, SourceContentProvider> providers = new Dictionary<string, SourceContentProvider> ();
+
+ public SourceContentManager ()
+ {
+ AddinManager.AddExtensionNodeHandler ("/Banshee/ThickClient/SourceContentProvider", OnExtensionChanged);
+ }
+
+ public void Dispose ()
+ {
+ AddinManager.RemoveExtensionNodeHandler ("/Banshee/ThickClient/SourceContentProvider", OnExtensionChanged);
+ }
+
+ private void OnExtensionChanged (object o, ExtensionNodeEventArgs args)
+ {
+ lock (providers) {
+ TypeExtensionNode node = (TypeExtensionNode)args.ExtensionNode;
+
+ if (args.Change == ExtensionChange.Add && !providers.ContainsKey (node.Id)) {
+ SourceContentProvider provider = (SourceContentProvider) node.CreateInstance ();
+ providers.Add (node.Id, provider);
+ Log.DebugFormat ("Loaded SourceContentProvider: '{0}'", provider.Id);
+ } else if (args.Change == ExtensionChange.Remove && providers.ContainsKey (node.Id)) {
+ //SourceContentProvider provider = providers[node.Id];
+ //provider.Dispose ();
+ providers.Remove (node.Id);
+ }
+ }
+ }
+
+ public IEnumerable<SourceContentProvider> GetProvidersFor (Source source)
+ {
+ foreach (SourceContentProvider provider in providers.Values) {
+ if (provider.Supports (source)) {
+ yield return provider;
+ }
+ }
+ }
+
+ public SourceContentProvider GetLastOrDefaultProviderFor (Source source)
+ {
+ string default_id = source.CreateSchema<string> ("last_content").Get ();
+
+ SourceContentProvider first = null;
+ SourceContentProvider first_default = null;
+
+ // Return the last provider used
+ foreach (var provider in GetProvidersFor (source)) {
+ if (provider.Id == default_id) {
+ return provider;
+ }
+
+ first = first ?? provider;
+ if (provider.IsDefault) {
+ first_default = first_default ?? provider;
+ }
+ }
+
+ // If none/not found, return the first default provider, or just the first
+ return first_default ?? first;
+ }
+
+ string IService.ServiceName {
+ get { return "SourceContentManager"; }
+ }
+ }
+}
diff --git a/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentMenu.cs b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentMenu.cs
new file mode 100644
index 0000000..12f465a
--- /dev/null
+++ b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentMenu.cs
@@ -0,0 +1,81 @@
+//
+// SourceContentMenu.cs
+//
+// Author:
+// Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 2009 Novell, Inc.
+//
+// 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 Hyena.Widgets;
+
+using Banshee.Widgets;
+using Banshee.Gui.Widgets;
+using Banshee.Sources.Gui;
+using Banshee.Collection;
+
+using Banshee.Gui;
+using Banshee.ServiceStack;
+using Banshee.Sources;
+
+namespace Banshee.Sources.Gui
+{
+ public class SourceContentMenu : Menu
+ {
+ private SourceContentNotebook notebook;
+
+ public SourceContentMenu (SourceContentNotebook notebook)
+ {
+ this.notebook = notebook;
+ }
+
+ public void SetSource (Source source, List<SourceContentProvider> providers, SourceContentProvider current_provider)
+ {
+ // Clear out the last source's content options, fill in ours, and show/hide the title
+ // label / button depending on if there's more than one option.
+ while (Children.Length > 0) {
+ Remove (Children [Children.Length - 1]);
+ }
+
+ RadioMenuItem first_item = new RadioMenuItem ("");
+ foreach (var provider in providers) {
+ RadioMenuItem item = new RadioMenuItem (first_item, provider.Name);
+ item.Active = provider == current_provider;
+
+ var p = provider; // Capture into a local var
+ item.Toggled += delegate (object o, EventArgs args) {
+ if (item.Active) {
+ notebook.Activate (p);
+ }
+ };
+
+ Append (item);
+ first_item = first_item ?? item;
+ }
+ }
+ }
+}
diff --git a/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentNotebook.cs b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentNotebook.cs
new file mode 100644
index 0000000..e30e034
--- /dev/null
+++ b/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/SourceContentNotebook.cs
@@ -0,0 +1,81 @@
+//
+// SourceContentNotebook.cs
+//
+// Authors:
+// Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 2009 Novell, Inc.
+//
+// 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.Reflection;
+using System.Collections.Generic;
+
+using Gtk;
+using Mono.Unix;
+
+using Hyena.Data;
+using Hyena.Data.Gui;
+using Hyena.Widgets;
+
+using Banshee.Sources;
+using Banshee.ServiceStack;
+using Banshee.Collection;
+using Banshee.Configuration;
+using Banshee.Gui;
+using Banshee.Collection.Gui;
+
+namespace Banshee.Sources.Gui
+{
+ public class SourceContentNotebook : Notebook
+ {
+ private Source source;
+
+ public SourceContentNotebook () : base ()
+ {
+ ShowBorder = false;
+ ShowTabs = false;
+ }
+
+ public void SetSource (Source source, SourceContentProvider provider)
+ {
+ this.source = source;
+
+ Activate (provider);
+ }
+
+ public void Activate (SourceContentProvider provider)
+ {
+ ISourceContents content = provider.CreateFor (source);
+ content.SetSource (source);
+ content.Widget.Show ();
+ source.CreateSchema<string> ("last_content").Set (provider.Id);
+
+ if (PageNum (content.Widget) < 0) {
+ AppendPage (content.Widget, null);
+ }
+
+ CurrentPage = PageNum (content.Widget);
+ }
+ }
+}
diff --git a/src/Core/Banshee.ThickClient/Banshee.ThickClient.addin.xml b/src/Core/Banshee.ThickClient/Banshee.ThickClient.addin.xml
index 9b094b0..593465b 100644
--- a/src/Core/Banshee.ThickClient/Banshee.ThickClient.addin.xml
+++ b/src/Core/Banshee.ThickClient/Banshee.ThickClient.addin.xml
@@ -19,7 +19,7 @@
<ImportSource class="Banshee.Library.Gui.PhotoFolderImportSource"/>
<ImportSource class="Banshee.Library.Gui.FileImportSource"/>
</Extension>
-
+
<Extension path="/Banshee/Gui/TrackEditor/NotebookPage">
<TrackEditorPage class="Banshee.Gui.TrackEditor.BasicTrackDetailsPage"/>
<TrackEditorPage class="Banshee.Gui.TrackEditor.ExtraTrackDetailsPage"/>
@@ -28,6 +28,11 @@
<TrackEditorPage class="Banshee.Gui.TrackEditor.StatisticsPage"/>
<!--<TrackEditorPage class="Banshee.Gui.TrackEditor.HelpPage"/>-->
</Extension>
+
+ <Extension path="/Banshee/ThickClient/SourceContentProvider">
+ <Provider class="Banshee.Sources.Gui.CompositeTrackContentProvider"/>
+ <Provider class="Banshee.Sources.Gui.ObjectListContentProvider"/>
+ </Extension>
<!-- Exported Extension Points -->
@@ -36,9 +41,9 @@
<ExtensionNode name="ActionGroup"/>
</ExtensionPoint>
- <ExtensionPoint path="/Banshee/ThickClient/SourceView">
+ <ExtensionPoint path="/Banshee/ThickClient/SourceContentProvider">
<Description>Defines a new GTK+ source view, possibly in conjunction with a Source extension.</Description>
- <ExtensionNode name="SourceView"/>
+ <ExtensionNode name="Provider"/>
</ExtensionPoint>
<ExtensionPoint path="/Banshee/Gui/TrackEditor/NotebookPage">
diff --git a/src/Core/Banshee.ThickClient/Makefile.am b/src/Core/Banshee.ThickClient/Makefile.am
index 317e690..c0fbb5f 100644
--- a/src/Core/Banshee.ThickClient/Makefile.am
+++ b/src/Core/Banshee.ThickClient/Makefile.am
@@ -142,6 +142,9 @@ SOURCES = \
Banshee.Sources.Gui/ITrackModelSourceContents.cs \
Banshee.Sources.Gui/ObjectListSourceContents.cs \
Banshee.Sources.Gui/SourceComboBox.cs \
+ Banshee.Sources.Gui/SourceContentManager.cs \
+ Banshee.Sources.Gui/SourceContentMenu.cs \
+ Banshee.Sources.Gui/SourceContentNotebook.cs \
Banshee.Sources.Gui/SourceIconResolver.cs \
Banshee.Sources.Gui/SourceModel.cs \
Banshee.Sources.Gui/SourceRowRenderer.cs \
diff --git a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying.addin.xml b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying.addin.xml
index 46c55b3..04ba776 100644
--- a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying.addin.xml
+++ b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying.addin.xml
@@ -24,6 +24,10 @@
<Source class="Banshee.NowPlaying.NowPlayingSource"/>
</Extension>
+ <Extension path="/Banshee/ThickClient/SourceContentProvider">
+ <Provider class="Banshee.NowPlaying.NowPlayingContentProvider"/>
+ </Extension>
+
<ExtensionPoint path="/Banshee/NowPlaying/FullscreenAdapter">
<ExtensionNode name="FullscreenAdapter"/>
</ExtensionPoint>
diff --git a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingInterface.cs b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingInterface.cs
index 7f8a823..8050bb1 100644
--- a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingInterface.cs
+++ b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingInterface.cs
@@ -38,6 +38,34 @@ using Banshee.Sources.Gui;
namespace Banshee.NowPlaying
{
+ public class NowPlayingContentProvider : SourceContentProvider
+ {
+ NowPlayingInterface contents;
+
+ public NowPlayingContentProvider ()
+ {
+ Id = "now-playing-standard";
+ Name = Catalog.GetString ("Now Playing (Video and Track Info)");
+ IsDefault = true;
+ }
+
+ public override bool Supports (Source source)
+ {
+ return source is NowPlayingSource;
+ }
+
+ public override ISourceContents CreateFor (Source source)
+ {
+ if (contents == null) {
+ contents = new NowPlayingInterface ();
+ }
+
+ contents.ResetSource ();
+ contents.SetSource (source);
+ return contents;
+ }
+ }
+
public class NowPlayingInterface : VBox, ISourceContents
{
private NowPlayingSource source;
diff --git a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs
index 44d0422..b6c15c2 100644
--- a/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs
+++ b/src/Extensions/Banshee.NowPlaying/Banshee.NowPlaying/NowPlayingSource.cs
@@ -43,7 +43,6 @@ namespace Banshee.NowPlaying
public class NowPlayingSource : Source, IDisposable
{
private TrackInfo transitioned_track;
- private NowPlayingInterface now_playing_interface;
public NowPlayingSource () : base ("now-playing", Catalog.GetString ("Now Playing"), 10, "now-playing")
{
@@ -52,11 +51,8 @@ namespace Banshee.NowPlaying
throw new ApplicationException ("Unsupported video display context");
}
- now_playing_interface = new NowPlayingInterface ();
-
Properties.SetString ("Icon.Name", "applications-multimedia");
- Properties.Set<ISourceContents> ("Nereid.SourceContents", now_playing_interface);
- Properties.Set<bool> ("Nereid.SourceContents.HeaderVisible", false);
+ //Properties.Set<bool> ("Nereid.SourceContents.HeaderVisible", false);
Properties.SetString ("ActiveSourceUIResource", "ActiveSourceUI.xml");
ServiceManager.SourceManager.AddSource (this);
@@ -72,11 +68,12 @@ namespace Banshee.NowPlaying
ServiceManager.PlaybackController.TrackStarted -= OnPlaybackControllerTrackStarted;
ServiceManager.PlayerEngine.DisconnectEvent (OnTrackInfoUpdated);
- if (now_playing_interface != null) {
+ // FIXME need to Dispose via the new SourceContentManager
+ /*if (now_playing_interface != null) {
now_playing_interface.Destroy ();
now_playing_interface.Dispose ();
now_playing_interface = null;
- }
+ }*/
}
private void OnTrackInfoUpdated (PlayerEventArgs args)
@@ -109,16 +106,16 @@ namespace Banshee.NowPlaying
public override void Activate ()
{
- if (now_playing_interface != null) {
+ /*if (now_playing_interface != null) {
now_playing_interface.OverrideFullscreen ();
- }
+ }*/
}
public override void Deactivate ()
{
- if (now_playing_interface != null) {
+ /*if (now_playing_interface != null) {
now_playing_interface.RelinquishFullscreen ();
- }
+ }*/
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]