/*
* 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