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.FlowBox;
26 
27 private import gio.ListModelIF;
28 private import glib.ConstructionException;
29 private import glib.ListG;
30 private import gobject.ObjectG;
31 private import gobject.Signals;
32 private import gtk.Adjustment;
33 private import gtk.Container;
34 private import gtk.FlowBoxChild;
35 private import gtk.OrientableIF;
36 private import gtk.OrientableT;
37 private import gtk.Widget;
38 private import gtkc.gtk;
39 public  import gtkc.gtktypes;
40 private import std.algorithm;
41 
42 
43 /**
44  * A GtkFlowBox positions child widgets in sequence according to its
45  * orientation.
46  * 
47  * For instance, with the horizontal orientation, the widgets will be
48  * arranged from left to right, starting a new row under the previous
49  * row when necessary. Reducing the width in this case will require more
50  * rows, so a larger height will be requested.
51  * 
52  * Likewise, with the vertical orientation, the widgets will be arranged
53  * from top to bottom, starting a new column to the right when necessary.
54  * Reducing the height will require more columns, so a larger width will
55  * be requested.
56  * 
57  * The children of a GtkFlowBox can be dynamically sorted and filtered.
58  * 
59  * Although a GtkFlowBox must have only #GtkFlowBoxChild children,
60  * you can add any kind of widget to it via gtk_container_add(), and
61  * a GtkFlowBoxChild widget will automatically be inserted between
62  * the box and the widget.
63  * 
64  * Also see #GtkListBox.
65  * 
66  * GtkFlowBox was added in GTK+ 3.12.
67  * 
68  * # CSS nodes
69  * 
70  * |[<!-- language="plain" -->
71  * flowbox
72  * ├── flowboxchild
73  * │   ╰── <child>
74  * ├── flowboxchild
75  * │   ╰── <child>
76  * ┊
77  * ╰── [rubberband]
78  * ]|
79  * 
80  * GtkFlowBox uses a single CSS node with name flowbox. GtkFlowBoxChild
81  * uses a single CSS node with name flowboxchild.
82  * For rubberband selection, a subnode with name rubberband is used.
83  */
84 public class FlowBox : Container, OrientableIF
85 {
86 	/** the main Gtk struct */
87 	protected GtkFlowBox* gtkFlowBox;
88 
89 	/** Get the main Gtk struct */
90 	public GtkFlowBox* getFlowBoxStruct()
91 	{
92 		return gtkFlowBox;
93 	}
94 
95 	/** the main Gtk struct as a void* */
96 	protected override void* getStruct()
97 	{
98 		return cast(void*)gtkFlowBox;
99 	}
100 
101 	protected override void setStruct(GObject* obj)
102 	{
103 		gtkFlowBox = cast(GtkFlowBox*)obj;
104 		super.setStruct(obj);
105 	}
106 
107 	/**
108 	 * Sets our main struct and passes it to the parent class.
109 	 */
110 	public this (GtkFlowBox* gtkFlowBox, bool ownedRef = false)
111 	{
112 		this.gtkFlowBox = gtkFlowBox;
113 		super(cast(GtkContainer*)gtkFlowBox, ownedRef);
114 	}
115 
116 	// add the Orientable capabilities
117 	mixin OrientableT!(GtkFlowBox);
118 
119 
120 	/** */
121 	public static GType getType()
122 	{
123 		return gtk_flow_box_get_type();
124 	}
125 
126 	/**
127 	 * Creates a GtkFlowBox.
128 	 *
129 	 * Returns: a new #GtkFlowBox container
130 	 *
131 	 * Since: 3.12
132 	 *
133 	 * Throws: ConstructionException GTK+ fails to create the object.
134 	 */
135 	public this()
136 	{
137 		auto p = gtk_flow_box_new();
138 		
139 		if(p is null)
140 		{
141 			throw new ConstructionException("null returned by new");
142 		}
143 		
144 		this(cast(GtkFlowBox*) p);
145 	}
146 
147 	/**
148 	 * Binds @model to @box.
149 	 *
150 	 * If @box was already bound to a model, that previous binding is
151 	 * destroyed.
152 	 *
153 	 * The contents of @box are cleared and then filled with widgets that
154 	 * represent items from @model. @box is updated whenever @model changes.
155 	 * If @model is %NULL, @box is left empty.
156 	 *
157 	 * It is undefined to add or remove widgets directly (for example, with
158 	 * gtk_flow_box_insert() or gtk_container_add()) while @box is bound to a
159 	 * model.
160 	 *
161 	 * Note that using a model is incompatible with the filtering and sorting
162 	 * functionality in GtkFlowBox. When using a model, filtering and sorting
163 	 * should be implemented by the model.
164 	 *
165 	 * Params:
166 	 *     model = the #GListModel to be bound to @box
167 	 *     createWidgetFunc = a function that creates widgets for items
168 	 *     userData = user data passed to @create_widget_func
169 	 *     userDataFreeFunc = function for freeing @user_data
170 	 *
171 	 * Since: 3.18
172 	 */
173 	public void bindModel(ListModelIF model, GtkFlowBoxCreateWidgetFunc createWidgetFunc, void* userData, GDestroyNotify userDataFreeFunc)
174 	{
175 		gtk_flow_box_bind_model(gtkFlowBox, (model is null) ? null : model.getListModelStruct(), createWidgetFunc, userData, userDataFreeFunc);
176 	}
177 
178 	/**
179 	 * Returns whether children activate on single clicks.
180 	 *
181 	 * Returns: %TRUE if children are activated on single click,
182 	 *     %FALSE otherwise
183 	 *
184 	 * Since: 3.12
185 	 */
186 	public bool getActivateOnSingleClick()
187 	{
188 		return gtk_flow_box_get_activate_on_single_click(gtkFlowBox) != 0;
189 	}
190 
191 	/**
192 	 * Gets the nth child in the @box.
193 	 *
194 	 * Params:
195 	 *     idx = the position of the child
196 	 *
197 	 * Returns: the child widget, which will
198 	 *     always be a #GtkFlowBoxChild or %NULL in case no child widget
199 	 *     with the given index exists.
200 	 *
201 	 * Since: 3.12
202 	 */
203 	public FlowBoxChild getChildAtIndex(int idx)
204 	{
205 		auto p = gtk_flow_box_get_child_at_index(gtkFlowBox, idx);
206 		
207 		if(p is null)
208 		{
209 			return null;
210 		}
211 		
212 		return ObjectG.getDObject!(FlowBoxChild)(cast(GtkFlowBoxChild*) p);
213 	}
214 
215 	/**
216 	 * Gets the child in the (@x, @y) position.
217 	 *
218 	 * Params:
219 	 *     x = the x coordinate of the child
220 	 *     y = the y coordinate of the child
221 	 *
222 	 * Returns: the child widget, which will
223 	 *     always be a #GtkFlowBoxChild or %NULL in case no child widget
224 	 *     exists for the given x and y coordinates.
225 	 *
226 	 * Since: 3.22.6
227 	 */
228 	public FlowBoxChild getChildAtPos(int x, int y)
229 	{
230 		auto p = gtk_flow_box_get_child_at_pos(gtkFlowBox, x, y);
231 		
232 		if(p is null)
233 		{
234 			return null;
235 		}
236 		
237 		return ObjectG.getDObject!(FlowBoxChild)(cast(GtkFlowBoxChild*) p);
238 	}
239 
240 	/**
241 	 * Gets the horizontal spacing.
242 	 *
243 	 * Returns: the horizontal spacing
244 	 *
245 	 * Since: 3.12
246 	 */
247 	public uint getColumnSpacing()
248 	{
249 		return gtk_flow_box_get_column_spacing(gtkFlowBox);
250 	}
251 
252 	/**
253 	 * Returns whether the box is homogeneous (all children are the
254 	 * same size). See gtk_box_set_homogeneous().
255 	 *
256 	 * Returns: %TRUE if the box is homogeneous.
257 	 *
258 	 * Since: 3.12
259 	 */
260 	public bool getHomogeneous()
261 	{
262 		return gtk_flow_box_get_homogeneous(gtkFlowBox) != 0;
263 	}
264 
265 	/**
266 	 * Gets the maximum number of children per line.
267 	 *
268 	 * Returns: the maximum number of children per line
269 	 *
270 	 * Since: 3.12
271 	 */
272 	public uint getMaxChildrenPerLine()
273 	{
274 		return gtk_flow_box_get_max_children_per_line(gtkFlowBox);
275 	}
276 
277 	/**
278 	 * Gets the minimum number of children per line.
279 	 *
280 	 * Returns: the minimum number of children per line
281 	 *
282 	 * Since: 3.12
283 	 */
284 	public uint getMinChildrenPerLine()
285 	{
286 		return gtk_flow_box_get_min_children_per_line(gtkFlowBox);
287 	}
288 
289 	/**
290 	 * Gets the vertical spacing.
291 	 *
292 	 * Returns: the vertical spacing
293 	 *
294 	 * Since: 3.12
295 	 */
296 	public uint getRowSpacing()
297 	{
298 		return gtk_flow_box_get_row_spacing(gtkFlowBox);
299 	}
300 
301 	/**
302 	 * Creates a list of all selected children.
303 	 *
304 	 * Returns: A #GList containing the #GtkWidget for each selected child.
305 	 *     Free with g_list_free() when done.
306 	 *
307 	 * Since: 3.12
308 	 */
309 	public ListG getSelectedChildren()
310 	{
311 		auto p = gtk_flow_box_get_selected_children(gtkFlowBox);
312 		
313 		if(p is null)
314 		{
315 			return null;
316 		}
317 		
318 		return new ListG(cast(GList*) p);
319 	}
320 
321 	/**
322 	 * Gets the selection mode of @box.
323 	 *
324 	 * Returns: the #GtkSelectionMode
325 	 *
326 	 * Since: 3.12
327 	 */
328 	public GtkSelectionMode getSelectionMode()
329 	{
330 		return gtk_flow_box_get_selection_mode(gtkFlowBox);
331 	}
332 
333 	/**
334 	 * Inserts the @widget into @box at @position.
335 	 *
336 	 * If a sort function is set, the widget will actually be inserted
337 	 * at the calculated position and this function has the same effect
338 	 * as gtk_container_add().
339 	 *
340 	 * If @position is -1, or larger than the total number of children
341 	 * in the @box, then the @widget will be appended to the end.
342 	 *
343 	 * Params:
344 	 *     widget = the #GtkWidget to add
345 	 *     position = the position to insert @child in
346 	 *
347 	 * Since: 3.12
348 	 */
349 	public void insert(Widget widget, int position)
350 	{
351 		gtk_flow_box_insert(gtkFlowBox, (widget is null) ? null : widget.getWidgetStruct(), position);
352 	}
353 
354 	/**
355 	 * Updates the filtering for all children.
356 	 *
357 	 * Call this function when the result of the filter
358 	 * function on the @box is changed due ot an external
359 	 * factor. For instance, this would be used if the
360 	 * filter function just looked for a specific search
361 	 * term, and the entry with the string has changed.
362 	 *
363 	 * Since: 3.12
364 	 */
365 	public void invalidateFilter()
366 	{
367 		gtk_flow_box_invalidate_filter(gtkFlowBox);
368 	}
369 
370 	/**
371 	 * Updates the sorting for all children.
372 	 *
373 	 * Call this when the result of the sort function on
374 	 * @box is changed due to an external factor.
375 	 *
376 	 * Since: 3.12
377 	 */
378 	public void invalidateSort()
379 	{
380 		gtk_flow_box_invalidate_sort(gtkFlowBox);
381 	}
382 
383 	/**
384 	 * Select all children of @box, if the selection
385 	 * mode allows it.
386 	 *
387 	 * Since: 3.12
388 	 */
389 	public void selectAll()
390 	{
391 		gtk_flow_box_select_all(gtkFlowBox);
392 	}
393 
394 	/**
395 	 * Selects a single child of @box, if the selection
396 	 * mode allows it.
397 	 *
398 	 * Params:
399 	 *     child = a child of @box
400 	 *
401 	 * Since: 3.12
402 	 */
403 	public void selectChild(FlowBoxChild child)
404 	{
405 		gtk_flow_box_select_child(gtkFlowBox, (child is null) ? null : child.getFlowBoxChildStruct());
406 	}
407 
408 	/**
409 	 * Calls a function for each selected child.
410 	 *
411 	 * Note that the selection cannot be modified from within
412 	 * this function.
413 	 *
414 	 * Params:
415 	 *     func = the function to call for each selected child
416 	 *     data = user data to pass to the function
417 	 *
418 	 * Since: 3.12
419 	 */
420 	public void selectedForeach(GtkFlowBoxForeachFunc func, void* data)
421 	{
422 		gtk_flow_box_selected_foreach(gtkFlowBox, func, data);
423 	}
424 
425 	/**
426 	 * If @single is %TRUE, children will be activated when you click
427 	 * on them, otherwise you need to double-click.
428 	 *
429 	 * Params:
430 	 *     single = %TRUE to emit child-activated on a single click
431 	 *
432 	 * Since: 3.12
433 	 */
434 	public void setActivateOnSingleClick(bool single)
435 	{
436 		gtk_flow_box_set_activate_on_single_click(gtkFlowBox, single);
437 	}
438 
439 	/**
440 	 * Sets the horizontal space to add between children.
441 	 * See the #GtkFlowBox:column-spacing property.
442 	 *
443 	 * Params:
444 	 *     spacing = the spacing to use
445 	 *
446 	 * Since: 3.12
447 	 */
448 	public void setColumnSpacing(uint spacing)
449 	{
450 		gtk_flow_box_set_column_spacing(gtkFlowBox, spacing);
451 	}
452 
453 	/**
454 	 * By setting a filter function on the @box one can decide dynamically
455 	 * which of the children to show. For instance, to implement a search
456 	 * function that only shows the children matching the search terms.
457 	 *
458 	 * The @filter_func will be called for each child after the call, and
459 	 * it will continue to be called each time a child changes (via
460 	 * gtk_flow_box_child_changed()) or when gtk_flow_box_invalidate_filter()
461 	 * is called.
462 	 *
463 	 * Note that using a filter function is incompatible with using a model
464 	 * (see gtk_flow_box_bind_model()).
465 	 *
466 	 * Params:
467 	 *     filterFunc = callback that
468 	 *         lets you filter which children to show
469 	 *     userData = user data passed to @filter_func
470 	 *     destroy = destroy notifier for @user_data
471 	 *
472 	 * Since: 3.12
473 	 */
474 	public void setFilterFunc(GtkFlowBoxFilterFunc filterFunc, void* userData, GDestroyNotify destroy)
475 	{
476 		gtk_flow_box_set_filter_func(gtkFlowBox, filterFunc, userData, destroy);
477 	}
478 
479 	/**
480 	 * Hooks up an adjustment to focus handling in @box.
481 	 * The adjustment is also used for autoscrolling during
482 	 * rubberband selection. See gtk_scrolled_window_get_hadjustment()
483 	 * for a typical way of obtaining the adjustment, and
484 	 * gtk_flow_box_set_vadjustment()for setting the vertical
485 	 * adjustment.
486 	 *
487 	 * The adjustments have to be in pixel units and in the same
488 	 * coordinate system as the allocation for immediate children
489 	 * of the box.
490 	 *
491 	 * Params:
492 	 *     adjustment = an adjustment which should be adjusted
493 	 *         when the focus is moved among the descendents of @container
494 	 *
495 	 * Since: 3.12
496 	 */
497 	public void setHadjustment(Adjustment adjustment)
498 	{
499 		gtk_flow_box_set_hadjustment(gtkFlowBox, (adjustment is null) ? null : adjustment.getAdjustmentStruct());
500 	}
501 
502 	/**
503 	 * Sets the #GtkFlowBox:homogeneous property of @box, controlling
504 	 * whether or not all children of @box are given equal space
505 	 * in the box.
506 	 *
507 	 * Params:
508 	 *     homogeneous = %TRUE to create equal allotments,
509 	 *         %FALSE for variable allotments
510 	 *
511 	 * Since: 3.12
512 	 */
513 	public void setHomogeneous(bool homogeneous)
514 	{
515 		gtk_flow_box_set_homogeneous(gtkFlowBox, homogeneous);
516 	}
517 
518 	/**
519 	 * Sets the maximum number of children to request and
520 	 * allocate space for in @box’s orientation.
521 	 *
522 	 * Setting the maximum number of children per line
523 	 * limits the overall natural size request to be no more
524 	 * than @n_children children long in the given orientation.
525 	 *
526 	 * Params:
527 	 *     nChildren = the maximum number of children per line
528 	 *
529 	 * Since: 3.12
530 	 */
531 	public void setMaxChildrenPerLine(uint nChildren)
532 	{
533 		gtk_flow_box_set_max_children_per_line(gtkFlowBox, nChildren);
534 	}
535 
536 	/**
537 	 * Sets the minimum number of children to line up
538 	 * in @box’s orientation before flowing.
539 	 *
540 	 * Params:
541 	 *     nChildren = the minimum number of children per line
542 	 *
543 	 * Since: 3.12
544 	 */
545 	public void setMinChildrenPerLine(uint nChildren)
546 	{
547 		gtk_flow_box_set_min_children_per_line(gtkFlowBox, nChildren);
548 	}
549 
550 	/**
551 	 * Sets the vertical space to add between children.
552 	 * See the #GtkFlowBox:row-spacing property.
553 	 *
554 	 * Params:
555 	 *     spacing = the spacing to use
556 	 *
557 	 * Since: 3.12
558 	 */
559 	public void setRowSpacing(uint spacing)
560 	{
561 		gtk_flow_box_set_row_spacing(gtkFlowBox, spacing);
562 	}
563 
564 	/**
565 	 * Sets how selection works in @box.
566 	 * See #GtkSelectionMode for details.
567 	 *
568 	 * Params:
569 	 *     mode = the new selection mode
570 	 *
571 	 * Since: 3.12
572 	 */
573 	public void setSelectionMode(GtkSelectionMode mode)
574 	{
575 		gtk_flow_box_set_selection_mode(gtkFlowBox, mode);
576 	}
577 
578 	/**
579 	 * By setting a sort function on the @box, one can dynamically
580 	 * reorder the children of the box, based on the contents of
581 	 * the children.
582 	 *
583 	 * The @sort_func will be called for each child after the call,
584 	 * and will continue to be called each time a child changes (via
585 	 * gtk_flow_box_child_changed()) and when gtk_flow_box_invalidate_sort()
586 	 * is called.
587 	 *
588 	 * Note that using a sort function is incompatible with using a model
589 	 * (see gtk_flow_box_bind_model()).
590 	 *
591 	 * Params:
592 	 *     sortFunc = the sort function
593 	 *     userData = user data passed to @sort_func
594 	 *     destroy = destroy notifier for @user_data
595 	 *
596 	 * Since: 3.12
597 	 */
598 	public void setSortFunc(GtkFlowBoxSortFunc sortFunc, void* userData, GDestroyNotify destroy)
599 	{
600 		gtk_flow_box_set_sort_func(gtkFlowBox, sortFunc, userData, destroy);
601 	}
602 
603 	/**
604 	 * Hooks up an adjustment to focus handling in @box.
605 	 * The adjustment is also used for autoscrolling during
606 	 * rubberband selection. See gtk_scrolled_window_get_vadjustment()
607 	 * for a typical way of obtaining the adjustment, and
608 	 * gtk_flow_box_set_hadjustment()for setting the horizontal
609 	 * adjustment.
610 	 *
611 	 * The adjustments have to be in pixel units and in the same
612 	 * coordinate system as the allocation for immediate children
613 	 * of the box.
614 	 *
615 	 * Params:
616 	 *     adjustment = an adjustment which should be adjusted
617 	 *         when the focus is moved among the descendents of @container
618 	 *
619 	 * Since: 3.12
620 	 */
621 	public void setVadjustment(Adjustment adjustment)
622 	{
623 		gtk_flow_box_set_vadjustment(gtkFlowBox, (adjustment is null) ? null : adjustment.getAdjustmentStruct());
624 	}
625 
626 	/**
627 	 * Unselect all children of @box, if the selection
628 	 * mode allows it.
629 	 *
630 	 * Since: 3.12
631 	 */
632 	public void unselectAll()
633 	{
634 		gtk_flow_box_unselect_all(gtkFlowBox);
635 	}
636 
637 	/**
638 	 * Unselects a single child of @box, if the selection
639 	 * mode allows it.
640 	 *
641 	 * Params:
642 	 *     child = a child of @box
643 	 *
644 	 * Since: 3.12
645 	 */
646 	public void unselectChild(FlowBoxChild child)
647 	{
648 		gtk_flow_box_unselect_child(gtkFlowBox, (child is null) ? null : child.getFlowBoxChildStruct());
649 	}
650 
651 	protected class OnActivateCursorChildDelegateWrapper
652 	{
653 		static OnActivateCursorChildDelegateWrapper[] listeners;
654 		void delegate(FlowBox) dlg;
655 		gulong handlerId;
656 		
657 		this(void delegate(FlowBox) dlg)
658 		{
659 			this.dlg = dlg;
660 			this.listeners ~= this;
661 		}
662 		
663 		void remove(OnActivateCursorChildDelegateWrapper source)
664 		{
665 			foreach(index, wrapper; listeners)
666 			{
667 				if (wrapper.handlerId == source.handlerId)
668 				{
669 					listeners[index] = null;
670 					listeners = std.algorithm.remove(listeners, index);
671 					break;
672 				}
673 			}
674 		}
675 	}
676 
677 	/**
678 	 * The ::activate-cursor-child signal is a
679 	 * [keybinding signal][GtkBindingSignal]
680 	 * which gets emitted when the user activates the @box.
681 	 */
682 	gulong addOnActivateCursorChild(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
683 	{
684 		auto wrapper = new OnActivateCursorChildDelegateWrapper(dlg);
685 		wrapper.handlerId = Signals.connectData(
686 			this,
687 			"activate-cursor-child",
688 			cast(GCallback)&callBackActivateCursorChild,
689 			cast(void*)wrapper,
690 			cast(GClosureNotify)&callBackActivateCursorChildDestroy,
691 			connectFlags);
692 		return wrapper.handlerId;
693 	}
694 	
695 	extern(C) static void callBackActivateCursorChild(GtkFlowBox* flowboxStruct, OnActivateCursorChildDelegateWrapper wrapper)
696 	{
697 		wrapper.dlg(wrapper.outer);
698 	}
699 	
700 	extern(C) static void callBackActivateCursorChildDestroy(OnActivateCursorChildDelegateWrapper wrapper, GClosure* closure)
701 	{
702 		wrapper.remove(wrapper);
703 	}
704 
705 	protected class OnChildActivatedDelegateWrapper
706 	{
707 		static OnChildActivatedDelegateWrapper[] listeners;
708 		void delegate(FlowBoxChild, FlowBox) dlg;
709 		gulong handlerId;
710 		
711 		this(void delegate(FlowBoxChild, FlowBox) dlg)
712 		{
713 			this.dlg = dlg;
714 			this.listeners ~= this;
715 		}
716 		
717 		void remove(OnChildActivatedDelegateWrapper source)
718 		{
719 			foreach(index, wrapper; listeners)
720 			{
721 				if (wrapper.handlerId == source.handlerId)
722 				{
723 					listeners[index] = null;
724 					listeners = std.algorithm.remove(listeners, index);
725 					break;
726 				}
727 			}
728 		}
729 	}
730 
731 	/**
732 	 * The ::child-activated signal is emitted when a child has been
733 	 * activated by the user.
734 	 *
735 	 * Params:
736 	 *     child = the child that is activated
737 	 */
738 	gulong addOnChildActivated(void delegate(FlowBoxChild, FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
739 	{
740 		auto wrapper = new OnChildActivatedDelegateWrapper(dlg);
741 		wrapper.handlerId = Signals.connectData(
742 			this,
743 			"child-activated",
744 			cast(GCallback)&callBackChildActivated,
745 			cast(void*)wrapper,
746 			cast(GClosureNotify)&callBackChildActivatedDestroy,
747 			connectFlags);
748 		return wrapper.handlerId;
749 	}
750 	
751 	extern(C) static void callBackChildActivated(GtkFlowBox* flowboxStruct, GtkFlowBoxChild* child, OnChildActivatedDelegateWrapper wrapper)
752 	{
753 		wrapper.dlg(ObjectG.getDObject!(FlowBoxChild)(child), wrapper.outer);
754 	}
755 	
756 	extern(C) static void callBackChildActivatedDestroy(OnChildActivatedDelegateWrapper wrapper, GClosure* closure)
757 	{
758 		wrapper.remove(wrapper);
759 	}
760 
761 	protected class OnMoveCursorDelegateWrapper
762 	{
763 		static OnMoveCursorDelegateWrapper[] listeners;
764 		bool delegate(GtkMovementStep, int, FlowBox) dlg;
765 		gulong handlerId;
766 		
767 		this(bool delegate(GtkMovementStep, int, FlowBox) dlg)
768 		{
769 			this.dlg = dlg;
770 			this.listeners ~= this;
771 		}
772 		
773 		void remove(OnMoveCursorDelegateWrapper source)
774 		{
775 			foreach(index, wrapper; listeners)
776 			{
777 				if (wrapper.handlerId == source.handlerId)
778 				{
779 					listeners[index] = null;
780 					listeners = std.algorithm.remove(listeners, index);
781 					break;
782 				}
783 			}
784 		}
785 	}
786 
787 	/**
788 	 * The ::move-cursor signal is a
789 	 * [keybinding signal][GtkBindingSignal]
790 	 * which gets emitted when the user initiates a cursor movement.
791 	 *
792 	 * Applications should not connect to it, but may emit it with
793 	 * g_signal_emit_by_name() if they need to control the cursor
794 	 * programmatically.
795 	 *
796 	 * The default bindings for this signal come in two variants,
797 	 * the variant with the Shift modifier extends the selection,
798 	 * the variant without the Shift modifer does not.
799 	 * There are too many key combinations to list them all here.
800 	 * - Arrow keys move by individual children
801 	 * - Home/End keys move to the ends of the box
802 	 * - PageUp/PageDown keys move vertically by pages
803 	 *
804 	 * Params:
805 	 *     step = the granularity fo the move, as a #GtkMovementStep
806 	 *     count = the number of @step units to move
807 	 *
808 	 * Returns: %TRUE to stop other handlers from being invoked for the event.
809 	 *     %FALSE to propagate the event further.
810 	 */
811 	gulong addOnMoveCursor(bool delegate(GtkMovementStep, int, FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
812 	{
813 		auto wrapper = new OnMoveCursorDelegateWrapper(dlg);
814 		wrapper.handlerId = Signals.connectData(
815 			this,
816 			"move-cursor",
817 			cast(GCallback)&callBackMoveCursor,
818 			cast(void*)wrapper,
819 			cast(GClosureNotify)&callBackMoveCursorDestroy,
820 			connectFlags);
821 		return wrapper.handlerId;
822 	}
823 	
824 	extern(C) static int callBackMoveCursor(GtkFlowBox* flowboxStruct, GtkMovementStep step, int count, OnMoveCursorDelegateWrapper wrapper)
825 	{
826 		return wrapper.dlg(step, count, wrapper.outer);
827 	}
828 	
829 	extern(C) static void callBackMoveCursorDestroy(OnMoveCursorDelegateWrapper wrapper, GClosure* closure)
830 	{
831 		wrapper.remove(wrapper);
832 	}
833 
834 	protected class OnSelectAllDelegateWrapper
835 	{
836 		static OnSelectAllDelegateWrapper[] listeners;
837 		void delegate(FlowBox) dlg;
838 		gulong handlerId;
839 		
840 		this(void delegate(FlowBox) dlg)
841 		{
842 			this.dlg = dlg;
843 			this.listeners ~= this;
844 		}
845 		
846 		void remove(OnSelectAllDelegateWrapper source)
847 		{
848 			foreach(index, wrapper; listeners)
849 			{
850 				if (wrapper.handlerId == source.handlerId)
851 				{
852 					listeners[index] = null;
853 					listeners = std.algorithm.remove(listeners, index);
854 					break;
855 				}
856 			}
857 		}
858 	}
859 
860 	/**
861 	 * The ::select-all signal is a
862 	 * [keybinding signal][GtkBindingSignal]
863 	 * which gets emitted to select all children of the box, if
864 	 * the selection mode permits it.
865 	 *
866 	 * The default bindings for this signal is Ctrl-a.
867 	 */
868 	gulong addOnSelectAll(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
869 	{
870 		auto wrapper = new OnSelectAllDelegateWrapper(dlg);
871 		wrapper.handlerId = Signals.connectData(
872 			this,
873 			"select-all",
874 			cast(GCallback)&callBackSelectAll,
875 			cast(void*)wrapper,
876 			cast(GClosureNotify)&callBackSelectAllDestroy,
877 			connectFlags);
878 		return wrapper.handlerId;
879 	}
880 	
881 	extern(C) static void callBackSelectAll(GtkFlowBox* flowboxStruct, OnSelectAllDelegateWrapper wrapper)
882 	{
883 		wrapper.dlg(wrapper.outer);
884 	}
885 	
886 	extern(C) static void callBackSelectAllDestroy(OnSelectAllDelegateWrapper wrapper, GClosure* closure)
887 	{
888 		wrapper.remove(wrapper);
889 	}
890 
891 	protected class OnSelectedChildrenChangedDelegateWrapper
892 	{
893 		static OnSelectedChildrenChangedDelegateWrapper[] listeners;
894 		void delegate(FlowBox) dlg;
895 		gulong handlerId;
896 		
897 		this(void delegate(FlowBox) dlg)
898 		{
899 			this.dlg = dlg;
900 			this.listeners ~= this;
901 		}
902 		
903 		void remove(OnSelectedChildrenChangedDelegateWrapper source)
904 		{
905 			foreach(index, wrapper; listeners)
906 			{
907 				if (wrapper.handlerId == source.handlerId)
908 				{
909 					listeners[index] = null;
910 					listeners = std.algorithm.remove(listeners, index);
911 					break;
912 				}
913 			}
914 		}
915 	}
916 
917 	/**
918 	 * The ::selected-children-changed signal is emitted when the
919 	 * set of selected children changes.
920 	 *
921 	 * Use gtk_flow_box_selected_foreach() or
922 	 * gtk_flow_box_get_selected_children() to obtain the
923 	 * selected children.
924 	 */
925 	gulong addOnSelectedChildrenChanged(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
926 	{
927 		auto wrapper = new OnSelectedChildrenChangedDelegateWrapper(dlg);
928 		wrapper.handlerId = Signals.connectData(
929 			this,
930 			"selected-children-changed",
931 			cast(GCallback)&callBackSelectedChildrenChanged,
932 			cast(void*)wrapper,
933 			cast(GClosureNotify)&callBackSelectedChildrenChangedDestroy,
934 			connectFlags);
935 		return wrapper.handlerId;
936 	}
937 	
938 	extern(C) static void callBackSelectedChildrenChanged(GtkFlowBox* flowboxStruct, OnSelectedChildrenChangedDelegateWrapper wrapper)
939 	{
940 		wrapper.dlg(wrapper.outer);
941 	}
942 	
943 	extern(C) static void callBackSelectedChildrenChangedDestroy(OnSelectedChildrenChangedDelegateWrapper wrapper, GClosure* closure)
944 	{
945 		wrapper.remove(wrapper);
946 	}
947 
948 	protected class OnToggleCursorChildDelegateWrapper
949 	{
950 		static OnToggleCursorChildDelegateWrapper[] listeners;
951 		void delegate(FlowBox) dlg;
952 		gulong handlerId;
953 		
954 		this(void delegate(FlowBox) dlg)
955 		{
956 			this.dlg = dlg;
957 			this.listeners ~= this;
958 		}
959 		
960 		void remove(OnToggleCursorChildDelegateWrapper source)
961 		{
962 			foreach(index, wrapper; listeners)
963 			{
964 				if (wrapper.handlerId == source.handlerId)
965 				{
966 					listeners[index] = null;
967 					listeners = std.algorithm.remove(listeners, index);
968 					break;
969 				}
970 			}
971 		}
972 	}
973 
974 	/**
975 	 * The ::toggle-cursor-child signal is a
976 	 * [keybinding signal][GtkBindingSignal]
977 	 * which toggles the selection of the child that has the focus.
978 	 *
979 	 * The default binding for this signal is Ctrl-Space.
980 	 */
981 	gulong addOnToggleCursorChild(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
982 	{
983 		auto wrapper = new OnToggleCursorChildDelegateWrapper(dlg);
984 		wrapper.handlerId = Signals.connectData(
985 			this,
986 			"toggle-cursor-child",
987 			cast(GCallback)&callBackToggleCursorChild,
988 			cast(void*)wrapper,
989 			cast(GClosureNotify)&callBackToggleCursorChildDestroy,
990 			connectFlags);
991 		return wrapper.handlerId;
992 	}
993 	
994 	extern(C) static void callBackToggleCursorChild(GtkFlowBox* flowboxStruct, OnToggleCursorChildDelegateWrapper wrapper)
995 	{
996 		wrapper.dlg(wrapper.outer);
997 	}
998 	
999 	extern(C) static void callBackToggleCursorChildDestroy(OnToggleCursorChildDelegateWrapper wrapper, GClosure* closure)
1000 	{
1001 		wrapper.remove(wrapper);
1002 	}
1003 
1004 	protected class OnUnselectAllDelegateWrapper
1005 	{
1006 		static OnUnselectAllDelegateWrapper[] listeners;
1007 		void delegate(FlowBox) dlg;
1008 		gulong handlerId;
1009 		
1010 		this(void delegate(FlowBox) dlg)
1011 		{
1012 			this.dlg = dlg;
1013 			this.listeners ~= this;
1014 		}
1015 		
1016 		void remove(OnUnselectAllDelegateWrapper source)
1017 		{
1018 			foreach(index, wrapper; listeners)
1019 			{
1020 				if (wrapper.handlerId == source.handlerId)
1021 				{
1022 					listeners[index] = null;
1023 					listeners = std.algorithm.remove(listeners, index);
1024 					break;
1025 				}
1026 			}
1027 		}
1028 	}
1029 
1030 	/**
1031 	 * The ::unselect-all signal is a
1032 	 * [keybinding signal][GtkBindingSignal]
1033 	 * which gets emitted to unselect all children of the box, if
1034 	 * the selection mode permits it.
1035 	 *
1036 	 * The default bindings for this signal is Ctrl-Shift-a.
1037 	 */
1038 	gulong addOnUnselectAll(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
1039 	{
1040 		auto wrapper = new OnUnselectAllDelegateWrapper(dlg);
1041 		wrapper.handlerId = Signals.connectData(
1042 			this,
1043 			"unselect-all",
1044 			cast(GCallback)&callBackUnselectAll,
1045 			cast(void*)wrapper,
1046 			cast(GClosureNotify)&callBackUnselectAllDestroy,
1047 			connectFlags);
1048 		return wrapper.handlerId;
1049 	}
1050 	
1051 	extern(C) static void callBackUnselectAll(GtkFlowBox* flowboxStruct, OnUnselectAllDelegateWrapper wrapper)
1052 	{
1053 		wrapper.dlg(wrapper.outer);
1054 	}
1055 	
1056 	extern(C) static void callBackUnselectAllDestroy(OnUnselectAllDelegateWrapper wrapper, GClosure* closure)
1057 	{
1058 		wrapper.remove(wrapper);
1059 	}
1060 }