1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gtk.FlowBox; 26 27 private import gio.ListModelIF; 28 private import glib.ConstructionException; 29 private import glib.ListG; 30 private import gobject.ObjectG; 31 private import gobject.Signals; 32 private import gtk.Adjustment; 33 private import gtk.Container; 34 private import gtk.FlowBoxChild; 35 private import gtk.OrientableIF; 36 private import gtk.OrientableT; 37 private import gtk.Widget; 38 private import gtkc.gtk; 39 public import gtkc.gtktypes; 40 private import std.algorithm; 41 42 43 /** 44 * A GtkFlowBox positions child widgets in sequence according to its 45 * orientation. 46 * 47 * For instance, with the horizontal orientation, the widgets will be 48 * arranged from left to right, starting a new row under the previous 49 * row when necessary. Reducing the width in this case will require more 50 * rows, so a larger height will be requested. 51 * 52 * Likewise, with the vertical orientation, the widgets will be arranged 53 * from top to bottom, starting a new column to the right when necessary. 54 * Reducing the height will require more columns, so a larger width will 55 * be requested. 56 * 57 * The children of a GtkFlowBox can be dynamically sorted and filtered. 58 * 59 * Although a GtkFlowBox must have only #GtkFlowBoxChild children, 60 * you can add any kind of widget to it via gtk_container_add(), and 61 * a GtkFlowBoxChild widget will automatically be inserted between 62 * the box and the widget. 63 * 64 * Also see #GtkListBox. 65 * 66 * GtkFlowBox was added in GTK+ 3.12. 67 * 68 * # CSS nodes 69 * 70 * |[<!-- language="plain" --> 71 * flowbox 72 * ├── flowboxchild 73 * │ ╰── <child> 74 * ├── flowboxchild 75 * │ ╰── <child> 76 * ┊ 77 * ╰── [rubberband] 78 * ]| 79 * 80 * GtkFlowBox uses a single CSS node with name flowbox. GtkFlowBoxChild 81 * uses a single CSS node with name flowboxchild. 82 * For rubberband selection, a subnode with name rubberband is used. 83 */ 84 public class FlowBox : Container, OrientableIF 85 { 86 /** the main Gtk struct */ 87 protected GtkFlowBox* gtkFlowBox; 88 89 /** Get the main Gtk struct */ 90 public GtkFlowBox* getFlowBoxStruct() 91 { 92 return gtkFlowBox; 93 } 94 95 /** the main Gtk struct as a void* */ 96 protected override void* getStruct() 97 { 98 return cast(void*)gtkFlowBox; 99 } 100 101 protected override void setStruct(GObject* obj) 102 { 103 gtkFlowBox = cast(GtkFlowBox*)obj; 104 super.setStruct(obj); 105 } 106 107 /** 108 * Sets our main struct and passes it to the parent class. 109 */ 110 public this (GtkFlowBox* gtkFlowBox, bool ownedRef = false) 111 { 112 this.gtkFlowBox = gtkFlowBox; 113 super(cast(GtkContainer*)gtkFlowBox, ownedRef); 114 } 115 116 // add the Orientable capabilities 117 mixin OrientableT!(GtkFlowBox); 118 119 120 /** */ 121 public static GType getType() 122 { 123 return gtk_flow_box_get_type(); 124 } 125 126 /** 127 * Creates a GtkFlowBox. 128 * 129 * Returns: a new #GtkFlowBox container 130 * 131 * Since: 3.12 132 * 133 * Throws: ConstructionException GTK+ fails to create the object. 134 */ 135 public this() 136 { 137 auto p = gtk_flow_box_new(); 138 139 if(p is null) 140 { 141 throw new ConstructionException("null returned by new"); 142 } 143 144 this(cast(GtkFlowBox*) p); 145 } 146 147 /** 148 * Binds @model to @box. 149 * 150 * If @box was already bound to a model, that previous binding is 151 * destroyed. 152 * 153 * The contents of @box are cleared and then filled with widgets that 154 * represent items from @model. @box is updated whenever @model changes. 155 * If @model is %NULL, @box is left empty. 156 * 157 * It is undefined to add or remove widgets directly (for example, with 158 * gtk_flow_box_insert() or gtk_container_add()) while @box is bound to a 159 * model. 160 * 161 * Note that using a model is incompatible with the filtering and sorting 162 * functionality in GtkFlowBox. When using a model, filtering and sorting 163 * should be implemented by the model. 164 * 165 * Params: 166 * model = the #GListModel to be bound to @box 167 * createWidgetFunc = a function that creates widgets for items 168 * userData = user data passed to @create_widget_func 169 * userDataFreeFunc = function for freeing @user_data 170 * 171 * Since: 3.18 172 */ 173 public void bindModel(ListModelIF model, GtkFlowBoxCreateWidgetFunc createWidgetFunc, void* userData, GDestroyNotify userDataFreeFunc) 174 { 175 gtk_flow_box_bind_model(gtkFlowBox, (model is null) ? null : model.getListModelStruct(), createWidgetFunc, userData, userDataFreeFunc); 176 } 177 178 /** 179 * Returns whether children activate on single clicks. 180 * 181 * Returns: %TRUE if children are activated on single click, 182 * %FALSE otherwise 183 * 184 * Since: 3.12 185 */ 186 public bool getActivateOnSingleClick() 187 { 188 return gtk_flow_box_get_activate_on_single_click(gtkFlowBox) != 0; 189 } 190 191 /** 192 * Gets the nth child in the @box. 193 * 194 * Params: 195 * idx = the position of the child 196 * 197 * Returns: the child widget, which will 198 * always be a #GtkFlowBoxChild or %NULL in case no child widget 199 * with the given index exists. 200 * 201 * Since: 3.12 202 */ 203 public FlowBoxChild getChildAtIndex(int idx) 204 { 205 auto p = gtk_flow_box_get_child_at_index(gtkFlowBox, idx); 206 207 if(p is null) 208 { 209 return null; 210 } 211 212 return ObjectG.getDObject!(FlowBoxChild)(cast(GtkFlowBoxChild*) p); 213 } 214 215 /** 216 * Gets the child in the (@x, @y) position. 217 * 218 * Params: 219 * x = the x coordinate of the child 220 * y = the y coordinate of the child 221 * 222 * Returns: the child widget, which will 223 * always be a #GtkFlowBoxChild or %NULL in case no child widget 224 * exists for the given x and y coordinates. 225 * 226 * Since: 3.22.6 227 */ 228 public FlowBoxChild getChildAtPos(int x, int y) 229 { 230 auto p = gtk_flow_box_get_child_at_pos(gtkFlowBox, x, y); 231 232 if(p is null) 233 { 234 return null; 235 } 236 237 return ObjectG.getDObject!(FlowBoxChild)(cast(GtkFlowBoxChild*) p); 238 } 239 240 /** 241 * Gets the horizontal spacing. 242 * 243 * Returns: the horizontal spacing 244 * 245 * Since: 3.12 246 */ 247 public uint getColumnSpacing() 248 { 249 return gtk_flow_box_get_column_spacing(gtkFlowBox); 250 } 251 252 /** 253 * Returns whether the box is homogeneous (all children are the 254 * same size). See gtk_box_set_homogeneous(). 255 * 256 * Returns: %TRUE if the box is homogeneous. 257 * 258 * Since: 3.12 259 */ 260 public bool getHomogeneous() 261 { 262 return gtk_flow_box_get_homogeneous(gtkFlowBox) != 0; 263 } 264 265 /** 266 * Gets the maximum number of children per line. 267 * 268 * Returns: the maximum number of children per line 269 * 270 * Since: 3.12 271 */ 272 public uint getMaxChildrenPerLine() 273 { 274 return gtk_flow_box_get_max_children_per_line(gtkFlowBox); 275 } 276 277 /** 278 * Gets the minimum number of children per line. 279 * 280 * Returns: the minimum number of children per line 281 * 282 * Since: 3.12 283 */ 284 public uint getMinChildrenPerLine() 285 { 286 return gtk_flow_box_get_min_children_per_line(gtkFlowBox); 287 } 288 289 /** 290 * Gets the vertical spacing. 291 * 292 * Returns: the vertical spacing 293 * 294 * Since: 3.12 295 */ 296 public uint getRowSpacing() 297 { 298 return gtk_flow_box_get_row_spacing(gtkFlowBox); 299 } 300 301 /** 302 * Creates a list of all selected children. 303 * 304 * Returns: A #GList containing the #GtkWidget for each selected child. 305 * Free with g_list_free() when done. 306 * 307 * Since: 3.12 308 */ 309 public ListG getSelectedChildren() 310 { 311 auto p = gtk_flow_box_get_selected_children(gtkFlowBox); 312 313 if(p is null) 314 { 315 return null; 316 } 317 318 return new ListG(cast(GList*) p); 319 } 320 321 /** 322 * Gets the selection mode of @box. 323 * 324 * Returns: the #GtkSelectionMode 325 * 326 * Since: 3.12 327 */ 328 public GtkSelectionMode getSelectionMode() 329 { 330 return gtk_flow_box_get_selection_mode(gtkFlowBox); 331 } 332 333 /** 334 * Inserts the @widget into @box at @position. 335 * 336 * If a sort function is set, the widget will actually be inserted 337 * at the calculated position and this function has the same effect 338 * as gtk_container_add(). 339 * 340 * If @position is -1, or larger than the total number of children 341 * in the @box, then the @widget will be appended to the end. 342 * 343 * Params: 344 * widget = the #GtkWidget to add 345 * position = the position to insert @child in 346 * 347 * Since: 3.12 348 */ 349 public void insert(Widget widget, int position) 350 { 351 gtk_flow_box_insert(gtkFlowBox, (widget is null) ? null : widget.getWidgetStruct(), position); 352 } 353 354 /** 355 * Updates the filtering for all children. 356 * 357 * Call this function when the result of the filter 358 * function on the @box is changed due ot an external 359 * factor. For instance, this would be used if the 360 * filter function just looked for a specific search 361 * term, and the entry with the string has changed. 362 * 363 * Since: 3.12 364 */ 365 public void invalidateFilter() 366 { 367 gtk_flow_box_invalidate_filter(gtkFlowBox); 368 } 369 370 /** 371 * Updates the sorting for all children. 372 * 373 * Call this when the result of the sort function on 374 * @box is changed due to an external factor. 375 * 376 * Since: 3.12 377 */ 378 public void invalidateSort() 379 { 380 gtk_flow_box_invalidate_sort(gtkFlowBox); 381 } 382 383 /** 384 * Select all children of @box, if the selection 385 * mode allows it. 386 * 387 * Since: 3.12 388 */ 389 public void selectAll() 390 { 391 gtk_flow_box_select_all(gtkFlowBox); 392 } 393 394 /** 395 * Selects a single child of @box, if the selection 396 * mode allows it. 397 * 398 * Params: 399 * child = a child of @box 400 * 401 * Since: 3.12 402 */ 403 public void selectChild(FlowBoxChild child) 404 { 405 gtk_flow_box_select_child(gtkFlowBox, (child is null) ? null : child.getFlowBoxChildStruct()); 406 } 407 408 /** 409 * Calls a function for each selected child. 410 * 411 * Note that the selection cannot be modified from within 412 * 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.12 419 */ 420 public void selectedForeach(GtkFlowBoxForeachFunc func, void* data) 421 { 422 gtk_flow_box_selected_foreach(gtkFlowBox, func, data); 423 } 424 425 /** 426 * If @single is %TRUE, children will be activated when you click 427 * on them, otherwise you need to double-click. 428 * 429 * Params: 430 * single = %TRUE to emit child-activated on a single click 431 * 432 * Since: 3.12 433 */ 434 public void setActivateOnSingleClick(bool single) 435 { 436 gtk_flow_box_set_activate_on_single_click(gtkFlowBox, single); 437 } 438 439 /** 440 * Sets the horizontal space to add between children. 441 * See the #GtkFlowBox:column-spacing property. 442 * 443 * Params: 444 * spacing = the spacing to use 445 * 446 * Since: 3.12 447 */ 448 public void setColumnSpacing(uint spacing) 449 { 450 gtk_flow_box_set_column_spacing(gtkFlowBox, spacing); 451 } 452 453 /** 454 * By setting a filter function on the @box one can decide dynamically 455 * which of the children to show. For instance, to implement a search 456 * function that only shows the children matching the search terms. 457 * 458 * The @filter_func will be called for each child after the call, and 459 * it will continue to be called each time a child changes (via 460 * gtk_flow_box_child_changed()) or when gtk_flow_box_invalidate_filter() 461 * is called. 462 * 463 * Note that using a filter function is incompatible with using a model 464 * (see gtk_flow_box_bind_model()). 465 * 466 * Params: 467 * filterFunc = callback that 468 * lets you filter which children to show 469 * userData = user data passed to @filter_func 470 * destroy = destroy notifier for @user_data 471 * 472 * Since: 3.12 473 */ 474 public void setFilterFunc(GtkFlowBoxFilterFunc filterFunc, void* userData, GDestroyNotify destroy) 475 { 476 gtk_flow_box_set_filter_func(gtkFlowBox, filterFunc, userData, destroy); 477 } 478 479 /** 480 * Hooks up an adjustment to focus handling in @box. 481 * The adjustment is also used for autoscrolling during 482 * rubberband selection. See gtk_scrolled_window_get_hadjustment() 483 * for a typical way of obtaining the adjustment, and 484 * gtk_flow_box_set_vadjustment()for setting the vertical 485 * adjustment. 486 * 487 * The adjustments have to be in pixel units and in the same 488 * coordinate system as the allocation for immediate children 489 * of the box. 490 * 491 * Params: 492 * adjustment = an adjustment which should be adjusted 493 * when the focus is moved among the descendents of @container 494 * 495 * Since: 3.12 496 */ 497 public void setHadjustment(Adjustment adjustment) 498 { 499 gtk_flow_box_set_hadjustment(gtkFlowBox, (adjustment is null) ? null : adjustment.getAdjustmentStruct()); 500 } 501 502 /** 503 * Sets the #GtkFlowBox:homogeneous property of @box, controlling 504 * whether or not all children of @box are given equal space 505 * in the box. 506 * 507 * Params: 508 * homogeneous = %TRUE to create equal allotments, 509 * %FALSE for variable allotments 510 * 511 * Since: 3.12 512 */ 513 public void setHomogeneous(bool homogeneous) 514 { 515 gtk_flow_box_set_homogeneous(gtkFlowBox, homogeneous); 516 } 517 518 /** 519 * Sets the maximum number of children to request and 520 * allocate space for in @box’s orientation. 521 * 522 * Setting the maximum number of children per line 523 * limits the overall natural size request to be no more 524 * than @n_children children long in the given orientation. 525 * 526 * Params: 527 * nChildren = the maximum number of children per line 528 * 529 * Since: 3.12 530 */ 531 public void setMaxChildrenPerLine(uint nChildren) 532 { 533 gtk_flow_box_set_max_children_per_line(gtkFlowBox, nChildren); 534 } 535 536 /** 537 * Sets the minimum number of children to line up 538 * in @box’s orientation before flowing. 539 * 540 * Params: 541 * nChildren = the minimum number of children per line 542 * 543 * Since: 3.12 544 */ 545 public void setMinChildrenPerLine(uint nChildren) 546 { 547 gtk_flow_box_set_min_children_per_line(gtkFlowBox, nChildren); 548 } 549 550 /** 551 * Sets the vertical space to add between children. 552 * See the #GtkFlowBox:row-spacing property. 553 * 554 * Params: 555 * spacing = the spacing to use 556 * 557 * Since: 3.12 558 */ 559 public void setRowSpacing(uint spacing) 560 { 561 gtk_flow_box_set_row_spacing(gtkFlowBox, spacing); 562 } 563 564 /** 565 * Sets how selection works in @box. 566 * See #GtkSelectionMode for details. 567 * 568 * Params: 569 * mode = the new selection mode 570 * 571 * Since: 3.12 572 */ 573 public void setSelectionMode(GtkSelectionMode mode) 574 { 575 gtk_flow_box_set_selection_mode(gtkFlowBox, mode); 576 } 577 578 /** 579 * By setting a sort function on the @box, one can dynamically 580 * reorder the children of the box, based on the contents of 581 * the children. 582 * 583 * The @sort_func will be called for each child after the call, 584 * and will continue to be called each time a child changes (via 585 * gtk_flow_box_child_changed()) and when gtk_flow_box_invalidate_sort() 586 * is called. 587 * 588 * Note that using a sort function is incompatible with using a model 589 * (see gtk_flow_box_bind_model()). 590 * 591 * Params: 592 * sortFunc = the sort function 593 * userData = user data passed to @sort_func 594 * destroy = destroy notifier for @user_data 595 * 596 * Since: 3.12 597 */ 598 public void setSortFunc(GtkFlowBoxSortFunc sortFunc, void* userData, GDestroyNotify destroy) 599 { 600 gtk_flow_box_set_sort_func(gtkFlowBox, sortFunc, userData, destroy); 601 } 602 603 /** 604 * Hooks up an adjustment to focus handling in @box. 605 * The adjustment is also used for autoscrolling during 606 * rubberband selection. See gtk_scrolled_window_get_vadjustment() 607 * for a typical way of obtaining the adjustment, and 608 * gtk_flow_box_set_hadjustment()for setting the horizontal 609 * adjustment. 610 * 611 * The adjustments have to be in pixel units and in the same 612 * coordinate system as the allocation for immediate children 613 * of the box. 614 * 615 * Params: 616 * adjustment = an adjustment which should be adjusted 617 * when the focus is moved among the descendents of @container 618 * 619 * Since: 3.12 620 */ 621 public void setVadjustment(Adjustment adjustment) 622 { 623 gtk_flow_box_set_vadjustment(gtkFlowBox, (adjustment is null) ? null : adjustment.getAdjustmentStruct()); 624 } 625 626 /** 627 * Unselect all children of @box, if the selection 628 * mode allows it. 629 * 630 * Since: 3.12 631 */ 632 public void unselectAll() 633 { 634 gtk_flow_box_unselect_all(gtkFlowBox); 635 } 636 637 /** 638 * Unselects a single child of @box, if the selection 639 * mode allows it. 640 * 641 * Params: 642 * child = a child of @box 643 * 644 * Since: 3.12 645 */ 646 public void unselectChild(FlowBoxChild child) 647 { 648 gtk_flow_box_unselect_child(gtkFlowBox, (child is null) ? null : child.getFlowBoxChildStruct()); 649 } 650 651 protected class OnActivateCursorChildDelegateWrapper 652 { 653 static OnActivateCursorChildDelegateWrapper[] listeners; 654 void delegate(FlowBox) dlg; 655 gulong handlerId; 656 657 this(void delegate(FlowBox) dlg) 658 { 659 this.dlg = dlg; 660 this.listeners ~= this; 661 } 662 663 void remove(OnActivateCursorChildDelegateWrapper source) 664 { 665 foreach(index, wrapper; listeners) 666 { 667 if (wrapper.handlerId == source.handlerId) 668 { 669 listeners[index] = null; 670 listeners = std.algorithm.remove(listeners, index); 671 break; 672 } 673 } 674 } 675 } 676 677 /** 678 * The ::activate-cursor-child signal is a 679 * [keybinding signal][GtkBindingSignal] 680 * which gets emitted when the user activates the @box. 681 */ 682 gulong addOnActivateCursorChild(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 683 { 684 auto wrapper = new OnActivateCursorChildDelegateWrapper(dlg); 685 wrapper.handlerId = Signals.connectData( 686 this, 687 "activate-cursor-child", 688 cast(GCallback)&callBackActivateCursorChild, 689 cast(void*)wrapper, 690 cast(GClosureNotify)&callBackActivateCursorChildDestroy, 691 connectFlags); 692 return wrapper.handlerId; 693 } 694 695 extern(C) static void callBackActivateCursorChild(GtkFlowBox* flowboxStruct, OnActivateCursorChildDelegateWrapper wrapper) 696 { 697 wrapper.dlg(wrapper.outer); 698 } 699 700 extern(C) static void callBackActivateCursorChildDestroy(OnActivateCursorChildDelegateWrapper wrapper, GClosure* closure) 701 { 702 wrapper.remove(wrapper); 703 } 704 705 protected class OnChildActivatedDelegateWrapper 706 { 707 static OnChildActivatedDelegateWrapper[] listeners; 708 void delegate(FlowBoxChild, FlowBox) dlg; 709 gulong handlerId; 710 711 this(void delegate(FlowBoxChild, FlowBox) dlg) 712 { 713 this.dlg = dlg; 714 this.listeners ~= this; 715 } 716 717 void remove(OnChildActivatedDelegateWrapper source) 718 { 719 foreach(index, wrapper; listeners) 720 { 721 if (wrapper.handlerId == source.handlerId) 722 { 723 listeners[index] = null; 724 listeners = std.algorithm.remove(listeners, index); 725 break; 726 } 727 } 728 } 729 } 730 731 /** 732 * The ::child-activated signal is emitted when a child has been 733 * activated by the user. 734 * 735 * Params: 736 * child = the child that is activated 737 */ 738 gulong addOnChildActivated(void delegate(FlowBoxChild, FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 739 { 740 auto wrapper = new OnChildActivatedDelegateWrapper(dlg); 741 wrapper.handlerId = Signals.connectData( 742 this, 743 "child-activated", 744 cast(GCallback)&callBackChildActivated, 745 cast(void*)wrapper, 746 cast(GClosureNotify)&callBackChildActivatedDestroy, 747 connectFlags); 748 return wrapper.handlerId; 749 } 750 751 extern(C) static void callBackChildActivated(GtkFlowBox* flowboxStruct, GtkFlowBoxChild* child, OnChildActivatedDelegateWrapper wrapper) 752 { 753 wrapper.dlg(ObjectG.getDObject!(FlowBoxChild)(child), wrapper.outer); 754 } 755 756 extern(C) static void callBackChildActivatedDestroy(OnChildActivatedDelegateWrapper wrapper, GClosure* closure) 757 { 758 wrapper.remove(wrapper); 759 } 760 761 protected class OnMoveCursorDelegateWrapper 762 { 763 static OnMoveCursorDelegateWrapper[] listeners; 764 bool delegate(GtkMovementStep, int, FlowBox) dlg; 765 gulong handlerId; 766 767 this(bool delegate(GtkMovementStep, int, FlowBox) dlg) 768 { 769 this.dlg = dlg; 770 this.listeners ~= this; 771 } 772 773 void remove(OnMoveCursorDelegateWrapper source) 774 { 775 foreach(index, wrapper; listeners) 776 { 777 if (wrapper.handlerId == source.handlerId) 778 { 779 listeners[index] = null; 780 listeners = std.algorithm.remove(listeners, index); 781 break; 782 } 783 } 784 } 785 } 786 787 /** 788 * The ::move-cursor signal is a 789 * [keybinding signal][GtkBindingSignal] 790 * which gets emitted when the user initiates a cursor movement. 791 * 792 * Applications should not connect to it, but may emit it with 793 * g_signal_emit_by_name() if they need to control the cursor 794 * programmatically. 795 * 796 * The default bindings for this signal come in two variants, 797 * the variant with the Shift modifier extends the selection, 798 * the variant without the Shift modifer does not. 799 * There are too many key combinations to list them all here. 800 * - Arrow keys move by individual children 801 * - Home/End keys move to the ends of the box 802 * - PageUp/PageDown keys move vertically by pages 803 * 804 * Params: 805 * step = the granularity fo the move, as a #GtkMovementStep 806 * count = the number of @step units to move 807 * 808 * Returns: %TRUE to stop other handlers from being invoked for the event. 809 * %FALSE to propagate the event further. 810 */ 811 gulong addOnMoveCursor(bool delegate(GtkMovementStep, int, FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 812 { 813 auto wrapper = new OnMoveCursorDelegateWrapper(dlg); 814 wrapper.handlerId = Signals.connectData( 815 this, 816 "move-cursor", 817 cast(GCallback)&callBackMoveCursor, 818 cast(void*)wrapper, 819 cast(GClosureNotify)&callBackMoveCursorDestroy, 820 connectFlags); 821 return wrapper.handlerId; 822 } 823 824 extern(C) static int callBackMoveCursor(GtkFlowBox* flowboxStruct, GtkMovementStep step, int count, OnMoveCursorDelegateWrapper wrapper) 825 { 826 return wrapper.dlg(step, count, wrapper.outer); 827 } 828 829 extern(C) static void callBackMoveCursorDestroy(OnMoveCursorDelegateWrapper wrapper, GClosure* closure) 830 { 831 wrapper.remove(wrapper); 832 } 833 834 protected class OnSelectAllDelegateWrapper 835 { 836 static OnSelectAllDelegateWrapper[] listeners; 837 void delegate(FlowBox) dlg; 838 gulong handlerId; 839 840 this(void delegate(FlowBox) dlg) 841 { 842 this.dlg = dlg; 843 this.listeners ~= this; 844 } 845 846 void remove(OnSelectAllDelegateWrapper source) 847 { 848 foreach(index, wrapper; listeners) 849 { 850 if (wrapper.handlerId == source.handlerId) 851 { 852 listeners[index] = null; 853 listeners = std.algorithm.remove(listeners, index); 854 break; 855 } 856 } 857 } 858 } 859 860 /** 861 * The ::select-all signal is a 862 * [keybinding signal][GtkBindingSignal] 863 * which gets emitted to select all children of the box, if 864 * the selection mode permits it. 865 * 866 * The default bindings for this signal is Ctrl-a. 867 */ 868 gulong addOnSelectAll(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 869 { 870 auto wrapper = new OnSelectAllDelegateWrapper(dlg); 871 wrapper.handlerId = Signals.connectData( 872 this, 873 "select-all", 874 cast(GCallback)&callBackSelectAll, 875 cast(void*)wrapper, 876 cast(GClosureNotify)&callBackSelectAllDestroy, 877 connectFlags); 878 return wrapper.handlerId; 879 } 880 881 extern(C) static void callBackSelectAll(GtkFlowBox* flowboxStruct, OnSelectAllDelegateWrapper wrapper) 882 { 883 wrapper.dlg(wrapper.outer); 884 } 885 886 extern(C) static void callBackSelectAllDestroy(OnSelectAllDelegateWrapper wrapper, GClosure* closure) 887 { 888 wrapper.remove(wrapper); 889 } 890 891 protected class OnSelectedChildrenChangedDelegateWrapper 892 { 893 static OnSelectedChildrenChangedDelegateWrapper[] listeners; 894 void delegate(FlowBox) dlg; 895 gulong handlerId; 896 897 this(void delegate(FlowBox) dlg) 898 { 899 this.dlg = dlg; 900 this.listeners ~= this; 901 } 902 903 void remove(OnSelectedChildrenChangedDelegateWrapper source) 904 { 905 foreach(index, wrapper; listeners) 906 { 907 if (wrapper.handlerId == source.handlerId) 908 { 909 listeners[index] = null; 910 listeners = std.algorithm.remove(listeners, index); 911 break; 912 } 913 } 914 } 915 } 916 917 /** 918 * The ::selected-children-changed signal is emitted when the 919 * set of selected children changes. 920 * 921 * Use gtk_flow_box_selected_foreach() or 922 * gtk_flow_box_get_selected_children() to obtain the 923 * selected children. 924 */ 925 gulong addOnSelectedChildrenChanged(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 926 { 927 auto wrapper = new OnSelectedChildrenChangedDelegateWrapper(dlg); 928 wrapper.handlerId = Signals.connectData( 929 this, 930 "selected-children-changed", 931 cast(GCallback)&callBackSelectedChildrenChanged, 932 cast(void*)wrapper, 933 cast(GClosureNotify)&callBackSelectedChildrenChangedDestroy, 934 connectFlags); 935 return wrapper.handlerId; 936 } 937 938 extern(C) static void callBackSelectedChildrenChanged(GtkFlowBox* flowboxStruct, OnSelectedChildrenChangedDelegateWrapper wrapper) 939 { 940 wrapper.dlg(wrapper.outer); 941 } 942 943 extern(C) static void callBackSelectedChildrenChangedDestroy(OnSelectedChildrenChangedDelegateWrapper wrapper, GClosure* closure) 944 { 945 wrapper.remove(wrapper); 946 } 947 948 protected class OnToggleCursorChildDelegateWrapper 949 { 950 static OnToggleCursorChildDelegateWrapper[] listeners; 951 void delegate(FlowBox) dlg; 952 gulong handlerId; 953 954 this(void delegate(FlowBox) dlg) 955 { 956 this.dlg = dlg; 957 this.listeners ~= this; 958 } 959 960 void remove(OnToggleCursorChildDelegateWrapper source) 961 { 962 foreach(index, wrapper; listeners) 963 { 964 if (wrapper.handlerId == source.handlerId) 965 { 966 listeners[index] = null; 967 listeners = std.algorithm.remove(listeners, index); 968 break; 969 } 970 } 971 } 972 } 973 974 /** 975 * The ::toggle-cursor-child signal is a 976 * [keybinding signal][GtkBindingSignal] 977 * which toggles the selection of the child that has the focus. 978 * 979 * The default binding for this signal is Ctrl-Space. 980 */ 981 gulong addOnToggleCursorChild(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 982 { 983 auto wrapper = new OnToggleCursorChildDelegateWrapper(dlg); 984 wrapper.handlerId = Signals.connectData( 985 this, 986 "toggle-cursor-child", 987 cast(GCallback)&callBackToggleCursorChild, 988 cast(void*)wrapper, 989 cast(GClosureNotify)&callBackToggleCursorChildDestroy, 990 connectFlags); 991 return wrapper.handlerId; 992 } 993 994 extern(C) static void callBackToggleCursorChild(GtkFlowBox* flowboxStruct, OnToggleCursorChildDelegateWrapper wrapper) 995 { 996 wrapper.dlg(wrapper.outer); 997 } 998 999 extern(C) static void callBackToggleCursorChildDestroy(OnToggleCursorChildDelegateWrapper wrapper, GClosure* closure) 1000 { 1001 wrapper.remove(wrapper); 1002 } 1003 1004 protected class OnUnselectAllDelegateWrapper 1005 { 1006 static OnUnselectAllDelegateWrapper[] listeners; 1007 void delegate(FlowBox) dlg; 1008 gulong handlerId; 1009 1010 this(void delegate(FlowBox) dlg) 1011 { 1012 this.dlg = dlg; 1013 this.listeners ~= this; 1014 } 1015 1016 void remove(OnUnselectAllDelegateWrapper source) 1017 { 1018 foreach(index, wrapper; listeners) 1019 { 1020 if (wrapper.handlerId == source.handlerId) 1021 { 1022 listeners[index] = null; 1023 listeners = std.algorithm.remove(listeners, index); 1024 break; 1025 } 1026 } 1027 } 1028 } 1029 1030 /** 1031 * The ::unselect-all signal is a 1032 * [keybinding signal][GtkBindingSignal] 1033 * which gets emitted to unselect all children of the box, if 1034 * the selection mode permits it. 1035 * 1036 * The default bindings for this signal is Ctrl-Shift-a. 1037 */ 1038 gulong addOnUnselectAll(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1039 { 1040 auto wrapper = new OnUnselectAllDelegateWrapper(dlg); 1041 wrapper.handlerId = Signals.connectData( 1042 this, 1043 "unselect-all", 1044 cast(GCallback)&callBackUnselectAll, 1045 cast(void*)wrapper, 1046 cast(GClosureNotify)&callBackUnselectAllDestroy, 1047 connectFlags); 1048 return wrapper.handlerId; 1049 } 1050 1051 extern(C) static void callBackUnselectAll(GtkFlowBox* flowboxStruct, OnUnselectAllDelegateWrapper wrapper) 1052 { 1053 wrapper.dlg(wrapper.outer); 1054 } 1055 1056 extern(C) static void callBackUnselectAllDestroy(OnUnselectAllDelegateWrapper wrapper, GClosure* closure) 1057 { 1058 wrapper.remove(wrapper); 1059 } 1060 }