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