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 gtk.Assistant;
26 
27 private import gdkpixbuf.Pixbuf;
28 private import glib.ConstructionException;
29 private import glib.Str;
30 private import gobject.ObjectG;
31 private import gobject.Signals;
32 private import gtk.Widget;
33 private import gtk.Window;
34 private import gtkc.gtk;
35 public  import gtkc.gtktypes;
36 private import std.algorithm;
37 
38 
39 /**
40  * A #GtkAssistant is a widget used to represent a generally complex
41  * operation splitted in several steps, guiding the user through its
42  * pages and controlling the page flow to collect the necessary data.
43  * 
44  * The design of GtkAssistant is that it controls what buttons to show
45  * and to make sensitive, based on what it knows about the page sequence
46  * and the [type][GtkAssistantPageType] of each page,
47  * in addition to state information like the page
48  * [completion][gtk-assistant-set-page-complete]
49  * and [committed][gtk-assistant-commit] status.
50  * 
51  * If you have a case that doesn’t quite fit in #GtkAssistants way of
52  * handling buttons, you can use the #GTK_ASSISTANT_PAGE_CUSTOM page
53  * type and handle buttons yourself.
54  * 
55  * # GtkAssistant as GtkBuildable
56  * 
57  * The GtkAssistant implementation of the #GtkBuildable interface
58  * exposes the @action_area as internal children with the name
59  * “action_area”.
60  * 
61  * To add pages to an assistant in #GtkBuilder, simply add it as a
62  * child to the GtkAssistant object, and set its child properties
63  * as necessary.
64  * 
65  * # CSS nodes
66  * 
67  * GtkAssistant has a single CSS node with the name assistant.
68  */
69 public class Assistant : Window
70 {
71 	/** the main Gtk struct */
72 	protected GtkAssistant* gtkAssistant;
73 
74 	/** Get the main Gtk struct */
75 	public GtkAssistant* getAssistantStruct(bool transferOwnership = false)
76 	{
77 		if (transferOwnership)
78 			ownedRef = false;
79 		return gtkAssistant;
80 	}
81 
82 	/** the main Gtk struct as a void* */
83 	protected override void* getStruct()
84 	{
85 		return cast(void*)gtkAssistant;
86 	}
87 
88 	protected override void setStruct(GObject* obj)
89 	{
90 		gtkAssistant = cast(GtkAssistant*)obj;
91 		super.setStruct(obj);
92 	}
93 
94 	/**
95 	 * Sets our main struct and passes it to the parent class.
96 	 */
97 	public this (GtkAssistant* gtkAssistant, bool ownedRef = false)
98 	{
99 		this.gtkAssistant = gtkAssistant;
100 		super(cast(GtkWindow*)gtkAssistant, ownedRef);
101 	}
102 
103 
104 	/** */
105 	public static GType getType()
106 	{
107 		return gtk_assistant_get_type();
108 	}
109 
110 	/**
111 	 * Creates a new #GtkAssistant.
112 	 *
113 	 * Returns: a newly created #GtkAssistant
114 	 *
115 	 * Since: 2.10
116 	 *
117 	 * Throws: ConstructionException GTK+ fails to create the object.
118 	 */
119 	public this()
120 	{
121 		auto p = gtk_assistant_new();
122 		
123 		if(p is null)
124 		{
125 			throw new ConstructionException("null returned by new");
126 		}
127 		
128 		this(cast(GtkAssistant*) p);
129 	}
130 
131 	/**
132 	 * Adds a widget to the action area of a #GtkAssistant.
133 	 *
134 	 * Params:
135 	 *     child = a #GtkWidget
136 	 *
137 	 * Since: 2.10
138 	 */
139 	public void addActionWidget(Widget child)
140 	{
141 		gtk_assistant_add_action_widget(gtkAssistant, (child is null) ? null : child.getWidgetStruct());
142 	}
143 
144 	/**
145 	 * Appends a page to the @assistant.
146 	 *
147 	 * Params:
148 	 *     page = a #GtkWidget
149 	 *
150 	 * Returns: the index (starting at 0) of the inserted page
151 	 *
152 	 * Since: 2.10
153 	 */
154 	public int appendPage(Widget page)
155 	{
156 		return gtk_assistant_append_page(gtkAssistant, (page is null) ? null : page.getWidgetStruct());
157 	}
158 
159 	/**
160 	 * Erases the visited page history so the back button is not
161 	 * shown on the current page, and removes the cancel button
162 	 * from subsequent pages.
163 	 *
164 	 * Use this when the information provided up to the current
165 	 * page is hereafter deemed permanent and cannot be modified
166 	 * or undone. For example, showing a progress page to track
167 	 * a long-running, unreversible operation after the user has
168 	 * clicked apply on a confirmation page.
169 	 *
170 	 * Since: 2.22
171 	 */
172 	public void commit()
173 	{
174 		gtk_assistant_commit(gtkAssistant);
175 	}
176 
177 	/**
178 	 * Returns the page number of the current page.
179 	 *
180 	 * Returns: The index (starting from 0) of the current
181 	 *     page in the @assistant, or -1 if the @assistant has no pages,
182 	 *     or no current page.
183 	 *
184 	 * Since: 2.10
185 	 */
186 	public int getCurrentPage()
187 	{
188 		return gtk_assistant_get_current_page(gtkAssistant);
189 	}
190 
191 	/**
192 	 * Returns the number of pages in the @assistant
193 	 *
194 	 * Returns: the number of pages in the @assistant
195 	 *
196 	 * Since: 2.10
197 	 */
198 	public int getNPages()
199 	{
200 		return gtk_assistant_get_n_pages(gtkAssistant);
201 	}
202 
203 	/**
204 	 * Returns the child widget contained in page number @page_num.
205 	 *
206 	 * Params:
207 	 *     pageNum = the index of a page in the @assistant,
208 	 *         or -1 to get the last page
209 	 *
210 	 * Returns: the child widget, or %NULL
211 	 *     if @page_num is out of bounds
212 	 *
213 	 * Since: 2.10
214 	 */
215 	public Widget getNthPage(int pageNum)
216 	{
217 		auto p = gtk_assistant_get_nth_page(gtkAssistant, pageNum);
218 		
219 		if(p is null)
220 		{
221 			return null;
222 		}
223 		
224 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
225 	}
226 
227 	/**
228 	 * Gets whether @page is complete.
229 	 *
230 	 * Params:
231 	 *     page = a page of @assistant
232 	 *
233 	 * Returns: %TRUE if @page is complete.
234 	 *
235 	 * Since: 2.10
236 	 */
237 	public bool getPageComplete(Widget page)
238 	{
239 		return gtk_assistant_get_page_complete(gtkAssistant, (page is null) ? null : page.getWidgetStruct()) != 0;
240 	}
241 
242 	/**
243 	 * Gets whether page has padding.
244 	 *
245 	 * Params:
246 	 *     page = a page of @assistant
247 	 *
248 	 * Returns: %TRUE if @page has padding
249 	 *
250 	 * Since: 3.18
251 	 */
252 	public bool getPageHasPadding(Widget page)
253 	{
254 		return gtk_assistant_get_page_has_padding(gtkAssistant, (page is null) ? null : page.getWidgetStruct()) != 0;
255 	}
256 
257 	/**
258 	 * Gets the header image for @page.
259 	 *
260 	 * Deprecated: Since GTK+ 3.2, a header is no longer shown;
261 	 * add your header decoration to the page content instead.
262 	 *
263 	 * Params:
264 	 *     page = a page of @assistant
265 	 *
266 	 * Returns: the header image for @page,
267 	 *     or %NULL if there’s no header image for the page
268 	 *
269 	 * Since: 2.10
270 	 */
271 	public Pixbuf getPageHeaderImage(Widget page)
272 	{
273 		auto p = gtk_assistant_get_page_header_image(gtkAssistant, (page is null) ? null : page.getWidgetStruct());
274 		
275 		if(p is null)
276 		{
277 			return null;
278 		}
279 		
280 		return ObjectG.getDObject!(Pixbuf)(cast(GdkPixbuf*) p);
281 	}
282 
283 	/**
284 	 * Gets the side image for @page.
285 	 *
286 	 * Deprecated: Since GTK+ 3.2, sidebar images are not
287 	 * shown anymore.
288 	 *
289 	 * Params:
290 	 *     page = a page of @assistant
291 	 *
292 	 * Returns: the side image for @page,
293 	 *     or %NULL if there’s no side image for the page
294 	 *
295 	 * Since: 2.10
296 	 */
297 	public Pixbuf getPageSideImage(Widget page)
298 	{
299 		auto p = gtk_assistant_get_page_side_image(gtkAssistant, (page is null) ? null : page.getWidgetStruct());
300 		
301 		if(p is null)
302 		{
303 			return null;
304 		}
305 		
306 		return ObjectG.getDObject!(Pixbuf)(cast(GdkPixbuf*) p);
307 	}
308 
309 	/**
310 	 * Gets the title for @page.
311 	 *
312 	 * Params:
313 	 *     page = a page of @assistant
314 	 *
315 	 * Returns: the title for @page
316 	 *
317 	 * Since: 2.10
318 	 */
319 	public string getPageTitle(Widget page)
320 	{
321 		return Str.toString(gtk_assistant_get_page_title(gtkAssistant, (page is null) ? null : page.getWidgetStruct()));
322 	}
323 
324 	/**
325 	 * Gets the page type of @page.
326 	 *
327 	 * Params:
328 	 *     page = a page of @assistant
329 	 *
330 	 * Returns: the page type of @page
331 	 *
332 	 * Since: 2.10
333 	 */
334 	public GtkAssistantPageType getPageType(Widget page)
335 	{
336 		return gtk_assistant_get_page_type(gtkAssistant, (page is null) ? null : page.getWidgetStruct());
337 	}
338 
339 	/**
340 	 * Inserts a page in the @assistant at a given position.
341 	 *
342 	 * Params:
343 	 *     page = a #GtkWidget
344 	 *     position = the index (starting at 0) at which to insert the page,
345 	 *         or -1 to append the page to the @assistant
346 	 *
347 	 * Returns: the index (starting from 0) of the inserted page
348 	 *
349 	 * Since: 2.10
350 	 */
351 	public int insertPage(Widget page, int position)
352 	{
353 		return gtk_assistant_insert_page(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), position);
354 	}
355 
356 	/**
357 	 * Navigate to the next page.
358 	 *
359 	 * It is a programming error to call this function when
360 	 * there is no next page.
361 	 *
362 	 * This function is for use when creating pages of the
363 	 * #GTK_ASSISTANT_PAGE_CUSTOM type.
364 	 *
365 	 * Since: 3.0
366 	 */
367 	public void nextPage()
368 	{
369 		gtk_assistant_next_page(gtkAssistant);
370 	}
371 
372 	/**
373 	 * Prepends a page to the @assistant.
374 	 *
375 	 * Params:
376 	 *     page = a #GtkWidget
377 	 *
378 	 * Returns: the index (starting at 0) of the inserted page
379 	 *
380 	 * Since: 2.10
381 	 */
382 	public int prependPage(Widget page)
383 	{
384 		return gtk_assistant_prepend_page(gtkAssistant, (page is null) ? null : page.getWidgetStruct());
385 	}
386 
387 	/**
388 	 * Navigate to the previous visited page.
389 	 *
390 	 * It is a programming error to call this function when
391 	 * no previous page is available.
392 	 *
393 	 * This function is for use when creating pages of the
394 	 * #GTK_ASSISTANT_PAGE_CUSTOM type.
395 	 *
396 	 * Since: 3.0
397 	 */
398 	public void previousPage()
399 	{
400 		gtk_assistant_previous_page(gtkAssistant);
401 	}
402 
403 	/**
404 	 * Removes a widget from the action area of a #GtkAssistant.
405 	 *
406 	 * Params:
407 	 *     child = a #GtkWidget
408 	 *
409 	 * Since: 2.10
410 	 */
411 	public void removeActionWidget(Widget child)
412 	{
413 		gtk_assistant_remove_action_widget(gtkAssistant, (child is null) ? null : child.getWidgetStruct());
414 	}
415 
416 	/**
417 	 * Removes the @page_num’s page from @assistant.
418 	 *
419 	 * Params:
420 	 *     pageNum = the index of a page in the @assistant,
421 	 *         or -1 to remove the last page
422 	 *
423 	 * Since: 3.2
424 	 */
425 	public void removePage(int pageNum)
426 	{
427 		gtk_assistant_remove_page(gtkAssistant, pageNum);
428 	}
429 
430 	/**
431 	 * Switches the page to @page_num.
432 	 *
433 	 * Note that this will only be necessary in custom buttons,
434 	 * as the @assistant flow can be set with
435 	 * gtk_assistant_set_forward_page_func().
436 	 *
437 	 * Params:
438 	 *     pageNum = index of the page to switch to, starting from 0.
439 	 *         If negative, the last page will be used. If greater
440 	 *         than the number of pages in the @assistant, nothing
441 	 *         will be done.
442 	 *
443 	 * Since: 2.10
444 	 */
445 	public void setCurrentPage(int pageNum)
446 	{
447 		gtk_assistant_set_current_page(gtkAssistant, pageNum);
448 	}
449 
450 	/**
451 	 * Sets the page forwarding function to be @page_func.
452 	 *
453 	 * This function will be used to determine what will be
454 	 * the next page when the user presses the forward button.
455 	 * Setting @page_func to %NULL will make the assistant to
456 	 * use the default forward function, which just goes to the
457 	 * next visible page.
458 	 *
459 	 * Params:
460 	 *     pageFunc = the #GtkAssistantPageFunc, or %NULL
461 	 *         to use the default one
462 	 *     data = user data for @page_func
463 	 *     destroy = destroy notifier for @data
464 	 *
465 	 * Since: 2.10
466 	 */
467 	public void setForwardPageFunc(GtkAssistantPageFunc pageFunc, void* data, GDestroyNotify destroy)
468 	{
469 		gtk_assistant_set_forward_page_func(gtkAssistant, pageFunc, data, destroy);
470 	}
471 
472 	/**
473 	 * Sets whether @page contents are complete.
474 	 *
475 	 * This will make @assistant update the buttons state
476 	 * to be able to continue the task.
477 	 *
478 	 * Params:
479 	 *     page = a page of @assistant
480 	 *     complete = the completeness status of the page
481 	 *
482 	 * Since: 2.10
483 	 */
484 	public void setPageComplete(Widget page, bool complete)
485 	{
486 		gtk_assistant_set_page_complete(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), complete);
487 	}
488 
489 	/**
490 	 * Sets whether the assistant is adding padding around
491 	 * the page.
492 	 *
493 	 * Params:
494 	 *     page = a page of @assistant
495 	 *     hasPadding = whether this page has padding
496 	 *
497 	 * Since: 3.18
498 	 */
499 	public void setPageHasPadding(Widget page, bool hasPadding)
500 	{
501 		gtk_assistant_set_page_has_padding(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), hasPadding);
502 	}
503 
504 	/**
505 	 * Sets a header image for @page.
506 	 *
507 	 * Deprecated: Since GTK+ 3.2, a header is no longer shown;
508 	 * add your header decoration to the page content instead.
509 	 *
510 	 * Params:
511 	 *     page = a page of @assistant
512 	 *     pixbuf = the new header image @page
513 	 *
514 	 * Since: 2.10
515 	 */
516 	public void setPageHeaderImage(Widget page, Pixbuf pixbuf)
517 	{
518 		gtk_assistant_set_page_header_image(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), (pixbuf is null) ? null : pixbuf.getPixbufStruct());
519 	}
520 
521 	/**
522 	 * Sets a side image for @page.
523 	 *
524 	 * This image used to be displayed in the side area of the assistant
525 	 * when @page is the current page.
526 	 *
527 	 * Deprecated: Since GTK+ 3.2, sidebar images are not
528 	 * shown anymore.
529 	 *
530 	 * Params:
531 	 *     page = a page of @assistant
532 	 *     pixbuf = the new side image @page
533 	 *
534 	 * Since: 2.10
535 	 */
536 	public void setPageSideImage(Widget page, Pixbuf pixbuf)
537 	{
538 		gtk_assistant_set_page_side_image(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), (pixbuf is null) ? null : pixbuf.getPixbufStruct());
539 	}
540 
541 	/**
542 	 * Sets a title for @page.
543 	 *
544 	 * The title is displayed in the header area of the assistant
545 	 * when @page is the current page.
546 	 *
547 	 * Params:
548 	 *     page = a page of @assistant
549 	 *     title = the new title for @page
550 	 *
551 	 * Since: 2.10
552 	 */
553 	public void setPageTitle(Widget page, string title)
554 	{
555 		gtk_assistant_set_page_title(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), Str.toStringz(title));
556 	}
557 
558 	/**
559 	 * Sets the page type for @page.
560 	 *
561 	 * The page type determines the page behavior in the @assistant.
562 	 *
563 	 * Params:
564 	 *     page = a page of @assistant
565 	 *     type = the new type for @page
566 	 *
567 	 * Since: 2.10
568 	 */
569 	public void setPageType(Widget page, GtkAssistantPageType type)
570 	{
571 		gtk_assistant_set_page_type(gtkAssistant, (page is null) ? null : page.getWidgetStruct(), type);
572 	}
573 
574 	/**
575 	 * Forces @assistant to recompute the buttons state.
576 	 *
577 	 * GTK+ automatically takes care of this in most situations,
578 	 * e.g. when the user goes to a different page, or when the
579 	 * visibility or completeness of a page changes.
580 	 *
581 	 * One situation where it can be necessary to call this
582 	 * function is when changing a value on the current page
583 	 * affects the future page flow of the assistant.
584 	 *
585 	 * Since: 2.10
586 	 */
587 	public void updateButtonsState()
588 	{
589 		gtk_assistant_update_buttons_state(gtkAssistant);
590 	}
591 
592 	protected class OnApplyDelegateWrapper
593 	{
594 		static OnApplyDelegateWrapper[] listeners;
595 		void delegate(Assistant) dlg;
596 		gulong handlerId;
597 		
598 		this(void delegate(Assistant) dlg)
599 		{
600 			this.dlg = dlg;
601 			this.listeners ~= this;
602 		}
603 		
604 		void remove(OnApplyDelegateWrapper source)
605 		{
606 			foreach(index, wrapper; listeners)
607 			{
608 				if (wrapper.handlerId == source.handlerId)
609 				{
610 					listeners[index] = null;
611 					listeners = std.algorithm.remove(listeners, index);
612 					break;
613 				}
614 			}
615 		}
616 	}
617 
618 	/**
619 	 * The ::apply signal is emitted when the apply button is clicked.
620 	 *
621 	 * The default behavior of the #GtkAssistant is to switch to the page
622 	 * after the current page, unless the current page is the last one.
623 	 *
624 	 * A handler for the ::apply signal should carry out the actions for
625 	 * which the wizard has collected data. If the action takes a long time
626 	 * to complete, you might consider putting a page of type
627 	 * %GTK_ASSISTANT_PAGE_PROGRESS after the confirmation page and handle
628 	 * this operation within the #GtkAssistant::prepare signal of the progress
629 	 * page.
630 	 *
631 	 * Since: 2.10
632 	 */
633 	gulong addOnApply(void delegate(Assistant) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
634 	{
635 		auto wrapper = new OnApplyDelegateWrapper(dlg);
636 		wrapper.handlerId = Signals.connectData(
637 			this,
638 			"apply",
639 			cast(GCallback)&callBackApply,
640 			cast(void*)wrapper,
641 			cast(GClosureNotify)&callBackApplyDestroy,
642 			connectFlags);
643 		return wrapper.handlerId;
644 	}
645 	
646 	extern(C) static void callBackApply(GtkAssistant* assistantStruct, OnApplyDelegateWrapper wrapper)
647 	{
648 		wrapper.dlg(wrapper.outer);
649 	}
650 	
651 	extern(C) static void callBackApplyDestroy(OnApplyDelegateWrapper wrapper, GClosure* closure)
652 	{
653 		wrapper.remove(wrapper);
654 	}
655 
656 	protected class OnCancelDelegateWrapper
657 	{
658 		static OnCancelDelegateWrapper[] listeners;
659 		void delegate(Assistant) dlg;
660 		gulong handlerId;
661 		
662 		this(void delegate(Assistant) dlg)
663 		{
664 			this.dlg = dlg;
665 			this.listeners ~= this;
666 		}
667 		
668 		void remove(OnCancelDelegateWrapper source)
669 		{
670 			foreach(index, wrapper; listeners)
671 			{
672 				if (wrapper.handlerId == source.handlerId)
673 				{
674 					listeners[index] = null;
675 					listeners = std.algorithm.remove(listeners, index);
676 					break;
677 				}
678 			}
679 		}
680 	}
681 
682 	/**
683 	 * The ::cancel signal is emitted when then the cancel button is clicked.
684 	 *
685 	 * Since: 2.10
686 	 */
687 	gulong addOnCancel(void delegate(Assistant) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
688 	{
689 		auto wrapper = new OnCancelDelegateWrapper(dlg);
690 		wrapper.handlerId = Signals.connectData(
691 			this,
692 			"cancel",
693 			cast(GCallback)&callBackCancel,
694 			cast(void*)wrapper,
695 			cast(GClosureNotify)&callBackCancelDestroy,
696 			connectFlags);
697 		return wrapper.handlerId;
698 	}
699 	
700 	extern(C) static void callBackCancel(GtkAssistant* assistantStruct, OnCancelDelegateWrapper wrapper)
701 	{
702 		wrapper.dlg(wrapper.outer);
703 	}
704 	
705 	extern(C) static void callBackCancelDestroy(OnCancelDelegateWrapper wrapper, GClosure* closure)
706 	{
707 		wrapper.remove(wrapper);
708 	}
709 
710 	protected class OnCloseDelegateWrapper
711 	{
712 		static OnCloseDelegateWrapper[] listeners;
713 		void delegate(Assistant) dlg;
714 		gulong handlerId;
715 		
716 		this(void delegate(Assistant) dlg)
717 		{
718 			this.dlg = dlg;
719 			this.listeners ~= this;
720 		}
721 		
722 		void remove(OnCloseDelegateWrapper source)
723 		{
724 			foreach(index, wrapper; listeners)
725 			{
726 				if (wrapper.handlerId == source.handlerId)
727 				{
728 					listeners[index] = null;
729 					listeners = std.algorithm.remove(listeners, index);
730 					break;
731 				}
732 			}
733 		}
734 	}
735 
736 	/**
737 	 * The ::close signal is emitted either when the close button of
738 	 * a summary page is clicked, or when the apply button in the last
739 	 * page in the flow (of type %GTK_ASSISTANT_PAGE_CONFIRM) is clicked.
740 	 *
741 	 * Since: 2.10
742 	 */
743 	gulong addOnClose(void delegate(Assistant) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
744 	{
745 		auto wrapper = new OnCloseDelegateWrapper(dlg);
746 		wrapper.handlerId = Signals.connectData(
747 			this,
748 			"close",
749 			cast(GCallback)&callBackClose,
750 			cast(void*)wrapper,
751 			cast(GClosureNotify)&callBackCloseDestroy,
752 			connectFlags);
753 		return wrapper.handlerId;
754 	}
755 	
756 	extern(C) static void callBackClose(GtkAssistant* assistantStruct, OnCloseDelegateWrapper wrapper)
757 	{
758 		wrapper.dlg(wrapper.outer);
759 	}
760 	
761 	extern(C) static void callBackCloseDestroy(OnCloseDelegateWrapper wrapper, GClosure* closure)
762 	{
763 		wrapper.remove(wrapper);
764 	}
765 
766 	protected class OnEscapeDelegateWrapper
767 	{
768 		static OnEscapeDelegateWrapper[] listeners;
769 		void delegate(Assistant) dlg;
770 		gulong handlerId;
771 		
772 		this(void delegate(Assistant) dlg)
773 		{
774 			this.dlg = dlg;
775 			this.listeners ~= this;
776 		}
777 		
778 		void remove(OnEscapeDelegateWrapper source)
779 		{
780 			foreach(index, wrapper; listeners)
781 			{
782 				if (wrapper.handlerId == source.handlerId)
783 				{
784 					listeners[index] = null;
785 					listeners = std.algorithm.remove(listeners, index);
786 					break;
787 				}
788 			}
789 		}
790 	}
791 
792 	/** */
793 	gulong addOnEscape(void delegate(Assistant) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
794 	{
795 		auto wrapper = new OnEscapeDelegateWrapper(dlg);
796 		wrapper.handlerId = Signals.connectData(
797 			this,
798 			"escape",
799 			cast(GCallback)&callBackEscape,
800 			cast(void*)wrapper,
801 			cast(GClosureNotify)&callBackEscapeDestroy,
802 			connectFlags);
803 		return wrapper.handlerId;
804 	}
805 	
806 	extern(C) static void callBackEscape(GtkAssistant* assistantStruct, OnEscapeDelegateWrapper wrapper)
807 	{
808 		wrapper.dlg(wrapper.outer);
809 	}
810 	
811 	extern(C) static void callBackEscapeDestroy(OnEscapeDelegateWrapper wrapper, GClosure* closure)
812 	{
813 		wrapper.remove(wrapper);
814 	}
815 
816 	protected class OnPrepareDelegateWrapper
817 	{
818 		static OnPrepareDelegateWrapper[] listeners;
819 		void delegate(Widget, Assistant) dlg;
820 		gulong handlerId;
821 		
822 		this(void delegate(Widget, Assistant) dlg)
823 		{
824 			this.dlg = dlg;
825 			this.listeners ~= this;
826 		}
827 		
828 		void remove(OnPrepareDelegateWrapper source)
829 		{
830 			foreach(index, wrapper; listeners)
831 			{
832 				if (wrapper.handlerId == source.handlerId)
833 				{
834 					listeners[index] = null;
835 					listeners = std.algorithm.remove(listeners, index);
836 					break;
837 				}
838 			}
839 		}
840 	}
841 
842 	/**
843 	 * The ::prepare signal is emitted when a new page is set as the
844 	 * assistant's current page, before making the new page visible.
845 	 *
846 	 * A handler for this signal can do any preparations which are
847 	 * necessary before showing @page.
848 	 *
849 	 * Params:
850 	 *     page = the current page
851 	 *
852 	 * Since: 2.10
853 	 */
854 	gulong addOnPrepare(void delegate(Widget, Assistant) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
855 	{
856 		auto wrapper = new OnPrepareDelegateWrapper(dlg);
857 		wrapper.handlerId = Signals.connectData(
858 			this,
859 			"prepare",
860 			cast(GCallback)&callBackPrepare,
861 			cast(void*)wrapper,
862 			cast(GClosureNotify)&callBackPrepareDestroy,
863 			connectFlags);
864 		return wrapper.handlerId;
865 	}
866 	
867 	extern(C) static void callBackPrepare(GtkAssistant* assistantStruct, GtkWidget* page, OnPrepareDelegateWrapper wrapper)
868 	{
869 		wrapper.dlg(ObjectG.getDObject!(Widget)(page), wrapper.outer);
870 	}
871 	
872 	extern(C) static void callBackPrepareDestroy(OnPrepareDelegateWrapper wrapper, GClosure* closure)
873 	{
874 		wrapper.remove(wrapper);
875 	}
876 }