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