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.Paned;
26 
27 private import gdk.Window;
28 private import glib.ConstructionException;
29 private import gobject.ObjectG;
30 private import gobject.Signals;
31 private import gtk.Container;
32 private import gtk.OrientableIF;
33 private import gtk.OrientableT;
34 private import gtk.Widget;
35 public  import gtkc.gdktypes;
36 private import gtkc.gtk;
37 public  import gtkc.gtktypes;
38 private import std.algorithm;
39 
40 
41 /**
42  * #GtkPaned has two panes, arranged either
43  * horizontally or vertically. The division between
44  * the two panes is adjustable by the user by dragging
45  * a handle.
46  * 
47  * Child widgets are
48  * added to the panes of the widget with gtk_paned_pack1() and
49  * gtk_paned_pack2(). The division between the two children is set by default
50  * from the size requests of the children, but it can be adjusted by the
51  * user.
52  * 
53  * A paned widget draws a separator between the two child widgets and a
54  * small handle that the user can drag to adjust the division. It does not
55  * draw any relief around the children or around the separator. (The space
56  * in which the separator is called the gutter.) Often, it is useful to put
57  * each child inside a #GtkFrame with the shadow type set to %GTK_SHADOW_IN
58  * so that the gutter appears as a ridge. No separator is drawn if one of
59  * the children is missing.
60  * 
61  * Each child has two options that can be set, @resize and @shrink. If
62  * @resize is true, then when the #GtkPaned is resized, that child will
63  * expand or shrink along with the paned widget. If @shrink is true, then
64  * that child can be made smaller than its requisition by the user.
65  * Setting @shrink to %FALSE allows the application to set a minimum size.
66  * If @resize is false for both children, then this is treated as if
67  * @resize is true for both children.
68  * 
69  * The application can set the position of the slider as if it were set
70  * by the user, by calling gtk_paned_set_position().
71  * 
72  * # CSS nodes
73  * 
74  * |[<!-- language="plain" -->
75  * paned
76  * ├── <child>
77  * ├── separator[.wide]
78  * ╰── <child>
79  * ]|
80  * 
81  * GtkPaned has a main CSS node with name paned, and a subnode for
82  * the separator with name separator. The subnodes gets a .wide style
83  * class when the paned is supposed to be wide.
84  * 
85  * In horizontal orientation, the nodes of the children are always arranged
86  * from left to right. So :first-child will always select the leftmost child,
87  * regardless of text direction.
88  * 
89  * ## Creating a paned widget with minimum sizes.
90  * 
91  * |[<!-- language="C" -->
92  * GtkWidget *hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
93  * GtkWidget *frame1 = gtk_frame_new (NULL);
94  * GtkWidget *frame2 = gtk_frame_new (NULL);
95  * gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
96  * gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN);
97  * 
98  * gtk_widget_set_size_request (hpaned, 200, -1);
99  * 
100  * gtk_paned_pack1 (GTK_PANED (hpaned), frame1, TRUE, FALSE);
101  * gtk_widget_set_size_request (frame1, 50, -1);
102  * 
103  * gtk_paned_pack2 (GTK_PANED (hpaned), frame2, FALSE, FALSE);
104  * gtk_widget_set_size_request (frame2, 50, -1);
105  * ]|
106  */
107 public class Paned : Container, OrientableIF
108 {
109 	/** the main Gtk struct */
110 	protected GtkPaned* gtkPaned;
111 
112 	/** Get the main Gtk struct */
113 	public GtkPaned* getPanedStruct()
114 	{
115 		return gtkPaned;
116 	}
117 
118 	/** the main Gtk struct as a void* */
119 	protected override void* getStruct()
120 	{
121 		return cast(void*)gtkPaned;
122 	}
123 
124 	protected override void setStruct(GObject* obj)
125 	{
126 		gtkPaned = cast(GtkPaned*)obj;
127 		super.setStruct(obj);
128 	}
129 
130 	/**
131 	 * Sets our main struct and passes it to the parent class.
132 	 */
133 	public this (GtkPaned* gtkPaned, bool ownedRef = false)
134 	{
135 		this.gtkPaned = gtkPaned;
136 		super(cast(GtkContainer*)gtkPaned, ownedRef);
137 	}
138 
139 	// add the Orientable capabilities
140 	mixin OrientableT!(GtkPaned);
141 
142 	/** */
143 	public void add(Widget child1, Widget child2)
144 	{
145 		add1(child1);
146 		add2(child2);
147 	}
148 
149 	/**
150 	 */
151 
152 	/** */
153 	public static GType getType()
154 	{
155 		return gtk_paned_get_type();
156 	}
157 
158 	/**
159 	 * Creates a new #GtkPaned widget.
160 	 *
161 	 * Params:
162 	 *     orientation = the paned’s orientation.
163 	 *
164 	 * Return: a new #GtkPaned.
165 	 *
166 	 * Since: 3.0
167 	 *
168 	 * Throws: ConstructionException GTK+ fails to create the object.
169 	 */
170 	public this(GtkOrientation orientation)
171 	{
172 		auto p = gtk_paned_new(orientation);
173 		
174 		if(p is null)
175 		{
176 			throw new ConstructionException("null returned by new");
177 		}
178 		
179 		this(cast(GtkPaned*) p);
180 	}
181 
182 	/**
183 	 * Adds a child to the top or left pane with default parameters. This is
184 	 * equivalent to
185 	 * `gtk_paned_pack1 (paned, child, FALSE, TRUE)`.
186 	 *
187 	 * Params:
188 	 *     child = the child to add
189 	 */
190 	public void add1(Widget child)
191 	{
192 		gtk_paned_add1(gtkPaned, (child is null) ? null : child.getWidgetStruct());
193 	}
194 
195 	/**
196 	 * Adds a child to the bottom or right pane with default parameters. This
197 	 * is equivalent to
198 	 * `gtk_paned_pack2 (paned, child, TRUE, TRUE)`.
199 	 *
200 	 * Params:
201 	 *     child = the child to add
202 	 */
203 	public void add2(Widget child)
204 	{
205 		gtk_paned_add2(gtkPaned, (child is null) ? null : child.getWidgetStruct());
206 	}
207 
208 	/**
209 	 * Obtains the first child of the paned widget.
210 	 *
211 	 * Return: first child, or %NULL if it is not set.
212 	 *
213 	 * Since: 2.4
214 	 */
215 	public Widget getChild1()
216 	{
217 		auto p = gtk_paned_get_child1(gtkPaned);
218 		
219 		if(p is null)
220 		{
221 			return null;
222 		}
223 		
224 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
225 	}
226 
227 	/**
228 	 * Obtains the second child of the paned widget.
229 	 *
230 	 * Return: second child, or %NULL if it is not set.
231 	 *
232 	 * Since: 2.4
233 	 */
234 	public Widget getChild2()
235 	{
236 		auto p = gtk_paned_get_child2(gtkPaned);
237 		
238 		if(p is null)
239 		{
240 			return null;
241 		}
242 		
243 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
244 	}
245 
246 	/**
247 	 * Returns the #GdkWindow of the handle. This function is
248 	 * useful when handling button or motion events because it
249 	 * enables the callback to distinguish between the window
250 	 * of the paned, a child and the handle.
251 	 *
252 	 * Return: the paned’s handle window.
253 	 *
254 	 * Since: 2.20
255 	 */
256 	public Window getHandleWindow()
257 	{
258 		auto p = gtk_paned_get_handle_window(gtkPaned);
259 		
260 		if(p is null)
261 		{
262 			return null;
263 		}
264 		
265 		return ObjectG.getDObject!(Window)(cast(GdkWindow*) p);
266 	}
267 
268 	/**
269 	 * Obtains the position of the divider between the two panes.
270 	 *
271 	 * Return: position of the divider
272 	 */
273 	public int getPosition()
274 	{
275 		return gtk_paned_get_position(gtkPaned);
276 	}
277 
278 	/**
279 	 * Gets the #GtkPaned:wide-handle property.
280 	 *
281 	 * Return: %TRUE if the paned should have a wide handle
282 	 *
283 	 * Since: 3.16
284 	 */
285 	public bool getWideHandle()
286 	{
287 		return gtk_paned_get_wide_handle(gtkPaned) != 0;
288 	}
289 
290 	/**
291 	 * Adds a child to the top or left pane.
292 	 *
293 	 * Params:
294 	 *     child = the child to add
295 	 *     resize = should this child expand when the paned widget is resized.
296 	 *     shrink = can this child be made smaller than its requisition.
297 	 */
298 	public void pack1(Widget child, bool resize, bool shrink)
299 	{
300 		gtk_paned_pack1(gtkPaned, (child is null) ? null : child.getWidgetStruct(), resize, shrink);
301 	}
302 
303 	/**
304 	 * Adds a child to the bottom or right pane.
305 	 *
306 	 * Params:
307 	 *     child = the child to add
308 	 *     resize = should this child expand when the paned widget is resized.
309 	 *     shrink = can this child be made smaller than its requisition.
310 	 */
311 	public void pack2(Widget child, bool resize, bool shrink)
312 	{
313 		gtk_paned_pack2(gtkPaned, (child is null) ? null : child.getWidgetStruct(), resize, shrink);
314 	}
315 
316 	/**
317 	 * Sets the position of the divider between the two panes.
318 	 *
319 	 * Params:
320 	 *     position = pixel position of divider, a negative value means that the position
321 	 *         is unset.
322 	 */
323 	public void setPosition(int position)
324 	{
325 		gtk_paned_set_position(gtkPaned, position);
326 	}
327 
328 	/**
329 	 * Sets the #GtkPaned:wide-handle property.
330 	 *
331 	 * Params:
332 	 *     wide = the new value for the #GtkPaned:wide-handle property
333 	 *
334 	 * Since: 3.16
335 	 */
336 	public void setWideHandle(bool wide)
337 	{
338 		gtk_paned_set_wide_handle(gtkPaned, wide);
339 	}
340 
341 	protected class OnAcceptPositionDelegateWrapper
342 	{
343 		bool delegate(Paned) dlg;
344 		gulong handlerId;
345 		ConnectFlags flags;
346 		this(bool delegate(Paned) dlg, gulong handlerId, ConnectFlags flags)
347 		{
348 			this.dlg = dlg;
349 			this.handlerId = handlerId;
350 			this.flags = flags;
351 		}
352 	}
353 	protected OnAcceptPositionDelegateWrapper[] onAcceptPositionListeners;
354 
355 	/**
356 	 * The ::accept-position signal is a
357 	 * [keybinding signal][GtkBindingSignal]
358 	 * which gets emitted to accept the current position of the handle when
359 	 * moving it using key bindings.
360 	 *
361 	 * The default binding for this signal is Return or Space.
362 	 *
363 	 * Since: 2.0
364 	 */
365 	gulong addOnAcceptPosition(bool delegate(Paned) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
366 	{
367 		onAcceptPositionListeners ~= new OnAcceptPositionDelegateWrapper(dlg, 0, connectFlags);
368 		onAcceptPositionListeners[onAcceptPositionListeners.length - 1].handlerId = Signals.connectData(
369 			this,
370 			"accept-position",
371 			cast(GCallback)&callBackAcceptPosition,
372 			cast(void*)onAcceptPositionListeners[onAcceptPositionListeners.length - 1],
373 			cast(GClosureNotify)&callBackAcceptPositionDestroy,
374 			connectFlags);
375 		return onAcceptPositionListeners[onAcceptPositionListeners.length - 1].handlerId;
376 	}
377 	
378 	extern(C) static int callBackAcceptPosition(GtkPaned* panedStruct,OnAcceptPositionDelegateWrapper wrapper)
379 	{
380 		return wrapper.dlg(wrapper.outer);
381 	}
382 	
383 	extern(C) static void callBackAcceptPositionDestroy(OnAcceptPositionDelegateWrapper wrapper, GClosure* closure)
384 	{
385 		wrapper.outer.internalRemoveOnAcceptPosition(wrapper);
386 	}
387 
388 	protected void internalRemoveOnAcceptPosition(OnAcceptPositionDelegateWrapper source)
389 	{
390 		foreach(index, wrapper; onAcceptPositionListeners)
391 		{
392 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
393 			{
394 				onAcceptPositionListeners[index] = null;
395 				onAcceptPositionListeners = std.algorithm.remove(onAcceptPositionListeners, index);
396 				break;
397 			}
398 		}
399 	}
400 	
401 
402 	protected class OnCancelPositionDelegateWrapper
403 	{
404 		bool delegate(Paned) dlg;
405 		gulong handlerId;
406 		ConnectFlags flags;
407 		this(bool delegate(Paned) dlg, gulong handlerId, ConnectFlags flags)
408 		{
409 			this.dlg = dlg;
410 			this.handlerId = handlerId;
411 			this.flags = flags;
412 		}
413 	}
414 	protected OnCancelPositionDelegateWrapper[] onCancelPositionListeners;
415 
416 	/**
417 	 * The ::cancel-position signal is a
418 	 * [keybinding signal][GtkBindingSignal]
419 	 * which gets emitted to cancel moving the position of the handle using key
420 	 * bindings. The position of the handle will be reset to the value prior to
421 	 * moving it.
422 	 *
423 	 * The default binding for this signal is Escape.
424 	 *
425 	 * Since: 2.0
426 	 */
427 	gulong addOnCancelPosition(bool delegate(Paned) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
428 	{
429 		onCancelPositionListeners ~= new OnCancelPositionDelegateWrapper(dlg, 0, connectFlags);
430 		onCancelPositionListeners[onCancelPositionListeners.length - 1].handlerId = Signals.connectData(
431 			this,
432 			"cancel-position",
433 			cast(GCallback)&callBackCancelPosition,
434 			cast(void*)onCancelPositionListeners[onCancelPositionListeners.length - 1],
435 			cast(GClosureNotify)&callBackCancelPositionDestroy,
436 			connectFlags);
437 		return onCancelPositionListeners[onCancelPositionListeners.length - 1].handlerId;
438 	}
439 	
440 	extern(C) static int callBackCancelPosition(GtkPaned* panedStruct,OnCancelPositionDelegateWrapper wrapper)
441 	{
442 		return wrapper.dlg(wrapper.outer);
443 	}
444 	
445 	extern(C) static void callBackCancelPositionDestroy(OnCancelPositionDelegateWrapper wrapper, GClosure* closure)
446 	{
447 		wrapper.outer.internalRemoveOnCancelPosition(wrapper);
448 	}
449 
450 	protected void internalRemoveOnCancelPosition(OnCancelPositionDelegateWrapper source)
451 	{
452 		foreach(index, wrapper; onCancelPositionListeners)
453 		{
454 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
455 			{
456 				onCancelPositionListeners[index] = null;
457 				onCancelPositionListeners = std.algorithm.remove(onCancelPositionListeners, index);
458 				break;
459 			}
460 		}
461 	}
462 	
463 
464 	protected class OnCycleChildFocusDelegateWrapper
465 	{
466 		bool delegate(bool, Paned) dlg;
467 		gulong handlerId;
468 		ConnectFlags flags;
469 		this(bool delegate(bool, Paned) dlg, gulong handlerId, ConnectFlags flags)
470 		{
471 			this.dlg = dlg;
472 			this.handlerId = handlerId;
473 			this.flags = flags;
474 		}
475 	}
476 	protected OnCycleChildFocusDelegateWrapper[] onCycleChildFocusListeners;
477 
478 	/**
479 	 * The ::cycle-child-focus signal is a
480 	 * [keybinding signal][GtkBindingSignal]
481 	 * which gets emitted to cycle the focus between the children of the paned.
482 	 *
483 	 * The default binding is f6.
484 	 *
485 	 * Params:
486 	 *     reversed = whether cycling backward or forward
487 	 *
488 	 * Since: 2.0
489 	 */
490 	gulong addOnCycleChildFocus(bool delegate(bool, Paned) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
491 	{
492 		onCycleChildFocusListeners ~= new OnCycleChildFocusDelegateWrapper(dlg, 0, connectFlags);
493 		onCycleChildFocusListeners[onCycleChildFocusListeners.length - 1].handlerId = Signals.connectData(
494 			this,
495 			"cycle-child-focus",
496 			cast(GCallback)&callBackCycleChildFocus,
497 			cast(void*)onCycleChildFocusListeners[onCycleChildFocusListeners.length - 1],
498 			cast(GClosureNotify)&callBackCycleChildFocusDestroy,
499 			connectFlags);
500 		return onCycleChildFocusListeners[onCycleChildFocusListeners.length - 1].handlerId;
501 	}
502 	
503 	extern(C) static int callBackCycleChildFocus(GtkPaned* panedStruct, bool reversed,OnCycleChildFocusDelegateWrapper wrapper)
504 	{
505 		return wrapper.dlg(reversed, wrapper.outer);
506 	}
507 	
508 	extern(C) static void callBackCycleChildFocusDestroy(OnCycleChildFocusDelegateWrapper wrapper, GClosure* closure)
509 	{
510 		wrapper.outer.internalRemoveOnCycleChildFocus(wrapper);
511 	}
512 
513 	protected void internalRemoveOnCycleChildFocus(OnCycleChildFocusDelegateWrapper source)
514 	{
515 		foreach(index, wrapper; onCycleChildFocusListeners)
516 		{
517 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
518 			{
519 				onCycleChildFocusListeners[index] = null;
520 				onCycleChildFocusListeners = std.algorithm.remove(onCycleChildFocusListeners, index);
521 				break;
522 			}
523 		}
524 	}
525 	
526 
527 	protected class OnCycleHandleFocusDelegateWrapper
528 	{
529 		bool delegate(bool, Paned) dlg;
530 		gulong handlerId;
531 		ConnectFlags flags;
532 		this(bool delegate(bool, Paned) dlg, gulong handlerId, ConnectFlags flags)
533 		{
534 			this.dlg = dlg;
535 			this.handlerId = handlerId;
536 			this.flags = flags;
537 		}
538 	}
539 	protected OnCycleHandleFocusDelegateWrapper[] onCycleHandleFocusListeners;
540 
541 	/**
542 	 * The ::cycle-handle-focus signal is a
543 	 * [keybinding signal][GtkBindingSignal]
544 	 * which gets emitted to cycle whether the paned should grab focus to allow
545 	 * the user to change position of the handle by using key bindings.
546 	 *
547 	 * The default binding for this signal is f8.
548 	 *
549 	 * Params:
550 	 *     reversed = whether cycling backward or forward
551 	 *
552 	 * Since: 2.0
553 	 */
554 	gulong addOnCycleHandleFocus(bool delegate(bool, Paned) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
555 	{
556 		onCycleHandleFocusListeners ~= new OnCycleHandleFocusDelegateWrapper(dlg, 0, connectFlags);
557 		onCycleHandleFocusListeners[onCycleHandleFocusListeners.length - 1].handlerId = Signals.connectData(
558 			this,
559 			"cycle-handle-focus",
560 			cast(GCallback)&callBackCycleHandleFocus,
561 			cast(void*)onCycleHandleFocusListeners[onCycleHandleFocusListeners.length - 1],
562 			cast(GClosureNotify)&callBackCycleHandleFocusDestroy,
563 			connectFlags);
564 		return onCycleHandleFocusListeners[onCycleHandleFocusListeners.length - 1].handlerId;
565 	}
566 	
567 	extern(C) static int callBackCycleHandleFocus(GtkPaned* panedStruct, bool reversed,OnCycleHandleFocusDelegateWrapper wrapper)
568 	{
569 		return wrapper.dlg(reversed, wrapper.outer);
570 	}
571 	
572 	extern(C) static void callBackCycleHandleFocusDestroy(OnCycleHandleFocusDelegateWrapper wrapper, GClosure* closure)
573 	{
574 		wrapper.outer.internalRemoveOnCycleHandleFocus(wrapper);
575 	}
576 
577 	protected void internalRemoveOnCycleHandleFocus(OnCycleHandleFocusDelegateWrapper source)
578 	{
579 		foreach(index, wrapper; onCycleHandleFocusListeners)
580 		{
581 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
582 			{
583 				onCycleHandleFocusListeners[index] = null;
584 				onCycleHandleFocusListeners = std.algorithm.remove(onCycleHandleFocusListeners, index);
585 				break;
586 			}
587 		}
588 	}
589 	
590 
591 	protected class OnMoveHandleDelegateWrapper
592 	{
593 		bool delegate(GtkScrollType, Paned) dlg;
594 		gulong handlerId;
595 		ConnectFlags flags;
596 		this(bool delegate(GtkScrollType, Paned) dlg, gulong handlerId, ConnectFlags flags)
597 		{
598 			this.dlg = dlg;
599 			this.handlerId = handlerId;
600 			this.flags = flags;
601 		}
602 	}
603 	protected OnMoveHandleDelegateWrapper[] onMoveHandleListeners;
604 
605 	/**
606 	 * The ::move-handle signal is a
607 	 * [keybinding signal][GtkBindingSignal]
608 	 * which gets emitted to move the handle when the user is using key bindings
609 	 * to move it.
610 	 *
611 	 * Params:
612 	 *     scrollType = a #GtkScrollType
613 	 *
614 	 * Since: 2.0
615 	 */
616 	gulong addOnMoveHandle(bool delegate(GtkScrollType, Paned) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
617 	{
618 		onMoveHandleListeners ~= new OnMoveHandleDelegateWrapper(dlg, 0, connectFlags);
619 		onMoveHandleListeners[onMoveHandleListeners.length - 1].handlerId = Signals.connectData(
620 			this,
621 			"move-handle",
622 			cast(GCallback)&callBackMoveHandle,
623 			cast(void*)onMoveHandleListeners[onMoveHandleListeners.length - 1],
624 			cast(GClosureNotify)&callBackMoveHandleDestroy,
625 			connectFlags);
626 		return onMoveHandleListeners[onMoveHandleListeners.length - 1].handlerId;
627 	}
628 	
629 	extern(C) static int callBackMoveHandle(GtkPaned* panedStruct, GtkScrollType scrollType,OnMoveHandleDelegateWrapper wrapper)
630 	{
631 		return wrapper.dlg(scrollType, wrapper.outer);
632 	}
633 	
634 	extern(C) static void callBackMoveHandleDestroy(OnMoveHandleDelegateWrapper wrapper, GClosure* closure)
635 	{
636 		wrapper.outer.internalRemoveOnMoveHandle(wrapper);
637 	}
638 
639 	protected void internalRemoveOnMoveHandle(OnMoveHandleDelegateWrapper source)
640 	{
641 		foreach(index, wrapper; onMoveHandleListeners)
642 		{
643 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
644 			{
645 				onMoveHandleListeners[index] = null;
646 				onMoveHandleListeners = std.algorithm.remove(onMoveHandleListeners, index);
647 				break;
648 			}
649 		}
650 	}
651 	
652 
653 	protected class OnToggleHandleFocusDelegateWrapper
654 	{
655 		bool delegate(Paned) dlg;
656 		gulong handlerId;
657 		ConnectFlags flags;
658 		this(bool delegate(Paned) dlg, gulong handlerId, ConnectFlags flags)
659 		{
660 			this.dlg = dlg;
661 			this.handlerId = handlerId;
662 			this.flags = flags;
663 		}
664 	}
665 	protected OnToggleHandleFocusDelegateWrapper[] onToggleHandleFocusListeners;
666 
667 	/**
668 	 * The ::toggle-handle-focus is a
669 	 * [keybinding signal][GtkBindingSignal]
670 	 * which gets emitted to accept the current position of the handle and then
671 	 * move focus to the next widget in the focus chain.
672 	 *
673 	 * The default binding is Tab.
674 	 *
675 	 * Since: 2.0
676 	 */
677 	gulong addOnToggleHandleFocus(bool delegate(Paned) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
678 	{
679 		onToggleHandleFocusListeners ~= new OnToggleHandleFocusDelegateWrapper(dlg, 0, connectFlags);
680 		onToggleHandleFocusListeners[onToggleHandleFocusListeners.length - 1].handlerId = Signals.connectData(
681 			this,
682 			"toggle-handle-focus",
683 			cast(GCallback)&callBackToggleHandleFocus,
684 			cast(void*)onToggleHandleFocusListeners[onToggleHandleFocusListeners.length - 1],
685 			cast(GClosureNotify)&callBackToggleHandleFocusDestroy,
686 			connectFlags);
687 		return onToggleHandleFocusListeners[onToggleHandleFocusListeners.length - 1].handlerId;
688 	}
689 	
690 	extern(C) static int callBackToggleHandleFocus(GtkPaned* panedStruct,OnToggleHandleFocusDelegateWrapper wrapper)
691 	{
692 		return wrapper.dlg(wrapper.outer);
693 	}
694 	
695 	extern(C) static void callBackToggleHandleFocusDestroy(OnToggleHandleFocusDelegateWrapper wrapper, GClosure* closure)
696 	{
697 		wrapper.outer.internalRemoveOnToggleHandleFocus(wrapper);
698 	}
699 
700 	protected void internalRemoveOnToggleHandleFocus(OnToggleHandleFocusDelegateWrapper source)
701 	{
702 		foreach(index, wrapper; onToggleHandleFocusListeners)
703 		{
704 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
705 			{
706 				onToggleHandleFocusListeners[index] = null;
707 				onToggleHandleFocusListeners = std.algorithm.remove(onToggleHandleFocusListeners, index);
708 				break;
709 			}
710 		}
711 	}
712 	
713 }