From 746ac78e98790564e3029e76189187f2541de3af Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Sun, 6 Nov 2016 16:46:14 -0600 Subject: [PATCH] Added a method to save an icon to a stream. This enables the scenario described in #779 via an IValueConverter. --- .../Avalonia.Android/AndroidPlatform.cs | 20 +------ .../Avalonia.Android/Avalonia.Android.csproj | 1 + .../Avalonia.Android/PlatformIconLoader.cs | 59 +++++++++++++++++++ .../Platform/IWindowIconImpl.cs | 3 + src/Avalonia.Controls/WindowIcon.cs | 2 + src/Gtk/Avalonia.Gtk/IconImpl.cs | 6 ++ src/Windows/Avalonia.Win32/IconImpl.cs | 16 +++++ src/iOS/Avalonia.iOS/PlatformIconLoader.cs | 36 ++++++++--- 8 files changed, 119 insertions(+), 24 deletions(-) create mode 100644 src/Android/Avalonia.Android/PlatformIconLoader.cs diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index c118bbd9a9..afaa314e6c 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -25,7 +25,7 @@ namespace Avalonia namespace Avalonia.Android { - public class AndroidPlatform : IPlatformSettings, IWindowingPlatform, IPlatformIconLoader + public class AndroidPlatform : IPlatformSettings, IWindowingPlatform { public static readonly AndroidPlatform Instance = new AndroidPlatform(); public Size DoubleClickSize => new Size(4, 4); @@ -50,7 +50,8 @@ namespace Avalonia.Android .Bind().ToConstant(Instance) .Bind().ToConstant(new AndroidThreadingInterface()) .Bind().ToTransient() - .Bind().ToConstant(Instance); + .Bind().ToConstant(Instance) + .Bind().ToSingleton(); SkiaPlatform.Initialize(); } @@ -74,20 +75,5 @@ namespace Avalonia.Android { throw new NotImplementedException(); } - - public IWindowIconImpl LoadIcon(string fileName) - { - return null; - } - - public IWindowIconImpl LoadIcon(Stream stream) - { - return null; - } - - public IWindowIconImpl LoadIcon(IBitmapImpl bitmap) - { - return null; - } } } \ No newline at end of file diff --git a/src/Android/Avalonia.Android/Avalonia.Android.csproj b/src/Android/Avalonia.Android/Avalonia.Android.csproj index 70c70ad56e..654cb13678 100644 --- a/src/Android/Avalonia.Android/Avalonia.Android.csproj +++ b/src/Android/Avalonia.Android/Avalonia.Android.csproj @@ -63,6 +63,7 @@ + diff --git a/src/Android/Avalonia.Android/PlatformIconLoader.cs b/src/Android/Avalonia.Android/PlatformIconLoader.cs new file mode 100644 index 0000000000..11fc5583a5 --- /dev/null +++ b/src/Android/Avalonia.Android/PlatformIconLoader.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using Avalonia.Platform; +using System.IO; + +namespace Avalonia.Android +{ + class PlatformIconLoader : IPlatformIconLoader + { + public IWindowIconImpl LoadIcon(IBitmapImpl bitmap) + { + using (var stream = new MemoryStream()) + { + bitmap.Save(stream); + return LoadIcon(stream); + } + } + + public IWindowIconImpl LoadIcon(Stream stream) + { + return new FakeIcon(stream); + } + + public IWindowIconImpl LoadIcon(string fileName) + { + using (var file = File.Open(fileName, FileMode.Open)) + { + return new FakeIcon(file); + } + } + } + + // Stores the icon created as a stream to support saving even though an icon is never shown + public class FakeIcon : IWindowIconImpl + { + private Stream stream = new MemoryStream(); + + public FakeIcon(Stream stream) + { + stream.CopyTo(this.stream); + } + + public Stream Save() + { + var returnStream = new MemoryStream(); + stream.CopyTo(returnStream); + return returnStream; + } + } +} \ No newline at end of file diff --git a/src/Avalonia.Controls/Platform/IWindowIconImpl.cs b/src/Avalonia.Controls/Platform/IWindowIconImpl.cs index 6262fdf488..cd339ff404 100644 --- a/src/Avalonia.Controls/Platform/IWindowIconImpl.cs +++ b/src/Avalonia.Controls/Platform/IWindowIconImpl.cs @@ -1,9 +1,12 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System.IO; + namespace Avalonia.Platform { public interface IWindowIconImpl { + Stream Save(); } } diff --git a/src/Avalonia.Controls/WindowIcon.cs b/src/Avalonia.Controls/WindowIcon.cs index e71555aa6e..debac7c981 100644 --- a/src/Avalonia.Controls/WindowIcon.cs +++ b/src/Avalonia.Controls/WindowIcon.cs @@ -30,5 +30,7 @@ namespace Avalonia.Controls } public IWindowIconImpl PlatformImpl { get; } + + public Stream Save() => PlatformImpl.Save(); } } diff --git a/src/Gtk/Avalonia.Gtk/IconImpl.cs b/src/Gtk/Avalonia.Gtk/IconImpl.cs index 5c8fe0eaa6..a3cf3be47a 100644 --- a/src/Gtk/Avalonia.Gtk/IconImpl.cs +++ b/src/Gtk/Avalonia.Gtk/IconImpl.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Gdk; +using System.IO; namespace Avalonia.Gtk { @@ -16,5 +17,10 @@ namespace Avalonia.Gtk } public Pixbuf Pixbuf { get; } + + public Stream Save() + { + return new MemoryStream(Pixbuf.SaveToBuffer("png")); + } } } diff --git a/src/Windows/Avalonia.Win32/IconImpl.cs b/src/Windows/Avalonia.Win32/IconImpl.cs index d5f227d0d9..b9e3378b6f 100644 --- a/src/Windows/Avalonia.Win32/IconImpl.cs +++ b/src/Windows/Avalonia.Win32/IconImpl.cs @@ -5,6 +5,8 @@ using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.IO; +using System.Drawing.Imaging; namespace Avalonia.Win32 { @@ -24,5 +26,19 @@ namespace Avalonia.Win32 } public IntPtr HIcon => icon?.Handle ?? bitmap.GetHicon(); + + public Stream Save() + { + var stream = new MemoryStream(); + if (icon != null) + { + icon.Save(stream); + } + else + { + bitmap.Save(stream, ImageFormat.Png); + } + return stream; + } } } diff --git a/src/iOS/Avalonia.iOS/PlatformIconLoader.cs b/src/iOS/Avalonia.iOS/PlatformIconLoader.cs index 4ad2dca97f..dc9d87660f 100644 --- a/src/iOS/Avalonia.iOS/PlatformIconLoader.cs +++ b/src/iOS/Avalonia.iOS/PlatformIconLoader.cs @@ -1,7 +1,4 @@ using Avalonia.Platform; -using System; -using System.Collections.Generic; -using System.Text; using System.IO; namespace Avalonia.iOS @@ -10,17 +7,42 @@ namespace Avalonia.iOS { public IWindowIconImpl LoadIcon(IBitmapImpl bitmap) { - return null; + using (var stream = new MemoryStream()) + { + bitmap.Save(stream); + return LoadIcon(stream); + } } public IWindowIconImpl LoadIcon(Stream stream) { - return null; + return new FakeIcon(stream); } public IWindowIconImpl LoadIcon(string fileName) { - return null; + using (var file = File.Open(fileName, FileMode.Open)) + { + return new FakeIcon(file); + } } } -} + + // Stores the icon created as a stream to support saving even though an icon is never shown + public class FakeIcon : IWindowIconImpl + { + private Stream stream = new MemoryStream(); + + public FakeIcon(Stream stream) + { + stream.CopyTo(this.stream); + } + + public Stream Save() + { + var returnStream = new MemoryStream(); + stream.CopyTo(returnStream); + return returnStream; + } + } +} \ No newline at end of file