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.ListBox;
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.ListBoxRow;
34 private import gtk.Widget;
35 private import gtk.c.functions;
36 public  import gtk.c.types;
37 private import std.algorithm;
38 
39 
40 /**
41  * `GtkListBox` is a vertical list.
42  * 
43  * A `GtkListBox` only contains `GtkListBoxRow` children. These rows can
44  * by dynamically sorted and filtered, and headers can be added dynamically
45  * depending on the row content. It also allows keyboard and mouse navigation
46  * and selection like a typical list.
47  * 
48  * Using `GtkListBox` is often an alternative to `GtkTreeView`, especially
49  * when the list contents has a more complicated layout than what is allowed
50  * by a `GtkCellRenderer`, or when the contents is interactive (i.e. has a
51  * button in it).
52  * 
53  * Although a `GtkListBox` must have only `GtkListBoxRow` children, you can
54  * add any kind of widget to it via [method@Gtk.ListBox.prepend],
55  * [method@Gtk.ListBox.append] and [method@Gtk.ListBox.insert] and a
56  * `GtkListBoxRow` widget will automatically be inserted between the list
57  * and the widget.
58  * 
59  * `GtkListBoxRows` can be marked as activatable or selectable. If a row is
60  * activatable, [signal@Gtk.ListBox::row-activated] will be emitted for it when
61  * the user tries to activate it. If it is selectable, the row will be marked
62  * as selected when the user tries to select it.
63  * 
64  * # GtkListBox as GtkBuildable
65  * 
66  * The `GtkListBox` implementation of the `GtkBuildable` interface supports
67  * setting a child as the placeholder by specifying “placeholder” as the “type”
68  * attribute of a <child> element. See [method@Gtk.ListBox.set_placeholder]
69  * for info.
70  * 
71  * # CSS nodes
72  * 
73  * |[<!-- language="plain" -->
74  * list[.separators][.rich-list][.navigation-sidebar]
75  * ╰── row[.activatable]
76  * ]|
77  * 
78  * `GtkListBox` uses a single CSS node named list. It may carry the .separators
79  * style class, when the [property@Gtk.ListBox:show-separators] property is set.
80  * Each `GtkListBoxRow` uses a single CSS node named row. The row nodes get the
81  * .activatable style class added when appropriate.
82  * 
83  * The main list node may also carry style classes to select
84  * the style of [list presentation](section-list-widget.html#list-styles):
85  * .rich-list, .navigation-sidebar or .data-table.
86  * 
87  * # Accessibility
88  * 
89  * `GtkListBox` uses the %GTK_ACCESSIBLE_ROLE_LIST role and `GtkListBoxRow` uses
90  * the %GTK_ACCESSIBLE_ROLE_LIST_ITEM role.
91  */
92 public class ListBox : Widget
93 {
94 	/** the main Gtk struct */
95 	protected GtkListBox* gtkListBox;
96 
97 	/** Get the main Gtk struct */
98 	public GtkListBox* getListBoxStruct(bool transferOwnership = false)
99 	{
100 		if (transferOwnership)
101 			ownedRef = false;
102 		return gtkListBox;
103 	}
104 
105 	/** the main Gtk struct as a void* */
106 	protected override void* getStruct()
107 	{
108 		return cast(void*)gtkListBox;
109 	}
110 
111 	/**
112 	 * Sets our main struct and passes it to the parent class.
113 	 */
114 	public this (GtkListBox* gtkListBox, bool ownedRef = false)
115 	{
116 		this.gtkListBox = gtkListBox;
117 		super(cast(GtkWidget*)gtkListBox, ownedRef);
118 	}
119 
120 
121 	/** */
122 	public static GType getType()
123 	{
124 		return gtk_list_box_get_type();
125 	}
126 
127 	/**
128 	 * Creates a new `GtkListBox` container.
129 	 *
130 	 * Returns: a new `GtkListBox`
131 	 *
132 	 * Throws: ConstructionException GTK+ fails to create the object.
133 	 */
134 	public this()
135 	{
136 		auto __p = gtk_list_box_new();
137 
138 		if(__p is null)
139 		{
140 			throw new ConstructionException("null returned by new");
141 		}
142 
143 		this(cast(GtkListBox*) __p);
144 	}
145 
146 	/**
147 	 * Append a widget to the list.
148 	 *
149 	 * If a sort function is set, the widget will
150 	 * actually be inserted at the calculated position.
151 	 *
152 	 * Params:
153 	 *     child = the `GtkWidget` to add
154 	 */
155 	public void append(Widget child)
156 	{
157 		gtk_list_box_append(gtkListBox, (child is null) ? null : child.getWidgetStruct());
158 	}
159 
160 	/**
161 	 * Binds @model to @box.
162 	 *
163 	 * If @box was already bound to a model, that previous binding is
164 	 * destroyed.
165 	 *
166 	 * The contents of @box are cleared and then filled with widgets that
167 	 * represent items from @model. @box is updated whenever @model changes.
168 	 * If @model is %NULL, @box is left empty.
169 	 *
170 	 * It is undefined to add or remove widgets directly (for example, with
171 	 * [method@Gtk.ListBox.insert]) while @box is bound to a model.
172 	 *
173 	 * Note that using a model is incompatible with the filtering and sorting
174 	 * functionality in `GtkListBox`. When using a model, filtering and sorting
175 	 * should be implemented by the model.
176 	 *
177 	 * Params:
178 	 *     model = the `GListModel` to be bound to @box
179 	 *     createWidgetFunc = a function that creates widgets for items
180 	 *         or %NULL in case you also passed %NULL as @model
181 	 *     userData = user data passed to @create_widget_func
182 	 *     userDataFreeFunc = function for freeing @user_data
183 	 */
184 	public void bindModel(ListModelIF model, GtkListBoxCreateWidgetFunc createWidgetFunc, void* userData, GDestroyNotify userDataFreeFunc)
185 	{
186 		gtk_list_box_bind_model(gtkListBox, (model is null) ? null : model.getListModelStruct(), createWidgetFunc, userData, userDataFreeFunc);
187 	}
188 
189 	/**
190 	 * Add a drag highlight to a row.
191 	 *
192 	 * This is a helper function for implementing DnD onto a `GtkListBox`.
193 	 * The passed in @row will be highlighted by setting the
194 	 * %GTK_STATE_FLAG_DROP_ACTIVE state and any previously highlighted
195 	 * row will be unhighlighted.
196 	 *
197 	 * The row will also be unhighlighted when the widget gets
198 	 * a drag leave event.
199 	 *
200 	 * Params:
201 	 *     row = a `GtkListBoxRow`
202 	 */
203 	public void dragHighlightRow(ListBoxRow row)
204 	{
205 		gtk_list_box_drag_highlight_row(gtkListBox, (row is null) ? null : row.getListBoxRowStruct());
206 	}
207 
208 	/**
209 	 * If a row has previously been highlighted via gtk_list_box_drag_highlight_row(),
210 	 * it will have the highlight removed.
211 	 */
212 	public void dragUnhighlightRow()
213 	{
214 		gtk_list_box_drag_unhighlight_row(gtkListBox);
215 	}
216 
217 	/**
218 	 * Returns whether rows activate on single clicks.
219 	 *
220 	 * Returns: %TRUE if rows are activated on single click, %FALSE otherwise
221 	 */
222 	public bool getActivateOnSingleClick()
223 	{
224 		return gtk_list_box_get_activate_on_single_click(gtkListBox) != 0;
225 	}
226 
227 	/**
228 	 * Gets the adjustment (if any) that the widget uses to
229 	 * for vertical scrolling.
230 	 *
231 	 * Returns: the adjustment
232 	 */
233 	public Adjustment getAdjustment()
234 	{
235 		auto __p = gtk_list_box_get_adjustment(gtkListBox);
236 
237 		if(__p is null)
238 		{
239 			return null;
240 		}
241 
242 		return ObjectG.getDObject!(Adjustment)(cast(GtkAdjustment*) __p);
243 	}
244 
245 	/**
246 	 * Gets the n-th child in the list (not counting headers).
247 	 *
248 	 * If @index_ is negative or larger than the number of items in the
249 	 * list, %NULL is returned.
250 	 *
251 	 * Params:
252 	 *     index = the index of the row
253 	 *
254 	 * Returns: the child `GtkWidget` or %NULL
255 	 */
256 	public ListBoxRow getRowAtIndex(int index)
257 	{
258 		auto __p = gtk_list_box_get_row_at_index(gtkListBox, index);
259 
260 		if(__p is null)
261 		{
262 			return null;
263 		}
264 
265 		return ObjectG.getDObject!(ListBoxRow)(cast(GtkListBoxRow*) __p);
266 	}
267 
268 	/**
269 	 * Gets the row at the @y position.
270 	 *
271 	 * Params:
272 	 *     y = position
273 	 *
274 	 * Returns: the row or %NULL
275 	 *     in case no row exists for the given y coordinate.
276 	 */
277 	public ListBoxRow getRowAtY(int y)
278 	{
279 		auto __p = gtk_list_box_get_row_at_y(gtkListBox, y);
280 
281 		if(__p is null)
282 		{
283 			return null;
284 		}
285 
286 		return ObjectG.getDObject!(ListBoxRow)(cast(GtkListBoxRow*) __p);
287 	}
288 
289 	/**
290 	 * Gets the selected row, or %NULL if no rows are selected.
291 	 *
292 	 * Note that the box may allow multiple selection, in which
293 	 * case you should use [method@Gtk.ListBox.selected_foreach] to
294 	 * find all selected rows.
295 	 *
296 	 * Returns: the selected row or %NULL
297 	 */
298 	public ListBoxRow getSelectedRow()
299 	{
300 		auto __p = gtk_list_box_get_selected_row(gtkListBox);
301 
302 		if(__p is null)
303 		{
304 			return null;
305 		}
306 
307 		return ObjectG.getDObject!(ListBoxRow)(cast(GtkListBoxRow*) __p);
308 	}
309 
310 	/**
311 	 * Creates a list of all selected children.
312 	 *
313 	 * Returns: A `GList` containing the `GtkWidget` for each selected child.
314 	 *     Free with g_list_free() when done.
315 	 */
316 	public ListG getSelectedRows()
317 	{
318 		auto __p = gtk_list_box_get_selected_rows(gtkListBox);
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 the listbox.
330 	 *
331 	 * Returns: a `GtkSelectionMode`
332 	 */
333 	public GtkSelectionMode getSelectionMode()
334 	{
335 		return gtk_list_box_get_selection_mode(gtkListBox);
336 	}
337 
338 	/**
339 	 * Returns whether the list box should show separators
340 	 * between rows.
341 	 *
342 	 * Returns: %TRUE if the list box shows separators
343 	 */
344 	public bool getShowSeparators()
345 	{
346 		return gtk_list_box_get_show_separators(gtkListBox) != 0;
347 	}
348 
349 	/**
350 	 * Insert the @child into the @box at @position.
351 	 *
352 	 * If a sort function is
353 	 * set, the widget will actually be inserted at the calculated position.
354 	 *
355 	 * If @position is -1, or larger than the total number of items in the
356 	 * @box, then the @child will be appended to the end.
357 	 *
358 	 * Params:
359 	 *     child = the `GtkWidget` to add
360 	 *     position = the position to insert @child in
361 	 */
362 	public void insert(Widget child, int position)
363 	{
364 		gtk_list_box_insert(gtkListBox, (child is null) ? null : child.getWidgetStruct(), position);
365 	}
366 
367 	/**
368 	 * Update the filtering for all rows.
369 	 *
370 	 * Call this when result
371 	 * of the filter function on the @box is changed due
372 	 * to an external factor. For instance, this would be used
373 	 * if the filter function just looked for a specific search
374 	 * string and the entry with the search string has changed.
375 	 */
376 	public void invalidateFilter()
377 	{
378 		gtk_list_box_invalidate_filter(gtkListBox);
379 	}
380 
381 	/**
382 	 * Update the separators for all rows.
383 	 *
384 	 * Call this when result
385 	 * of the header function on the @box is changed due
386 	 * to an external factor.
387 	 */
388 	public void invalidateHeaders()
389 	{
390 		gtk_list_box_invalidate_headers(gtkListBox);
391 	}
392 
393 	/**
394 	 * Update the sorting for all rows.
395 	 *
396 	 * Call this when result
397 	 * of the sort function on the @box is changed due
398 	 * to an external factor.
399 	 */
400 	public void invalidateSort()
401 	{
402 		gtk_list_box_invalidate_sort(gtkListBox);
403 	}
404 
405 	/**
406 	 * Prepend a widget to the list.
407 	 *
408 	 * If a sort function is set, the widget will
409 	 * actually be inserted at the calculated position.
410 	 *
411 	 * Params:
412 	 *     child = the `GtkWidget` to add
413 	 */
414 	public void prepend(Widget child)
415 	{
416 		gtk_list_box_prepend(gtkListBox, (child is null) ? null : child.getWidgetStruct());
417 	}
418 
419 	/**
420 	 * Removes a child from @box.
421 	 *
422 	 * Params:
423 	 *     child = the child to remove
424 	 */
425 	public void remove(Widget child)
426 	{
427 		gtk_list_box_remove(gtkListBox, (child is null) ? null : child.getWidgetStruct());
428 	}
429 
430 	/**
431 	 * Select all children of @box, if the selection mode allows it.
432 	 */
433 	public void selectAll()
434 	{
435 		gtk_list_box_select_all(gtkListBox);
436 	}
437 
438 	/**
439 	 * Make @row the currently selected row.
440 	 *
441 	 * Params:
442 	 *     row = The row to select or %NULL
443 	 */
444 	public void selectRow(ListBoxRow row)
445 	{
446 		gtk_list_box_select_row(gtkListBox, (row is null) ? null : row.getListBoxRowStruct());
447 	}
448 
449 	/**
450 	 * Calls a function for each selected child.
451 	 *
452 	 * Note that the selection cannot be modified from within this function.
453 	 *
454 	 * Params:
455 	 *     func = the function to call for each selected child
456 	 *     data = user data to pass to the function
457 	 */
458 	public void selectedForeach(GtkListBoxForeachFunc func, void* data)
459 	{
460 		gtk_list_box_selected_foreach(gtkListBox, func, data);
461 	}
462 
463 	/**
464 	 * If @single is %TRUE, rows will be activated when you click on them,
465 	 * otherwise you need to double-click.
466 	 *
467 	 * Params:
468 	 *     single = a boolean
469 	 */
470 	public void setActivateOnSingleClick(bool single)
471 	{
472 		gtk_list_box_set_activate_on_single_click(gtkListBox, single);
473 	}
474 
475 	/**
476 	 * Sets the adjustment (if any) that the widget uses to
477 	 * for vertical scrolling.
478 	 *
479 	 * For instance, this is used to get the page size for
480 	 * PageUp/Down key handling.
481 	 *
482 	 * In the normal case when the @box is packed inside
483 	 * a `GtkScrolledWindow` the adjustment from that will
484 	 * be picked up automatically, so there is no need
485 	 * to manually do that.
486 	 *
487 	 * Params:
488 	 *     adjustment = the adjustment, or %NULL
489 	 */
490 	public void setAdjustment(Adjustment adjustment)
491 	{
492 		gtk_list_box_set_adjustment(gtkListBox, (adjustment is null) ? null : adjustment.getAdjustmentStruct());
493 	}
494 
495 	/**
496 	 * By setting a filter function on the @box one can decide dynamically which
497 	 * of the rows to show.
498 	 *
499 	 * For instance, to implement a search function on a list that
500 	 * filters the original list to only show the matching rows.
501 	 *
502 	 * The @filter_func will be called for each row after the call, and
503 	 * it will continue to be called each time a row changes (via
504 	 * [method@Gtk.ListBoxRow.changed]) or when [method@Gtk.ListBox.invalidate_filter]
505 	 * is called.
506 	 *
507 	 * Note that using a filter function is incompatible with using a model
508 	 * (see [method@Gtk.ListBox.bind_model]).
509 	 *
510 	 * Params:
511 	 *     filterFunc = callback that lets you filter which rows to show
512 	 *     userData = user data passed to @filter_func
513 	 *     destroy = destroy notifier for @user_data
514 	 */
515 	public void setFilterFunc(GtkListBoxFilterFunc filterFunc, void* userData, GDestroyNotify destroy)
516 	{
517 		gtk_list_box_set_filter_func(gtkListBox, filterFunc, userData, destroy);
518 	}
519 
520 	/**
521 	 * Sets a header function.
522 	 *
523 	 * By setting a header function on the @box one can dynamically add headers
524 	 * in front of rows, depending on the contents of the row and its position
525 	 * in the list.
526 	 *
527 	 * For instance, one could use it to add headers in front of the first item
528 	 * of a new kind, in a list sorted by the kind.
529 	 *
530 	 * The @update_header can look at the current header widget using
531 	 * [method@Gtk.ListBoxRow.get_header] and either update the state of the widget
532 	 * as needed, or set a new one using [method@Gtk.ListBoxRow.set_header]. If no
533 	 * header is needed, set the header to %NULL.
534 	 *
535 	 * Note that you may get many calls @update_header to this for a particular
536 	 * row when e.g. changing things that don’t affect the header. In this case
537 	 * it is important for performance to not blindly replace an existing header
538 	 * with an identical one.
539 	 *
540 	 * The @update_header function will be called for each row after the call,
541 	 * and it will continue to be called each time a row changes (via
542 	 * [method@Gtk.ListBoxRow.changed]) and when the row before changes (either
543 	 * by [method@Gtk.ListBoxRow.changed] on the previous row, or when the previous
544 	 * row becomes a different row). It is also called for all rows when
545 	 * [method@Gtk.ListBox.invalidate_headers] is called.
546 	 *
547 	 * Params:
548 	 *     updateHeader = callback that lets you add row headers
549 	 *     userData = user data passed to @update_header
550 	 *     destroy = destroy notifier for @user_data
551 	 */
552 	public void setHeaderFunc(GtkListBoxUpdateHeaderFunc updateHeader, void* userData, GDestroyNotify destroy)
553 	{
554 		gtk_list_box_set_header_func(gtkListBox, updateHeader, userData, destroy);
555 	}
556 
557 	/**
558 	 * Sets the placeholder widget that is shown in the list when
559 	 * it doesn't display any visible children.
560 	 *
561 	 * Params:
562 	 *     placeholder = a #GtkWidget or %NULL
563 	 */
564 	public void setPlaceholder(Widget placeholder)
565 	{
566 		gtk_list_box_set_placeholder(gtkListBox, (placeholder is null) ? null : placeholder.getWidgetStruct());
567 	}
568 
569 	/**
570 	 * Sets how selection works in the listbox.
571 	 *
572 	 * Params:
573 	 *     mode = The `GtkSelectionMode`
574 	 */
575 	public void setSelectionMode(GtkSelectionMode mode)
576 	{
577 		gtk_list_box_set_selection_mode(gtkListBox, mode);
578 	}
579 
580 	/**
581 	 * Sets whether the list box should show separators
582 	 * between rows.
583 	 *
584 	 * Params:
585 	 *     showSeparators = %TRUE to show separators
586 	 */
587 	public void setShowSeparators(bool showSeparators)
588 	{
589 		gtk_list_box_set_show_separators(gtkListBox, showSeparators);
590 	}
591 
592 	/**
593 	 * Sets a sort function.
594 	 *
595 	 * By setting a sort function on the @box one can dynamically reorder
596 	 * the rows of the list, based on the contents of the rows.
597 	 *
598 	 * The @sort_func will be called for each row after the call, and will
599 	 * continue to be called each time a row changes (via
600 	 * [method@Gtk.ListBoxRow.changed]) and when [method@Gtk.ListBox.invalidate_sort]
601 	 * is called.
602 	 *
603 	 * Note that using a sort function is incompatible with using a model
604 	 * (see [method@Gtk.ListBox.bind_model]).
605 	 *
606 	 * Params:
607 	 *     sortFunc = the sort function
608 	 *     userData = user data passed to @sort_func
609 	 *     destroy = destroy notifier for @user_data
610 	 */
611 	public void setSortFunc(GtkListBoxSortFunc sortFunc, void* userData, GDestroyNotify destroy)
612 	{
613 		gtk_list_box_set_sort_func(gtkListBox, sortFunc, userData, destroy);
614 	}
615 
616 	/**
617 	 * Unselect all children of @box, if the selection mode allows it.
618 	 */
619 	public void unselectAll()
620 	{
621 		gtk_list_box_unselect_all(gtkListBox);
622 	}
623 
624 	/**
625 	 * Unselects a single row of @box, if the selection mode allows it.
626 	 *
627 	 * Params:
628 	 *     row = the row to unselected
629 	 */
630 	public void unselectRow(ListBoxRow row)
631 	{
632 		gtk_list_box_unselect_row(gtkListBox, (row is null) ? null : row.getListBoxRowStruct());
633 	}
634 
635 	/** */
636 	gulong addOnActivateCursorRow(void delegate(ListBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
637 	{
638 		return Signals.connect(this, "activate-cursor-row", dlg, connectFlags ^ ConnectFlags.SWAPPED);
639 	}
640 
641 	/** */
642 	gulong addOnMoveCursor(void delegate(GtkMovementStep, int, bool, bool, ListBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
643 	{
644 		return Signals.connect(this, "move-cursor", dlg, connectFlags ^ ConnectFlags.SWAPPED);
645 	}
646 
647 	/**
648 	 * Emitted when a row has been activated by the user.
649 	 *
650 	 * Params:
651 	 *     row = the activated row
652 	 */
653 	gulong addOnRowActivated(void delegate(ListBoxRow, ListBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
654 	{
655 		return Signals.connect(this, "row-activated", dlg, connectFlags ^ ConnectFlags.SWAPPED);
656 	}
657 
658 	/**
659 	 * Emitted when a new row is selected, or (with a %NULL @row)
660 	 * when the selection is cleared.
661 	 *
662 	 * When the @box is using %GTK_SELECTION_MULTIPLE, this signal will not
663 	 * give you the full picture of selection changes, and you should use
664 	 * the [signal@Gtk.ListBox::selected-rows-changed] signal instead.
665 	 *
666 	 * Params:
667 	 *     row = the selected row
668 	 */
669 	gulong addOnRowSelected(void delegate(ListBoxRow, ListBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
670 	{
671 		return Signals.connect(this, "row-selected", dlg, connectFlags ^ ConnectFlags.SWAPPED);
672 	}
673 
674 	/**
675 	 * Emitted to select all children of the box, if the selection
676 	 * mode permits it.
677 	 *
678 	 * This is a [keybinding signal](class.SignalAction.html).
679 	 *
680 	 * The default binding for this signal is <kbd>Ctrl</kbd>-<kbd>a</kbd>.
681 	 */
682 	gulong addOnSelectAll(void delegate(ListBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
683 	{
684 		return Signals.connect(this, "select-all", dlg, connectFlags ^ ConnectFlags.SWAPPED);
685 	}
686 
687 	/**
688 	 * Emitted when the set of selected rows changes.
689 	 */
690 	gulong addOnSelectedRowsChanged(void delegate(ListBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
691 	{
692 		return Signals.connect(this, "selected-rows-changed", dlg, connectFlags ^ ConnectFlags.SWAPPED);
693 	}
694 
695 	/** */
696 	gulong addOnToggleCursorRow(void delegate(ListBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
697 	{
698 		return Signals.connect(this, "toggle-cursor-row", dlg, connectFlags ^ ConnectFlags.SWAPPED);
699 	}
700 
701 	/**
702 	 * Emitted to unselect all children of the box, if the selection
703 	 * mode permits it.
704 	 *
705 	 * This is a [keybinding signal](class.SignalAction.html).
706 	 *
707 	 * The default binding for this signal is
708 	 * <kbd>Ctrl</kbd>-<kbd>Shift</kbd>-<kbd>a</kbd>.
709 	 */
710 	gulong addOnUnselectAll(void delegate(ListBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
711 	{
712 		return Signals.connect(this, "unselect-all", dlg, connectFlags ^ ConnectFlags.SWAPPED);
713 	}
714 }