1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gdkpixbuf.PixbufLoader;
26 
27 private import gdkpixbuf.Pixbuf;
28 private import gdkpixbuf.PixbufAnimation;
29 private import gdkpixbuf.PixbufFormat;
30 private import glib.Bytes;
31 private import glib.ConstructionException;
32 private import glib.ErrorG;
33 private import glib.GException;
34 private import glib.Str;
35 private import gobject.ObjectG;
36 private import gobject.Signals;
37 private import gtkc.gdkpixbuf;
38 public  import gtkc.gdkpixbuftypes;
39 public  import gtkc.gdktypes;
40 private import std.algorithm;
41 
42 
43 /**
44  * The GdkPixbufLoader struct contains only private
45  * fields.
46  */
47 public class PixbufLoader : ObjectG
48 {
49 	/** the main Gtk struct */
50 	protected GdkPixbufLoader* gdkPixbufLoader;
51 
52 	/** Get the main Gtk struct */
53 	public GdkPixbufLoader* getPixbufLoaderStruct()
54 	{
55 		return gdkPixbufLoader;
56 	}
57 
58 	/** the main Gtk struct as a void* */
59 	protected override void* getStruct()
60 	{
61 		return cast(void*)gdkPixbufLoader;
62 	}
63 
64 	protected override void setStruct(GObject* obj)
65 	{
66 		gdkPixbufLoader = cast(GdkPixbufLoader*)obj;
67 		super.setStruct(obj);
68 	}
69 
70 	/**
71 	 * Sets our main struct and passes it to the parent class.
72 	 */
73 	public this (GdkPixbufLoader* gdkPixbufLoader, bool ownedRef = false)
74 	{
75 		this.gdkPixbufLoader = gdkPixbufLoader;
76 		super(cast(GObject*)gdkPixbufLoader, ownedRef);
77 	}
78 
79 	/**
80 	 * Creates a new pixbuf loader object that always attempts to parse
81 	 * image data as if it were an image of type @image_type, instead of
82 	 * identifying the type automatically. Useful if you want an error if
83 	 * the image isn't the expected type, for loading image formats
84 	 * that can't be reliably identified by looking at the data, or if
85 	 * the user manually forces a specific type.
86 	 *
87 	 * The list of supported image formats depends on what image loaders
88 	 * are installed, but typically "png", "jpeg", "gif", "tiff" and
89 	 * "xpm" are among the supported formats. To obtain the full list of
90 	 * supported image formats, call gdk_pixbuf_format_get_name() on each
91 	 * of the #GdkPixbufFormat structs returned by gdk_pixbuf_get_formats().
92 	 *
93 	 * Params:
94 	 *     imageType  = name of the image format to be loaded with the image
95 	 *     isMimeType = Set to true if type is a mime type
96 	 *
97 	 * Return: A newly-created pixbuf loader.
98 	 *
99 	 * Throws: GException on failure.
100 	 */
101 	public this(string type, bool isMimeType=false)
102 	{
103 		GError* err = null;
104 		GdkPixbufLoader* p;
105 		
106 		if ( isMimeType )
107 		{
108 			p = cast(GdkPixbufLoader*)gdk_pixbuf_loader_new_with_mime_type(Str.toStringz(type), &err);
109 		}
110 		else
111 		{
112 			p = cast(GdkPixbufLoader*)gdk_pixbuf_loader_new_with_type(Str.toStringz(type), &err);
113 		}
114 		
115 		if (err !is null)
116 		{
117 			throw new GException( new ErrorG(err) );
118 		}
119 		
120 		this(cast(GdkPixbufLoader*) p, true);
121 	}
122 
123 	/**
124 	 */
125 
126 	/** */
127 	public static GType getType()
128 	{
129 		return gdk_pixbuf_loader_get_type();
130 	}
131 
132 	/**
133 	 * Creates a new pixbuf loader object.
134 	 *
135 	 * Return: A newly-created pixbuf loader.
136 	 *
137 	 * Throws: ConstructionException GTK+ fails to create the object.
138 	 */
139 	public this()
140 	{
141 		auto p = gdk_pixbuf_loader_new();
142 		
143 		if(p is null)
144 		{
145 			throw new ConstructionException("null returned by new");
146 		}
147 		
148 		this(cast(GdkPixbufLoader*) p, true);
149 	}
150 
151 	/**
152 	 * Informs a pixbuf loader that no further writes with
153 	 * gdk_pixbuf_loader_write() will occur, so that it can free its
154 	 * internal loading structures. Also, tries to parse any data that
155 	 * hasn't yet been parsed; if the remaining data is partial or
156 	 * corrupt, an error will be returned.  If %FALSE is returned, @error
157 	 * will be set to an error from the #GDK_PIXBUF_ERROR or #G_FILE_ERROR
158 	 * domains. If you're just cancelling a load rather than expecting it
159 	 * to be finished, passing %NULL for @error to ignore it is
160 	 * reasonable.
161 	 *
162 	 * Remember that this does not unref the loader, so if you plan not to
163 	 * use it anymore, please g_object_unref() it.
164 	 *
165 	 * Return: %TRUE if all image data written so far was successfully
166 	 *     passed out via the update_area signal
167 	 *
168 	 * Throws: GException on failure.
169 	 */
170 	public bool close()
171 	{
172 		GError* err = null;
173 		
174 		auto p = gdk_pixbuf_loader_close(gdkPixbufLoader, &err) != 0;
175 		
176 		if (err !is null)
177 		{
178 			throw new GException( new ErrorG(err) );
179 		}
180 		
181 		return p;
182 	}
183 
184 	/**
185 	 * Queries the #GdkPixbufAnimation that a pixbuf loader is currently creating.
186 	 * In general it only makes sense to call this function after the "area-prepared"
187 	 * signal has been emitted by the loader. If the loader doesn't have enough
188 	 * bytes yet (hasn't emitted the "area-prepared" signal) this function will
189 	 * return %NULL.
190 	 *
191 	 * Return: The #GdkPixbufAnimation that the loader is loading, or %NULL if
192 	 *     not enough data has been read to determine the information.
193 	 */
194 	public PixbufAnimation getAnimation()
195 	{
196 		auto p = gdk_pixbuf_loader_get_animation(gdkPixbufLoader);
197 		
198 		if(p is null)
199 		{
200 			return null;
201 		}
202 		
203 		return ObjectG.getDObject!(PixbufAnimation)(cast(GdkPixbufAnimation*) p);
204 	}
205 
206 	/**
207 	 * Obtains the available information about the format of the
208 	 * currently loading image file.
209 	 *
210 	 * Return: A #GdkPixbufFormat or
211 	 *     %NULL. The return value is owned by GdkPixbuf and should not be
212 	 *     freed.
213 	 *
214 	 * Since: 2.2
215 	 */
216 	public PixbufFormat getFormat()
217 	{
218 		auto p = gdk_pixbuf_loader_get_format(gdkPixbufLoader);
219 		
220 		if(p is null)
221 		{
222 			return null;
223 		}
224 		
225 		return ObjectG.getDObject!(PixbufFormat)(cast(GdkPixbufFormat*) p);
226 	}
227 
228 	/**
229 	 * Queries the #GdkPixbuf that a pixbuf loader is currently creating.
230 	 * In general it only makes sense to call this function after the
231 	 * "area-prepared" signal has been emitted by the loader; this means
232 	 * that enough data has been read to know the size of the image that
233 	 * will be allocated.  If the loader has not received enough data via
234 	 * gdk_pixbuf_loader_write(), then this function returns %NULL.  The
235 	 * returned pixbuf will be the same in all future calls to the loader,
236 	 * so simply calling g_object_ref() should be sufficient to continue
237 	 * using it.  Additionally, if the loader is an animation, it will
238 	 * return the "static image" of the animation
239 	 * (see gdk_pixbuf_animation_get_static_image()).
240 	 *
241 	 * Return: The #GdkPixbuf that the loader is creating, or %NULL if not
242 	 *     enough data has been read to determine how to create the image buffer.
243 	 */
244 	public Pixbuf getPixbuf()
245 	{
246 		auto p = gdk_pixbuf_loader_get_pixbuf(gdkPixbufLoader);
247 		
248 		if(p is null)
249 		{
250 			return null;
251 		}
252 		
253 		return ObjectG.getDObject!(Pixbuf)(cast(GdkPixbuf*) p);
254 	}
255 
256 	/**
257 	 * Causes the image to be scaled while it is loaded. The desired
258 	 * image size can be determined relative to the original size of
259 	 * the image by calling gdk_pixbuf_loader_set_size() from a
260 	 * signal handler for the ::size-prepared signal.
261 	 *
262 	 * Attempts to set the desired image size  are ignored after the
263 	 * emission of the ::size-prepared signal.
264 	 *
265 	 * Params:
266 	 *     width = The desired width of the image being loaded.
267 	 *     height = The desired height of the image being loaded.
268 	 *
269 	 * Since: 2.2
270 	 */
271 	public void setSize(int width, int height)
272 	{
273 		gdk_pixbuf_loader_set_size(gdkPixbufLoader, width, height);
274 	}
275 
276 	/**
277 	 * This will cause a pixbuf loader to parse the next @count bytes of
278 	 * an image.  It will return %TRUE if the data was loaded successfully,
279 	 * and %FALSE if an error occurred.  In the latter case, the loader
280 	 * will be closed, and will not accept further writes. If %FALSE is
281 	 * returned, @error will be set to an error from the #GDK_PIXBUF_ERROR
282 	 * or #G_FILE_ERROR domains.
283 	 *
284 	 * Params:
285 	 *     buf = Pointer to image data.
286 	 *     count = Length of the @buf buffer in bytes.
287 	 *
288 	 * Return: %TRUE if the write was successful, or %FALSE if the loader
289 	 *     cannot parse the buffer.
290 	 *
291 	 * Throws: GException on failure.
292 	 */
293 	public bool write(char[] buf)
294 	{
295 		GError* err = null;
296 		
297 		auto p = gdk_pixbuf_loader_write(gdkPixbufLoader, buf.ptr, cast(size_t)buf.length, &err) != 0;
298 		
299 		if (err !is null)
300 		{
301 			throw new GException( new ErrorG(err) );
302 		}
303 		
304 		return p;
305 	}
306 
307 	/**
308 	 * This will cause a pixbuf loader to parse a buffer inside a #GBytes
309 	 * for an image.  It will return %TRUE if the data was loaded successfully,
310 	 * and %FALSE if an error occurred.  In the latter case, the loader
311 	 * will be closed, and will not accept further writes. If %FALSE is
312 	 * returned, @error will be set to an error from the #GDK_PIXBUF_ERROR
313 	 * or #G_FILE_ERROR domains.
314 	 *
315 	 * See also: gdk_pixbuf_loader_write()
316 	 *
317 	 * Params:
318 	 *     buffer = The image data as a #GBytes
319 	 *
320 	 * Return: %TRUE if the write was successful, or %FALSE if the loader
321 	 *     cannot parse the buffer.
322 	 *
323 	 * Since: 2.30
324 	 *
325 	 * Throws: GException on failure.
326 	 */
327 	public bool writeBytes(Bytes buffer)
328 	{
329 		GError* err = null;
330 		
331 		auto p = gdk_pixbuf_loader_write_bytes(gdkPixbufLoader, (buffer is null) ? null : buffer.getBytesStruct(), &err) != 0;
332 		
333 		if (err !is null)
334 		{
335 			throw new GException( new ErrorG(err) );
336 		}
337 		
338 		return p;
339 	}
340 
341 	protected class OnAreaPreparedDelegateWrapper
342 	{
343 		void delegate(PixbufLoader) dlg;
344 		gulong handlerId;
345 		ConnectFlags flags;
346 		this(void delegate(PixbufLoader) dlg, gulong handlerId, ConnectFlags flags)
347 		{
348 			this.dlg = dlg;
349 			this.handlerId = handlerId;
350 			this.flags = flags;
351 		}
352 	}
353 	protected OnAreaPreparedDelegateWrapper[] onAreaPreparedListeners;
354 
355 	/**
356 	 * This signal is emitted when the pixbuf loader has allocated the
357 	 * pixbuf in the desired size.  After this signal is emitted,
358 	 * applications can call gdk_pixbuf_loader_get_pixbuf() to fetch
359 	 * the partially-loaded pixbuf.
360 	 */
361 	gulong addOnAreaPrepared(void delegate(PixbufLoader) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
362 	{
363 		onAreaPreparedListeners ~= new OnAreaPreparedDelegateWrapper(dlg, 0, connectFlags);
364 		onAreaPreparedListeners[onAreaPreparedListeners.length - 1].handlerId = Signals.connectData(
365 			this,
366 			"area-prepared",
367 			cast(GCallback)&callBackAreaPrepared,
368 			cast(void*)onAreaPreparedListeners[onAreaPreparedListeners.length - 1],
369 			cast(GClosureNotify)&callBackAreaPreparedDestroy,
370 			connectFlags);
371 		return onAreaPreparedListeners[onAreaPreparedListeners.length - 1].handlerId;
372 	}
373 	
374 	extern(C) static void callBackAreaPrepared(GdkPixbufLoader* pixbufloaderStruct,OnAreaPreparedDelegateWrapper wrapper)
375 	{
376 		wrapper.dlg(wrapper.outer);
377 	}
378 	
379 	extern(C) static void callBackAreaPreparedDestroy(OnAreaPreparedDelegateWrapper wrapper, GClosure* closure)
380 	{
381 		wrapper.outer.internalRemoveOnAreaPrepared(wrapper);
382 	}
383 
384 	protected void internalRemoveOnAreaPrepared(OnAreaPreparedDelegateWrapper source)
385 	{
386 		foreach(index, wrapper; onAreaPreparedListeners)
387 		{
388 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
389 			{
390 				onAreaPreparedListeners[index] = null;
391 				onAreaPreparedListeners = std.algorithm.remove(onAreaPreparedListeners, index);
392 				break;
393 			}
394 		}
395 	}
396 	
397 
398 	protected class OnAreaUpdatedDelegateWrapper
399 	{
400 		void delegate(int, int, int, int, PixbufLoader) dlg;
401 		gulong handlerId;
402 		ConnectFlags flags;
403 		this(void delegate(int, int, int, int, PixbufLoader) dlg, gulong handlerId, ConnectFlags flags)
404 		{
405 			this.dlg = dlg;
406 			this.handlerId = handlerId;
407 			this.flags = flags;
408 		}
409 	}
410 	protected OnAreaUpdatedDelegateWrapper[] onAreaUpdatedListeners;
411 
412 	/**
413 	 * This signal is emitted when a significant area of the image being
414 	 * loaded has been updated.  Normally it means that a complete
415 	 * scanline has been read in, but it could be a different area as
416 	 * well.  Applications can use this signal to know when to repaint
417 	 * areas of an image that is being loaded.
418 	 *
419 	 * Params:
420 	 *     x = X offset of upper-left corner of the updated area.
421 	 *     y = Y offset of upper-left corner of the updated area.
422 	 *     width = Width of updated area.
423 	 *     height = Height of updated area.
424 	 */
425 	gulong addOnAreaUpdated(void delegate(int, int, int, int, PixbufLoader) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
426 	{
427 		onAreaUpdatedListeners ~= new OnAreaUpdatedDelegateWrapper(dlg, 0, connectFlags);
428 		onAreaUpdatedListeners[onAreaUpdatedListeners.length - 1].handlerId = Signals.connectData(
429 			this,
430 			"area-updated",
431 			cast(GCallback)&callBackAreaUpdated,
432 			cast(void*)onAreaUpdatedListeners[onAreaUpdatedListeners.length - 1],
433 			cast(GClosureNotify)&callBackAreaUpdatedDestroy,
434 			connectFlags);
435 		return onAreaUpdatedListeners[onAreaUpdatedListeners.length - 1].handlerId;
436 	}
437 	
438 	extern(C) static void callBackAreaUpdated(GdkPixbufLoader* pixbufloaderStruct, int x, int y, int width, int height,OnAreaUpdatedDelegateWrapper wrapper)
439 	{
440 		wrapper.dlg(x, y, width, height, wrapper.outer);
441 	}
442 	
443 	extern(C) static void callBackAreaUpdatedDestroy(OnAreaUpdatedDelegateWrapper wrapper, GClosure* closure)
444 	{
445 		wrapper.outer.internalRemoveOnAreaUpdated(wrapper);
446 	}
447 
448 	protected void internalRemoveOnAreaUpdated(OnAreaUpdatedDelegateWrapper source)
449 	{
450 		foreach(index, wrapper; onAreaUpdatedListeners)
451 		{
452 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
453 			{
454 				onAreaUpdatedListeners[index] = null;
455 				onAreaUpdatedListeners = std.algorithm.remove(onAreaUpdatedListeners, index);
456 				break;
457 			}
458 		}
459 	}
460 	
461 
462 	protected class OnClosedDelegateWrapper
463 	{
464 		void delegate(PixbufLoader) dlg;
465 		gulong handlerId;
466 		ConnectFlags flags;
467 		this(void delegate(PixbufLoader) dlg, gulong handlerId, ConnectFlags flags)
468 		{
469 			this.dlg = dlg;
470 			this.handlerId = handlerId;
471 			this.flags = flags;
472 		}
473 	}
474 	protected OnClosedDelegateWrapper[] onClosedListeners;
475 
476 	/**
477 	 * This signal is emitted when gdk_pixbuf_loader_close() is called.
478 	 * It can be used by different parts of an application to receive
479 	 * notification when an image loader is closed by the code that
480 	 * drives it.
481 	 */
482 	gulong addOnClosed(void delegate(PixbufLoader) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
483 	{
484 		onClosedListeners ~= new OnClosedDelegateWrapper(dlg, 0, connectFlags);
485 		onClosedListeners[onClosedListeners.length - 1].handlerId = Signals.connectData(
486 			this,
487 			"closed",
488 			cast(GCallback)&callBackClosed,
489 			cast(void*)onClosedListeners[onClosedListeners.length - 1],
490 			cast(GClosureNotify)&callBackClosedDestroy,
491 			connectFlags);
492 		return onClosedListeners[onClosedListeners.length - 1].handlerId;
493 	}
494 	
495 	extern(C) static void callBackClosed(GdkPixbufLoader* pixbufloaderStruct,OnClosedDelegateWrapper wrapper)
496 	{
497 		wrapper.dlg(wrapper.outer);
498 	}
499 	
500 	extern(C) static void callBackClosedDestroy(OnClosedDelegateWrapper wrapper, GClosure* closure)
501 	{
502 		wrapper.outer.internalRemoveOnClosed(wrapper);
503 	}
504 
505 	protected void internalRemoveOnClosed(OnClosedDelegateWrapper source)
506 	{
507 		foreach(index, wrapper; onClosedListeners)
508 		{
509 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
510 			{
511 				onClosedListeners[index] = null;
512 				onClosedListeners = std.algorithm.remove(onClosedListeners, index);
513 				break;
514 			}
515 		}
516 	}
517 	
518 
519 	protected class OnSizePreparedDelegateWrapper
520 	{
521 		void delegate(int, int, PixbufLoader) dlg;
522 		gulong handlerId;
523 		ConnectFlags flags;
524 		this(void delegate(int, int, PixbufLoader) dlg, gulong handlerId, ConnectFlags flags)
525 		{
526 			this.dlg = dlg;
527 			this.handlerId = handlerId;
528 			this.flags = flags;
529 		}
530 	}
531 	protected OnSizePreparedDelegateWrapper[] onSizePreparedListeners;
532 
533 	/**
534 	 * This signal is emitted when the pixbuf loader has been fed the
535 	 * initial amount of data that is required to figure out the size
536 	 * of the image that it will create.  Applications can call
537 	 * gdk_pixbuf_loader_set_size() in response to this signal to set
538 	 * the desired size to which the image should be scaled.
539 	 *
540 	 * Params:
541 	 *     width = the original width of the image
542 	 *     height = the original height of the image
543 	 */
544 	gulong addOnSizePrepared(void delegate(int, int, PixbufLoader) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
545 	{
546 		onSizePreparedListeners ~= new OnSizePreparedDelegateWrapper(dlg, 0, connectFlags);
547 		onSizePreparedListeners[onSizePreparedListeners.length - 1].handlerId = Signals.connectData(
548 			this,
549 			"size-prepared",
550 			cast(GCallback)&callBackSizePrepared,
551 			cast(void*)onSizePreparedListeners[onSizePreparedListeners.length - 1],
552 			cast(GClosureNotify)&callBackSizePreparedDestroy,
553 			connectFlags);
554 		return onSizePreparedListeners[onSizePreparedListeners.length - 1].handlerId;
555 	}
556 	
557 	extern(C) static void callBackSizePrepared(GdkPixbufLoader* pixbufloaderStruct, int width, int height,OnSizePreparedDelegateWrapper wrapper)
558 	{
559 		wrapper.dlg(width, height, wrapper.outer);
560 	}
561 	
562 	extern(C) static void callBackSizePreparedDestroy(OnSizePreparedDelegateWrapper wrapper, GClosure* closure)
563 	{
564 		wrapper.outer.internalRemoveOnSizePrepared(wrapper);
565 	}
566 
567 	protected void internalRemoveOnSizePrepared(OnSizePreparedDelegateWrapper source)
568 	{
569 		foreach(index, wrapper; onSizePreparedListeners)
570 		{
571 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
572 			{
573 				onSizePreparedListeners[index] = null;
574 				onSizePreparedListeners = std.algorithm.remove(onSizePreparedListeners, index);
575 				break;
576 			}
577 		}
578 	}
579 	
580 }