File: DemoImages.cs

package info (click to toggle)
gtk-sharp 1%3A1.0.10-5
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 18,416 kB
  • ctags: 4,465
  • sloc: xml: 224,361; cs: 17,961; sh: 8,422; ansic: 2,724; makefile: 1,604; perl: 1,089
file content (177 lines) | stat: -rw-r--r-- 5,119 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
//
// DemoImages.cs - port of images.c gtk-demo
//
// Author: Daniel Kornhauser <dkor@alum.mit.edu>
//
// 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 ("<u>Image loaded from a file</u>");
			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 ("<u>Animation loaded from a file</u>");
			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 ("<u>Progressive image loading</u>");
			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);
				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 ();
		}
	}
}