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.Notebook;
26 
27 private import glib.ConstructionException;
28 private import glib.Str;
29 private import gobject.ObjectG;
30 private import gobject.Signals;
31 private import gtk.Container;
32 private import gtk.Label;
33 private import gtk.Widget;
34 private import gtkc.gtk;
35 public  import gtkc.gtktypes;
36 private import std.algorithm;
37 
38 
39 /**
40  * The #GtkNotebook widget is a #GtkContainer whose children are pages that
41  * can be switched between using tab labels along one edge.
42  * 
43  * There are many configuration options for GtkNotebook. Among other
44  * things, you can choose on which edge the tabs appear
45  * (see gtk_notebook_set_tab_pos()), whether, if there are too many
46  * tabs to fit the notebook should be made bigger or scrolling
47  * arrows added (see gtk_notebook_set_scrollable()), and whether there
48  * will be a popup menu allowing the users to switch pages.
49  * (see gtk_notebook_popup_enable(), gtk_notebook_popup_disable())
50  * 
51  * # GtkNotebook as GtkBuildable
52  * 
53  * The GtkNotebook implementation of the #GtkBuildable interface
54  * supports placing children into tabs by specifying “tab” as the
55  * “type” attribute of a <child> element. Note that the content
56  * of the tab must be created before the tab can be filled.
57  * A tab child can be specified without specifying a <child>
58  * type attribute.
59  * 
60  * To add a child widget in the notebooks action area, specify
61  * "action-start" or “action-end” as the “type” attribute of the
62  * <child> element.
63  * 
64  * An example of a UI definition fragment with GtkNotebook:
65  * |[
66  * <object class="GtkNotebook">
67  * <child>
68  * <object class="GtkLabel" id="notebook-content">
69  * <property name="label">Content</property>
70  * </object>
71  * </child>
72  * <child type="tab">
73  * <object class="GtkLabel" id="notebook-tab">
74  * <property name="label">Tab</property>
75  * </object>
76  * </child>
77  * </object>
78  * ]|
79  * 
80  * # CSS nodes
81  * 
82  * |[<!-- language="plain" -->
83  * notebook
84  * ├── header.top
85  * │   ├── [<action widget>]
86  * │   ├── tabs
87  * │   │   ├── [arrow]
88  * │   │   ├── tab
89  * │   │   │   ╰── <tab label>
90  * ┊   ┊   ┊
91  * │   │   ├── tab[.reorderable-page]
92  * │   │   │   ╰── <tab label>
93  * │   │   ╰── [arrow]
94  * │   ╰── [<action widget>]
95  * │
96  * ╰── stack
97  * ├── <child>
98  * ┊
99  * ╰── <child>
100  * ]|
101  * 
102  * GtkNotebook has a main CSS node with name notebook, a subnode
103  * with name header and below that a subnode with name tabs which
104  * contains one subnode per tab with name tab.
105  * 
106  * If action widgets are present, their CSS nodes are placed next
107  * to the tabs node. If the notebook is scrollable, CSS nodes with
108  * name arrow are placed as first and last child of the tabs node.
109  * 
110  * The main node gets the .frame style class when the notebook
111  * has a border (see gtk_notebook_set_show_border()).
112  * 
113  * The header node gets one of the style class .top, .bottom,
114  * .left or .right, depending on where the tabs are placed. For
115  * reorderable pages, the tab node gets the .reorderable-page class.
116  * 
117  * A tab node gets the .dnd style class while it is moved with drag-and-drop.
118  * 
119  * The nodes are always arranged from left-to-right, regarldess of text direction.
120  */
121 public class Notebook : Container
122 {
123 	/** the main Gtk struct */
124 	protected GtkNotebook* gtkNotebook;
125 
126 	/** Get the main Gtk struct */
127 	public GtkNotebook* getNotebookStruct(bool transferOwnership = false)
128 	{
129 		if (transferOwnership)
130 			ownedRef = false;
131 		return gtkNotebook;
132 	}
133 
134 	/** the main Gtk struct as a void* */
135 	protected override void* getStruct()
136 	{
137 		return cast(void*)gtkNotebook;
138 	}
139 
140 	protected override void setStruct(GObject* obj)
141 	{
142 		gtkNotebook = cast(GtkNotebook*)obj;
143 		super.setStruct(obj);
144 	}
145 
146 	/**
147 	 * Sets our main struct and passes it to the parent class.
148 	 */
149 	public this (GtkNotebook* gtkNotebook, bool ownedRef = false)
150 	{
151 		this.gtkNotebook = gtkNotebook;
152 		super(cast(GtkContainer*)gtkNotebook, ownedRef);
153 	}
154 
155 	/**
156 	 * Append a page with a widget and a text for a label
157 	 */
158 	public int appendPage(Widget child, string tabLabel)
159 	{
160 		return appendPage(child, new Label(tabLabel));
161 	}
162 	
163 	/** */
164 	void setCurrentPage(Widget child)
165 	{
166 		gtk_notebook_set_current_page(gtkNotebook,gtk_notebook_page_num(gtkNotebook, child.getWidgetStruct()));
167 	}
168 
169 	/**
170 	 */
171 
172 	/** */
173 	public static GType getType()
174 	{
175 		return gtk_notebook_get_type();
176 	}
177 
178 	/**
179 	 * Creates a new #GtkNotebook widget with no pages.
180 	 *
181 	 * Returns: the newly created #GtkNotebook
182 	 *
183 	 * Throws: ConstructionException GTK+ fails to create the object.
184 	 */
185 	public this()
186 	{
187 		auto p = gtk_notebook_new();
188 		
189 		if(p is null)
190 		{
191 			throw new ConstructionException("null returned by new");
192 		}
193 		
194 		this(cast(GtkNotebook*) p);
195 	}
196 
197 	/**
198 	 * Appends a page to @notebook.
199 	 *
200 	 * Params:
201 	 *     child = the #GtkWidget to use as the contents of the page
202 	 *     tabLabel = the #GtkWidget to be used as the label
203 	 *         for the page, or %NULL to use the default label, “page N”
204 	 *
205 	 * Returns: the index (starting from 0) of the appended
206 	 *     page in the notebook, or -1 if function fails
207 	 */
208 	public int appendPage(Widget child, Widget tabLabel)
209 	{
210 		return gtk_notebook_append_page(gtkNotebook, (child is null) ? null : child.getWidgetStruct(), (tabLabel is null) ? null : tabLabel.getWidgetStruct());
211 	}
212 
213 	/**
214 	 * Appends a page to @notebook, specifying the widget to use as the
215 	 * label in the popup menu.
216 	 *
217 	 * Params:
218 	 *     child = the #GtkWidget to use as the contents of the page
219 	 *     tabLabel = the #GtkWidget to be used as the label
220 	 *         for the page, or %NULL to use the default label, “page N”
221 	 *     menuLabel = the widget to use as a label for the
222 	 *         page-switch menu, if that is enabled. If %NULL, and @tab_label
223 	 *         is a #GtkLabel or %NULL, then the menu label will be a newly
224 	 *         created label with the same text as @tab_label; if @tab_label
225 	 *         is not a #GtkLabel, @menu_label must be specified if the
226 	 *         page-switch menu is to be used.
227 	 *
228 	 * Returns: the index (starting from 0) of the appended
229 	 *     page in the notebook, or -1 if function fails
230 	 */
231 	public int appendPageMenu(Widget child, Widget tabLabel, Widget menuLabel)
232 	{
233 		return gtk_notebook_append_page_menu(gtkNotebook, (child is null) ? null : child.getWidgetStruct(), (tabLabel is null) ? null : tabLabel.getWidgetStruct(), (menuLabel is null) ? null : menuLabel.getWidgetStruct());
234 	}
235 
236 	/**
237 	 * Removes the child from the notebook.
238 	 *
239 	 * This function is very similar to gtk_container_remove(),
240 	 * but additionally informs the notebook that the removal
241 	 * is happening as part of a tab DND operation, which should
242 	 * not be cancelled.
243 	 *
244 	 * Params:
245 	 *     child = a child
246 	 *
247 	 * Since: 3.16
248 	 */
249 	public void detachTab(Widget child)
250 	{
251 		gtk_notebook_detach_tab(gtkNotebook, (child is null) ? null : child.getWidgetStruct());
252 	}
253 
254 	/**
255 	 * Gets one of the action widgets. See gtk_notebook_set_action_widget().
256 	 *
257 	 * Params:
258 	 *     packType = pack type of the action widget to receive
259 	 *
260 	 * Returns: The action widget with the given
261 	 *     @pack_type or %NULL when this action widget has not been set
262 	 *
263 	 * Since: 2.20
264 	 */
265 	public Widget getActionWidget(GtkPackType packType)
266 	{
267 		auto p = gtk_notebook_get_action_widget(gtkNotebook, packType);
268 		
269 		if(p is null)
270 		{
271 			return null;
272 		}
273 		
274 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
275 	}
276 
277 	/**
278 	 * Returns the page number of the current page.
279 	 *
280 	 * Returns: the index (starting from 0) of the current
281 	 *     page in the notebook. If the notebook has no pages,
282 	 *     then -1 will be returned.
283 	 */
284 	public int getCurrentPage()
285 	{
286 		return gtk_notebook_get_current_page(gtkNotebook);
287 	}
288 
289 	/**
290 	 * Gets the current group name for @notebook.
291 	 *
292 	 * Returns: the group name, or %NULL if none is set
293 	 *
294 	 * Since: 2.24
295 	 */
296 	public string getGroupName()
297 	{
298 		return Str.toString(gtk_notebook_get_group_name(gtkNotebook));
299 	}
300 
301 	/**
302 	 * Retrieves the menu label widget of the page containing @child.
303 	 *
304 	 * Params:
305 	 *     child = a widget contained in a page of @notebook
306 	 *
307 	 * Returns: the menu label, or %NULL if the
308 	 *     notebook page does not have a menu label other than the default (the tab
309 	 *     label).
310 	 */
311 	public Widget getMenuLabel(Widget child)
312 	{
313 		auto p = gtk_notebook_get_menu_label(gtkNotebook, (child is null) ? null : child.getWidgetStruct());
314 		
315 		if(p is null)
316 		{
317 			return null;
318 		}
319 		
320 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
321 	}
322 
323 	/**
324 	 * Retrieves the text of the menu label for the page containing
325 	 * @child.
326 	 *
327 	 * Params:
328 	 *     child = the child widget of a page of the notebook.
329 	 *
330 	 * Returns: the text of the tab label, or %NULL if the widget does
331 	 *     not have a menu label other than the default menu label, or the menu label
332 	 *     widget is not a #GtkLabel. The string is owned by the widget and must not be
333 	 *     freed.
334 	 */
335 	public string getMenuLabelText(Widget child)
336 	{
337 		return Str.toString(gtk_notebook_get_menu_label_text(gtkNotebook, (child is null) ? null : child.getWidgetStruct()));
338 	}
339 
340 	/**
341 	 * Gets the number of pages in a notebook.
342 	 *
343 	 * Returns: the number of pages in the notebook
344 	 *
345 	 * Since: 2.2
346 	 */
347 	public int getNPages()
348 	{
349 		return gtk_notebook_get_n_pages(gtkNotebook);
350 	}
351 
352 	/**
353 	 * Returns the child widget contained in page number @page_num.
354 	 *
355 	 * Params:
356 	 *     pageNum = the index of a page in the notebook, or -1
357 	 *         to get the last page
358 	 *
359 	 * Returns: the child widget, or %NULL if @page_num
360 	 *     is out of bounds
361 	 */
362 	public Widget getNthPage(int pageNum)
363 	{
364 		auto p = gtk_notebook_get_nth_page(gtkNotebook, pageNum);
365 		
366 		if(p is null)
367 		{
368 			return null;
369 		}
370 		
371 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
372 	}
373 
374 	/**
375 	 * Returns whether the tab label area has arrows for scrolling.
376 	 * See gtk_notebook_set_scrollable().
377 	 *
378 	 * Returns: %TRUE if arrows for scrolling are present
379 	 */
380 	public bool getScrollable()
381 	{
382 		return gtk_notebook_get_scrollable(gtkNotebook) != 0;
383 	}
384 
385 	/**
386 	 * Returns whether a bevel will be drawn around the notebook pages.
387 	 * See gtk_notebook_set_show_border().
388 	 *
389 	 * Returns: %TRUE if the bevel is drawn
390 	 */
391 	public bool getShowBorder()
392 	{
393 		return gtk_notebook_get_show_border(gtkNotebook) != 0;
394 	}
395 
396 	/**
397 	 * Returns whether the tabs of the notebook are shown.
398 	 * See gtk_notebook_set_show_tabs().
399 	 *
400 	 * Returns: %TRUE if the tabs are shown
401 	 */
402 	public bool getShowTabs()
403 	{
404 		return gtk_notebook_get_show_tabs(gtkNotebook) != 0;
405 	}
406 
407 	/**
408 	 * Returns whether the tab contents can be detached from @notebook.
409 	 *
410 	 * Params:
411 	 *     child = a child #GtkWidget
412 	 *
413 	 * Returns: %TRUE if the tab is detachable.
414 	 *
415 	 * Since: 2.10
416 	 */
417 	public bool getTabDetachable(Widget child)
418 	{
419 		return gtk_notebook_get_tab_detachable(gtkNotebook, (child is null) ? null : child.getWidgetStruct()) != 0;
420 	}
421 
422 	/**
423 	 * Returns the horizontal width of a tab border.
424 	 *
425 	 * Deprecated: this function returns zero
426 	 *
427 	 * Returns: horizontal width of a tab border
428 	 *
429 	 * Since: 2.22
430 	 */
431 	public ushort getTabHborder()
432 	{
433 		return gtk_notebook_get_tab_hborder(gtkNotebook);
434 	}
435 
436 	/**
437 	 * Returns the tab label widget for the page @child.
438 	 * %NULL is returned if @child is not in @notebook or
439 	 * if no tab label has specifically been set for @child.
440 	 *
441 	 * Params:
442 	 *     child = the page
443 	 *
444 	 * Returns: the tab label
445 	 */
446 	public Widget getTabLabel(Widget child)
447 	{
448 		auto p = gtk_notebook_get_tab_label(gtkNotebook, (child is null) ? null : child.getWidgetStruct());
449 		
450 		if(p is null)
451 		{
452 			return null;
453 		}
454 		
455 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
456 	}
457 
458 	/**
459 	 * Retrieves the text of the tab label for the page containing
460 	 * @child.
461 	 *
462 	 * Params:
463 	 *     child = a widget contained in a page of @notebook
464 	 *
465 	 * Returns: the text of the tab label, or %NULL if the tab label
466 	 *     widget is not a #GtkLabel. The string is owned by the widget and must not be
467 	 *     freed.
468 	 */
469 	public string getTabLabelText(Widget child)
470 	{
471 		return Str.toString(gtk_notebook_get_tab_label_text(gtkNotebook, (child is null) ? null : child.getWidgetStruct()));
472 	}
473 
474 	/**
475 	 * Gets the edge at which the tabs for switching pages in the
476 	 * notebook are drawn.
477 	 *
478 	 * Returns: the edge at which the tabs are drawn
479 	 */
480 	public GtkPositionType getTabPos()
481 	{
482 		return gtk_notebook_get_tab_pos(gtkNotebook);
483 	}
484 
485 	/**
486 	 * Gets whether the tab can be reordered via drag and drop or not.
487 	 *
488 	 * Params:
489 	 *     child = a child #GtkWidget
490 	 *
491 	 * Returns: %TRUE if the tab is reorderable.
492 	 *
493 	 * Since: 2.10
494 	 */
495 	public bool getTabReorderable(Widget child)
496 	{
497 		return gtk_notebook_get_tab_reorderable(gtkNotebook, (child is null) ? null : child.getWidgetStruct()) != 0;
498 	}
499 
500 	/**
501 	 * Returns the vertical width of a tab border.
502 	 *
503 	 * Deprecated: this function returns zero
504 	 *
505 	 * Returns: vertical width of a tab border
506 	 *
507 	 * Since: 2.22
508 	 */
509 	public ushort getTabVborder()
510 	{
511 		return gtk_notebook_get_tab_vborder(gtkNotebook);
512 	}
513 
514 	/**
515 	 * Insert a page into @notebook at the given position.
516 	 *
517 	 * Params:
518 	 *     child = the #GtkWidget to use as the contents of the page
519 	 *     tabLabel = the #GtkWidget to be used as the label
520 	 *         for the page, or %NULL to use the default label, “page N”
521 	 *     position = the index (starting at 0) at which to insert the page,
522 	 *         or -1 to append the page after all other pages
523 	 *
524 	 * Returns: the index (starting from 0) of the inserted
525 	 *     page in the notebook, or -1 if function fails
526 	 */
527 	public int insertPage(Widget child, Widget tabLabel, int position)
528 	{
529 		return gtk_notebook_insert_page(gtkNotebook, (child is null) ? null : child.getWidgetStruct(), (tabLabel is null) ? null : tabLabel.getWidgetStruct(), position);
530 	}
531 
532 	/**
533 	 * Insert a page into @notebook at the given position, specifying
534 	 * the widget to use as the label in the popup menu.
535 	 *
536 	 * Params:
537 	 *     child = the #GtkWidget to use as the contents of the page
538 	 *     tabLabel = the #GtkWidget to be used as the label
539 	 *         for the page, or %NULL to use the default label, “page N”
540 	 *     menuLabel = the widget to use as a label for the
541 	 *         page-switch menu, if that is enabled. If %NULL, and @tab_label
542 	 *         is a #GtkLabel or %NULL, then the menu label will be a newly
543 	 *         created label with the same text as @tab_label; if @tab_label
544 	 *         is not a #GtkLabel, @menu_label must be specified if the
545 	 *         page-switch menu is to be used.
546 	 *     position = the index (starting at 0) at which to insert the page,
547 	 *         or -1 to append the page after all other pages.
548 	 *
549 	 * Returns: the index (starting from 0) of the inserted
550 	 *     page in the notebook
551 	 */
552 	public int insertPageMenu(Widget child, Widget tabLabel, Widget menuLabel, int position)
553 	{
554 		return gtk_notebook_insert_page_menu(gtkNotebook, (child is null) ? null : child.getWidgetStruct(), (tabLabel is null) ? null : tabLabel.getWidgetStruct(), (menuLabel is null) ? null : menuLabel.getWidgetStruct(), position);
555 	}
556 
557 	/**
558 	 * Switches to the next page. Nothing happens if the current page is
559 	 * the last page.
560 	 */
561 	public void nextPage()
562 	{
563 		gtk_notebook_next_page(gtkNotebook);
564 	}
565 
566 	/**
567 	 * Finds the index of the page which contains the given child
568 	 * widget.
569 	 *
570 	 * Params:
571 	 *     child = a #GtkWidget
572 	 *
573 	 * Returns: the index of the page containing @child, or
574 	 *     -1 if @child is not in the notebook
575 	 */
576 	public int pageNum(Widget child)
577 	{
578 		return gtk_notebook_page_num(gtkNotebook, (child is null) ? null : child.getWidgetStruct());
579 	}
580 
581 	/**
582 	 * Disables the popup menu.
583 	 */
584 	public void popupDisable()
585 	{
586 		gtk_notebook_popup_disable(gtkNotebook);
587 	}
588 
589 	/**
590 	 * Enables the popup menu: if the user clicks with the right
591 	 * mouse button on the tab labels, a menu with all the pages
592 	 * will be popped up.
593 	 */
594 	public void popupEnable()
595 	{
596 		gtk_notebook_popup_enable(gtkNotebook);
597 	}
598 
599 	/**
600 	 * Prepends a page to @notebook.
601 	 *
602 	 * Params:
603 	 *     child = the #GtkWidget to use as the contents of the page
604 	 *     tabLabel = the #GtkWidget to be used as the label
605 	 *         for the page, or %NULL to use the default label, “page N”
606 	 *
607 	 * Returns: the index (starting from 0) of the prepended
608 	 *     page in the notebook, or -1 if function fails
609 	 */
610 	public int prependPage(Widget child, Widget tabLabel)
611 	{
612 		return gtk_notebook_prepend_page(gtkNotebook, (child is null) ? null : child.getWidgetStruct(), (tabLabel is null) ? null : tabLabel.getWidgetStruct());
613 	}
614 
615 	/**
616 	 * Prepends a page to @notebook, specifying the widget to use as the
617 	 * label in the popup menu.
618 	 *
619 	 * Params:
620 	 *     child = the #GtkWidget to use as the contents of the page
621 	 *     tabLabel = the #GtkWidget to be used as the label
622 	 *         for the page, or %NULL to use the default label, “page N”
623 	 *     menuLabel = the widget to use as a label for the
624 	 *         page-switch menu, if that is enabled. If %NULL, and @tab_label
625 	 *         is a #GtkLabel or %NULL, then the menu label will be a newly
626 	 *         created label with the same text as @tab_label; if @tab_label
627 	 *         is not a #GtkLabel, @menu_label must be specified if the
628 	 *         page-switch menu is to be used.
629 	 *
630 	 * Returns: the index (starting from 0) of the prepended
631 	 *     page in the notebook, or -1 if function fails
632 	 */
633 	public int prependPageMenu(Widget child, Widget tabLabel, Widget menuLabel)
634 	{
635 		return gtk_notebook_prepend_page_menu(gtkNotebook, (child is null) ? null : child.getWidgetStruct(), (tabLabel is null) ? null : tabLabel.getWidgetStruct(), (menuLabel is null) ? null : menuLabel.getWidgetStruct());
636 	}
637 
638 	/**
639 	 * Switches to the previous page. Nothing happens if the current page
640 	 * is the first page.
641 	 */
642 	public void prevPage()
643 	{
644 		gtk_notebook_prev_page(gtkNotebook);
645 	}
646 
647 	/**
648 	 * Removes a page from the notebook given its index
649 	 * in the notebook.
650 	 *
651 	 * Params:
652 	 *     pageNum = the index of a notebook page, starting
653 	 *         from 0. If -1, the last page will be removed.
654 	 */
655 	public void removePage(int pageNum)
656 	{
657 		gtk_notebook_remove_page(gtkNotebook, pageNum);
658 	}
659 
660 	/**
661 	 * Reorders the page containing @child, so that it appears in position
662 	 * @position. If @position is greater than or equal to the number of
663 	 * children in the list or negative, @child will be moved to the end
664 	 * of the list.
665 	 *
666 	 * Params:
667 	 *     child = the child to move
668 	 *     position = the new position, or -1 to move to the end
669 	 */
670 	public void reorderChild(Widget child, int position)
671 	{
672 		gtk_notebook_reorder_child(gtkNotebook, (child is null) ? null : child.getWidgetStruct(), position);
673 	}
674 
675 	/**
676 	 * Sets @widget as one of the action widgets. Depending on the pack type
677 	 * the widget will be placed before or after the tabs. You can use
678 	 * a #GtkBox if you need to pack more than one widget on the same side.
679 	 *
680 	 * Note that action widgets are “internal” children of the notebook and thus
681 	 * not included in the list returned from gtk_container_foreach().
682 	 *
683 	 * Params:
684 	 *     widget = a #GtkWidget
685 	 *     packType = pack type of the action widget
686 	 *
687 	 * Since: 2.20
688 	 */
689 	public void setActionWidget(Widget widget, GtkPackType packType)
690 	{
691 		gtk_notebook_set_action_widget(gtkNotebook, (widget is null) ? null : widget.getWidgetStruct(), packType);
692 	}
693 
694 	/**
695 	 * Switches to the page number @page_num.
696 	 *
697 	 * Note that due to historical reasons, GtkNotebook refuses
698 	 * to switch to a page unless the child widget is visible.
699 	 * Therefore, it is recommended to show child widgets before
700 	 * adding them to a notebook.
701 	 *
702 	 * Params:
703 	 *     pageNum = index of the page to switch to, starting from 0.
704 	 *         If negative, the last page will be used. If greater
705 	 *         than the number of pages in the notebook, nothing
706 	 *         will be done.
707 	 */
708 	public void setCurrentPage(int pageNum)
709 	{
710 		gtk_notebook_set_current_page(gtkNotebook, pageNum);
711 	}
712 
713 	/**
714 	 * Sets a group name for @notebook.
715 	 *
716 	 * Notebooks with the same name will be able to exchange tabs
717 	 * via drag and drop. A notebook with a %NULL group name will
718 	 * not be able to exchange tabs with any other notebook.
719 	 *
720 	 * Params:
721 	 *     groupName = the name of the notebook group,
722 	 *         or %NULL to unset it
723 	 *
724 	 * Since: 2.24
725 	 */
726 	public void setGroupName(string groupName)
727 	{
728 		gtk_notebook_set_group_name(gtkNotebook, Str.toStringz(groupName));
729 	}
730 
731 	/**
732 	 * Changes the menu label for the page containing @child.
733 	 *
734 	 * Params:
735 	 *     child = the child widget
736 	 *     menuLabel = the menu label, or %NULL for default
737 	 */
738 	public void setMenuLabel(Widget child, Widget menuLabel)
739 	{
740 		gtk_notebook_set_menu_label(gtkNotebook, (child is null) ? null : child.getWidgetStruct(), (menuLabel is null) ? null : menuLabel.getWidgetStruct());
741 	}
742 
743 	/**
744 	 * Creates a new label and sets it as the menu label of @child.
745 	 *
746 	 * Params:
747 	 *     child = the child widget
748 	 *     menuText = the label text
749 	 */
750 	public void setMenuLabelText(Widget child, string menuText)
751 	{
752 		gtk_notebook_set_menu_label_text(gtkNotebook, (child is null) ? null : child.getWidgetStruct(), Str.toStringz(menuText));
753 	}
754 
755 	/**
756 	 * Sets whether the tab label area will have arrows for
757 	 * scrolling if there are too many tabs to fit in the area.
758 	 *
759 	 * Params:
760 	 *     scrollable = %TRUE if scroll arrows should be added
761 	 */
762 	public void setScrollable(bool scrollable)
763 	{
764 		gtk_notebook_set_scrollable(gtkNotebook, scrollable);
765 	}
766 
767 	/**
768 	 * Sets whether a bevel will be drawn around the notebook pages.
769 	 * This only has a visual effect when the tabs are not shown.
770 	 * See gtk_notebook_set_show_tabs().
771 	 *
772 	 * Params:
773 	 *     showBorder = %TRUE if a bevel should be drawn around the notebook
774 	 */
775 	public void setShowBorder(bool showBorder)
776 	{
777 		gtk_notebook_set_show_border(gtkNotebook, showBorder);
778 	}
779 
780 	/**
781 	 * Sets whether to show the tabs for the notebook or not.
782 	 *
783 	 * Params:
784 	 *     showTabs = %TRUE if the tabs should be shown
785 	 */
786 	public void setShowTabs(bool showTabs)
787 	{
788 		gtk_notebook_set_show_tabs(gtkNotebook, showTabs);
789 	}
790 
791 	/**
792 	 * Sets whether the tab can be detached from @notebook to another
793 	 * notebook or widget.
794 	 *
795 	 * Note that 2 notebooks must share a common group identificator
796 	 * (see gtk_notebook_set_group_name()) to allow automatic tabs
797 	 * interchange between them.
798 	 *
799 	 * If you want a widget to interact with a notebook through DnD
800 	 * (i.e.: accept dragged tabs from it) it must be set as a drop
801 	 * destination and accept the target “GTK_NOTEBOOK_TAB”. The notebook
802 	 * will fill the selection with a GtkWidget** pointing to the child
803 	 * widget that corresponds to the dropped tab.
804 	 *
805 	 * Note that you should use gtk_notebook_detach_tab() instead
806 	 * of gtk_container_remove() if you want to remove the tab from
807 	 * the source notebook as part of accepting a drop. Otherwise,
808 	 * the source notebook will think that the dragged tab was
809 	 * removed from underneath the ongoing drag operation, and
810 	 * will initiate a drag cancel animation.
811 	 *
812 	 * |[<!-- language="C" -->
813 	 * static void
814 	 * on_drag_data_received (GtkWidget        *widget,
815 	 * GdkDragContext   *context,
816 	 * gint              x,
817 	 * gint              y,
818 	 * GtkSelectionData *data,
819 	 * guint             info,
820 	 * guint             time,
821 	 * gpointer          user_data)
822 	 * {
823 	 * GtkWidget *notebook;
824 	 * GtkWidget **child;
825 	 *
826 	 * notebook = gtk_drag_get_source_widget (context);
827 	 * child = (void*) gtk_selection_data_get_data (data);
828 	 *
829 	 * process_widget (*child);
830 	 * gtk_notebook_detach_tab (GTK_NOTEBOOK (notebook), *child);
831 	 * }
832 	 * ]|
833 	 *
834 	 * If you want a notebook to accept drags from other widgets,
835 	 * you will have to set your own DnD code to do it.
836 	 *
837 	 * Params:
838 	 *     child = a child #GtkWidget
839 	 *     detachable = whether the tab is detachable or not
840 	 *
841 	 * Since: 2.10
842 	 */
843 	public void setTabDetachable(Widget child, bool detachable)
844 	{
845 		gtk_notebook_set_tab_detachable(gtkNotebook, (child is null) ? null : child.getWidgetStruct(), detachable);
846 	}
847 
848 	/**
849 	 * Changes the tab label for @child.
850 	 * If %NULL is specified for @tab_label, then the page will
851 	 * have the label “page N”.
852 	 *
853 	 * Params:
854 	 *     child = the page
855 	 *     tabLabel = the tab label widget to use, or %NULL
856 	 *         for default tab label
857 	 */
858 	public void setTabLabel(Widget child, Widget tabLabel)
859 	{
860 		gtk_notebook_set_tab_label(gtkNotebook, (child is null) ? null : child.getWidgetStruct(), (tabLabel is null) ? null : tabLabel.getWidgetStruct());
861 	}
862 
863 	/**
864 	 * Creates a new label and sets it as the tab label for the page
865 	 * containing @child.
866 	 *
867 	 * Params:
868 	 *     child = the page
869 	 *     tabText = the label text
870 	 */
871 	public void setTabLabelText(Widget child, string tabText)
872 	{
873 		gtk_notebook_set_tab_label_text(gtkNotebook, (child is null) ? null : child.getWidgetStruct(), Str.toStringz(tabText));
874 	}
875 
876 	/**
877 	 * Sets the edge at which the tabs for switching pages in the
878 	 * notebook are drawn.
879 	 *
880 	 * Params:
881 	 *     pos = the edge to draw the tabs at
882 	 */
883 	public void setTabPos(GtkPositionType pos)
884 	{
885 		gtk_notebook_set_tab_pos(gtkNotebook, pos);
886 	}
887 
888 	/**
889 	 * Sets whether the notebook tab can be reordered
890 	 * via drag and drop or not.
891 	 *
892 	 * Params:
893 	 *     child = a child #GtkWidget
894 	 *     reorderable = whether the tab is reorderable or not
895 	 *
896 	 * Since: 2.10
897 	 */
898 	public void setTabReorderable(Widget child, bool reorderable)
899 	{
900 		gtk_notebook_set_tab_reorderable(gtkNotebook, (child is null) ? null : child.getWidgetStruct(), reorderable);
901 	}
902 
903 	protected class OnChangeCurrentPageDelegateWrapper
904 	{
905 		static OnChangeCurrentPageDelegateWrapper[] listeners;
906 		bool delegate(int, Notebook) dlg;
907 		gulong handlerId;
908 		
909 		this(bool delegate(int, Notebook) dlg)
910 		{
911 			this.dlg = dlg;
912 			this.listeners ~= this;
913 		}
914 		
915 		void remove(OnChangeCurrentPageDelegateWrapper source)
916 		{
917 			foreach(index, wrapper; listeners)
918 			{
919 				if (wrapper.handlerId == source.handlerId)
920 				{
921 					listeners[index] = null;
922 					listeners = std.algorithm.remove(listeners, index);
923 					break;
924 				}
925 			}
926 		}
927 	}
928 
929 	/** */
930 	gulong addOnChangeCurrentPage(bool delegate(int, Notebook) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
931 	{
932 		auto wrapper = new OnChangeCurrentPageDelegateWrapper(dlg);
933 		wrapper.handlerId = Signals.connectData(
934 			this,
935 			"change-current-page",
936 			cast(GCallback)&callBackChangeCurrentPage,
937 			cast(void*)wrapper,
938 			cast(GClosureNotify)&callBackChangeCurrentPageDestroy,
939 			connectFlags);
940 		return wrapper.handlerId;
941 	}
942 	
943 	extern(C) static int callBackChangeCurrentPage(GtkNotebook* notebookStruct, int object, OnChangeCurrentPageDelegateWrapper wrapper)
944 	{
945 		return wrapper.dlg(object, wrapper.outer);
946 	}
947 	
948 	extern(C) static void callBackChangeCurrentPageDestroy(OnChangeCurrentPageDelegateWrapper wrapper, GClosure* closure)
949 	{
950 		wrapper.remove(wrapper);
951 	}
952 
953 	protected class OnCreateWindowDelegateWrapper
954 	{
955 		static OnCreateWindowDelegateWrapper[] listeners;
956 		Notebook delegate(Widget, int, int, Notebook) dlg;
957 		gulong handlerId;
958 		
959 		this(Notebook delegate(Widget, int, int, Notebook) dlg)
960 		{
961 			this.dlg = dlg;
962 			this.listeners ~= this;
963 		}
964 		
965 		void remove(OnCreateWindowDelegateWrapper source)
966 		{
967 			foreach(index, wrapper; listeners)
968 			{
969 				if (wrapper.handlerId == source.handlerId)
970 				{
971 					listeners[index] = null;
972 					listeners = std.algorithm.remove(listeners, index);
973 					break;
974 				}
975 			}
976 		}
977 	}
978 
979 	/**
980 	 * The ::create-window signal is emitted when a detachable
981 	 * tab is dropped on the root window.
982 	 *
983 	 * A handler for this signal can create a window containing
984 	 * a notebook where the tab will be attached. It is also
985 	 * responsible for moving/resizing the window and adding the
986 	 * necessary properties to the notebook (e.g. the
987 	 * #GtkNotebook:group-name ).
988 	 *
989 	 * Params:
990 	 *     page = the tab of @notebook that is being detached
991 	 *     x = the X coordinate where the drop happens
992 	 *     y = the Y coordinate where the drop happens
993 	 *
994 	 * Returns: a #GtkNotebook that @page should be
995 	 *     added to, or %NULL.
996 	 *
997 	 * Since: 2.12
998 	 */
999 	gulong addOnCreateWindow(Notebook delegate(Widget, int, int, Notebook) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1000 	{
1001 		auto wrapper = new OnCreateWindowDelegateWrapper(dlg);
1002 		wrapper.handlerId = Signals.connectData(
1003 			this,
1004 			"create-window",
1005 			cast(GCallback)&callBackCreateWindow,
1006 			cast(void*)wrapper,
1007 			cast(GClosureNotify)&callBackCreateWindowDestroy,
1008 			connectFlags);
1009 		return wrapper.handlerId;
1010 	}
1011 	
1012 	extern(C) static GtkNotebook* callBackCreateWindow(GtkNotebook* notebookStruct, GtkWidget* page, int x, int y, OnCreateWindowDelegateWrapper wrapper)
1013 	{
1014 		auto r = wrapper.dlg(ObjectG.getDObject!(Widget)(page), x, y, wrapper.outer);
1015 		return r.getNotebookStruct();
1016 	}
1017 	
1018 	extern(C) static void callBackCreateWindowDestroy(OnCreateWindowDelegateWrapper wrapper, GClosure* closure)
1019 	{
1020 		wrapper.remove(wrapper);
1021 	}
1022 
1023 	protected class OnFocusTabDelegateWrapper
1024 	{
1025 		static OnFocusTabDelegateWrapper[] listeners;
1026 		bool delegate(GtkNotebookTab, Notebook) dlg;
1027 		gulong handlerId;
1028 		
1029 		this(bool delegate(GtkNotebookTab, Notebook) dlg)
1030 		{
1031 			this.dlg = dlg;
1032 			this.listeners ~= this;
1033 		}
1034 		
1035 		void remove(OnFocusTabDelegateWrapper source)
1036 		{
1037 			foreach(index, wrapper; listeners)
1038 			{
1039 				if (wrapper.handlerId == source.handlerId)
1040 				{
1041 					listeners[index] = null;
1042 					listeners = std.algorithm.remove(listeners, index);
1043 					break;
1044 				}
1045 			}
1046 		}
1047 	}
1048 
1049 	/** */
1050 	gulong addOnFocusTab(bool delegate(GtkNotebookTab, Notebook) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1051 	{
1052 		auto wrapper = new OnFocusTabDelegateWrapper(dlg);
1053 		wrapper.handlerId = Signals.connectData(
1054 			this,
1055 			"focus-tab",
1056 			cast(GCallback)&callBackFocusTab,
1057 			cast(void*)wrapper,
1058 			cast(GClosureNotify)&callBackFocusTabDestroy,
1059 			connectFlags);
1060 		return wrapper.handlerId;
1061 	}
1062 	
1063 	extern(C) static int callBackFocusTab(GtkNotebook* notebookStruct, GtkNotebookTab object, OnFocusTabDelegateWrapper wrapper)
1064 	{
1065 		return wrapper.dlg(object, wrapper.outer);
1066 	}
1067 	
1068 	extern(C) static void callBackFocusTabDestroy(OnFocusTabDelegateWrapper wrapper, GClosure* closure)
1069 	{
1070 		wrapper.remove(wrapper);
1071 	}
1072 
1073 	protected class OnMoveFocusOutDelegateWrapper
1074 	{
1075 		static OnMoveFocusOutDelegateWrapper[] listeners;
1076 		void delegate(GtkDirectionType, Notebook) dlg;
1077 		gulong handlerId;
1078 		
1079 		this(void delegate(GtkDirectionType, Notebook) dlg)
1080 		{
1081 			this.dlg = dlg;
1082 			this.listeners ~= this;
1083 		}
1084 		
1085 		void remove(OnMoveFocusOutDelegateWrapper source)
1086 		{
1087 			foreach(index, wrapper; listeners)
1088 			{
1089 				if (wrapper.handlerId == source.handlerId)
1090 				{
1091 					listeners[index] = null;
1092 					listeners = std.algorithm.remove(listeners, index);
1093 					break;
1094 				}
1095 			}
1096 		}
1097 	}
1098 
1099 	/** */
1100 	gulong addOnMoveFocusOut(void delegate(GtkDirectionType, Notebook) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1101 	{
1102 		auto wrapper = new OnMoveFocusOutDelegateWrapper(dlg);
1103 		wrapper.handlerId = Signals.connectData(
1104 			this,
1105 			"move-focus-out",
1106 			cast(GCallback)&callBackMoveFocusOut,
1107 			cast(void*)wrapper,
1108 			cast(GClosureNotify)&callBackMoveFocusOutDestroy,
1109 			connectFlags);
1110 		return wrapper.handlerId;
1111 	}
1112 	
1113 	extern(C) static void callBackMoveFocusOut(GtkNotebook* notebookStruct, GtkDirectionType object, OnMoveFocusOutDelegateWrapper wrapper)
1114 	{
1115 		wrapper.dlg(object, wrapper.outer);
1116 	}
1117 	
1118 	extern(C) static void callBackMoveFocusOutDestroy(OnMoveFocusOutDelegateWrapper wrapper, GClosure* closure)
1119 	{
1120 		wrapper.remove(wrapper);
1121 	}
1122 
1123 	protected class OnPageAddedDelegateWrapper
1124 	{
1125 		static OnPageAddedDelegateWrapper[] listeners;
1126 		void delegate(Widget, uint, Notebook) dlg;
1127 		gulong handlerId;
1128 		
1129 		this(void delegate(Widget, uint, Notebook) dlg)
1130 		{
1131 			this.dlg = dlg;
1132 			this.listeners ~= this;
1133 		}
1134 		
1135 		void remove(OnPageAddedDelegateWrapper source)
1136 		{
1137 			foreach(index, wrapper; listeners)
1138 			{
1139 				if (wrapper.handlerId == source.handlerId)
1140 				{
1141 					listeners[index] = null;
1142 					listeners = std.algorithm.remove(listeners, index);
1143 					break;
1144 				}
1145 			}
1146 		}
1147 	}
1148 
1149 	/**
1150 	 * the ::page-added signal is emitted in the notebook
1151 	 * right after a page is added to the notebook.
1152 	 *
1153 	 * Params:
1154 	 *     child = the child #GtkWidget affected
1155 	 *     pageNum = the new page number for @child
1156 	 *
1157 	 * Since: 2.10
1158 	 */
1159 	gulong addOnPageAdded(void delegate(Widget, uint, Notebook) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1160 	{
1161 		auto wrapper = new OnPageAddedDelegateWrapper(dlg);
1162 		wrapper.handlerId = Signals.connectData(
1163 			this,
1164 			"page-added",
1165 			cast(GCallback)&callBackPageAdded,
1166 			cast(void*)wrapper,
1167 			cast(GClosureNotify)&callBackPageAddedDestroy,
1168 			connectFlags);
1169 		return wrapper.handlerId;
1170 	}
1171 	
1172 	extern(C) static void callBackPageAdded(GtkNotebook* notebookStruct, GtkWidget* child, uint pageNum, OnPageAddedDelegateWrapper wrapper)
1173 	{
1174 		wrapper.dlg(ObjectG.getDObject!(Widget)(child), pageNum, wrapper.outer);
1175 	}
1176 	
1177 	extern(C) static void callBackPageAddedDestroy(OnPageAddedDelegateWrapper wrapper, GClosure* closure)
1178 	{
1179 		wrapper.remove(wrapper);
1180 	}
1181 
1182 	protected class OnPageRemovedDelegateWrapper
1183 	{
1184 		static OnPageRemovedDelegateWrapper[] listeners;
1185 		void delegate(Widget, uint, Notebook) dlg;
1186 		gulong handlerId;
1187 		
1188 		this(void delegate(Widget, uint, Notebook) dlg)
1189 		{
1190 			this.dlg = dlg;
1191 			this.listeners ~= this;
1192 		}
1193 		
1194 		void remove(OnPageRemovedDelegateWrapper source)
1195 		{
1196 			foreach(index, wrapper; listeners)
1197 			{
1198 				if (wrapper.handlerId == source.handlerId)
1199 				{
1200 					listeners[index] = null;
1201 					listeners = std.algorithm.remove(listeners, index);
1202 					break;
1203 				}
1204 			}
1205 		}
1206 	}
1207 
1208 	/**
1209 	 * the ::page-removed signal is emitted in the notebook
1210 	 * right after a page is removed from the notebook.
1211 	 *
1212 	 * Params:
1213 	 *     child = the child #GtkWidget affected
1214 	 *     pageNum = the @child page number
1215 	 *
1216 	 * Since: 2.10
1217 	 */
1218 	gulong addOnPageRemoved(void delegate(Widget, uint, Notebook) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1219 	{
1220 		auto wrapper = new OnPageRemovedDelegateWrapper(dlg);
1221 		wrapper.handlerId = Signals.connectData(
1222 			this,
1223 			"page-removed",
1224 			cast(GCallback)&callBackPageRemoved,
1225 			cast(void*)wrapper,
1226 			cast(GClosureNotify)&callBackPageRemovedDestroy,
1227 			connectFlags);
1228 		return wrapper.handlerId;
1229 	}
1230 	
1231 	extern(C) static void callBackPageRemoved(GtkNotebook* notebookStruct, GtkWidget* child, uint pageNum, OnPageRemovedDelegateWrapper wrapper)
1232 	{
1233 		wrapper.dlg(ObjectG.getDObject!(Widget)(child), pageNum, wrapper.outer);
1234 	}
1235 	
1236 	extern(C) static void callBackPageRemovedDestroy(OnPageRemovedDelegateWrapper wrapper, GClosure* closure)
1237 	{
1238 		wrapper.remove(wrapper);
1239 	}
1240 
1241 	protected class OnPageReorderedDelegateWrapper
1242 	{
1243 		static OnPageReorderedDelegateWrapper[] listeners;
1244 		void delegate(Widget, uint, Notebook) dlg;
1245 		gulong handlerId;
1246 		
1247 		this(void delegate(Widget, uint, Notebook) dlg)
1248 		{
1249 			this.dlg = dlg;
1250 			this.listeners ~= this;
1251 		}
1252 		
1253 		void remove(OnPageReorderedDelegateWrapper source)
1254 		{
1255 			foreach(index, wrapper; listeners)
1256 			{
1257 				if (wrapper.handlerId == source.handlerId)
1258 				{
1259 					listeners[index] = null;
1260 					listeners = std.algorithm.remove(listeners, index);
1261 					break;
1262 				}
1263 			}
1264 		}
1265 	}
1266 
1267 	/**
1268 	 * the ::page-reordered signal is emitted in the notebook
1269 	 * right after a page has been reordered.
1270 	 *
1271 	 * Params:
1272 	 *     child = the child #GtkWidget affected
1273 	 *     pageNum = the new page number for @child
1274 	 *
1275 	 * Since: 2.10
1276 	 */
1277 	gulong addOnPageReordered(void delegate(Widget, uint, Notebook) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1278 	{
1279 		auto wrapper = new OnPageReorderedDelegateWrapper(dlg);
1280 		wrapper.handlerId = Signals.connectData(
1281 			this,
1282 			"page-reordered",
1283 			cast(GCallback)&callBackPageReordered,
1284 			cast(void*)wrapper,
1285 			cast(GClosureNotify)&callBackPageReorderedDestroy,
1286 			connectFlags);
1287 		return wrapper.handlerId;
1288 	}
1289 	
1290 	extern(C) static void callBackPageReordered(GtkNotebook* notebookStruct, GtkWidget* child, uint pageNum, OnPageReorderedDelegateWrapper wrapper)
1291 	{
1292 		wrapper.dlg(ObjectG.getDObject!(Widget)(child), pageNum, wrapper.outer);
1293 	}
1294 	
1295 	extern(C) static void callBackPageReorderedDestroy(OnPageReorderedDelegateWrapper wrapper, GClosure* closure)
1296 	{
1297 		wrapper.remove(wrapper);
1298 	}
1299 
1300 	protected class OnReorderTabDelegateWrapper
1301 	{
1302 		static OnReorderTabDelegateWrapper[] listeners;
1303 		bool delegate(GtkDirectionType, bool, Notebook) dlg;
1304 		gulong handlerId;
1305 		
1306 		this(bool delegate(GtkDirectionType, bool, Notebook) dlg)
1307 		{
1308 			this.dlg = dlg;
1309 			this.listeners ~= this;
1310 		}
1311 		
1312 		void remove(OnReorderTabDelegateWrapper source)
1313 		{
1314 			foreach(index, wrapper; listeners)
1315 			{
1316 				if (wrapper.handlerId == source.handlerId)
1317 				{
1318 					listeners[index] = null;
1319 					listeners = std.algorithm.remove(listeners, index);
1320 					break;
1321 				}
1322 			}
1323 		}
1324 	}
1325 
1326 	/** */
1327 	gulong addOnReorderTab(bool delegate(GtkDirectionType, bool, Notebook) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1328 	{
1329 		auto wrapper = new OnReorderTabDelegateWrapper(dlg);
1330 		wrapper.handlerId = Signals.connectData(
1331 			this,
1332 			"reorder-tab",
1333 			cast(GCallback)&callBackReorderTab,
1334 			cast(void*)wrapper,
1335 			cast(GClosureNotify)&callBackReorderTabDestroy,
1336 			connectFlags);
1337 		return wrapper.handlerId;
1338 	}
1339 	
1340 	extern(C) static int callBackReorderTab(GtkNotebook* notebookStruct, GtkDirectionType object, bool p0, OnReorderTabDelegateWrapper wrapper)
1341 	{
1342 		return wrapper.dlg(object, p0, wrapper.outer);
1343 	}
1344 	
1345 	extern(C) static void callBackReorderTabDestroy(OnReorderTabDelegateWrapper wrapper, GClosure* closure)
1346 	{
1347 		wrapper.remove(wrapper);
1348 	}
1349 
1350 	protected class OnSelectPageDelegateWrapper
1351 	{
1352 		static OnSelectPageDelegateWrapper[] listeners;
1353 		bool delegate(bool, Notebook) dlg;
1354 		gulong handlerId;
1355 		
1356 		this(bool delegate(bool, Notebook) dlg)
1357 		{
1358 			this.dlg = dlg;
1359 			this.listeners ~= this;
1360 		}
1361 		
1362 		void remove(OnSelectPageDelegateWrapper source)
1363 		{
1364 			foreach(index, wrapper; listeners)
1365 			{
1366 				if (wrapper.handlerId == source.handlerId)
1367 				{
1368 					listeners[index] = null;
1369 					listeners = std.algorithm.remove(listeners, index);
1370 					break;
1371 				}
1372 			}
1373 		}
1374 	}
1375 
1376 	/** */
1377 	gulong addOnSelectPage(bool delegate(bool, Notebook) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1378 	{
1379 		auto wrapper = new OnSelectPageDelegateWrapper(dlg);
1380 		wrapper.handlerId = Signals.connectData(
1381 			this,
1382 			"select-page",
1383 			cast(GCallback)&callBackSelectPage,
1384 			cast(void*)wrapper,
1385 			cast(GClosureNotify)&callBackSelectPageDestroy,
1386 			connectFlags);
1387 		return wrapper.handlerId;
1388 	}
1389 	
1390 	extern(C) static int callBackSelectPage(GtkNotebook* notebookStruct, bool object, OnSelectPageDelegateWrapper wrapper)
1391 	{
1392 		return wrapper.dlg(object, wrapper.outer);
1393 	}
1394 	
1395 	extern(C) static void callBackSelectPageDestroy(OnSelectPageDelegateWrapper wrapper, GClosure* closure)
1396 	{
1397 		wrapper.remove(wrapper);
1398 	}
1399 
1400 	protected class OnSwitchPageDelegateWrapper
1401 	{
1402 		static OnSwitchPageDelegateWrapper[] listeners;
1403 		void delegate(Widget, uint, Notebook) dlg;
1404 		gulong handlerId;
1405 		
1406 		this(void delegate(Widget, uint, Notebook) dlg)
1407 		{
1408 			this.dlg = dlg;
1409 			this.listeners ~= this;
1410 		}
1411 		
1412 		void remove(OnSwitchPageDelegateWrapper source)
1413 		{
1414 			foreach(index, wrapper; listeners)
1415 			{
1416 				if (wrapper.handlerId == source.handlerId)
1417 				{
1418 					listeners[index] = null;
1419 					listeners = std.algorithm.remove(listeners, index);
1420 					break;
1421 				}
1422 			}
1423 		}
1424 	}
1425 
1426 	/**
1427 	 * Emitted when the user or a function changes the current page.
1428 	 *
1429 	 * Params:
1430 	 *     page = the new current page
1431 	 *     pageNum = the index of the page
1432 	 */
1433 	gulong addOnSwitchPage(void delegate(Widget, uint, Notebook) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1434 	{
1435 		auto wrapper = new OnSwitchPageDelegateWrapper(dlg);
1436 		wrapper.handlerId = Signals.connectData(
1437 			this,
1438 			"switch-page",
1439 			cast(GCallback)&callBackSwitchPage,
1440 			cast(void*)wrapper,
1441 			cast(GClosureNotify)&callBackSwitchPageDestroy,
1442 			connectFlags);
1443 		return wrapper.handlerId;
1444 	}
1445 	
1446 	extern(C) static void callBackSwitchPage(GtkNotebook* notebookStruct, GtkWidget* page, uint pageNum, OnSwitchPageDelegateWrapper wrapper)
1447 	{
1448 		wrapper.dlg(ObjectG.getDObject!(Widget)(page), pageNum, wrapper.outer);
1449 	}
1450 	
1451 	extern(C) static void callBackSwitchPageDestroy(OnSwitchPageDelegateWrapper wrapper, GClosure* closure)
1452 	{
1453 		wrapper.remove(wrapper);
1454 	}
1455 }