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