/* * AlbumArt Banshee Plugin, Copyright (c) 2006 Nick Bargnesi * nick at den-4.com * * THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: * * 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. * * Author's note: * AlbumArt borrows heavily from the code found in the sample plugin * for Banshee, the CoverArtThumbnail class contained in the Banshee.Widgets * package, the NotificationAreaIconPlugin, and bits of the Wikimedia plugin. * * My thanks to all authors for allowing an ex-KDE/amaroK user to "scratch an itch". */ using System; using Gtk; using Gdk; using Mono.Unix; using GConf; using Banshee.Base; using Banshee.Sources; using Banshee.MediaEngine; using Banshee.Widgets; public static class PluginModuleEntry { public static Type[] GetTypes() { return new Type[] { typeof(Banshee.Plugins.AlbumArt.AlbumArtPlugin) }; } } namespace Banshee.Plugins.AlbumArt { public class AlbumArtPlugin : Banshee.Plugins.Plugin { /// Describes whether this plugin is enabled or not private bool enabled = true; /// The popup used by the plugin CoverArtPopup popup; /// /// Refers to the x delta between the popup and the closest side of the screen. Defaults to 20. /// private int x; /// /// Refers to the y delta between the popup and the closest side of the screen. Defaults to 20. private int y; /// Refers to whether the popup should stick to the glass as the viewport changes. private bool stick; /// Defines the size of the popup as configured by the user. private int size; /// Holds the current CoverArtFilename. private string coverArtFileName; /// An integer representing which CD case we're using. private int cd; /// An enum defining the current popup's state. private enum PopupState { INITIAL, BLANK, VALID }; /// The popup's state. private PopupState state = PopupState.INITIAL; private GConf.Client gconfClient = new GConf.Client(); private string baseKey = "/apps/Banshee/AlbumArt/"; private bool inPoll = false; /// Returns the configuration name, AlbumArt protected override string ConfigurationName { get { return "AlbumArt"; } } /// Returns the string displayed in the Banshee Plugins, Plugin Name column public override string DisplayName { get { return "Album Art"; } } /// Returns a brief description of the Banshee Plugin public override string Description { get { return Catalog.GetString( "Displays album cover art for the current track." ); } } /// Returns the author's name public override string[] Authors { get { return new string[] { "Nick Bargnesi" }; } } /// Gets/Sets the enabled property public bool Enabled { get { return enabled; } set { enabled = value; } } /// The plugin's entry point. /// /// /// PluginInitialize() sets default values for x, y, and cd , then registers with the /// PlayerEngineCore to receive OnPlayerEventChanged events. /// /// protected override void PluginInitialize() { try { x = (int) gconfClient.Get(baseKey + "X"); } catch { x = 20; } try { y = (int) gconfClient.Get(baseKey + "Y"); } catch { y = 20; } try { stick = (bool) gconfClient.Get(baseKey + "Stick"); } catch { stick = true; } try { size = (int) gconfClient.Get(baseKey + "Size"); } catch { size = 150; } try { cd = (int) gconfClient.Get(baseKey + "CD"); } catch { cd = 0; } GLib.Timeout.Add((uint) 1000, Poll); PlayerEngineCore.EventChanged += OnPlayerEngineEventChanged; } /// Clean up after ourselves because we're no longer wanted like a red-headed stepchild. protected override void PluginDispose() { if (popup != null) { popup.Hide(); popup = null; } } /// Returns the configuration widget AlbumArtConfigDialog public override Gtk.Widget GetConfigurationWidget() { return new AlbumArtConfigPage(this); } /// Determines if the current track playing can be considered valid public bool ValidTrack { get { if (PlayerEngineCore.CurrentTrack != null && PlayerEngineCore.CurrentTrack.CoverArtFileName != null) return true; else return false; } } /// Gets/Sets the size properties internal int Size { get { try { return (int) gconfClient.Get(baseKey + "Size"); } catch { return 150; } } set { gconfClient.Set(baseKey + "Size", (int) value); size = value; resetPopup(); } } /// Gets/Sets the CD property internal int CD { get { try { return (int) gconfClient.Get(baseKey + "CD"); } catch { return 0; } } set { gconfClient.Set(baseKey + "CD", (int) value); cd = value; resetPopup(); } } /// Gets/Sets the x property internal int X { get { try { return (int) gconfClient.Get(baseKey + "X"); } catch { return 20; // Default X position in pixels } } set { gconfClient.Set(baseKey + "X", (int) value); x = value; if (popup != null) popup.Move(x, y); } } /// Gets/Sets the y property internal int Y { get { try { return (int) gconfClient.Get(baseKey + "Y"); } catch { return 20; // Default Y position in pixels } } set { gconfClient.Set(baseKey + "Y", (int) value); y = value; if (popup != null) popup.Move(x, y); } } /// Gets/Sets the stick property internal bool Stick { get { try { return (bool) gconfClient.Get(baseKey + "Stick"); } catch { return true; // Defaults } } set { gconfClient.Set(baseKey + "Stick", (bool) value); stick = value; if (popup != null) resetPopup(); } } /// Event triggered on poll. private bool Poll() { if (inPoll) { return true; } inPoll = true; displayPopup(); inPoll = false; return true; } /// Static method to convert the integer representation of a cd to the string. public static string cdAsResource(int i) { switch (i) { case 0: return "cd-case-black.png"; case 1: return "cd-case-blue.png"; case 2: return "cd-case-brown.png"; case 3: return "cd-case-red.png"; case 4: return "cd-case-white.png"; case 5: return "cd-case-purple.png"; case 6: return "cd-case-green.png"; default: return "cd-case-black.png"; } } /// Resets the popup as a result of a configuration change. private void resetPopup() { if (popup != null) { popup.Hide(); popup = null; } state = PopupState.INITIAL; displayPopup(); } /// Displays the popup as a result of the plugin being enabled or a poll. private void displayPopup() { if (ValidTrack) { if (coverArtFileName == null || coverArtFileName != PlayerEngineCore.CurrentTrack.CoverArtFileName) { // The cover artwork has changed. coverArtFileName = PlayerEngineCore.CurrentTrack.CoverArtFileName; switch (state) { case PopupState.VALID: case PopupState.BLANK: popup.Hide(); popup = null; break; } filledPopup(); state = PopupState.VALID; } else { switch (state) { case PopupState.INITIAL: filledPopup(); state = PopupState.VALID; return; case PopupState.VALID: return; case PopupState.BLANK: if (popup != null) { popup.Hide(); popup = null; } filledPopup(); state = PopupState.VALID; return; } } return; } else { switch (state) { case PopupState.INITIAL: emptyPopup(); state = PopupState.BLANK; break; case PopupState.VALID: popup.Hide(); popup = null; emptyPopup(); state = PopupState.BLANK; break; case PopupState.BLANK: return; } } } /// Receives PlayerEngineEvents private void OnPlayerEngineEventChanged(object o, PlayerEngineEventArgs args) { if (!Enabled) return; switch (args.Event) { case PlayerEngineEvent.StartOfStream: case PlayerEngineEvent.EndOfStream: displayPopup(); break; } } private void emptyPopup() { popup = new CoverArtPopup(size, cd, true); popup.SetPixbufs(Gdk.Pixbuf.LoadFromResource(AlbumArtPlugin.cdAsResource(cd)), null); popup.Move(x, y); popup.QueueDraw(); popup.Show(); if (stick) popup.Stick(); else popup.Unstick(); } private void filledPopup() { // Create a new popup. Pixbuf pixbuf = new Pixbuf(PlayerEngineCore.CurrentTrack.CoverArtFileName); popup = new CoverArtPopup(size, cd, true); popup.SetPixbufs(Gdk.Pixbuf.LoadFromResource(AlbumArtPlugin.cdAsResource(cd)), pixbuf); popup.Move(x, y); popup.QueueDraw(); popup.Show(); if (stick) popup.Stick(); else popup.Unstick(); } } } // vim:ts=4:sw=4