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 }