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 		void delegate(Button) dlg;
615 		gulong handlerId;
616 		
617 		this(void delegate(Button) dlg)
618 		{
619 			this.dlg = dlg;
620 			onActivateListeners ~= this;
621 		}
622 		
623 		void remove(OnActivateDelegateWrapper source)
624 		{
625 			foreach(index, wrapper; onActivateListeners)
626 			{
627 				if (wrapper.handlerId == source.handlerId)
628 				{
629 					onActivateListeners[index] = null;
630 					onActivateListeners = std.algorithm.remove(onActivateListeners, index);
631 					break;
632 				}
633 			}
634 		}
635 	}
636 	OnActivateDelegateWrapper[] onActivateListeners;
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 		void delegate(Button) dlg;
670 		gulong handlerId;
671 		
672 		this(void delegate(Button) dlg)
673 		{
674 			this.dlg = dlg;
675 			onClickedListeners ~= this;
676 		}
677 		
678 		void remove(OnClickedDelegateWrapper source)
679 		{
680 			foreach(index, wrapper; onClickedListeners)
681 			{
682 				if (wrapper.handlerId == source.handlerId)
683 				{
684 					onClickedListeners[index] = null;
685 					onClickedListeners = std.algorithm.remove(onClickedListeners, index);
686 					break;
687 				}
688 			}
689 		}
690 	}
691 	OnClickedDelegateWrapper[] onClickedListeners;
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 		void delegate(Button) dlg;
722 		gulong handlerId;
723 		
724 		this(void delegate(Button) dlg)
725 		{
726 			this.dlg = dlg;
727 			onEnterListeners ~= this;
728 		}
729 		
730 		void remove(OnEnterDelegateWrapper source)
731 		{
732 			foreach(index, wrapper; onEnterListeners)
733 			{
734 				if (wrapper.handlerId == source.handlerId)
735 				{
736 					onEnterListeners[index] = null;
737 					onEnterListeners = std.algorithm.remove(onEnterListeners, index);
738 					break;
739 				}
740 			}
741 		}
742 	}
743 	OnEnterDelegateWrapper[] onEnterListeners;
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 		void delegate(Button) dlg;
776 		gulong handlerId;
777 		
778 		this(void delegate(Button) dlg)
779 		{
780 			this.dlg = dlg;
781 			onLeaveListeners ~= this;
782 		}
783 		
784 		void remove(OnLeaveDelegateWrapper source)
785 		{
786 			foreach(index, wrapper; onLeaveListeners)
787 			{
788 				if (wrapper.handlerId == source.handlerId)
789 				{
790 					onLeaveListeners[index] = null;
791 					onLeaveListeners = std.algorithm.remove(onLeaveListeners, index);
792 					break;
793 				}
794 			}
795 		}
796 	}
797 	OnLeaveDelegateWrapper[] onLeaveListeners;
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 		void delegate(Button) dlg;
830 		gulong handlerId;
831 		
832 		this(void delegate(Button) dlg)
833 		{
834 			this.dlg = dlg;
835 			onPressedListeners ~= this;
836 		}
837 		
838 		void remove(OnPressedDelegateWrapper source)
839 		{
840 			foreach(index, wrapper; onPressedListeners)
841 			{
842 				if (wrapper.handlerId == source.handlerId)
843 				{
844 					onPressedListeners[index] = null;
845 					onPressedListeners = std.algorithm.remove(onPressedListeners, index);
846 					break;
847 				}
848 			}
849 		}
850 	}
851 	OnPressedDelegateWrapper[] onPressedListeners;
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 		void delegate(Button) dlg;
884 		gulong handlerId;
885 		
886 		this(void delegate(Button) dlg)
887 		{
888 			this.dlg = dlg;
889 			onReleasedListeners ~= this;
890 		}
891 		
892 		void remove(OnReleasedDelegateWrapper source)
893 		{
894 			foreach(index, wrapper; onReleasedListeners)
895 			{
896 				if (wrapper.handlerId == source.handlerId)
897 				{
898 					onReleasedListeners[index] = null;
899 					onReleasedListeners = std.algorithm.remove(onReleasedListeners, index);
900 					break;
901 				}
902 			}
903 		}
904 	}
905 	OnReleasedDelegateWrapper[] onReleasedListeners;
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 }