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