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