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 gtk.c.functions; 39 public import gtk.c.types; 40 public import gtkc.gtktypes; 41 private import std.algorithm; 42 43 44 /** 45 * A GtkFlowBox positions child widgets in sequence according to its 46 * orientation. 47 * 48 * For instance, with the horizontal orientation, the widgets will be 49 * arranged from left to right, starting a new row under the previous 50 * row when necessary. Reducing the width in this case will require more 51 * rows, so a larger height will be requested. 52 * 53 * Likewise, with the vertical orientation, the widgets will be arranged 54 * from top to bottom, starting a new column to the right when necessary. 55 * Reducing the height will require more columns, so a larger width will 56 * be requested. 57 * 58 * The size request of a GtkFlowBox alone may not be what you expect; if you 59 * need to be able to shrink it along both axes and dynamically reflow its 60 * children, you may have to wrap it in a #GtkScrolledWindow to enable that. 61 * 62 * The children of a GtkFlowBox can be dynamically sorted and filtered. 63 * 64 * Although a GtkFlowBox must have only #GtkFlowBoxChild children, 65 * you can add any kind of widget to it via gtk_container_add(), and 66 * a GtkFlowBoxChild widget will automatically be inserted between 67 * the box and the widget. 68 * 69 * Also see #GtkListBox. 70 * 71 * GtkFlowBox was added in GTK+ 3.12. 72 * 73 * # CSS nodes 74 * 75 * |[<!-- language="plain" --> 76 * flowbox 77 * ├── flowboxchild 78 * │ ╰── <child> 79 * ├── flowboxchild 80 * │ ╰── <child> 81 * ┊ 82 * ╰── [rubberband] 83 * ]| 84 * 85 * GtkFlowBox uses a single CSS node with name flowbox. GtkFlowBoxChild 86 * uses a single CSS node with name flowboxchild. 87 * For rubberband selection, a subnode with name rubberband is used. 88 */ 89 public class FlowBox : Container, OrientableIF 90 { 91 /** the main Gtk struct */ 92 protected GtkFlowBox* gtkFlowBox; 93 94 /** Get the main Gtk struct */ 95 public GtkFlowBox* getFlowBoxStruct(bool transferOwnership = false) 96 { 97 if (transferOwnership) 98 ownedRef = false; 99 return gtkFlowBox; 100 } 101 102 /** the main Gtk struct as a void* */ 103 protected override void* getStruct() 104 { 105 return cast(void*)gtkFlowBox; 106 } 107 108 /** 109 * Sets our main struct and passes it to the parent class. 110 */ 111 public this (GtkFlowBox* gtkFlowBox, bool ownedRef = false) 112 { 113 this.gtkFlowBox = gtkFlowBox; 114 super(cast(GtkContainer*)gtkFlowBox, ownedRef); 115 } 116 117 // add the Orientable capabilities 118 mixin OrientableT!(GtkFlowBox); 119 120 121 /** */ 122 public static GType getType() 123 { 124 return gtk_flow_box_get_type(); 125 } 126 127 /** 128 * Creates a GtkFlowBox. 129 * 130 * Returns: a new #GtkFlowBox container 131 * 132 * Since: 3.12 133 * 134 * Throws: ConstructionException GTK+ fails to create the object. 135 */ 136 public this() 137 { 138 auto p = gtk_flow_box_new(); 139 140 if(p is null) 141 { 142 throw new ConstructionException("null returned by new"); 143 } 144 145 this(cast(GtkFlowBox*) p); 146 } 147 148 /** 149 * Binds @model to @box. 150 * 151 * If @box was already bound to a model, that previous binding is 152 * destroyed. 153 * 154 * The contents of @box are cleared and then filled with widgets that 155 * represent items from @model. @box is updated whenever @model changes. 156 * If @model is %NULL, @box is left empty. 157 * 158 * It is undefined to add or remove widgets directly (for example, with 159 * gtk_flow_box_insert() or gtk_container_add()) while @box is bound to a 160 * model. 161 * 162 * Note that using a model is incompatible with the filtering and sorting 163 * functionality in GtkFlowBox. When using a model, filtering and sorting 164 * should be implemented by the model. 165 * 166 * Params: 167 * model = the #GListModel to be bound to @box 168 * createWidgetFunc = a function that creates widgets for items 169 * userData = user data passed to @create_widget_func 170 * userDataFreeFunc = function for freeing @user_data 171 * 172 * Since: 3.18 173 */ 174 public void bindModel(ListModelIF model, GtkFlowBoxCreateWidgetFunc createWidgetFunc, void* userData, GDestroyNotify userDataFreeFunc) 175 { 176 gtk_flow_box_bind_model(gtkFlowBox, (model is null) ? null : model.getListModelStruct(), createWidgetFunc, userData, userDataFreeFunc); 177 } 178 179 /** 180 * Returns whether children activate on single clicks. 181 * 182 * Returns: %TRUE if children are activated on single click, 183 * %FALSE otherwise 184 * 185 * Since: 3.12 186 */ 187 public bool getActivateOnSingleClick() 188 { 189 return gtk_flow_box_get_activate_on_single_click(gtkFlowBox) != 0; 190 } 191 192 /** 193 * Gets the nth child in the @box. 194 * 195 * Params: 196 * idx = the position of the child 197 * 198 * Returns: the child widget, which will 199 * always be a #GtkFlowBoxChild or %NULL in case no child widget 200 * with the given index exists. 201 * 202 * Since: 3.12 203 */ 204 public FlowBoxChild getChildAtIndex(int idx) 205 { 206 auto p = gtk_flow_box_get_child_at_index(gtkFlowBox, idx); 207 208 if(p is null) 209 { 210 return null; 211 } 212 213 return ObjectG.getDObject!(FlowBoxChild)(cast(GtkFlowBoxChild*) p); 214 } 215 216 /** 217 * Gets the child in the (@x, @y) position. 218 * 219 * Params: 220 * x = the x coordinate of the child 221 * y = the y coordinate of the child 222 * 223 * Returns: the child widget, which will 224 * always be a #GtkFlowBoxChild or %NULL in case no child widget 225 * exists for the given x and y coordinates. 226 * 227 * Since: 3.22.6 228 */ 229 public FlowBoxChild getChildAtPos(int x, int y) 230 { 231 auto p = gtk_flow_box_get_child_at_pos(gtkFlowBox, x, y); 232 233 if(p is null) 234 { 235 return null; 236 } 237 238 return ObjectG.getDObject!(FlowBoxChild)(cast(GtkFlowBoxChild*) p); 239 } 240 241 /** 242 * Gets the horizontal spacing. 243 * 244 * Returns: the horizontal spacing 245 * 246 * Since: 3.12 247 */ 248 public uint getColumnSpacing() 249 { 250 return gtk_flow_box_get_column_spacing(gtkFlowBox); 251 } 252 253 /** 254 * Returns whether the box is homogeneous (all children are the 255 * same size). See gtk_box_set_homogeneous(). 256 * 257 * Returns: %TRUE if the box is homogeneous. 258 * 259 * Since: 3.12 260 */ 261 public bool getHomogeneous() 262 { 263 return gtk_flow_box_get_homogeneous(gtkFlowBox) != 0; 264 } 265 266 /** 267 * Gets the maximum number of children per line. 268 * 269 * Returns: the maximum number of children per line 270 * 271 * Since: 3.12 272 */ 273 public uint getMaxChildrenPerLine() 274 { 275 return gtk_flow_box_get_max_children_per_line(gtkFlowBox); 276 } 277 278 /** 279 * Gets the minimum number of children per line. 280 * 281 * Returns: the minimum number of children per line 282 * 283 * Since: 3.12 284 */ 285 public uint getMinChildrenPerLine() 286 { 287 return gtk_flow_box_get_min_children_per_line(gtkFlowBox); 288 } 289 290 /** 291 * Gets the vertical spacing. 292 * 293 * Returns: the vertical spacing 294 * 295 * Since: 3.12 296 */ 297 public uint getRowSpacing() 298 { 299 return gtk_flow_box_get_row_spacing(gtkFlowBox); 300 } 301 302 /** 303 * Creates a list of all selected children. 304 * 305 * Returns: A #GList containing the #GtkWidget for each selected child. 306 * Free with g_list_free() when done. 307 * 308 * Since: 3.12 309 */ 310 public ListG getSelectedChildren() 311 { 312 auto p = gtk_flow_box_get_selected_children(gtkFlowBox); 313 314 if(p is null) 315 { 316 return null; 317 } 318 319 return new ListG(cast(GList*) p); 320 } 321 322 /** 323 * Gets the selection mode of @box. 324 * 325 * Returns: the #GtkSelectionMode 326 * 327 * Since: 3.12 328 */ 329 public GtkSelectionMode getSelectionMode() 330 { 331 return gtk_flow_box_get_selection_mode(gtkFlowBox); 332 } 333 334 /** 335 * Inserts the @widget into @box at @position. 336 * 337 * If a sort function is set, the widget will actually be inserted 338 * at the calculated position and this function has the same effect 339 * as gtk_container_add(). 340 * 341 * If @position is -1, or larger than the total number of children 342 * in the @box, then the @widget will be appended to the end. 343 * 344 * Params: 345 * widget = the #GtkWidget to add 346 * position = the position to insert @child in 347 * 348 * Since: 3.12 349 */ 350 public void insert(Widget widget, int position) 351 { 352 gtk_flow_box_insert(gtkFlowBox, (widget is null) ? null : widget.getWidgetStruct(), position); 353 } 354 355 /** 356 * Updates the filtering for all children. 357 * 358 * Call this function when the result of the filter 359 * function on the @box is changed due ot an external 360 * factor. For instance, this would be used if the 361 * filter function just looked for a specific search 362 * term, and the entry with the string has changed. 363 * 364 * Since: 3.12 365 */ 366 public void invalidateFilter() 367 { 368 gtk_flow_box_invalidate_filter(gtkFlowBox); 369 } 370 371 /** 372 * Updates the sorting for all children. 373 * 374 * Call this when the result of the sort function on 375 * @box is changed due to an external factor. 376 * 377 * Since: 3.12 378 */ 379 public void invalidateSort() 380 { 381 gtk_flow_box_invalidate_sort(gtkFlowBox); 382 } 383 384 /** 385 * Select all children of @box, if the selection 386 * mode allows it. 387 * 388 * Since: 3.12 389 */ 390 public void selectAll() 391 { 392 gtk_flow_box_select_all(gtkFlowBox); 393 } 394 395 /** 396 * Selects a single child of @box, if the selection 397 * mode allows it. 398 * 399 * Params: 400 * child = a child of @box 401 * 402 * Since: 3.12 403 */ 404 public void selectChild(FlowBoxChild child) 405 { 406 gtk_flow_box_select_child(gtkFlowBox, (child is null) ? null : child.getFlowBoxChildStruct()); 407 } 408 409 /** 410 * Calls a function for each selected child. 411 * 412 * Note that the selection cannot be modified from within 413 * this function. 414 * 415 * Params: 416 * func = the function to call for each selected child 417 * data = user data to pass to the function 418 * 419 * Since: 3.12 420 */ 421 public void selectedForeach(GtkFlowBoxForeachFunc func, void* data) 422 { 423 gtk_flow_box_selected_foreach(gtkFlowBox, func, data); 424 } 425 426 /** 427 * If @single is %TRUE, children will be activated when you click 428 * on them, otherwise you need to double-click. 429 * 430 * Params: 431 * single = %TRUE to emit child-activated on a single click 432 * 433 * Since: 3.12 434 */ 435 public void setActivateOnSingleClick(bool single) 436 { 437 gtk_flow_box_set_activate_on_single_click(gtkFlowBox, single); 438 } 439 440 /** 441 * Sets the horizontal space to add between children. 442 * See the #GtkFlowBox:column-spacing property. 443 * 444 * Params: 445 * spacing = the spacing to use 446 * 447 * Since: 3.12 448 */ 449 public void setColumnSpacing(uint spacing) 450 { 451 gtk_flow_box_set_column_spacing(gtkFlowBox, spacing); 452 } 453 454 /** 455 * By setting a filter function on the @box one can decide dynamically 456 * which of the children to show. For instance, to implement a search 457 * function that only shows the children matching the search terms. 458 * 459 * The @filter_func will be called for each child after the call, and 460 * it will continue to be called each time a child changes (via 461 * gtk_flow_box_child_changed()) or when gtk_flow_box_invalidate_filter() 462 * is called. 463 * 464 * Note that using a filter function is incompatible with using a model 465 * (see gtk_flow_box_bind_model()). 466 * 467 * Params: 468 * filterFunc = callback that 469 * lets you filter which children to show 470 * userData = user data passed to @filter_func 471 * destroy = destroy notifier for @user_data 472 * 473 * Since: 3.12 474 */ 475 public void setFilterFunc(GtkFlowBoxFilterFunc filterFunc, void* userData, GDestroyNotify destroy) 476 { 477 gtk_flow_box_set_filter_func(gtkFlowBox, filterFunc, userData, destroy); 478 } 479 480 /** 481 * Hooks up an adjustment to focus handling in @box. 482 * The adjustment is also used for autoscrolling during 483 * rubberband selection. See gtk_scrolled_window_get_hadjustment() 484 * for a typical way of obtaining the adjustment, and 485 * gtk_flow_box_set_vadjustment()for setting the vertical 486 * adjustment. 487 * 488 * The adjustments have to be in pixel units and in the same 489 * coordinate system as the allocation for immediate children 490 * of the box. 491 * 492 * Params: 493 * adjustment = an adjustment which should be adjusted 494 * when the focus is moved among the descendents of @container 495 * 496 * Since: 3.12 497 */ 498 public void setHadjustment(Adjustment adjustment) 499 { 500 gtk_flow_box_set_hadjustment(gtkFlowBox, (adjustment is null) ? null : adjustment.getAdjustmentStruct()); 501 } 502 503 /** 504 * Sets the #GtkFlowBox:homogeneous property of @box, controlling 505 * whether or not all children of @box are given equal space 506 * in the box. 507 * 508 * Params: 509 * homogeneous = %TRUE to create equal allotments, 510 * %FALSE for variable allotments 511 * 512 * Since: 3.12 513 */ 514 public void setHomogeneous(bool homogeneous) 515 { 516 gtk_flow_box_set_homogeneous(gtkFlowBox, homogeneous); 517 } 518 519 /** 520 * Sets the maximum number of children to request and 521 * allocate space for in @box’s orientation. 522 * 523 * Setting the maximum number of children per line 524 * limits the overall natural size request to be no more 525 * than @n_children children long in the given orientation. 526 * 527 * Params: 528 * nChildren = the maximum number of children per line 529 * 530 * Since: 3.12 531 */ 532 public void setMaxChildrenPerLine(uint nChildren) 533 { 534 gtk_flow_box_set_max_children_per_line(gtkFlowBox, nChildren); 535 } 536 537 /** 538 * Sets the minimum number of children to line up 539 * in @box’s orientation before flowing. 540 * 541 * Params: 542 * nChildren = the minimum number of children per line 543 * 544 * Since: 3.12 545 */ 546 public void setMinChildrenPerLine(uint nChildren) 547 { 548 gtk_flow_box_set_min_children_per_line(gtkFlowBox, nChildren); 549 } 550 551 /** 552 * Sets the vertical space to add between children. 553 * See the #GtkFlowBox:row-spacing property. 554 * 555 * Params: 556 * spacing = the spacing to use 557 * 558 * Since: 3.12 559 */ 560 public void setRowSpacing(uint spacing) 561 { 562 gtk_flow_box_set_row_spacing(gtkFlowBox, spacing); 563 } 564 565 /** 566 * Sets how selection works in @box. 567 * See #GtkSelectionMode for details. 568 * 569 * Params: 570 * mode = the new selection mode 571 * 572 * Since: 3.12 573 */ 574 public void setSelectionMode(GtkSelectionMode mode) 575 { 576 gtk_flow_box_set_selection_mode(gtkFlowBox, mode); 577 } 578 579 /** 580 * By setting a sort function on the @box, one can dynamically 581 * reorder the children of the box, based on the contents of 582 * the children. 583 * 584 * The @sort_func will be called for each child after the call, 585 * and will continue to be called each time a child changes (via 586 * gtk_flow_box_child_changed()) and when gtk_flow_box_invalidate_sort() 587 * is called. 588 * 589 * Note that using a sort function is incompatible with using a model 590 * (see gtk_flow_box_bind_model()). 591 * 592 * Params: 593 * sortFunc = the sort function 594 * userData = user data passed to @sort_func 595 * destroy = destroy notifier for @user_data 596 * 597 * Since: 3.12 598 */ 599 public void setSortFunc(GtkFlowBoxSortFunc sortFunc, void* userData, GDestroyNotify destroy) 600 { 601 gtk_flow_box_set_sort_func(gtkFlowBox, sortFunc, userData, destroy); 602 } 603 604 /** 605 * Hooks up an adjustment to focus handling in @box. 606 * The adjustment is also used for autoscrolling during 607 * rubberband selection. See gtk_scrolled_window_get_vadjustment() 608 * for a typical way of obtaining the adjustment, and 609 * gtk_flow_box_set_hadjustment()for setting the horizontal 610 * adjustment. 611 * 612 * The adjustments have to be in pixel units and in the same 613 * coordinate system as the allocation for immediate children 614 * of the box. 615 * 616 * Params: 617 * adjustment = an adjustment which should be adjusted 618 * when the focus is moved among the descendents of @container 619 * 620 * Since: 3.12 621 */ 622 public void setVadjustment(Adjustment adjustment) 623 { 624 gtk_flow_box_set_vadjustment(gtkFlowBox, (adjustment is null) ? null : adjustment.getAdjustmentStruct()); 625 } 626 627 /** 628 * Unselect all children of @box, if the selection 629 * mode allows it. 630 * 631 * Since: 3.12 632 */ 633 public void unselectAll() 634 { 635 gtk_flow_box_unselect_all(gtkFlowBox); 636 } 637 638 /** 639 * Unselects a single child of @box, if the selection 640 * mode allows it. 641 * 642 * Params: 643 * child = a child of @box 644 * 645 * Since: 3.12 646 */ 647 public void unselectChild(FlowBoxChild child) 648 { 649 gtk_flow_box_unselect_child(gtkFlowBox, (child is null) ? null : child.getFlowBoxChildStruct()); 650 } 651 652 /** 653 * The ::activate-cursor-child signal is a 654 * [keybinding signal][GtkBindingSignal] 655 * which gets emitted when the user activates the @box. 656 */ 657 gulong addOnActivateCursorChild(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 658 { 659 return Signals.connect(this, "activate-cursor-child", dlg, connectFlags ^ ConnectFlags.SWAPPED); 660 } 661 662 /** 663 * The ::child-activated signal is emitted when a child has been 664 * activated by the user. 665 * 666 * Params: 667 * child = the child that is activated 668 */ 669 gulong addOnChildActivated(void delegate(FlowBoxChild, FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 670 { 671 return Signals.connect(this, "child-activated", dlg, connectFlags ^ ConnectFlags.SWAPPED); 672 } 673 674 /** 675 * The ::move-cursor signal is a 676 * [keybinding signal][GtkBindingSignal] 677 * which gets emitted when the user initiates a cursor movement. 678 * 679 * Applications should not connect to it, but may emit it with 680 * g_signal_emit_by_name() if they need to control the cursor 681 * programmatically. 682 * 683 * The default bindings for this signal come in two variants, 684 * the variant with the Shift modifier extends the selection, 685 * the variant without the Shift modifer does not. 686 * There are too many key combinations to list them all here. 687 * - Arrow keys move by individual children 688 * - Home/End keys move to the ends of the box 689 * - PageUp/PageDown keys move vertically by pages 690 * 691 * Params: 692 * step = the granularity fo the move, as a #GtkMovementStep 693 * count = the number of @step units to move 694 * 695 * Returns: %TRUE to stop other handlers from being invoked for the event. 696 * %FALSE to propagate the event further. 697 */ 698 gulong addOnMoveCursor(bool delegate(GtkMovementStep, int, FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 699 { 700 return Signals.connect(this, "move-cursor", dlg, connectFlags ^ ConnectFlags.SWAPPED); 701 } 702 703 /** 704 * The ::select-all signal is a 705 * [keybinding signal][GtkBindingSignal] 706 * which gets emitted to select all children of the box, if 707 * the selection mode permits it. 708 * 709 * The default bindings for this signal is Ctrl-a. 710 */ 711 gulong addOnSelectAll(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 712 { 713 return Signals.connect(this, "select-all", dlg, connectFlags ^ ConnectFlags.SWAPPED); 714 } 715 716 /** 717 * The ::selected-children-changed signal is emitted when the 718 * set of selected children changes. 719 * 720 * Use gtk_flow_box_selected_foreach() or 721 * gtk_flow_box_get_selected_children() to obtain the 722 * selected children. 723 */ 724 gulong addOnSelectedChildrenChanged(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 725 { 726 return Signals.connect(this, "selected-children-changed", dlg, connectFlags ^ ConnectFlags.SWAPPED); 727 } 728 729 /** 730 * The ::toggle-cursor-child signal is a 731 * [keybinding signal][GtkBindingSignal] 732 * which toggles the selection of the child that has the focus. 733 * 734 * The default binding for this signal is Ctrl-Space. 735 */ 736 gulong addOnToggleCursorChild(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 737 { 738 return Signals.connect(this, "toggle-cursor-child", dlg, connectFlags ^ ConnectFlags.SWAPPED); 739 } 740 741 /** 742 * The ::unselect-all signal is a 743 * [keybinding signal][GtkBindingSignal] 744 * which gets emitted to unselect all children of the box, if 745 * the selection mode permits it. 746 * 747 * The default bindings for this signal is Ctrl-Shift-a. 748 */ 749 gulong addOnUnselectAll(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 750 { 751 return Signals.connect(this, "unselect-all", dlg, connectFlags ^ ConnectFlags.SWAPPED); 752 } 753 }