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.Button; 26 27 private import gdk.Window; 28 private import glib.ConstructionException; 29 private import glib.Str; 30 private import gobject.ObjectG; 31 private import gobject.Signals; 32 private import gtk.ActionableIF; 33 private import gtk.ActionableT; 34 private import gtk.ActivatableIF; 35 private import gtk.ActivatableT; 36 private import gtk.Bin; 37 private import gtk.Image; 38 private import gtk.Widget; 39 public import gtkc.gdktypes; 40 private import gtkc.gtk; 41 public import gtkc.gtktypes; 42 private import std.algorithm; 43 44 45 /** 46 * The #GtkButton widget is generally used to trigger a callback function that is 47 * called when the button is pressed. The various signals and how to use them 48 * are outlined below. 49 * 50 * The #GtkButton widget can hold any valid child widget. That is, it can hold 51 * almost any other standard #GtkWidget. The most commonly used child is the 52 * #GtkLabel. 53 * 54 * # CSS nodes 55 * 56 * GtkButton has a single CSS node with name button. The node will get the 57 * style classes .image-button or .text-button, if the content is just an 58 * image or label, respectively. It may also receive the .flat style class. 59 * 60 * Other style classes that are commonly used with GtkButton include 61 * .suggested-action and .destructive-action. In special cases, buttons 62 * can be made round by adding the .circular style class. 63 * 64 * Button-like widgets like #GtkToggleButton, #GtkMenuButton, #GtkVolumeButton, 65 * #GtkLockButton, #GtkColorButton, #GtkFontButton or #GtkFileChooserButton use 66 * style classes such as .toggle, .popup, .scale, .lock, .color, .font, .file 67 * to differentiate themselves from a plain GtkButton. 68 */ 69 public class Button : Bin, ActionableIF, ActivatableIF 70 { 71 /** the main Gtk struct */ 72 protected GtkButton* gtkButton; 73 74 /** Get the main Gtk struct */ 75 public GtkButton* getButtonStruct() 76 { 77 return gtkButton; 78 } 79 80 /** the main Gtk struct as a void* */ 81 protected override void* getStruct() 82 { 83 return cast(void*)gtkButton; 84 } 85 86 protected override void setStruct(GObject* obj) 87 { 88 gtkButton = cast(GtkButton*)obj; 89 super.setStruct(obj); 90 } 91 92 /** 93 * Sets our main struct and passes it to the parent class. 94 */ 95 public this (GtkButton* gtkButton, bool ownedRef = false) 96 { 97 this.gtkButton = gtkButton; 98 super(cast(GtkBin*)gtkButton, ownedRef); 99 } 100 101 // add the Actionable capabilities 102 mixin ActionableT!(GtkButton); 103 104 // add the Activatable capabilities 105 mixin ActivatableT!(GtkButton); 106 107 private static IconSize currentIconSize = IconSize.BUTTON; 108 109 /** */ 110 public static void setIconSize(IconSize iconSize) 111 { 112 currentIconSize = iconSize; 113 } 114 115 /** */ 116 public static IconSize getIconSize() 117 { 118 return currentIconSize; 119 } 120 121 /** 122 * Creates a new GtkButton containing a label. 123 * If characters in label are preceded by an underscore, they are underlined. 124 * If you need a literal underscore character in a label, use '__' (two 125 * underscores). The first underlined character represents a keyboard 126 * accelerator called a mnemonic. 127 * Pressing Alt and that key activates the button. 128 * Params: 129 * label = The text of the button, with an underscore in front of the 130 * mnemonic character 131 * mnemonic = true if the button has an mnemnonic 132 * Returns: 133 * a new GtkButton 134 * Throws: ConstructionException GTK+ fails to create the object. 135 */ 136 public this (string label, bool mnemonic=true) 137 { 138 GtkButton* p; 139 140 if ( mnemonic ) 141 { 142 // GtkWidget* gtk_button_new_with_mnemonic (const gchar *label); 143 p = cast(GtkButton*)gtk_button_new_with_mnemonic(Str.toStringz(label)); 144 } 145 else 146 { 147 // GtkWidget* gtk_button_new_with_label (const gchar *label); 148 p = cast(GtkButton*)gtk_button_new_with_label(Str.toStringz(label)); 149 } 150 151 if(p is null) 152 { 153 throw new ConstructionException("null returned by gtk_button_new_with_label"); 154 } 155 156 this(p); 157 } 158 159 /** 160 * Creates a new GtkButton containing the image and text from a stock item. 161 * Some stock ids have preprocessor macros like GTK_STOCK_OK and 162 * GTK_STOCK_APPLY. 163 * If stock_id is unknown, then it will be treated as a mnemonic 164 * label (as for gtk_button_new_with_mnemonic()). 165 * Params: 166 * StockID = the name of the stock item 167 * Throws: ConstructionException GTK+ fails to create the object. 168 */ 169 public this (StockID stockID, bool hideLabel=false) 170 { 171 // GtkWidget* gtk_button_new_from_stock (const gchar *stock_id); 172 if ( hideLabel ) 173 { 174 this(); 175 Image image = new Image(stockID,currentIconSize); 176 add(image); 177 } 178 else 179 { 180 auto p = gtk_button_new_from_stock(Str.toStringz(stockID)); 181 182 if(p is null) 183 { 184 throw new ConstructionException("null returned by gtk_button_new_from_stock"); 185 } 186 187 this(cast(GtkButton*) p); 188 } 189 } 190 191 /** */ 192 public this(StockID stockID, void delegate(Button) dlg, bool hideLabel=false) 193 { 194 this(stockID, hideLabel); 195 addOnClicked(dlg); 196 } 197 198 /** */ 199 public this(string label, void delegate(Button) dlg, bool mnemonic=true) 200 { 201 this(label, mnemonic); 202 addOnClicked(dlg); 203 } 204 205 /** */ 206 public this(string label, void delegate(Button) dlg, string action) 207 { 208 this(label); 209 setActionName(action); 210 addOnClicked(dlg); 211 } 212 213 /** 214 */ 215 216 /** */ 217 public static GType getType() 218 { 219 return gtk_button_get_type(); 220 } 221 222 /** 223 * Creates a new #GtkButton widget. To add a child widget to the button, 224 * use gtk_container_add(). 225 * 226 * Return: The newly created #GtkButton widget. 227 * 228 * Throws: ConstructionException GTK+ fails to create the object. 229 */ 230 public this() 231 { 232 auto p = gtk_button_new(); 233 234 if(p is null) 235 { 236 throw new ConstructionException("null returned by new"); 237 } 238 239 this(cast(GtkButton*) p); 240 } 241 242 /** 243 * Creates a new button containing an icon from the current icon theme. 244 * 245 * If the icon name isn’t known, a “broken image” icon will be 246 * displayed instead. If the current icon theme is changed, the icon 247 * will be updated appropriately. 248 * 249 * This function is a convenience wrapper around gtk_button_new() and 250 * gtk_button_set_image(). 251 * 252 * Params: 253 * iconName = an icon name 254 * size = an icon size (#GtkIconSize) 255 * 256 * Return: a new #GtkButton displaying the themed icon 257 * 258 * Since: 3.10 259 * 260 * Throws: ConstructionException GTK+ fails to create the object. 261 */ 262 public this(string iconName, GtkIconSize size) 263 { 264 auto p = gtk_button_new_from_icon_name(Str.toStringz(iconName), size); 265 266 if(p is null) 267 { 268 throw new ConstructionException("null returned by new_from_icon_name"); 269 } 270 271 this(cast(GtkButton*) p); 272 } 273 274 /** 275 * Emits a #GtkButton::clicked signal to the given #GtkButton. 276 */ 277 public void clicked() 278 { 279 gtk_button_clicked(gtkButton); 280 } 281 282 /** 283 * Emits a #GtkButton::enter signal to the given #GtkButton. 284 * 285 * Deprecated: Use the #GtkWidget::enter-notify-event signal. 286 */ 287 public void enter() 288 { 289 gtk_button_enter(gtkButton); 290 } 291 292 /** 293 * Gets the alignment of the child in the button. 294 * 295 * Deprecated: Access the child widget directly if you need to control 296 * its alignment. 297 * 298 * Params: 299 * xalign = return location for horizontal alignment 300 * yalign = return location for vertical alignment 301 * 302 * Since: 2.4 303 */ 304 public void getAlignment(out float xalign, out float yalign) 305 { 306 gtk_button_get_alignment(gtkButton, &xalign, &yalign); 307 } 308 309 /** 310 * Returns whether the button will ignore the #GtkSettings:gtk-button-images 311 * setting and always show the image, if available. 312 * 313 * Return: %TRUE if the button will always show the image 314 * 315 * Since: 3.6 316 */ 317 public bool getAlwaysShowImage() 318 { 319 return gtk_button_get_always_show_image(gtkButton) != 0; 320 } 321 322 /** 323 * Returns the button’s event window if it is realized, %NULL otherwise. 324 * This function should be rarely needed. 325 * 326 * Return: @button’s event window. 327 * 328 * Since: 2.22 329 */ 330 public Window getEventWindow() 331 { 332 auto p = gtk_button_get_event_window(gtkButton); 333 334 if(p is null) 335 { 336 return null; 337 } 338 339 return ObjectG.getDObject!(Window)(cast(GdkWindow*) p); 340 } 341 342 /** 343 * Returns whether the button grabs focus when it is clicked with the mouse. 344 * See gtk_button_set_focus_on_click(). 345 * 346 * Deprecated: Use gtk_widget_get_focus_on_click() instead 347 * 348 * Return: %TRUE if the button grabs focus when it is clicked with 349 * the mouse. 350 * 351 * Since: 2.4 352 */ 353 public override bool getFocusOnClick() 354 { 355 return gtk_button_get_focus_on_click(gtkButton) != 0; 356 } 357 358 /** 359 * Gets the widget that is currenty set as the image of @button. 360 * This may have been explicitly set by gtk_button_set_image() 361 * or constructed by gtk_button_new_from_stock(). 362 * 363 * Return: a #GtkWidget or %NULL in case 364 * there is no image 365 * 366 * Since: 2.6 367 */ 368 public Widget getImage() 369 { 370 auto p = gtk_button_get_image(gtkButton); 371 372 if(p is null) 373 { 374 return null; 375 } 376 377 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 378 } 379 380 /** 381 * Gets the position of the image relative to the text 382 * inside the button. 383 * 384 * Return: the position 385 * 386 * Since: 2.10 387 */ 388 public GtkPositionType getImagePosition() 389 { 390 return gtk_button_get_image_position(gtkButton); 391 } 392 393 /** 394 * Fetches the text from the label of the button, as set by 395 * gtk_button_set_label(). If the label text has not 396 * been set the return value will be %NULL. This will be the 397 * case if you create an empty button with gtk_button_new() to 398 * use as a container. 399 * 400 * Return: The text of the label widget. This string is owned 401 * by the widget and must not be modified or freed. 402 */ 403 public string getLabel() 404 { 405 return Str.toString(gtk_button_get_label(gtkButton)); 406 } 407 408 /** 409 * Returns the current relief style of the given #GtkButton. 410 * 411 * Return: The current #GtkReliefStyle 412 */ 413 public GtkReliefStyle getRelief() 414 { 415 return gtk_button_get_relief(gtkButton); 416 } 417 418 /** 419 * Returns whether the button label is a stock item. 420 * 421 * Return: %TRUE if the button label is used to 422 * select a stock item instead of being 423 * used directly as the label text. 424 */ 425 public bool getUseStock() 426 { 427 return gtk_button_get_use_stock(gtkButton) != 0; 428 } 429 430 /** 431 * Returns whether an embedded underline in the button label indicates a 432 * mnemonic. See gtk_button_set_use_underline (). 433 * 434 * Return: %TRUE if an embedded underline in the button label 435 * indicates the mnemonic accelerator keys. 436 */ 437 public bool getUseUnderline() 438 { 439 return gtk_button_get_use_underline(gtkButton) != 0; 440 } 441 442 /** 443 * Emits a #GtkButton::leave signal to the given #GtkButton. 444 * 445 * Deprecated: Use the #GtkWidget::leave-notify-event signal. 446 */ 447 public void leave() 448 { 449 gtk_button_leave(gtkButton); 450 } 451 452 /** 453 * Emits a #GtkButton::pressed signal to the given #GtkButton. 454 * 455 * Deprecated: Use the #GtkWidget::button-press-event signal. 456 */ 457 public void pressed() 458 { 459 gtk_button_pressed(gtkButton); 460 } 461 462 /** 463 * Emits a #GtkButton::released signal to the given #GtkButton. 464 * 465 * Deprecated: Use the #GtkWidget::button-release-event signal. 466 */ 467 public void released() 468 { 469 gtk_button_released(gtkButton); 470 } 471 472 /** 473 * Sets the alignment of the child. This property has no effect unless 474 * the child is a #GtkMisc or a #GtkAlignment. 475 * 476 * Deprecated: Access the child widget directly if you need to control 477 * its alignment. 478 * 479 * Params: 480 * xalign = the horizontal position of the child, 0.0 is left aligned, 481 * 1.0 is right aligned 482 * yalign = the vertical position of the child, 0.0 is top aligned, 483 * 1.0 is bottom aligned 484 * 485 * Since: 2.4 486 */ 487 public void setAlignment(float xalign, float yalign) 488 { 489 gtk_button_set_alignment(gtkButton, xalign, yalign); 490 } 491 492 /** 493 * If %TRUE, the button will ignore the #GtkSettings:gtk-button-images 494 * setting and always show the image, if available. 495 * 496 * Use this property if the button would be useless or hard to use 497 * without the image. 498 * 499 * Params: 500 * alwaysShow = %TRUE if the menuitem should always show the image 501 * 502 * Since: 3.6 503 */ 504 public void setAlwaysShowImage(bool alwaysShow) 505 { 506 gtk_button_set_always_show_image(gtkButton, alwaysShow); 507 } 508 509 /** 510 * Sets whether the button will grab focus when it is clicked with the mouse. 511 * Making mouse clicks not grab focus is useful in places like toolbars where 512 * you don’t want the keyboard focus removed from the main area of the 513 * application. 514 * 515 * Deprecated: Use gtk_widget_set_focus_on_click() instead 516 * 517 * Params: 518 * focusOnClick = whether the button grabs focus when clicked with the mouse 519 * 520 * Since: 2.4 521 */ 522 public override void setFocusOnClick(bool focusOnClick) 523 { 524 gtk_button_set_focus_on_click(gtkButton, focusOnClick); 525 } 526 527 /** 528 * Set the image of @button to the given widget. The image will be 529 * displayed if the label text is %NULL or if 530 * #GtkButton:always-show-image is %TRUE. You don’t have to call 531 * gtk_widget_show() on @image yourself. 532 * 533 * Params: 534 * image = a widget to set as the image for the button 535 * 536 * Since: 2.6 537 */ 538 public void setImage(Widget image) 539 { 540 gtk_button_set_image(gtkButton, (image is null) ? null : image.getWidgetStruct()); 541 } 542 543 /** 544 * Sets the position of the image relative to the text 545 * inside the button. 546 * 547 * Params: 548 * position = the position 549 * 550 * Since: 2.10 551 */ 552 public void setImagePosition(GtkPositionType position) 553 { 554 gtk_button_set_image_position(gtkButton, position); 555 } 556 557 /** 558 * Sets the text of the label of the button to @str. This text is 559 * also used to select the stock item if gtk_button_set_use_stock() 560 * is used. 561 * 562 * This will also clear any previously set labels. 563 * 564 * Params: 565 * label = a string 566 */ 567 public void setLabel(string label) 568 { 569 gtk_button_set_label(gtkButton, Str.toStringz(label)); 570 } 571 572 /** 573 * Sets the relief style of the edges of the given #GtkButton widget. 574 * Two styles exist, %GTK_RELIEF_NORMAL and %GTK_RELIEF_NONE. 575 * The default style is, as one can guess, %GTK_RELIEF_NORMAL. 576 * The deprecated value %GTK_RELIEF_HALF behaves the same as 577 * %GTK_RELIEF_NORMAL. 578 * 579 * Params: 580 * relief = The GtkReliefStyle as described above 581 */ 582 public void setRelief(GtkReliefStyle relief) 583 { 584 gtk_button_set_relief(gtkButton, relief); 585 } 586 587 /** 588 * If %TRUE, the label set on the button is used as a 589 * stock id to select the stock item for the button. 590 * 591 * Params: 592 * useStock = %TRUE if the button should use a stock item 593 */ 594 public void setUseStock(bool useStock) 595 { 596 gtk_button_set_use_stock(gtkButton, useStock); 597 } 598 599 /** 600 * If true, an underline in the text of the button label indicates 601 * the next character should be used for the mnemonic accelerator key. 602 * 603 * Params: 604 * useUnderline = %TRUE if underlines in the text indicate mnemonics 605 */ 606 public void setUseUnderline(bool useUnderline) 607 { 608 gtk_button_set_use_underline(gtkButton, useUnderline); 609 } 610 611 protected class OnActivateDelegateWrapper 612 { 613 void delegate(Button) dlg; 614 gulong handlerId; 615 ConnectFlags flags; 616 this(void delegate(Button) dlg, gulong handlerId, ConnectFlags flags) 617 { 618 this.dlg = dlg; 619 this.handlerId = handlerId; 620 this.flags = flags; 621 } 622 } 623 protected OnActivateDelegateWrapper[] onActivateListeners; 624 625 /** 626 * The ::activate signal on GtkButton is an action signal and 627 * emitting it causes the button to animate press then release. 628 * Applications should never connect to this signal, but use the 629 * #GtkButton::clicked signal. 630 */ 631 gulong addOnActivate(void delegate(Button) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 632 { 633 onActivateListeners ~= new OnActivateDelegateWrapper(dlg, 0, connectFlags); 634 onActivateListeners[onActivateListeners.length - 1].handlerId = Signals.connectData( 635 this, 636 "activate", 637 cast(GCallback)&callBackActivate, 638 cast(void*)onActivateListeners[onActivateListeners.length - 1], 639 cast(GClosureNotify)&callBackActivateDestroy, 640 connectFlags); 641 return onActivateListeners[onActivateListeners.length - 1].handlerId; 642 } 643 644 extern(C) static void callBackActivate(GtkButton* buttonStruct,OnActivateDelegateWrapper wrapper) 645 { 646 wrapper.dlg(wrapper.outer); 647 } 648 649 extern(C) static void callBackActivateDestroy(OnActivateDelegateWrapper wrapper, GClosure* closure) 650 { 651 wrapper.outer.internalRemoveOnActivate(wrapper); 652 } 653 654 protected void internalRemoveOnActivate(OnActivateDelegateWrapper source) 655 { 656 foreach(index, wrapper; onActivateListeners) 657 { 658 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 659 { 660 onActivateListeners[index] = null; 661 onActivateListeners = std.algorithm.remove(onActivateListeners, index); 662 break; 663 } 664 } 665 } 666 667 668 protected class OnClickedDelegateWrapper 669 { 670 void delegate(Button) dlg; 671 gulong handlerId; 672 ConnectFlags flags; 673 this(void delegate(Button) dlg, gulong handlerId, ConnectFlags flags) 674 { 675 this.dlg = dlg; 676 this.handlerId = handlerId; 677 this.flags = flags; 678 } 679 } 680 protected OnClickedDelegateWrapper[] onClickedListeners; 681 682 /** 683 * Emitted when the button has been activated (pressed and released). 684 */ 685 gulong addOnClicked(void delegate(Button) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 686 { 687 onClickedListeners ~= new OnClickedDelegateWrapper(dlg, 0, connectFlags); 688 onClickedListeners[onClickedListeners.length - 1].handlerId = Signals.connectData( 689 this, 690 "clicked", 691 cast(GCallback)&callBackClicked, 692 cast(void*)onClickedListeners[onClickedListeners.length - 1], 693 cast(GClosureNotify)&callBackClickedDestroy, 694 connectFlags); 695 return onClickedListeners[onClickedListeners.length - 1].handlerId; 696 } 697 698 extern(C) static void callBackClicked(GtkButton* buttonStruct,OnClickedDelegateWrapper wrapper) 699 { 700 wrapper.dlg(wrapper.outer); 701 } 702 703 extern(C) static void callBackClickedDestroy(OnClickedDelegateWrapper wrapper, GClosure* closure) 704 { 705 wrapper.outer.internalRemoveOnClicked(wrapper); 706 } 707 708 protected void internalRemoveOnClicked(OnClickedDelegateWrapper source) 709 { 710 foreach(index, wrapper; onClickedListeners) 711 { 712 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 713 { 714 onClickedListeners[index] = null; 715 onClickedListeners = std.algorithm.remove(onClickedListeners, index); 716 break; 717 } 718 } 719 } 720 721 722 protected class OnEnterDelegateWrapper 723 { 724 void delegate(Button) dlg; 725 gulong handlerId; 726 ConnectFlags flags; 727 this(void delegate(Button) dlg, gulong handlerId, ConnectFlags flags) 728 { 729 this.dlg = dlg; 730 this.handlerId = handlerId; 731 this.flags = flags; 732 } 733 } 734 protected OnEnterDelegateWrapper[] onEnterListeners; 735 736 /** 737 * Emitted when the pointer enters the button. 738 * 739 * Deprecated: Use the #GtkWidget::enter-notify-event signal. 740 */ 741 gulong addOnEnter(void delegate(Button) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 742 { 743 onEnterListeners ~= new OnEnterDelegateWrapper(dlg, 0, connectFlags); 744 onEnterListeners[onEnterListeners.length - 1].handlerId = Signals.connectData( 745 this, 746 "enter", 747 cast(GCallback)&callBackEnter, 748 cast(void*)onEnterListeners[onEnterListeners.length - 1], 749 cast(GClosureNotify)&callBackEnterDestroy, 750 connectFlags); 751 return onEnterListeners[onEnterListeners.length - 1].handlerId; 752 } 753 754 extern(C) static void callBackEnter(GtkButton* buttonStruct,OnEnterDelegateWrapper wrapper) 755 { 756 wrapper.dlg(wrapper.outer); 757 } 758 759 extern(C) static void callBackEnterDestroy(OnEnterDelegateWrapper wrapper, GClosure* closure) 760 { 761 wrapper.outer.internalRemoveOnEnter(wrapper); 762 } 763 764 protected void internalRemoveOnEnter(OnEnterDelegateWrapper source) 765 { 766 foreach(index, wrapper; onEnterListeners) 767 { 768 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 769 { 770 onEnterListeners[index] = null; 771 onEnterListeners = std.algorithm.remove(onEnterListeners, index); 772 break; 773 } 774 } 775 } 776 777 778 protected class OnLeaveDelegateWrapper 779 { 780 void delegate(Button) dlg; 781 gulong handlerId; 782 ConnectFlags flags; 783 this(void delegate(Button) dlg, gulong handlerId, ConnectFlags flags) 784 { 785 this.dlg = dlg; 786 this.handlerId = handlerId; 787 this.flags = flags; 788 } 789 } 790 protected OnLeaveDelegateWrapper[] onLeaveListeners; 791 792 /** 793 * Emitted when the pointer leaves the button. 794 * 795 * Deprecated: Use the #GtkWidget::leave-notify-event signal. 796 */ 797 gulong addOnLeave(void delegate(Button) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 798 { 799 onLeaveListeners ~= new OnLeaveDelegateWrapper(dlg, 0, connectFlags); 800 onLeaveListeners[onLeaveListeners.length - 1].handlerId = Signals.connectData( 801 this, 802 "leave", 803 cast(GCallback)&callBackLeave, 804 cast(void*)onLeaveListeners[onLeaveListeners.length - 1], 805 cast(GClosureNotify)&callBackLeaveDestroy, 806 connectFlags); 807 return onLeaveListeners[onLeaveListeners.length - 1].handlerId; 808 } 809 810 extern(C) static void callBackLeave(GtkButton* buttonStruct,OnLeaveDelegateWrapper wrapper) 811 { 812 wrapper.dlg(wrapper.outer); 813 } 814 815 extern(C) static void callBackLeaveDestroy(OnLeaveDelegateWrapper wrapper, GClosure* closure) 816 { 817 wrapper.outer.internalRemoveOnLeave(wrapper); 818 } 819 820 protected void internalRemoveOnLeave(OnLeaveDelegateWrapper source) 821 { 822 foreach(index, wrapper; onLeaveListeners) 823 { 824 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 825 { 826 onLeaveListeners[index] = null; 827 onLeaveListeners = std.algorithm.remove(onLeaveListeners, index); 828 break; 829 } 830 } 831 } 832 833 834 protected class OnPressedDelegateWrapper 835 { 836 void delegate(Button) dlg; 837 gulong handlerId; 838 ConnectFlags flags; 839 this(void delegate(Button) dlg, gulong handlerId, ConnectFlags flags) 840 { 841 this.dlg = dlg; 842 this.handlerId = handlerId; 843 this.flags = flags; 844 } 845 } 846 protected OnPressedDelegateWrapper[] onPressedListeners; 847 848 /** 849 * Emitted when the button is pressed. 850 * 851 * Deprecated: Use the #GtkWidget::button-press-event signal. 852 */ 853 gulong addOnPressed(void delegate(Button) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 854 { 855 onPressedListeners ~= new OnPressedDelegateWrapper(dlg, 0, connectFlags); 856 onPressedListeners[onPressedListeners.length - 1].handlerId = Signals.connectData( 857 this, 858 "pressed", 859 cast(GCallback)&callBackPressed, 860 cast(void*)onPressedListeners[onPressedListeners.length - 1], 861 cast(GClosureNotify)&callBackPressedDestroy, 862 connectFlags); 863 return onPressedListeners[onPressedListeners.length - 1].handlerId; 864 } 865 866 extern(C) static void callBackPressed(GtkButton* buttonStruct,OnPressedDelegateWrapper wrapper) 867 { 868 wrapper.dlg(wrapper.outer); 869 } 870 871 extern(C) static void callBackPressedDestroy(OnPressedDelegateWrapper wrapper, GClosure* closure) 872 { 873 wrapper.outer.internalRemoveOnPressed(wrapper); 874 } 875 876 protected void internalRemoveOnPressed(OnPressedDelegateWrapper source) 877 { 878 foreach(index, wrapper; onPressedListeners) 879 { 880 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 881 { 882 onPressedListeners[index] = null; 883 onPressedListeners = std.algorithm.remove(onPressedListeners, index); 884 break; 885 } 886 } 887 } 888 889 890 protected class OnReleasedDelegateWrapper 891 { 892 void delegate(Button) dlg; 893 gulong handlerId; 894 ConnectFlags flags; 895 this(void delegate(Button) dlg, gulong handlerId, ConnectFlags flags) 896 { 897 this.dlg = dlg; 898 this.handlerId = handlerId; 899 this.flags = flags; 900 } 901 } 902 protected OnReleasedDelegateWrapper[] onReleasedListeners; 903 904 /** 905 * Emitted when the button is released. 906 * 907 * Deprecated: Use the #GtkWidget::button-release-event signal. 908 */ 909 gulong addOnReleased(void delegate(Button) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 910 { 911 onReleasedListeners ~= new OnReleasedDelegateWrapper(dlg, 0, connectFlags); 912 onReleasedListeners[onReleasedListeners.length - 1].handlerId = Signals.connectData( 913 this, 914 "released", 915 cast(GCallback)&callBackReleased, 916 cast(void*)onReleasedListeners[onReleasedListeners.length - 1], 917 cast(GClosureNotify)&callBackReleasedDestroy, 918 connectFlags); 919 return onReleasedListeners[onReleasedListeners.length - 1].handlerId; 920 } 921 922 extern(C) static void callBackReleased(GtkButton* buttonStruct,OnReleasedDelegateWrapper wrapper) 923 { 924 wrapper.dlg(wrapper.outer); 925 } 926 927 extern(C) static void callBackReleasedDestroy(OnReleasedDelegateWrapper wrapper, GClosure* closure) 928 { 929 wrapper.outer.internalRemoveOnReleased(wrapper); 930 } 931 932 protected void internalRemoveOnReleased(OnReleasedDelegateWrapper source) 933 { 934 foreach(index, wrapper; onReleasedListeners) 935 { 936 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 937 { 938 onReleasedListeners[index] = null; 939 onReleasedListeners = std.algorithm.remove(onReleasedListeners, index); 940 break; 941 } 942 } 943 } 944 945 }