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