// // DemoImages.cs - port of images.c gtk-demo // // Author: Daniel Kornhauser // // Copyright (C) 2003, Ximian Inc. // /* Images * * Gtk.Image is used to display an image; the image can be in a number of formats. * Typically, you load an image into a Gdk.Pixbuf, then display the pixbuf. * * This demo code shows some of the more obscure cases, in the simple * case a call to the constructor Gtk.Image (string filename) is all you need. * * If you want to put image data in your program compile it in as a resource. * This way you will not need to depend on loading external files, your * application binary can be self-contained. */ // TODO: // Finish implementing the callback, I can't get the image // to show up, and I'm stuck in the ProgressivePreparedCallback // because I can't get a white background to appear using System; using System.IO; using System.Reflection; using Gtk; using Gdk; namespace GtkDemo { public class DemoImages : Gtk.Window { private static Gtk.Image progressiveImage; private VBox vbox; BinaryReader imageStream; public DemoImages () : base ("images") { this.DeleteEvent += new DeleteEventHandler (WindowDelete); this.BorderWidth = 8; vbox = new VBox (false, 8); vbox.BorderWidth = 8; this.Add (vbox); Gtk.Label label = new Gtk.Label ("Image loaded from a file"); label.UseMarkup = true; vbox.PackStart (label, false, false, 0); Gtk.Frame frame = new Gtk.Frame (); frame.ShadowType = ShadowType.In; // The alignment keeps the frame from growing when users resize // the window Alignment alignment = new Alignment (0.5f, 0.5f, 0f, 0f); alignment.Add (frame); vbox.PackStart (alignment, false, false, 0); Gtk.Image image = new Gtk.Image (Gdk.Pixbuf.LoadFromResource ("gtk-logo-rgb.gif")); frame.Add (image); // Animation label = new Gtk.Label ("Animation loaded from a file"); label.UseMarkup = true; vbox.PackStart (label); frame = new Gtk.Frame (); frame.ShadowType = ShadowType.In; alignment = new Alignment (0.5f, 0.5f, 0f, 0f); alignment.Add (frame); vbox.PackStart (alignment, false, false, 0); image = new Gtk.Image (Gdk.Pixbuf.LoadFromResource ("floppybuddy.gif")); frame.Add (image); // Progressive label = new Gtk.Label ("Progressive image loading"); label.UseMarkup = true; vbox.PackStart (label); frame = new Gtk.Frame (); frame.ShadowType = ShadowType.In; alignment = new Alignment (0.5f, 0.5f, 0f, 0f); alignment.Add (frame); vbox.PackStart (alignment, false, false, 0); // Create an empty image for now; the progressive loader // will create the pixbuf and fill it in. // progressiveImage = new Gtk.Image (); frame.Add (progressiveImage); StartProgressiveLoading (); // Sensitivity control Gtk.ToggleButton button = new Gtk.ToggleButton ("_Insensitive"); vbox.PackStart (button, false, false, 0); button.Toggled += new EventHandler (ToggleSensitivity); this.ShowAll (); } private void WindowDelete (object o, DeleteEventArgs args) { this.Hide (); this.Destroy (); args.RetVal = true; } private void ToggleSensitivity (object o, EventArgs args) { Widget[] children = vbox.Children; foreach (Widget widget in children) /* don't disable our toggle */ if (widget.GetType () != o.GetType () ) widget.Sensitive = !widget.Sensitive; } private uint timeout_id; private void StartProgressiveLoading () { /* This is obviously totally contrived (we slow down loading * on purpose to show how incremental loading works). * The real purpose of incremental loading is the case where * you are reading data from a slow source such as the network. * The timeout simply simulates a slow data source by inserting * pauses in the reading process. */ timeout_id = GLib.Timeout.Add (150, new GLib.TimeoutHandler (ProgressiveTimeout)); } static Gdk.PixbufLoader pixbufLoader; // TODO: Decide if we want to perform crazy error handling private bool ProgressiveTimeout () { if (imageStream == null) { Stream stream = Assembly.GetExecutingAssembly ().GetManifestResourceStream ("alphatest.png"); imageStream = new BinaryReader (stream); pixbufLoader = new Gdk.PixbufLoader (); pixbufLoader.AreaPrepared += new EventHandler (ProgressivePreparedCallback); pixbufLoader.AreaUpdated += new AreaUpdatedHandler (ProgressiveUpdatedCallback); } if (imageStream.PeekChar () != -1) { byte[] bytes = imageStream.ReadBytes (256); pixbufLoader.Write (bytes, (uint) bytes.Length); return true; // leave the timeout active } else { imageStream.Close (); return false; // removes the timeout } } static void ProgressivePreparedCallback (object obj, EventArgs args) { Gdk.Pixbuf pixbuf = pixbufLoader.Pixbuf; pixbuf.Fill (0xaaaaaaff); progressiveImage.FromPixbuf = pixbuf; } static void ProgressiveUpdatedCallback (object obj, AreaUpdatedArgs args) { progressiveImage.QueueDraw (); } } }