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