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