[banshee] Windows: Add Win7 thumbnail toolbar playback buttons (bgo#630730)
- From: Gabriel Burt <gburt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [banshee] Windows: Add Win7 thumbnail toolbar playback buttons (bgo#630730)
- Date: Sun, 27 Feb 2011 22:58:04 +0000 (UTC)
commit d6bc9b395a36c069245ac1085ce6603c1f524cdc
Author: Pete Johanson <peter peterjohanson com>
Date: Fri Sep 24 15:22:12 2010 -0400
Windows: Add Win7 thumbnail toolbar playback buttons (bgo#630730)
Signed-off-by: Gabriel Burt <gabriel burt gmail com>
.../Banshee.Windows/Banshee.Windows.addin.xml | 3 +-
.../Banshee.Windows/Banshee.Windows.csproj | 14 ++-
.../Banshee.Windows/ExtensionsForGtkAction.cs | 73 +++++++++
.../GtkWindowThumbnailToolbarManager.cs | 75 +++++++++
.../Banshee.Windows/WindowsService.cs | 83 +++++++++--
.../Windows7Support/TaskbarInterop.cs | 151 ++++++++++++++++++
.../Windows7Support/ThumbnailToolbar.cs | 130 ++++++++++++++++
.../Windows7Support/ThumbnailToolbarButton.cs | 163 ++++++++++++++++++++
.../Windows7Support/ThumbnailToolbarManager.cs | 125 +++++++++++++++
.../Banshee.Windows/media-playback-pause.ico | Bin 0 -> 1150 bytes
.../Banshee.Windows/media-playback-start.ico | Bin 0 -> 1150 bytes
.../Banshee.Windows/media-skip-backward.ico | Bin 0 -> 1150 bytes
.../Banshee.Windows/media-skip-forward.ico | Bin 0 -> 1150 bytes
13 files changed, 801 insertions(+), 16 deletions(-)
---
diff --git a/src/Backends/Banshee.Windows/Banshee.Windows.addin.xml b/src/Backends/Banshee.Windows/Banshee.Windows.addin.xml
index 25b0218..5f4b6f6 100644
--- a/src/Backends/Banshee.Windows/Banshee.Windows.addin.xml
+++ b/src/Backends/Banshee.Windows/Banshee.Windows.addin.xml
@@ -11,6 +11,7 @@
<Dependencies>
<Addin id="Banshee.Core" version="1.0"/>
<Addin id="Banshee.Services" version="1.0"/>
+ <Addin id="Banshee.ThickClient" version="1.0"/>
</Dependencies>
<Extension path="/Banshee/ServiceManager/Service">
@@ -20,4 +21,4 @@
<Extension path="/Banshee/Platform/HardwareManager">
<HardwareManager class="Banshee.Windows.Hardware.HardwareManager" id="Banshee.Windows.HardwareManager"/>
</Extension>
-</Addin>
\ No newline at end of file
+</Addin>
diff --git a/src/Backends/Banshee.Windows/Banshee.Windows.csproj b/src/Backends/Banshee.Windows/Banshee.Windows.csproj
index 05b68b7..295f3f6 100644
--- a/src/Backends/Banshee.Windows/Banshee.Windows.csproj
+++ b/src/Backends/Banshee.Windows/Banshee.Windows.csproj
@@ -3,7 +3,7 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>8.0.50727</ProductVersion>
+ <ProductVersion>9.0.21022</ProductVersion>
<ProjectGuid>{9AA07695-3EF9-45CE-849E-A0AB9A1F4006}</ProjectGuid>
<OutputType>Library</OutputType>
<UseParentDirectoryAsNamespace>true</UseParentDirectoryAsNamespace>
@@ -77,16 +77,24 @@
<Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
<Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
<Reference Include="atk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+ <Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.Core">
</Reference>
+ <Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="Banshee.Windows\WindowsService.cs" />
+ <Compile Include="Banshee.Windows\ExtensionsForGtkAction.cs" />
+ <Compile Include="Banshee.Windows\GtkWindowThumbnailToolbarManager.cs" />
<Compile Include="Banshee.Windows.Hardware\HardwareManager.cs" />
<Compile Include="Banshee.Windows.Hardware\Device.cs" />
<Compile Include="Banshee.Windows.Hardware\UsbDevice.cs" />
<Compile Include="Banshee.Windows.Hardware\Volume.cs" />
+ <Compile Include="Windows7Support\TaskbarInterop.cs" />
+ <Compile Include="Windows7Support\ThumbnailToolbar.cs" />
+ <Compile Include="Windows7Support\ThumbnailToolbarButton.cs" />
+ <Compile Include="Windows7Support\ThumbnailToolbarManager.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Banshee.Windows.addin.xml">
@@ -108,8 +116,6 @@
</MonoDevelop.Autotools.MakefileInfo>
</Properties>
</MonoDevelop>
+ <VisualStudio />
</ProjectExtensions>
- <ItemGroup>
- <Folder Include="Banshee.Windows.Hardware\" />
- </ItemGroup>
</Project>
diff --git a/src/Backends/Banshee.Windows/Banshee.Windows/ExtensionsForGtkAction.cs b/src/Backends/Banshee.Windows/Banshee.Windows/ExtensionsForGtkAction.cs
new file mode 100644
index 0000000..d5479f6
--- /dev/null
+++ b/src/Backends/Banshee.Windows/Banshee.Windows/ExtensionsForGtkAction.cs
@@ -0,0 +1,73 @@
+//
+// ExtensionsForGtkAction.cs
+//
+// Authors:
+// Pete Johanson <peter peterjohanson com>
+//
+// Copyright (C) 2010 Pete Johanson
+//
+// 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 System.Linq;
+using System.Drawing;
+using System.Text.RegularExpressions;
+
+using Gtk;
+using Windows7Support;
+
+namespace Banshee.Windows
+{
+ // TODO: If Gtk# ever supports implementing GtkActivatable interface,
+ // we could use that for updating the ThumbnailtToolbarButton 'automatically'
+ public static class ExtensionsForGtkAction
+ {
+ static short id = 1;
+
+ public static ThumbnailToolbarButton CreateThumbnailToolbarButton (this Gtk.Action action)
+ {
+ return action.CreateThumbnailToolbarButton (null);
+ }
+
+ public static ThumbnailToolbarButton CreateThumbnailToolbarButton (this Gtk.Action action,
+ Func<Gtk.Action, System.Drawing.Icon> icon_callback)
+ {
+ var button = new ThumbnailToolbarButton (id++) {
+ DismissOnClick = false,
+ Tooltip = action.Label.Replace ("_", ""),
+ Enabled = action.Sensitive,
+ Hidden = !action.Visible,
+ Icon = icon_callback != null ? icon_callback (action) : null
+ };
+
+ button.Clicked += (o, e) => action.Activate ();
+
+ action.AddNotification ("icon-name", (o, args) => button.Icon = icon_callback != null ? icon_callback (action) : null);
+ action.AddNotification ("stock-id", (o, args) => button.Icon = icon_callback != null ? icon_callback (action) : null);
+ action.AddNotification ("tooltip", (o, args) => button.Tooltip = action.Label.Replace ("_", ""));
+ action.AddNotification ("sensitive", (o, args) => button.Enabled = action.Sensitive);
+ action.AddNotification ("visible", (o, args) => button.Hidden = !action.Visible);
+
+ return button;
+ }
+ }
+}
diff --git a/src/Backends/Banshee.Windows/Banshee.Windows/GtkWindowThumbnailToolbarManager.cs b/src/Backends/Banshee.Windows/Banshee.Windows/GtkWindowThumbnailToolbarManager.cs
new file mode 100644
index 0000000..72c7971
--- /dev/null
+++ b/src/Backends/Banshee.Windows/Banshee.Windows/GtkWindowThumbnailToolbarManager.cs
@@ -0,0 +1,75 @@
+//
+// GtkWindowThumbnailToolbarManager.cs
+//
+// Authors:
+// Pete Johanson <peter peterjohanson com>
+//
+// Copyright (C) 2010 Pete Johanson
+//
+// 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 System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+
+using Gtk;
+
+using Windows7Support;
+
+namespace Banshee.Windows
+{
+ public static class GtkWindowThumbnailToolbarManager
+ {
+ public static void Register (Window window, Action<ThumbnailToolbar> toolbar_creation_callback)
+ {
+ callback_dict[window] = toolbar_creation_callback;
+
+ if (window.IsRealized) {
+ CreateForWindow (window);
+ } else {
+ window.Realized += OnWindowRealized;
+ }
+ }
+
+ static Dictionary<Window, Action<ThumbnailToolbar>> callback_dict = new Dictionary<Window, Action<ThumbnailToolbar>> ();
+
+ static void OnWindowRealized (object o, EventArgs args)
+ {
+ CreateForWindow ((Window)o);
+ }
+
+ static void CreateForWindow (Window window)
+ {
+ Action<ThumbnailToolbar> cb = null;
+
+ if (!callback_dict.TryGetValue (window, out cb)) {
+ return;
+ }
+
+ ThumbnailToolbarManager.Register (gdk_win32_drawable_get_handle (window.GdkWindow.Handle), cb);
+ }
+
+ [DllImport ("libgdk-win32-2.0-0.dll")]
+ static extern IntPtr gdk_win32_drawable_get_handle (IntPtr drawable);
+ }
+}
diff --git a/src/Backends/Banshee.Windows/Banshee.Windows/WindowsService.cs b/src/Backends/Banshee.Windows/Banshee.Windows/WindowsService.cs
index f18beb7..ecc9684 100644
--- a/src/Backends/Banshee.Windows/Banshee.Windows/WindowsService.cs
+++ b/src/Backends/Banshee.Windows/Banshee.Windows/WindowsService.cs
@@ -3,6 +3,7 @@
//
// Authors:
// Gabriel Burt <gabriel burt gmail com>
+// Pete Johanson <peter peterjohanson com>
//
// Copyright 2011 Novell, Inc.
//
@@ -27,29 +28,91 @@
//
using System;
+using System.Collections.Generic;
+using System.Drawing;
using System.Linq;
-using System.Collections;
-using Gtk;
-using Mono.Unix;
+using System.Text;
using Banshee.ServiceStack;
using Banshee.Gui;
-using Hyena.Downloader;
-using GLib;
-using System.Management;
+using Windows7Support;
namespace Banshee.Windows
{
- public class WindowsService : IExtensionService, IDisposable
+ public class WindowsService : IExtensionService
{
bool disposed;
+ GtkElementsService elements_service;
+ InterfaceActionService interface_action_service;
- void IExtensionService.Initialize ()
+ private IList<ThumbnailToolbarButton> buttons;
+
+ bool ServiceStart ()
+ {
+ if (elements_service == null || interface_action_service == null)
+ return false;
+
+ buttons = new List<ThumbnailToolbarButton> () {
+ interface_action_service.PlaybackActions["PreviousAction"].CreateThumbnailToolbarButton (a => new Icon (GetResourceStream ("media-skip-backward.ico"))),
+ interface_action_service.PlaybackActions["PlayPauseAction"].CreateThumbnailToolbarButton (a => a.StockId == Gtk.Stock.MediaPlay ? new Icon (GetResourceStream ("media-playback-start.ico")) : new Icon (GetResourceStream ("media-playback-pause.ico"))),
+ interface_action_service.PlaybackActions["NextAction"].CreateThumbnailToolbarButton (a => new Icon (GetResourceStream ("media-skip-forward.ico"))),
+ };
+
+ ServiceManager.ServiceStarted -= OnServiceStarted;
+
+ GtkWindowThumbnailToolbarManager.Register (elements_service.PrimaryWindow, tb => { tb.Buttons = buttons; });
+
+ return true;
+ }
+
+ System.IO.Stream GetResourceStream (string resource_name)
+ {
+ string name = typeof (WindowsService).Assembly.GetManifestResourceNames ().FirstOrDefault (n => n.EndsWith (resource_name));
+
+ if (String.IsNullOrEmpty (name))
+ throw new ArgumentException (String.Format ("Resource named '{0}' not located", resource_name));
+
+ return typeof (WindowsService).Assembly.GetManifestResourceStream (name);
+ }
+
+ void OnServiceStarted (ServiceStartedArgs args)
+ {
+ if (args.Service is GtkElementsService) {
+ elements_service = (GtkElementsService)args.Service;
+ ServiceStart ();
+ } else if (args.Service is InterfaceActionService) {
+ interface_action_service = (InterfaceActionService)args.Service;
+ ServiceStart ();
+ }
+ }
+
+ #region IExtensionService Members
+
+ public void Initialize ()
{
// TODO check for updates and other cool stuff
+
+ elements_service = ServiceManager.Get<GtkElementsService> ();
+ interface_action_service = ServiceManager.Get<InterfaceActionService> ();
+
+ if (!ServiceStart ()) {
+ ServiceManager.ServiceStarted += OnServiceStarted;
+ }
+ }
+
+ #endregion
+
+ #region IService Members
+
+ public string ServiceName {
+ get { return "WindowsService"; }
}
+ #endregion
+
+ #region IDisposable Members
+
public void Dispose ()
{
if (disposed) {
@@ -59,8 +122,6 @@ namespace Banshee.Windows
disposed = true;
}
- string IService.ServiceName {
- get { return "WindowsService"; }
- }
+ #endregion
}
}
diff --git a/src/Backends/Banshee.Windows/Windows7Support/TaskbarInterop.cs b/src/Backends/Banshee.Windows/Windows7Support/TaskbarInterop.cs
new file mode 100644
index 0000000..68ff35a
--- /dev/null
+++ b/src/Backends/Banshee.Windows/Windows7Support/TaskbarInterop.cs
@@ -0,0 +1,151 @@
+//
+// TaskbarInterop.cs
+//
+// Authors:
+// Pete Johanson <peter peterjohanson com>
+//
+// Copyright (C) 2010 Pete Johanson
+//
+// 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 System.Linq;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.ComTypes;
+using System.Text;
+
+namespace Windows7Support
+{
+ // See http://msdn.microsoft.com/en-us/library/dd391692(v=VS.85).aspx
+ // for the definition of ITaskbarList3.
+ // The definitions here are used for interop via COM with ITaskbarList3.
+
+ [ComImport, Guid ("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")]
+ [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)]
+ internal interface ITaskbarList3
+ {
+
+ #region ITaskbarList API
+
+ [PreserveSig]
+ void HrInit ();
+ [PreserveSig]
+ void AddTab (IntPtr hwnd);
+ [PreserveSig]
+ void DeleteTab (IntPtr hwnd);
+ [PreserveSig]
+ void ActivateTab (IntPtr hwnd);
+ [PreserveSig]
+ void SetActiveAlt (IntPtr hwnd);
+
+ #endregion
+
+ #region ITaskbarList2 API
+
+ [PreserveSig]
+ void MarkFullscreenWindow (IntPtr hwnd, [MarshalAs (UnmanagedType.Bool)] bool fFullscreen);
+
+ #endregion
+
+ #region ITaskbarList3 API
+
+ [PreserveSig]
+ void SetProgressState ([In] IntPtr hwnd, [In] TASKBAR_PROGRESS_STATUS flags);
+ [PreserveSig]
+ void SetProgressValue ([In] IntPtr hwnd, [In] ulong ullCompleted, [In] ulong ullTotal);
+
+ [PreserveSig]
+ void RegisterTab (IntPtr hwndTab, IntPtr hwndMDI);
+ [PreserveSig]
+ void UnregisterTab ([In] IntPtr hwndTab);
+ [PreserveSig]
+ void SetTabOrder ([In] IntPtr hwndTab, [In, Optional] IntPtr hwndInsertBefore);
+ [PreserveSig]
+ void SetTabActive ([In] IntPtr hwndTab, [In] IntPtr hwndMDI, [In] uint flags);
+
+ [PreserveSig]
+ int ThumbBarAddButtons ([In] IntPtr hwnd, [In] uint numberOfButtons, [In, MarshalAs (UnmanagedType.LPArray)] THUMBBUTTON[] buttons);
+ [PreserveSig]
+ int ThumbBarUpdateButtons ([In] IntPtr hwnd, [In] uint numberOfButtons, [In, MarshalAs (UnmanagedType.LPArray)] THUMBBUTTON[] buttons);
+ [PreserveSig]
+ int ThumbBarSetImageList ([In] IntPtr hwnd, [In] IntPtr hImageList);
+
+ [PreserveSig]
+ void SetOverlayIcon ([In] IntPtr hwnd, [In] IntPtr hIcon, [In, MarshalAs (UnmanagedType.LPWStr)] string pszDescription);
+
+ [PreserveSig]
+ void SetThumbnailTooltip ([In] IntPtr hwnd, [In, MarshalAs (UnmanagedType.LPWStr)] string pszTip);
+
+ [PreserveSig]
+ void SetThumbnailClip ([In] IntPtr hwnd, [In] IntPtr rect);
+
+ #endregion
+ }
+
+ internal enum THUMBBUTTONMASK
+ {
+ THB_BITMAP = 0x1,
+ THB_ICON = 0x2,
+ THB_TOOLTIP = 0x4,
+ THB_FLAGS = 0x8
+ }
+
+ [Flags]
+ internal enum THUMBBUTTONFLAGS
+ {
+ THBF_ENABLED = 0x00000000,
+ THBF_DISABLED = 0x00000001,
+ THBF_DISMISSONCLICK = 0x00000002,
+ THBF_NOBACKGROUND = 0x00000004,
+ THBF_HIDDEN = 0x00000008,
+ THBF_NONINTERACTIVE = 0x00000010
+ }
+
+ internal enum TASKBAR_PROGRESS_STATUS
+ {
+ NO_PROGRESS = 0x0,
+ INDETERMINATE = 0x1,
+ NORMAL = 0x2,
+ ERROR = 0x4,
+ Paused = 0x8
+ }
+
+ [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ internal struct THUMBBUTTON
+ {
+ [MarshalAs (UnmanagedType.U4)]
+ public THUMBBUTTONMASK dwMask;
+ public UInt32 uId;
+ public UInt32 iBitmap;
+ public IntPtr hIcon;
+
+ [MarshalAs (UnmanagedType.ByValTStr, SizeConst = 260)]
+ public string szTip;
+ [MarshalAs (UnmanagedType.U4)]
+ public THUMBBUTTONFLAGS dwFlags;
+ }
+
+ internal static class CLSID
+ {
+ public static readonly Guid TaskbarList = new Guid ("56FDF344-FD6D-11d0-958A-006097C9A090");
+ }
+}
diff --git a/src/Backends/Banshee.Windows/Windows7Support/ThumbnailToolbar.cs b/src/Backends/Banshee.Windows/Windows7Support/ThumbnailToolbar.cs
new file mode 100644
index 0000000..b02549e
--- /dev/null
+++ b/src/Backends/Banshee.Windows/Windows7Support/ThumbnailToolbar.cs
@@ -0,0 +1,130 @@
+//
+// ThumbnailToolbar.cs
+//
+// Authors:
+// Pete Johanson <peter peterjohanson com>
+//
+// Copyright (C) 2010 Pete Johanson
+//
+// 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 System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Windows.Forms;
+
+namespace Windows7Support
+{
+ public class ThumbnailToolbar
+ {
+ public void SetImageList (ImageList list)
+ {
+ image_list = list;
+ taskbar.ThumbBarSetImageList (hwnd, list.Handle);
+ }
+
+ public IList<ThumbnailToolbarButton> Buttons {
+ get { return buttons; }
+ set {
+ if (buttons != null)
+ throw new InvalidOperationException ("The toolbar buttons can only be set once, due to a Windows limitation");
+
+ if (value == null || value.Count == 0)
+ return;
+
+ buttons = value;
+
+ foreach (ThumbnailToolbarButton b in buttons)
+ b.Changed += new EventHandler (OnButtonChanged);
+
+ IEnumerable<THUMBBUTTON> native_buttons = GetNativeButtons ();
+ taskbar.ThumbBarAddButtons (hwnd, (uint)native_buttons.Count (), native_buttons.ToArray ());
+ }
+ }
+
+ ImageList image_list;
+ IList<ThumbnailToolbarButton> buttons;
+ ITaskbarList3 taskbar;
+ IntPtr hwnd;
+
+
+ internal ThumbnailToolbar (IntPtr hwnd)
+ {
+ this.hwnd = hwnd;
+ taskbar = (ITaskbarList3)Activator.CreateInstance (Type.GetTypeFromCLSID (CLSID.TaskbarList));
+ taskbar.HrInit ();
+ }
+
+ void OnButtonChanged (object sender, EventArgs e)
+ {
+ UpdateButtons ();
+ }
+
+ IEnumerable<THUMBBUTTON> GetNativeButtons ()
+ {
+ return buttons.Select (b =>
+ {
+ THUMBBUTTONMASK mask = THUMBBUTTONMASK.THB_FLAGS;
+ THUMBBUTTON native_button = new THUMBBUTTON () { uId = (uint)b.Id, dwFlags = GetFlags (b) };
+ if (b.Icon != null) {
+ mask |= THUMBBUTTONMASK.THB_ICON;
+ native_button.hIcon = b.Icon.Handle;
+ }
+
+ if (!String.IsNullOrEmpty (b.Tooltip)) {
+ mask |= THUMBBUTTONMASK.THB_TOOLTIP;
+ native_button.szTip = b.Tooltip;
+ }
+
+ // TODO: ImageLIst index support.
+
+ native_button.dwMask = mask;
+
+ return native_button;
+ }).ToList ();
+ }
+
+ void UpdateButtons ()
+ {
+ IEnumerable<THUMBBUTTON> native = GetNativeButtons ();
+
+ taskbar.ThumbBarUpdateButtons (hwnd, (uint)native.Count (), native.ToArray ());
+ }
+
+ THUMBBUTTONFLAGS GetFlags (ThumbnailToolbarButton button)
+ {
+ THUMBBUTTONFLAGS flags = button.Enabled ? THUMBBUTTONFLAGS.THBF_ENABLED : THUMBBUTTONFLAGS.THBF_DISABLED;
+
+ if (button.Hidden)
+ flags |= THUMBBUTTONFLAGS.THBF_HIDDEN;
+ if (button.NonInteractive)
+ flags |= THUMBBUTTONFLAGS.THBF_NONINTERACTIVE;
+ if (button.DismissOnClick)
+ flags |= THUMBBUTTONFLAGS.THBF_DISMISSONCLICK;
+ if (button.NoBackground)
+ flags |= THUMBBUTTONFLAGS.THBF_NOBACKGROUND;
+
+ return flags;
+ }
+
+ }
+}
diff --git a/src/Backends/Banshee.Windows/Windows7Support/ThumbnailToolbarButton.cs b/src/Backends/Banshee.Windows/Windows7Support/ThumbnailToolbarButton.cs
new file mode 100644
index 0000000..c468f28
--- /dev/null
+++ b/src/Backends/Banshee.Windows/Windows7Support/ThumbnailToolbarButton.cs
@@ -0,0 +1,163 @@
+//
+// ThumbnailToolbarButton.cs
+//
+// Authors:
+// Pete Johanson <peter peterjohanson com>
+//
+// Copyright (C) 2010 Pete Johanson
+//
+// 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 System.Linq;
+using System.Drawing;
+using System.Text;
+
+namespace Windows7Support
+{
+ public class ThumbnailToolbarButton
+ {
+ public event EventHandler Clicked;
+ public event EventHandler Changed;
+
+ public Int16 Id { get; private set; }
+
+ int image_index = -1;
+ public int ImageIndex {
+ get { return image_index; }
+ set {
+ if (image_index == value)
+ return;
+
+ image_index = value;
+
+ FireChanged ();
+ }
+ }
+
+ Icon icon;
+ public Icon Icon {
+ get { return icon; }
+ set {
+ if (icon == value)
+ return;
+
+ icon = value;
+ FireChanged ();
+ }
+ }
+
+ string tooltip;
+ public string Tooltip {
+ get { return tooltip; }
+ set {
+ if (tooltip == value)
+ return;
+
+ if (tooltip != null && tooltip.Length > 260)
+ throw new ArgumentException ("Tooltip cannot be greater than 260 characters long.");
+
+ tooltip = value;
+ FireChanged ();
+ }
+ }
+
+ bool enabled = true;
+ public bool Enabled {
+ get { return enabled; }
+ set {
+ if (enabled == value)
+ return;
+
+ enabled = value;
+ FireChanged ();
+ }
+ }
+
+ bool dismiss_on_click = true;
+ public bool DismissOnClick {
+ get { return dismiss_on_click; }
+ set {
+ if (dismiss_on_click == value)
+ return;
+
+ dismiss_on_click = value;
+ FireChanged ();
+ }
+ }
+
+ bool hidden;
+ public bool Hidden {
+ get { return hidden; }
+ set {
+ if (hidden == value)
+ return;
+
+ hidden = value;
+ FireChanged ();
+ }
+ }
+
+ bool non_interactive;
+ public bool NonInteractive {
+ get { return non_interactive; }
+ set {
+ if (non_interactive == value)
+ return;
+
+ non_interactive = value;
+ FireChanged ();
+ }
+ }
+
+ bool no_background = false;
+ public bool NoBackground {
+ get { return no_background; }
+ set {
+ if (no_background == value)
+ return;
+
+ no_background = value;
+ FireChanged ();
+ }
+ }
+
+ public ThumbnailToolbarButton (Int16 id)
+ {
+ Id = id;
+ }
+
+ internal void FireClicked ()
+ {
+ var handler = Clicked;
+ if (handler != null)
+ handler (this, EventArgs.Empty);
+ }
+
+ void FireChanged ()
+ {
+ var handler = Changed;
+ if (handler != null)
+ handler (this, EventArgs.Empty);
+ }
+ }
+}
diff --git a/src/Backends/Banshee.Windows/Windows7Support/ThumbnailToolbarManager.cs b/src/Backends/Banshee.Windows/Windows7Support/ThumbnailToolbarManager.cs
new file mode 100644
index 0000000..2ee5c46
--- /dev/null
+++ b/src/Backends/Banshee.Windows/Windows7Support/ThumbnailToolbarManager.cs
@@ -0,0 +1,125 @@
+//
+// ThumbnailToolbarManager.cs
+//
+// Authors:
+// Pete Johanson <peter peterjohanson com>
+//
+// Copyright (C) 2010 Pete Johanson
+//
+// 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 System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Windows7Support
+{
+ public static class ThumbnailToolbarManager
+ {
+ static ThumbnailToolbarManager ()
+ {
+ toolbar_created_msg = RegisterWindowMessage (TASKBAR_BUTTON_CREATED_MSG);
+ }
+
+
+ public static void Register (IntPtr hwnd, Action<ThumbnailToolbar> toolbar_created_callback)
+ {
+ Win32WinProc proc = new Win32WinProc (WndProc);
+ orig_winproc_dict[hwnd] = new Registration ()
+ {
+ ManagedProc = proc,
+ OrigWinProc = SetWindowLongW (hwnd, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate (proc)),
+ CreationCallback = toolbar_created_callback
+ };
+ }
+
+ static Dictionary<IntPtr, ThumbnailToolbar> toolbars = new Dictionary<IntPtr, ThumbnailToolbar> ();
+ static Dictionary<IntPtr, Registration> orig_winproc_dict = new Dictionary<IntPtr, Registration> ();
+
+ private static IntPtr WndProc (IntPtr hWnd, int Msg, int wParam, int lParam)
+ {
+ Registration reg = null;
+
+ if (!orig_winproc_dict.TryGetValue (hWnd, out reg))
+ return IntPtr.Zero;
+
+ if (Msg == toolbar_created_msg) {
+
+ ThumbnailToolbar tb = new ThumbnailToolbar (hWnd);
+ toolbars[hWnd] = tb;
+ reg.CreationCallback (tb);
+
+ } else if (Msg == WM_COMMAND && HiWord (wParam) == THBN_CLICKED) {
+ int button_id = LoWord (wParam);
+ ThumbnailToolbar tb;
+
+ if (toolbars.TryGetValue (hWnd, out tb)) {
+ ThumbnailToolbarButton button = tb.Buttons.SingleOrDefault (b => b.Id == button_id);
+ if (button != null)
+ button.FireClicked ();
+ }
+ }
+
+ return CallWindowProcW (reg.OrigWinProc, hWnd, Msg, wParam, lParam);
+ }
+
+ static int LoWord (int dw)
+ {
+ return dw & 0xFFFF;
+ }
+
+ static int HiWord (int dw)
+ {
+ return (dw >> 16) & 0xFFFF;
+ }
+
+ class Registration
+ {
+ public Win32WinProc ManagedProc;
+ public IntPtr OrigWinProc;
+ public Action<ThumbnailToolbar> CreationCallback;
+ }
+
+ #region native imports
+
+ static readonly uint toolbar_created_msg;
+
+ const string TASKBAR_BUTTON_CREATED_MSG = "TaskbarButtonCreated";
+ const int GWL_WNDPROC = -4;
+ const int WM_COMMAND = 0x0111;
+ const int THBN_CLICKED = 0x1800;
+
+ private delegate IntPtr Win32WinProc (IntPtr hWnd, int Msg, int wParam, int lParam);
+
+ [DllImport ("user32.dll")]
+ private static extern IntPtr SetWindowLongW (IntPtr hWnd, int nIndex, IntPtr dwNewLong);
+
+ [DllImport ("user32.dll")]
+ private static extern IntPtr CallWindowProcW (IntPtr proc, IntPtr hWnd, int Msg, int wParam, int lParam);
+
+ [DllImport ("user32.dll")]
+ private static extern uint RegisterWindowMessage (string lpProcName);
+
+ #endregion
+ }
+}
diff --git a/src/Backends/Banshee.Windows/media-playback-pause.ico b/src/Backends/Banshee.Windows/media-playback-pause.ico
new file mode 100644
index 0000000..cfc371c
Binary files /dev/null and b/src/Backends/Banshee.Windows/media-playback-pause.ico differ
diff --git a/src/Backends/Banshee.Windows/media-playback-start.ico b/src/Backends/Banshee.Windows/media-playback-start.ico
new file mode 100644
index 0000000..06f4c7f
Binary files /dev/null and b/src/Backends/Banshee.Windows/media-playback-start.ico differ
diff --git a/src/Backends/Banshee.Windows/media-skip-backward.ico b/src/Backends/Banshee.Windows/media-skip-backward.ico
new file mode 100644
index 0000000..9743b91
Binary files /dev/null and b/src/Backends/Banshee.Windows/media-skip-backward.ico differ
diff --git a/src/Backends/Banshee.Windows/media-skip-forward.ico b/src/Backends/Banshee.Windows/media-skip-forward.ico
new file mode 100644
index 0000000..afb20eb
Binary files /dev/null and b/src/Backends/Banshee.Windows/media-skip-forward.ico differ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]