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