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 }