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