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