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