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