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