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