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