[banshee/art-caching] Add drag support to cover art



commit 1b15c414e2940316912287be854a2214ed80383d
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Fri Dec 4 17:22:34 2009 -0800

    Add drag support to cover art
    
    Add CoverArtEditor class that will wrap a cover art widget (either a
    TrackInfoDisplay or the track editor image) and add support for dragging
    from it to, say, nautilus.  Should be pretty straightforward to add
    drop support as well.

 src/Clients/Nereid/Nereid/PlayerInterface.cs       |    9 ++-
 .../Banshee.Collection.Gui/CoverArtEditor.cs       |   83 ++++++++++++++++++++
 .../Banshee.Gui.TrackEditor/TrackEditorDialog.cs   |   41 +++++++---
 .../Banshee.Gui.Widgets/TrackInfoDisplay.cs        |   25 ++++++
 src/Core/Banshee.ThickClient/Makefile.am           |    1 +
 5 files changed, 145 insertions(+), 14 deletions(-)
---
diff --git a/src/Clients/Nereid/Nereid/PlayerInterface.cs b/src/Clients/Nereid/Nereid/PlayerInterface.cs
index 3ac9401..9100971 100644
--- a/src/Clients/Nereid/Nereid/PlayerInterface.cs
+++ b/src/Clients/Nereid/Nereid/PlayerInterface.cs
@@ -66,6 +66,7 @@ namespace Nereid
         private ViewContainer view_container;
         private VBox source_box;
         private CoverArtDisplay cover_art_display;
+        private Widget cover_art_container;
 
         // Major Interaction Components
         private SourceView source_view;
@@ -170,7 +171,9 @@ namespace Nereid
 
             TrackInfoDisplay track_info_display = new ClassicTrackInfoDisplay ();
             track_info_display.Show ();
-            ActionService.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/TrackInfoDisplay", track_info_display, true);
+            var editable = TrackInfoDisplay.GetEditable (track_info_display);
+            editable.Show ();
+            ActionService.PopulateToolbarPlaceholder (header_toolbar, "/HeaderToolbar/TrackInfoDisplay", editable, true);
 
             ConnectedVolumeButton volume_button = new ConnectedVolumeButton ();
             volume_button.Show ();
@@ -219,12 +222,12 @@ namespace Nereid
                     cover_art_display = new CoverArtDisplay () { Visible = true };
                     source_box.SizeAllocated += OnSourceBoxSizeAllocated;
                     cover_art_display.HeightRequest = SourceViewWidth.Get ();
-                    source_box.PackStart (cover_art_display, false, false, 0);
+                    source_box.PackStart (cover_art_container = TrackInfoDisplay.GetEditable (cover_art_display), false, false, 0);
                     source_box.ShowAll ();
                 }
             } else if (cover_art_display != null) {
                 cover_art_display.Hide ();
-                source_box.Remove (cover_art_display);
+                source_box.Remove (cover_art_container);
                 source_box.SizeAllocated -= OnSourceBoxSizeAllocated;
                 cover_art_display.Dispose ();
                 cover_art_display = null;
diff --git a/src/Core/Banshee.ThickClient/Banshee.Collection.Gui/CoverArtEditor.cs b/src/Core/Banshee.ThickClient/Banshee.Collection.Gui/CoverArtEditor.cs
new file mode 100644
index 0000000..09aa33e
--- /dev/null
+++ b/src/Core/Banshee.ThickClient/Banshee.Collection.Gui/CoverArtEditor.cs
@@ -0,0 +1,83 @@
+//
+// CoverArtEditor.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.Unix;
+using Mono.Addins;
+using Gtk;
+
+using Hyena.Gui;
+using Hyena.Widgets;
+
+using Banshee.Base;
+using Banshee.Kernel;
+using Banshee.Sources;
+using Banshee.ServiceStack;
+using Banshee.Collection;
+using Banshee.Collection.Database;
+using Banshee.Configuration.Schema;
+
+using Banshee.Widgets;
+using Banshee.Gui.DragDrop;
+
+namespace Banshee.Collection.Gui
+{
+    public class CoverArtEditor
+    {
+        public static Widget For (Widget widget, Func<int, int, bool> is_sensitive, Func<TrackInfo> get_track, System.Action on_updated)
+        {
+            var box = new EventBox ();
+            box.Child = widget;
+
+            Gtk.Drag.SourceSet (box, Gdk.ModifierType.Button1Mask, new TargetEntry [] { DragDropTarget.UriList }, Gdk.DragAction.Copy | Gdk.DragAction.Move);
+            box.DragDataGet += (o, a) => {
+                var uri = GetCoverArtPath (get_track ());
+                if (uri != null) {
+                    a.SelectionData.Set (Gdk.Atom.Intern (DragDropTarget.UriList.Target, false), 8, System.Text.Encoding.UTF8.GetBytes (uri));
+                    a.RetVal = true;
+                }
+            };
+
+            return box;
+        }
+
+        private static string GetCoverArtPath (TrackInfo track)
+        {
+            if (track != null) {
+                var uri = new SafeUri (CoverArtSpec.GetPath (track.ArtworkId));
+                if (Banshee.IO.File.Exists (uri)) {
+                    return uri.AbsoluteUri;
+                }
+            }
+
+            return null;
+        }
+    }
+}
diff --git a/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs b/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs
index d322d4f..d4b6987 100644
--- a/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs
@@ -153,7 +153,14 @@ namespace Banshee.Gui.TrackEditor
             header_image = new Image ();
             header_image.IconName = "media-optical";
             header_image.PixelSize = 64;
-            header_image_frame.Add (header_image);
+
+            header_image_frame.Add (
+                CoverArtEditor.For (header_image,
+                    (x, y) => true,
+                    () => CurrentTrack,
+                    () => { LoadCoverArt (CurrentTrack); }
+                )
+            );
 
             header.Attach (header_image_frame, 0, 1, 0, 3,
                 AttachOptions.Fill, AttachOptions.Expand, 0, 0);
@@ -166,6 +173,10 @@ namespace Banshee.Gui.TrackEditor
             main_vbox.PackStart (header, false, false, 0);
         }
 
+        private TrackInfo CurrentTrack {
+            get { return TrackCount == 0 ? null : GetTrack (CurrentTrackIndex); }
+        }
+
         private void AddHeaderRow (Table header, uint row, string title, out Label label)
         {
             Label title_label = new Label ();
@@ -367,16 +378,7 @@ namespace Banshee.Gui.TrackEditor
                     CurrentTrackIndex + 1, TrackCount);
             }
 
-            ArtworkManager artwork = ServiceManager.Get<ArtworkManager> ();
-            Gdk.Pixbuf cover_art = artwork.LookupScalePixbuf (current_track.ArtworkId, 64);
-            header_image.Pixbuf = cover_art;
-            if (cover_art == null) {
-                header_image.IconName = "media-optical";
-                header_image.PixelSize = 64;
-                header_image_frame.ShadowType = ShadowType.None;
-            } else {
-                header_image_frame.ShadowType = ShadowType.In;
-            }
+            LoadCoverArt (current_track);
 
             // Disconnect all the undo adapters
             ForeachWidget<ICanUndo> (delegate (ICanUndo undoable) {
@@ -412,6 +414,23 @@ namespace Banshee.Gui.TrackEditor
             }
         }
 
+        private void LoadCoverArt (TrackInfo current_track)
+        {
+            if (current_track == null)
+                return;
+
+            ArtworkManager artwork = ServiceManager.Get<ArtworkManager> ();
+            Gdk.Pixbuf cover_art = artwork.LookupScalePixbuf (current_track.ArtworkId, 64);
+            header_image.Pixbuf = cover_art;
+            if (cover_art == null) {
+                header_image.IconName = "media-optical";
+                header_image.PixelSize = 64;
+                header_image_frame.ShadowType = ShadowType.None;
+            } else {
+                header_image_frame.ShadowType = ShadowType.In;
+            }
+        }
+
         public void ForeachNonCurrentTrack (EditorTrackOperationClosure closure)
         {
             for (int i = 0; i < TrackCount; i++) {
diff --git a/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/TrackInfoDisplay.cs b/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/TrackInfoDisplay.cs
index be833d8..19f5f48 100644
--- a/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/TrackInfoDisplay.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/TrackInfoDisplay.cs
@@ -123,6 +123,25 @@ namespace Banshee.Gui.Widgets
                 PlayerEvent.StateChange);
 
             WidgetFlags |= WidgetFlags.NoWindow;
+
+            Events |= Gdk.EventMask.ButtonPressMask;
+
+            ButtonPressEvent += (o, a) => { ShowPopupMenu (); };
+            PopupMenu += (o, a) => { ShowPopupMenu (); };
+        }
+
+        public static Widget GetEditable (TrackInfoDisplay display)
+        {
+            return CoverArtEditor.For (display,
+                (x, y) => display.IsWithinCoverart (x, y),
+                () => display.CurrentTrack,
+                () => display.LoadImage (display.CurrentTrack, false, true)
+            );
+        }
+
+        private void ShowPopupMenu ()
+        {
+            Console.WriteLine ("Context menu for track info display!");
         }
 
         public override void Dispose ()
@@ -302,6 +321,12 @@ namespace Banshee.Gui.Widgets
                 IsMissingImage (image), BackgroundColor);
         }
 
+        protected virtual bool IsWithinCoverart (int x, int y)
+        {
+            return x >= Allocation.X && y >= Allocation.Y &&
+                x <= (Allocation.X + ArtworkSizeRequest) && y <= (Allocation.Y + ArtworkSizeRequest);
+        }
+
         protected bool IsMissingImage (ImageSurface pb)
         {
             return pb == missing_audio_image || pb == missing_video_image;
diff --git a/src/Core/Banshee.ThickClient/Makefile.am b/src/Core/Banshee.ThickClient/Makefile.am
index 25defba..b9eb38d 100644
--- a/src/Core/Banshee.ThickClient/Makefile.am
+++ b/src/Core/Banshee.ThickClient/Makefile.am
@@ -25,6 +25,7 @@ SOURCES =  \
 	Banshee.Collection.Gui/ColumnCellTrack.cs \
 	Banshee.Collection.Gui/ColumnCellTrackAndCount.cs \
 	Banshee.Collection.Gui/ColumnCellTrackNumber.cs \
+	Banshee.Collection.Gui/CoverArtEditor.cs \
 	Banshee.Collection.Gui/DefaultColumnController.cs \
 	Banshee.Collection.Gui/PersistentColumnController.cs \
 	Banshee.Collection.Gui/QueryFilterView.cs \



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