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