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  * # 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 	 * Return: 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 	 * Return: 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 	 * Return: 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 	 * Return: %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 	 * Return: %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 	 * Return: 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 	 * Return: %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 	int[string] connectedSignals;
486 
487 	void delegate(MenuItem)[] onActivateListeners;
488 	/**
489 	 * Emitted when the item is activated.
490 	 */
491 	void addOnActivate(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
492 	{
493 		if ( "activate" !in connectedSignals )
494 		{
495 			Signals.connectData(
496 				this,
497 				"activate",
498 				cast(GCallback)&callBackActivate,
499 				cast(void*)this,
500 				null,
501 				connectFlags);
502 			connectedSignals["activate"] = 1;
503 		}
504 		onActivateListeners ~= dlg;
505 	}
506 	extern(C) static void callBackActivate(GtkMenuItem* menuitemStruct, MenuItem _menuitem)
507 	{
508 		foreach ( void delegate(MenuItem) dlg; _menuitem.onActivateListeners )
509 		{
510 			dlg(_menuitem);
511 		}
512 	}
513 
514 	void delegate(MenuItem)[] onActivateItemListeners;
515 	/**
516 	 * Emitted when the item is activated, but also if the menu item has a
517 	 * submenu. For normal applications, the relevant signal is
518 	 * #GtkMenuItem::activate.
519 	 */
520 	void addOnActivateItem(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
521 	{
522 		if ( "activate-item" !in connectedSignals )
523 		{
524 			Signals.connectData(
525 				this,
526 				"activate-item",
527 				cast(GCallback)&callBackActivateItem,
528 				cast(void*)this,
529 				null,
530 				connectFlags);
531 			connectedSignals["activate-item"] = 1;
532 		}
533 		onActivateItemListeners ~= dlg;
534 	}
535 	extern(C) static void callBackActivateItem(GtkMenuItem* menuitemStruct, MenuItem _menuitem)
536 	{
537 		foreach ( void delegate(MenuItem) dlg; _menuitem.onActivateItemListeners )
538 		{
539 			dlg(_menuitem);
540 		}
541 	}
542 
543 	void delegate(MenuItem)[] onDeselectListeners;
544 	/** */
545 	void addOnDeselect(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
546 	{
547 		if ( "deselect" !in connectedSignals )
548 		{
549 			Signals.connectData(
550 				this,
551 				"deselect",
552 				cast(GCallback)&callBackDeselect,
553 				cast(void*)this,
554 				null,
555 				connectFlags);
556 			connectedSignals["deselect"] = 1;
557 		}
558 		onDeselectListeners ~= dlg;
559 	}
560 	extern(C) static void callBackDeselect(GtkMenuItem* menuitemStruct, MenuItem _menuitem)
561 	{
562 		foreach ( void delegate(MenuItem) dlg; _menuitem.onDeselectListeners )
563 		{
564 			dlg(_menuitem);
565 		}
566 	}
567 
568 	void delegate(MenuItem)[] onSelectListeners;
569 	/** */
570 	void addOnSelect(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
571 	{
572 		if ( "select" !in connectedSignals )
573 		{
574 			Signals.connectData(
575 				this,
576 				"select",
577 				cast(GCallback)&callBackSelect,
578 				cast(void*)this,
579 				null,
580 				connectFlags);
581 			connectedSignals["select"] = 1;
582 		}
583 		onSelectListeners ~= dlg;
584 	}
585 	extern(C) static void callBackSelect(GtkMenuItem* menuitemStruct, MenuItem _menuitem)
586 	{
587 		foreach ( void delegate(MenuItem) dlg; _menuitem.onSelectListeners )
588 		{
589 			dlg(_menuitem);
590 		}
591 	}
592 
593 	void delegate(int, MenuItem)[] onToggleSizeAllocateListeners;
594 	/** */
595 	void addOnToggleSizeAllocate(void delegate(int, MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
596 	{
597 		if ( "toggle-size-allocate" !in connectedSignals )
598 		{
599 			Signals.connectData(
600 				this,
601 				"toggle-size-allocate",
602 				cast(GCallback)&callBackToggleSizeAllocate,
603 				cast(void*)this,
604 				null,
605 				connectFlags);
606 			connectedSignals["toggle-size-allocate"] = 1;
607 		}
608 		onToggleSizeAllocateListeners ~= dlg;
609 	}
610 	extern(C) static void callBackToggleSizeAllocate(GtkMenuItem* menuitemStruct, int object, MenuItem _menuitem)
611 	{
612 		foreach ( void delegate(int, MenuItem) dlg; _menuitem.onToggleSizeAllocateListeners )
613 		{
614 			dlg(object, _menuitem);
615 		}
616 	}
617 
618 	void delegate(void*, MenuItem)[] onToggleSizeRequestListeners;
619 	/** */
620 	void addOnToggleSizeRequest(void delegate(void*, MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
621 	{
622 		if ( "toggle-size-request" !in connectedSignals )
623 		{
624 			Signals.connectData(
625 				this,
626 				"toggle-size-request",
627 				cast(GCallback)&callBackToggleSizeRequest,
628 				cast(void*)this,
629 				null,
630 				connectFlags);
631 			connectedSignals["toggle-size-request"] = 1;
632 		}
633 		onToggleSizeRequestListeners ~= dlg;
634 	}
635 	extern(C) static void callBackToggleSizeRequest(GtkMenuItem* menuitemStruct, void* object, MenuItem _menuitem)
636 	{
637 		foreach ( void delegate(void*, MenuItem) dlg; _menuitem.onToggleSizeRequestListeners )
638 		{
639 			dlg(object, _menuitem);
640 		}
641 	}
642 }