using System; using System.IO; using System.CodeDom; namespace Stetic { public enum ImageSource { Theme, Resource, File } public class ImageInfo { ImageSource source; string name; Gtk.IconSize size; Gdk.Pixbuf image; private ImageInfo () { } public string Label { get { if (source == ImageSource.File) return Path.GetFileName (name); else return name; } } public string Name { get { return name; } } public Gtk.IconSize ThemeIconSize { get { return size; } } public ImageSource Source { get { return source; } } public override string ToString () { if (source == ImageSource.Theme) return "stock:" + name + " " + size; else if (source == ImageSource.Resource) return "resource:" + name; else return "file:" + name; } public static ImageInfo FromResource (string resourceName) { ImageInfo info = new ImageInfo (); info.name = resourceName; info.source = ImageSource.Resource; return info; } public static ImageInfo FromTheme (string iconId, Gtk.IconSize size) { ImageInfo info = new ImageInfo (); info.name = iconId; info.size = size; info.source = ImageSource.Theme; return info; } public static ImageInfo FromFile (string file) { ImageInfo info = new ImageInfo (); info.name = file; info.source = ImageSource.File; return info; } public static ImageInfo FromString (string str) { ImageInfo info = new ImageInfo (); if (str.StartsWith ("resource:")) { info.source = ImageSource.Resource; info.name = str.Substring (9); } else if (str.StartsWith ("stock:")) { info.source = ImageSource.Theme; string[] s = str.Substring (6).Split (' '); if (s.Length != 2) return null; info.name = s[0]; info.size = (Gtk.IconSize) Enum.Parse (typeof(Gtk.IconSize), s[1]); } else if (str.StartsWith ("file:")) { info.source = ImageSource.File; info.name = str.Substring (5); } else return null; return info; } public Gdk.Pixbuf GetImage (IProject project) { if (image != null) return image; switch (source) { case ImageSource.Resource: if (project.ResourceProvider == null) return null; System.IO.Stream s = project.ResourceProvider.GetResourceStream (name); if (s == null) return null; try { return image = new Gdk.Pixbuf (s); } catch { // Not a valid image return WidgetUtils.MissingIcon; } case ImageSource.Theme: return image = WidgetUtils.LoadIcon (name, size); case ImageSource.File: try { string file = Path.Combine (project.ImagesRootPath, name); return image = new Gdk.Pixbuf (file); } catch { return WidgetUtils.MissingIcon; } } return null; } public Gdk.Pixbuf GetThumbnail (IProject project, int thumbnailSize) { Gdk.Pixbuf pix = GetImage (project); if (pix == null) return null; if (pix.Width >= pix.Height && pix.Width > thumbnailSize) { return ScaleImage (pix, thumbnailSize, thumbnailSize); } else if (pix.Height > pix.Width && pix.Height > thumbnailSize) { return ScaleImage (pix, thumbnailSize, thumbnailSize); } return pix; } public Gdk.Pixbuf GetScaledImage (IProject project, Gtk.IconSize size) { int w, h; Gtk.Icon.SizeLookup (size, out w, out h); return GetScaledImage (project, w, h); } public Gdk.Pixbuf GetScaledImage (IProject project, int width, int height) { Gdk.Pixbuf pix = GetImage (project); if (pix == null) return null; else return ScaleImage (pix, width, height); } Gdk.Pixbuf ScaleImage (Gdk.Pixbuf pix, int width, int height) { if ((pix.Width - width) > (pix.Height - height)) { if (pix.Width != width) { float prop = (float) pix.Height / (float) pix.Width; return pix.ScaleSimple (width, (int)(width * prop), Gdk.InterpType.Bilinear); } } else { if (pix.Height != height) { float prop = (float) pix.Width / (float) pix.Height; return pix.ScaleSimple ((int)(height * prop), height, Gdk.InterpType.Bilinear); } } return pix; } public CodeExpression ToCodeExpression (GeneratorContext ctx) { switch (source) { case ImageSource.Resource: return new CodeMethodInvokeExpression ( new CodeTypeReferenceExpression (new CodeTypeReference (ctx.Options.ImageResourceLoaderClass, CodeTypeReferenceOptions.GlobalReference)), "LoadFromResource", new CodePrimitiveExpression (name) ); case ImageSource.Theme: return ctx.GenerateLoadPixbuf (name, size); case ImageSource.File: return new CodeObjectCreateExpression ( typeof(Gdk.Pixbuf).ToGlobalTypeRef (), new CodeMethodInvokeExpression ( new CodeTypeReferenceExpression (new CodeTypeReference (typeof(System.IO.Path), CodeTypeReferenceOptions.GlobalReference)), "Combine", new CodePropertyReferenceExpression ( new CodePropertyReferenceExpression ( new CodeTypeReferenceExpression (new CodeTypeReference (typeof(AppDomain), CodeTypeReferenceOptions.GlobalReference)), "CurrentDomain" ), "BaseDirectory" ), new CodePrimitiveExpression (name) ) ); } return new CodePrimitiveExpression (null); } } }