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.MenuItem;
26 
27 private import glib.ConstructionException;
28 private import glib.Str;
29 private import gobject.ObjectG;
30 private import gobject.Signals;
31 private import gtk.AccelGroup;
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.Menu;
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 #GtkMenuItem widget and the derived widgets are the only valid
46  * children for menus. Their function is to correctly handle highlighting,
47  * alignment, events and submenus.
48  * 
49  * As a GtkMenuItem derives from #GtkBin it can hold any valid child widget,
50  * although only a few are really useful.
51  * 
52  * By default, a GtkMenuItem sets a #GtkAccelLabel as its child.
53  * GtkMenuItem has direct functions to set the label and its mnemonic.
54  * For more advanced label settings, you can fetch the child widget from the GtkBin.
55  * 
56  * An example for setting markup and accelerator on a MenuItem:
57  * |[<!-- language="C" -->
58  * GtkWidget *child = gtk_bin_get_child (GTK_BIN (menu_item));
59  * gtk_label_set_markup (GTK_LABEL (child), "<i>new label</i> with <b>markup</b>");
60  * gtk_accel_label_set_accel (GTK_ACCEL_LABEL (child), GDK_KEY_1, 0);
61  * ]|
62  * 
63  * # GtkMenuItem as GtkBuildable
64  * 
65  * The GtkMenuItem implementation of the #GtkBuildable interface supports
66  * adding a submenu by specifying “submenu” as the “type” attribute of
67  * a <child> element.
68  * 
69  * An example of UI definition fragment with submenus:
70  * |[
71  * <object class="GtkMenuItem">
72  * <child type="submenu">
73  * <object class="GtkMenu"/>
74  * </child>
75  * </object>
76  * ]|
77  * 
78  * # CSS nodes
79  * 
80  * |[<!-- language="plain" -->
81  * menuitem
82  * ├── <child>
83  * ╰── [arrow.right]
84  * ]|
85  * 
86  * GtkMenuItem has a single CSS node with name menuitem. If the menuitem
87  * has a submenu, it gets another CSS node with name arrow, which has
88  * the .left or .right style class.
89  */
90 public class MenuItem : Bin, ActionableIF, ActivatableIF
91 {
92 	/** the main Gtk struct */
93 	protected GtkMenuItem* gtkMenuItem;
94 
95 	/** Get the main Gtk struct */
96 	public GtkMenuItem* getMenuItemStruct()
97 	{
98 		return gtkMenuItem;
99 	}
100 
101 	/** the main Gtk struct as a void* */
102 	protected override void* getStruct()
103 	{
104 		return cast(void*)gtkMenuItem;
105 	}
106 
107 	protected override void setStruct(GObject* obj)
108 	{
109 		gtkMenuItem = cast(GtkMenuItem*)obj;
110 		super.setStruct(obj);
111 	}
112 
113 	/**
114 	 * Sets our main struct and passes it to the parent class.
115 	 */
116 	public this (GtkMenuItem* gtkMenuItem, bool ownedRef = false)
117 	{
118 		this.gtkMenuItem = gtkMenuItem;
119 		super(cast(GtkBin*)gtkMenuItem, ownedRef);
120 	}
121 
122 	// add the Actionable capabilities
123 	mixin ActionableT!(GtkMenuItem);
124 
125 	// add the Activatable capabilities
126 	mixin ActivatableT!(GtkMenuItem);
127 
128 	/** store the action code passed in by the applcation */
129 	private string actionLabel;
130 	
131 	/** Gets the application set action code */
132 	public string getActionName()
133 	{
134 		if ( actionLabel is null )
135 		{
136 			actionLabel = "";
137 		}
138 		return actionLabel;
139 	}
140 	
141 	/**
142 	 * Creates a new menu item with a label and a listener and a action.
143 	 * used for backward compatibily with DUI.
144 	 */
145 	this(string label, void delegate(MenuItem)dlg, string action)
146 	{
147 		this(label);
148 		this.actionLabel = action;
149 		addOnActivate(dlg);
150 	}
151 	
152 	/**
153 	 * Creates a new Item associated with a "activate" delegate and with a action code
154 	 * and optionally accelGroup
155 	 */
156 	public this(void delegate(MenuItem) dlg, string label, string action,
157 	bool mnemonic=true,
158 	AccelGroup accelGroup=null,
159 	char accelKey='\0',
160 	GdkModifierType modifierType=GdkModifierType.CONTROL_MASK,
161 	GtkAccelFlags accelFlags=GtkAccelFlags.VISIBLE
162 	)
163 	{
164 		this(label, mnemonic);
165 		this.actionLabel = action;
166 		addOnActivate(dlg);
167 		if ( accelGroup !is null && accelKey != '\0' )
168 		{
169 			addAccelerator("activate",accelGroup,accelKey,modifierType,accelFlags);
170 		}
171 	}
172 	
173 	/**
174 	 * Creates a new Item associated with a "activate" delegate
175 	 */
176 	public this(void delegate(MenuItem) dlg, string label, bool mnemonic=true)
177 	{
178 		this(label, mnemonic);
179 		addOnActivate(dlg);
180 	}
181 	
182 	/**
183 	 * Creates a new GtkMenuItem whose child is a GtkLabel.
184 	 * Params:
185 	 *  label = the text for the label
186 	 *  mnemonic = if true the label
187 	 *  will be created using gtk_label_new_with_mnemonic(), so underscores
188 	 *  in label indicate the mnemonic for the menu item.
189 	 * Throws: ConstructionException GTK+ fails to create the object.
190 	 */
191 	public this (string label, bool mnemonic=true)
192 	{
193 		GtkMenuItem* p;
194 		
195 		if ( mnemonic )
196 		{
197 			// GtkWidget* gtk_menu_item_new_with_mnemonic (const gchar *label);
198 			p = cast(GtkMenuItem*)gtk_menu_item_new_with_mnemonic(Str.toStringz(label));
199 		}
200 		else
201 		{
202 			// GtkWidget* gtk_menu_item_new_with_label (const gchar *label);
203 			p = cast(GtkMenuItem*)gtk_menu_item_new_with_label(Str.toStringz(label));
204 		}
205 		
206 		if(p is null)
207 		{
208 			throw new ConstructionException("null returned by gtk_menu_item_new_with_");
209 		}
210 		
211 		this(p);
212 		
213 		setName(label);
214 	}
215 
216 	/**
217 	 */
218 
219 	/** */
220 	public static GType getType()
221 	{
222 		return gtk_menu_item_get_type();
223 	}
224 
225 	/**
226 	 * Creates a new #GtkMenuItem.
227 	 *
228 	 * Returns: the newly created #GtkMenuItem
229 	 *
230 	 * Throws: ConstructionException GTK+ fails to create the object.
231 	 */
232 	public this()
233 	{
234 		auto p = gtk_menu_item_new();
235 		
236 		if(p is null)
237 		{
238 			throw new ConstructionException("null returned by new");
239 		}
240 		
241 		this(cast(GtkMenuItem*) p);
242 	}
243 
244 	/**
245 	 * Emits the #GtkMenuItem::activate signal on the given item
246 	 */
247 	public void itemActivate()
248 	{
249 		gtk_menu_item_activate(gtkMenuItem);
250 	}
251 
252 	/**
253 	 * Emits the #GtkMenuItem::deselect signal on the given item.
254 	 */
255 	public void deselect()
256 	{
257 		gtk_menu_item_deselect(gtkMenuItem);
258 	}
259 
260 	/**
261 	 * Retrieve the accelerator path that was previously set on @menu_item.
262 	 *
263 	 * See gtk_menu_item_set_accel_path() for details.
264 	 *
265 	 * Returns: the accelerator path corresponding to
266 	 *     this menu item’s functionality, or %NULL if not set
267 	 *
268 	 * Since: 2.14
269 	 */
270 	public string getAccelPath()
271 	{
272 		return Str.toString(gtk_menu_item_get_accel_path(gtkMenuItem));
273 	}
274 
275 	/**
276 	 * Sets @text on the @menu_item label
277 	 *
278 	 * Returns: The text in the @menu_item label. This is the internal
279 	 *     string used by the label, and must not be modified.
280 	 *
281 	 * Since: 2.16
282 	 */
283 	public string getLabel()
284 	{
285 		return Str.toString(gtk_menu_item_get_label(gtkMenuItem));
286 	}
287 
288 	/**
289 	 * Returns whether the @menu_item reserves space for
290 	 * the submenu indicator, regardless if it has a submenu
291 	 * or not.
292 	 *
293 	 * Returns: %TRUE if @menu_item always reserves space for the
294 	 *     submenu indicator
295 	 *
296 	 * Since: 3.0
297 	 */
298 	public bool getReserveIndicator()
299 	{
300 		return gtk_menu_item_get_reserve_indicator(gtkMenuItem) != 0;
301 	}
302 
303 	/**
304 	 * Gets whether the menu item appears justified at the right
305 	 * side of the menu bar.
306 	 *
307 	 * Deprecated: See gtk_menu_item_set_right_justified()
308 	 *
309 	 * Returns: %TRUE if the menu item will appear at the
310 	 *     far right if added to a menu bar.
311 	 */
312 	public bool getRightJustified()
313 	{
314 		return gtk_menu_item_get_right_justified(gtkMenuItem) != 0;
315 	}
316 
317 	/**
318 	 * Gets the submenu underneath this menu item, if any.
319 	 * See gtk_menu_item_set_submenu().
320 	 *
321 	 * Returns: submenu for this menu item, or %NULL if none
322 	 */
323 	public Widget getSubmenu()
324 	{
325 		auto p = gtk_menu_item_get_submenu(gtkMenuItem);
326 		
327 		if(p is null)
328 		{
329 			return null;
330 		}
331 		
332 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
333 	}
334 
335 	/**
336 	 * Checks if an underline in the text indicates the next character
337 	 * should be used for the mnemonic accelerator key.
338 	 *
339 	 * Returns: %TRUE if an embedded underline in the label
340 	 *     indicates the mnemonic accelerator key.
341 	 *
342 	 * Since: 2.16
343 	 */
344 	public bool getUseUnderline()
345 	{
346 		return gtk_menu_item_get_use_underline(gtkMenuItem) != 0;
347 	}
348 
349 	/**
350 	 * Emits the #GtkMenuItem::select signal on the given item.
351 	 */
352 	public void select()
353 	{
354 		gtk_menu_item_select(gtkMenuItem);
355 	}
356 
357 	/**
358 	 * Set the accelerator path on @menu_item, through which runtime
359 	 * changes of the menu item’s accelerator caused by the user can be
360 	 * identified and saved to persistent storage (see gtk_accel_map_save()
361 	 * on this). To set up a default accelerator for this menu item, call
362 	 * gtk_accel_map_add_entry() with the same @accel_path. See also
363 	 * gtk_accel_map_add_entry() on the specifics of accelerator paths,
364 	 * and gtk_menu_set_accel_path() for a more convenient variant of
365 	 * this function.
366 	 *
367 	 * This function is basically a convenience wrapper that handles
368 	 * calling gtk_widget_set_accel_path() with the appropriate accelerator
369 	 * group for the menu item.
370 	 *
371 	 * Note that you do need to set an accelerator on the parent menu with
372 	 * gtk_menu_set_accel_group() for this to work.
373 	 *
374 	 * Note that @accel_path string will be stored in a #GQuark.
375 	 * Therefore, if you pass a static string, you can save some memory
376 	 * by interning it first with g_intern_static_string().
377 	 *
378 	 * Params:
379 	 *     accelPath = accelerator path, corresponding to this menu
380 	 *         item’s functionality, or %NULL to unset the current path.
381 	 */
382 	public void setAccelPath(string accelPath)
383 	{
384 		gtk_menu_item_set_accel_path(gtkMenuItem, Str.toStringz(accelPath));
385 	}
386 
387 	/**
388 	 * Sets @text on the @menu_item label
389 	 *
390 	 * Params:
391 	 *     label = the text you want to set
392 	 *
393 	 * Since: 2.16
394 	 */
395 	public void setLabel(string label)
396 	{
397 		gtk_menu_item_set_label(gtkMenuItem, Str.toStringz(label));
398 	}
399 
400 	/**
401 	 * Sets whether the @menu_item should reserve space for
402 	 * the submenu indicator, regardless if it actually has
403 	 * a submenu or not.
404 	 *
405 	 * There should be little need for applications to call
406 	 * this functions.
407 	 *
408 	 * Params:
409 	 *     reserve = the new value
410 	 *
411 	 * Since: 3.0
412 	 */
413 	public void setReserveIndicator(bool reserve)
414 	{
415 		gtk_menu_item_set_reserve_indicator(gtkMenuItem, reserve);
416 	}
417 
418 	/**
419 	 * Sets whether the menu item appears justified at the right
420 	 * side of a menu bar. This was traditionally done for “Help”
421 	 * menu items, but is now considered a bad idea. (If the widget
422 	 * layout is reversed for a right-to-left language like Hebrew
423 	 * or Arabic, right-justified-menu-items appear at the left.)
424 	 *
425 	 * Deprecated: If you insist on using it, use
426 	 * gtk_widget_set_hexpand() and gtk_widget_set_halign().
427 	 *
428 	 * Params:
429 	 *     rightJustified = if %TRUE the menu item will appear at the
430 	 *         far right if added to a menu bar
431 	 */
432 	public void setRightJustified(bool rightJustified)
433 	{
434 		gtk_menu_item_set_right_justified(gtkMenuItem, rightJustified);
435 	}
436 
437 	/**
438 	 * Sets or replaces the menu item’s submenu, or removes it when a %NULL
439 	 * submenu is passed.
440 	 *
441 	 * Params:
442 	 *     submenu = the submenu, or %NULL
443 	 */
444 	public void setSubmenu(Menu submenu)
445 	{
446 		gtk_menu_item_set_submenu(gtkMenuItem, (submenu is null) ? null : cast(GtkWidget*)submenu.getMenuStruct());
447 	}
448 
449 	/**
450 	 * If true, an underline in the text indicates the next character
451 	 * should be used for the mnemonic accelerator key.
452 	 *
453 	 * Params:
454 	 *     setting = %TRUE if underlines in the text indicate mnemonics
455 	 *
456 	 * Since: 2.16
457 	 */
458 	public void setUseUnderline(bool setting)
459 	{
460 		gtk_menu_item_set_use_underline(gtkMenuItem, setting);
461 	}
462 
463 	/**
464 	 * Emits the #GtkMenuItem::toggle-size-allocate signal on the given item.
465 	 *
466 	 * Params:
467 	 *     allocation = the allocation to use as signal data.
468 	 */
469 	public void toggleSizeAllocate(int allocation)
470 	{
471 		gtk_menu_item_toggle_size_allocate(gtkMenuItem, allocation);
472 	}
473 
474 	/**
475 	 * Emits the #GtkMenuItem::toggle-size-request signal on the given item.
476 	 *
477 	 * Params:
478 	 *     requisition = the requisition to use as signal data.
479 	 */
480 	public void toggleSizeRequest(ref int requisition)
481 	{
482 		gtk_menu_item_toggle_size_request(gtkMenuItem, &requisition);
483 	}
484 
485 	protected class OnActivateDelegateWrapper
486 	{
487 		static OnActivateDelegateWrapper[] listeners;
488 		void delegate(MenuItem) dlg;
489 		gulong handlerId;
490 		
491 		this(void delegate(MenuItem) dlg)
492 		{
493 			this.dlg = dlg;
494 			this.listeners ~= this;
495 		}
496 		
497 		void remove(OnActivateDelegateWrapper source)
498 		{
499 			foreach(index, wrapper; listeners)
500 			{
501 				if (wrapper.handlerId == source.handlerId)
502 				{
503 					listeners[index] = null;
504 					listeners = std.algorithm.remove(listeners, index);
505 					break;
506 				}
507 			}
508 		}
509 	}
510 
511 	/**
512 	 * Emitted when the item is activated.
513 	 */
514 	gulong addOnActivate(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
515 	{
516 		auto wrapper = new OnActivateDelegateWrapper(dlg);
517 		wrapper.handlerId = Signals.connectData(
518 			this,
519 			"activate",
520 			cast(GCallback)&callBackActivate,
521 			cast(void*)wrapper,
522 			cast(GClosureNotify)&callBackActivateDestroy,
523 			connectFlags);
524 		return wrapper.handlerId;
525 	}
526 	
527 	extern(C) static void callBackActivate(GtkMenuItem* menuitemStruct, OnActivateDelegateWrapper wrapper)
528 	{
529 		wrapper.dlg(wrapper.outer);
530 	}
531 	
532 	extern(C) static void callBackActivateDestroy(OnActivateDelegateWrapper wrapper, GClosure* closure)
533 	{
534 		wrapper.remove(wrapper);
535 	}
536 
537 	protected class OnActivateItemDelegateWrapper
538 	{
539 		static OnActivateItemDelegateWrapper[] listeners;
540 		void delegate(MenuItem) dlg;
541 		gulong handlerId;
542 		
543 		this(void delegate(MenuItem) dlg)
544 		{
545 			this.dlg = dlg;
546 			this.listeners ~= this;
547 		}
548 		
549 		void remove(OnActivateItemDelegateWrapper source)
550 		{
551 			foreach(index, wrapper; listeners)
552 			{
553 				if (wrapper.handlerId == source.handlerId)
554 				{
555 					listeners[index] = null;
556 					listeners = std.algorithm.remove(listeners, index);
557 					break;
558 				}
559 			}
560 		}
561 	}
562 
563 	/**
564 	 * Emitted when the item is activated, but also if the menu item has a
565 	 * submenu. For normal applications, the relevant signal is
566 	 * #GtkMenuItem::activate.
567 	 */
568 	gulong addOnActivateItem(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
569 	{
570 		auto wrapper = new OnActivateItemDelegateWrapper(dlg);
571 		wrapper.handlerId = Signals.connectData(
572 			this,
573 			"activate-item",
574 			cast(GCallback)&callBackActivateItem,
575 			cast(void*)wrapper,
576 			cast(GClosureNotify)&callBackActivateItemDestroy,
577 			connectFlags);
578 		return wrapper.handlerId;
579 	}
580 	
581 	extern(C) static void callBackActivateItem(GtkMenuItem* menuitemStruct, OnActivateItemDelegateWrapper wrapper)
582 	{
583 		wrapper.dlg(wrapper.outer);
584 	}
585 	
586 	extern(C) static void callBackActivateItemDestroy(OnActivateItemDelegateWrapper wrapper, GClosure* closure)
587 	{
588 		wrapper.remove(wrapper);
589 	}
590 
591 	protected class OnDeselectDelegateWrapper
592 	{
593 		static OnDeselectDelegateWrapper[] listeners;
594 		void delegate(MenuItem) dlg;
595 		gulong handlerId;
596 		
597 		this(void delegate(MenuItem) dlg)
598 		{
599 			this.dlg = dlg;
600 			this.listeners ~= this;
601 		}
602 		
603 		void remove(OnDeselectDelegateWrapper source)
604 		{
605 			foreach(index, wrapper; listeners)
606 			{
607 				if (wrapper.handlerId == source.handlerId)
608 				{
609 					listeners[index] = null;
610 					listeners = std.algorithm.remove(listeners, index);
611 					break;
612 				}
613 			}
614 		}
615 	}
616 
617 	/** */
618 	gulong addOnDeselect(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
619 	{
620 		auto wrapper = new OnDeselectDelegateWrapper(dlg);
621 		wrapper.handlerId = Signals.connectData(
622 			this,
623 			"deselect",
624 			cast(GCallback)&callBackDeselect,
625 			cast(void*)wrapper,
626 			cast(GClosureNotify)&callBackDeselectDestroy,
627 			connectFlags);
628 		return wrapper.handlerId;
629 	}
630 	
631 	extern(C) static void callBackDeselect(GtkMenuItem* menuitemStruct, OnDeselectDelegateWrapper wrapper)
632 	{
633 		wrapper.dlg(wrapper.outer);
634 	}
635 	
636 	extern(C) static void callBackDeselectDestroy(OnDeselectDelegateWrapper wrapper, GClosure* closure)
637 	{
638 		wrapper.remove(wrapper);
639 	}
640 
641 	protected class OnSelectDelegateWrapper
642 	{
643 		static OnSelectDelegateWrapper[] listeners;
644 		void delegate(MenuItem) dlg;
645 		gulong handlerId;
646 		
647 		this(void delegate(MenuItem) dlg)
648 		{
649 			this.dlg = dlg;
650 			this.listeners ~= this;
651 		}
652 		
653 		void remove(OnSelectDelegateWrapper source)
654 		{
655 			foreach(index, wrapper; listeners)
656 			{
657 				if (wrapper.handlerId == source.handlerId)
658 				{
659 					listeners[index] = null;
660 					listeners = std.algorithm.remove(listeners, index);
661 					break;
662 				}
663 			}
664 		}
665 	}
666 
667 	/** */
668 	gulong addOnSelect(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
669 	{
670 		auto wrapper = new OnSelectDelegateWrapper(dlg);
671 		wrapper.handlerId = Signals.connectData(
672 			this,
673 			"select",
674 			cast(GCallback)&callBackSelect,
675 			cast(void*)wrapper,
676 			cast(GClosureNotify)&callBackSelectDestroy,
677 			connectFlags);
678 		return wrapper.handlerId;
679 	}
680 	
681 	extern(C) static void callBackSelect(GtkMenuItem* menuitemStruct, OnSelectDelegateWrapper wrapper)
682 	{
683 		wrapper.dlg(wrapper.outer);
684 	}
685 	
686 	extern(C) static void callBackSelectDestroy(OnSelectDelegateWrapper wrapper, GClosure* closure)
687 	{
688 		wrapper.remove(wrapper);
689 	}
690 
691 	protected class OnToggleSizeAllocateDelegateWrapper
692 	{
693 		static OnToggleSizeAllocateDelegateWrapper[] listeners;
694 		void delegate(int, MenuItem) dlg;
695 		gulong handlerId;
696 		
697 		this(void delegate(int, MenuItem) dlg)
698 		{
699 			this.dlg = dlg;
700 			this.listeners ~= this;
701 		}
702 		
703 		void remove(OnToggleSizeAllocateDelegateWrapper source)
704 		{
705 			foreach(index, wrapper; listeners)
706 			{
707 				if (wrapper.handlerId == source.handlerId)
708 				{
709 					listeners[index] = null;
710 					listeners = std.algorithm.remove(listeners, index);
711 					break;
712 				}
713 			}
714 		}
715 	}
716 
717 	/** */
718 	gulong addOnToggleSizeAllocate(void delegate(int, MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
719 	{
720 		auto wrapper = new OnToggleSizeAllocateDelegateWrapper(dlg);
721 		wrapper.handlerId = Signals.connectData(
722 			this,
723 			"toggle-size-allocate",
724 			cast(GCallback)&callBackToggleSizeAllocate,
725 			cast(void*)wrapper,
726 			cast(GClosureNotify)&callBackToggleSizeAllocateDestroy,
727 			connectFlags);
728 		return wrapper.handlerId;
729 	}
730 	
731 	extern(C) static void callBackToggleSizeAllocate(GtkMenuItem* menuitemStruct, int object, OnToggleSizeAllocateDelegateWrapper wrapper)
732 	{
733 		wrapper.dlg(object, wrapper.outer);
734 	}
735 	
736 	extern(C) static void callBackToggleSizeAllocateDestroy(OnToggleSizeAllocateDelegateWrapper wrapper, GClosure* closure)
737 	{
738 		wrapper.remove(wrapper);
739 	}
740 
741 	protected class OnToggleSizeRequestDelegateWrapper
742 	{
743 		static OnToggleSizeRequestDelegateWrapper[] listeners;
744 		void delegate(void*, MenuItem) dlg;
745 		gulong handlerId;
746 		
747 		this(void delegate(void*, MenuItem) dlg)
748 		{
749 			this.dlg = dlg;
750 			this.listeners ~= this;
751 		}
752 		
753 		void remove(OnToggleSizeRequestDelegateWrapper source)
754 		{
755 			foreach(index, wrapper; listeners)
756 			{
757 				if (wrapper.handlerId == source.handlerId)
758 				{
759 					listeners[index] = null;
760 					listeners = std.algorithm.remove(listeners, index);
761 					break;
762 				}
763 			}
764 		}
765 	}
766 
767 	/** */
768 	gulong addOnToggleSizeRequest(void delegate(void*, MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
769 	{
770 		auto wrapper = new OnToggleSizeRequestDelegateWrapper(dlg);
771 		wrapper.handlerId = Signals.connectData(
772 			this,
773 			"toggle-size-request",
774 			cast(GCallback)&callBackToggleSizeRequest,
775 			cast(void*)wrapper,
776 			cast(GClosureNotify)&callBackToggleSizeRequestDestroy,
777 			connectFlags);
778 		return wrapper.handlerId;
779 	}
780 	
781 	extern(C) static void callBackToggleSizeRequest(GtkMenuItem* menuitemStruct, void* object, OnToggleSizeRequestDelegateWrapper wrapper)
782 	{
783 		wrapper.dlg(object, wrapper.outer);
784 	}
785 	
786 	extern(C) static void callBackToggleSizeRequestDestroy(OnToggleSizeRequestDelegateWrapper wrapper, GClosure* closure)
787 	{
788 		wrapper.remove(wrapper);
789 	}
790 }