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