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.MenuShell;
26 
27 private import gio.MenuModel;
28 private import glib.Str;
29 private import gobject.ObjectG;
30 private import gobject.Signals;
31 private import gtk.Container;
32 private import gtk.MenuItem;
33 private import gtk.Widget;
34 public  import gtkc.gdktypes;
35 private import gtkc.gtk;
36 public  import gtkc.gtktypes;
37 
38 
39 /**
40  * A #GtkMenuShell is the abstract base class used to derive the
41  * #GtkMenu and #GtkMenuBar subclasses.
42  * 
43  * A #GtkMenuShell is a container of #GtkMenuItem objects arranged
44  * in a list which can be navigated, selected, and activated by the
45  * user to perform application functions. A #GtkMenuItem can have a
46  * submenu associated with it, allowing for nested hierarchical menus.
47  * 
48  * # Terminology
49  * 
50  * A menu item can be “selected”, this means that it is displayed
51  * in the prelight state, and if it has a submenu, that submenu
52  * will be popped up.
53  * 
54  * A menu is “active” when it is visible onscreen and the user
55  * is selecting from it. A menubar is not active until the user
56  * clicks on one of its menuitems. When a menu is active,
57  * passing the mouse over a submenu will pop it up.
58  * 
59  * There is also is a concept of the current menu and a current
60  * menu item. The current menu item is the selected menu item
61  * that is furthest down in the hierarchy. (Every active menu shell
62  * does not necessarily contain a selected menu item, but if
63  * it does, then the parent menu shell must also contain
64  * a selected menu item.) The current menu is the menu that
65  * contains the current menu item. It will always have a GTK
66  * grab and receive all key presses.
67  */
68 public class MenuShell : Container
69 {
70 	/** the main Gtk struct */
71 	protected GtkMenuShell* gtkMenuShell;
72 
73 	/** Get the main Gtk struct */
74 	public GtkMenuShell* getMenuShellStruct()
75 	{
76 		return gtkMenuShell;
77 	}
78 
79 	/** the main Gtk struct as a void* */
80 	protected override void* getStruct()
81 	{
82 		return cast(void*)gtkMenuShell;
83 	}
84 
85 	protected override void setStruct(GObject* obj)
86 	{
87 		gtkMenuShell = cast(GtkMenuShell*)obj;
88 		super.setStruct(obj);
89 	}
90 
91 	/**
92 	 * Sets our main struct and passes it to the parent class.
93 	 */
94 	public this (GtkMenuShell* gtkMenuShell, bool ownedRef = false)
95 	{
96 		this.gtkMenuShell = gtkMenuShell;
97 		super(cast(GtkContainer*)gtkMenuShell, ownedRef);
98 	}
99 
100 	/**
101 	 */
102 
103 	public static GType getType()
104 	{
105 		return gtk_menu_shell_get_type();
106 	}
107 
108 	/**
109 	 * Activates the menu item within the menu shell.
110 	 *
111 	 * Params:
112 	 *     menuItem = the #GtkMenuItem to activate
113 	 *     forceDeactivate = if %TRUE, force the deactivation of the
114 	 *         menu shell after the menu item is activated
115 	 */
116 	public void activateItem(Widget menuItem, bool forceDeactivate)
117 	{
118 		gtk_menu_shell_activate_item(gtkMenuShell, (menuItem is null) ? null : menuItem.getWidgetStruct(), forceDeactivate);
119 	}
120 
121 	/**
122 	 * Adds a new #GtkMenuItem to the end of the menu shell's
123 	 * item list.
124 	 *
125 	 * Params:
126 	 *     child = The #GtkMenuItem to add
127 	 */
128 	public void append(MenuItem child)
129 	{
130 		gtk_menu_shell_append(gtkMenuShell, (child is null) ? null : cast(GtkWidget*)child.getMenuItemStruct());
131 	}
132 
133 	/**
134 	 * Establishes a binding between a #GtkMenuShell and a #GMenuModel.
135 	 *
136 	 * The contents of @shell are removed and then refilled with menu items
137 	 * according to @model.  When @model changes, @shell is updated.
138 	 * Calling this function twice on @shell with different @model will
139 	 * cause the first binding to be replaced with a binding to the new
140 	 * model. If @model is %NULL then any previous binding is undone and
141 	 * all children are removed.
142 	 *
143 	 * @with_separators determines if toplevel items (eg: sections) have
144 	 * separators inserted between them.  This is typically desired for
145 	 * menus but doesn’t make sense for menubars.
146 	 *
147 	 * If @action_namespace is non-%NULL then the effect is as if all
148 	 * actions mentioned in the @model have their names prefixed with the
149 	 * namespace, plus a dot.  For example, if the action “quit” is
150 	 * mentioned and @action_namespace is “app” then the effective action
151 	 * name is “app.quit”.
152 	 *
153 	 * This function uses #GtkActionable to define the action name and
154 	 * target values on the created menu items.  If you want to use an
155 	 * action group other than “app” and “win”, or if you want to use a
156 	 * #GtkMenuShell outside of a #GtkApplicationWindow, then you will need
157 	 * to attach your own action group to the widget hierarchy using
158 	 * gtk_widget_insert_action_group().  As an example, if you created a
159 	 * group with a “quit” action and inserted it with the name “mygroup”
160 	 * then you would use the action name “mygroup.quit” in your
161 	 * #GMenuModel.
162 	 *
163 	 * For most cases you are probably better off using
164 	 * gtk_menu_new_from_model() or gtk_menu_bar_new_from_model() or just
165 	 * directly passing the #GMenuModel to gtk_application_set_app_menu() or
166 	 * gtk_application_set_menubar().
167 	 *
168 	 * Params:
169 	 *     model = the #GMenuModel to bind to or %NULL to remove
170 	 *         binding
171 	 *     actionNamespace = the namespace for actions in @model
172 	 *     withSeparators = %TRUE if toplevel items in @shell should have
173 	 *         separators between them
174 	 *
175 	 * Since: 3.6
176 	 */
177 	public void bindModel(MenuModel model, string actionNamespace, bool withSeparators)
178 	{
179 		gtk_menu_shell_bind_model(gtkMenuShell, (model is null) ? null : model.getMenuModelStruct(), Str.toStringz(actionNamespace), withSeparators);
180 	}
181 
182 	/**
183 	 * Cancels the selection within the menu shell.
184 	 *
185 	 * Since: 2.4
186 	 */
187 	public void cancel()
188 	{
189 		gtk_menu_shell_cancel(gtkMenuShell);
190 	}
191 
192 	/**
193 	 * Deactivates the menu shell.
194 	 *
195 	 * Typically this results in the menu shell being erased
196 	 * from the screen.
197 	 */
198 	public void deactivate()
199 	{
200 		gtk_menu_shell_deactivate(gtkMenuShell);
201 	}
202 
203 	/**
204 	 * Deselects the currently selected item from the menu shell,
205 	 * if any.
206 	 */
207 	public void deselect()
208 	{
209 		gtk_menu_shell_deselect(gtkMenuShell);
210 	}
211 
212 	/**
213 	 * Gets the parent menu shell.
214 	 *
215 	 * The parent menu shell of a submenu is the #GtkMenu or #GtkMenuBar
216 	 * from which it was opened up.
217 	 *
218 	 * Return: the parent #GtkMenuShell
219 	 *
220 	 * Since: 3.0
221 	 */
222 	public Widget getParentShell()
223 	{
224 		auto p = gtk_menu_shell_get_parent_shell(gtkMenuShell);
225 		
226 		if(p is null)
227 		{
228 			return null;
229 		}
230 		
231 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
232 	}
233 
234 	/**
235 	 * Gets the currently selected item.
236 	 *
237 	 * Return: the currently selected item
238 	 *
239 	 * Since: 3.0
240 	 */
241 	public Widget getSelectedItem()
242 	{
243 		auto p = gtk_menu_shell_get_selected_item(gtkMenuShell);
244 		
245 		if(p is null)
246 		{
247 			return null;
248 		}
249 		
250 		return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
251 	}
252 
253 	/**
254 	 * Returns %TRUE if the menu shell will take the keyboard focus on popup.
255 	 *
256 	 * Return: %TRUE if the menu shell will take the keyboard focus on popup.
257 	 *
258 	 * Since: 2.8
259 	 */
260 	public bool getTakeFocus()
261 	{
262 		return gtk_menu_shell_get_take_focus(gtkMenuShell) != 0;
263 	}
264 
265 	/**
266 	 * Adds a new #GtkMenuItem to the menu shell’s item list
267 	 * at the position indicated by @position.
268 	 *
269 	 * Params:
270 	 *     child = The #GtkMenuItem to add
271 	 *     position = The position in the item list where @child
272 	 *         is added. Positions are numbered from 0 to n-1
273 	 */
274 	public void insert(Widget child, int position)
275 	{
276 		gtk_menu_shell_insert(gtkMenuShell, (child is null) ? null : child.getWidgetStruct(), position);
277 	}
278 
279 	/**
280 	 * Adds a new #GtkMenuItem to the beginning of the menu shell's
281 	 * item list.
282 	 *
283 	 * Params:
284 	 *     child = The #GtkMenuItem to add
285 	 */
286 	public void prepend(Widget child)
287 	{
288 		gtk_menu_shell_prepend(gtkMenuShell, (child is null) ? null : child.getWidgetStruct());
289 	}
290 
291 	/**
292 	 * Select the first visible or selectable child of the menu shell;
293 	 * don’t select tearoff items unless the only item is a tearoff
294 	 * item.
295 	 *
296 	 * Params:
297 	 *     searchSensitive = if %TRUE, search for the first selectable
298 	 *         menu item, otherwise select nothing if
299 	 *         the first item isn’t sensitive. This
300 	 *         should be %FALSE if the menu is being
301 	 *         popped up initially.
302 	 *
303 	 * Since: 2.2
304 	 */
305 	public void selectFirst(bool searchSensitive)
306 	{
307 		gtk_menu_shell_select_first(gtkMenuShell, searchSensitive);
308 	}
309 
310 	/**
311 	 * Selects the menu item from the menu shell.
312 	 *
313 	 * Params:
314 	 *     menuItem = The #GtkMenuItem to select
315 	 */
316 	public void selectItem(Widget menuItem)
317 	{
318 		gtk_menu_shell_select_item(gtkMenuShell, (menuItem is null) ? null : menuItem.getWidgetStruct());
319 	}
320 
321 	/**
322 	 * If @take_focus is %TRUE (the default) the menu shell will take
323 	 * the keyboard focus so that it will receive all keyboard events
324 	 * which is needed to enable keyboard navigation in menus.
325 	 *
326 	 * Setting @take_focus to %FALSE is useful only for special applications
327 	 * like virtual keyboard implementations which should not take keyboard
328 	 * focus.
329 	 *
330 	 * The @take_focus state of a menu or menu bar is automatically
331 	 * propagated to submenus whenever a submenu is popped up, so you
332 	 * don’t have to worry about recursively setting it for your entire
333 	 * menu hierarchy. Only when programmatically picking a submenu and
334 	 * popping it up manually, the @take_focus property of the submenu
335 	 * needs to be set explicitly.
336 	 *
337 	 * Note that setting it to %FALSE has side-effects:
338 	 *
339 	 * If the focus is in some other app, it keeps the focus and keynav in
340 	 * the menu doesn’t work. Consequently, keynav on the menu will only
341 	 * work if the focus is on some toplevel owned by the onscreen keyboard.
342 	 *
343 	 * To avoid confusing the user, menus with @take_focus set to %FALSE
344 	 * should not display mnemonics or accelerators, since it cannot be
345 	 * guaranteed that they will work.
346 	 *
347 	 * See also gdk_keyboard_grab()
348 	 *
349 	 * Params:
350 	 *     takeFocus = %TRUE if the menu shell should take the keyboard
351 	 *         focus on popup
352 	 *
353 	 * Since: 2.8
354 	 */
355 	public void setTakeFocus(bool takeFocus)
356 	{
357 		gtk_menu_shell_set_take_focus(gtkMenuShell, takeFocus);
358 	}
359 
360 	int[string] connectedSignals;
361 
362 	void delegate(bool, MenuShell)[] onActivateCurrentListeners;
363 	/**
364 	 * An action signal that activates the current menu item within
365 	 * the menu shell.
366 	 *
367 	 * Params:
368 	 *     forceHide = if %TRUE, hide the menu after activating the menu item
369 	 */
370 	void addOnActivateCurrent(void delegate(bool, MenuShell) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
371 	{
372 		if ( "activate-current" !in connectedSignals )
373 		{
374 			Signals.connectData(
375 				this,
376 				"activate-current",
377 				cast(GCallback)&callBackActivateCurrent,
378 				cast(void*)this,
379 				null,
380 				connectFlags);
381 			connectedSignals["activate-current"] = 1;
382 		}
383 		onActivateCurrentListeners ~= dlg;
384 	}
385 	extern(C) static void callBackActivateCurrent(GtkMenuShell* menushellStruct, bool forceHide, MenuShell _menushell)
386 	{
387 		foreach ( void delegate(bool, MenuShell) dlg; _menushell.onActivateCurrentListeners )
388 		{
389 			dlg(forceHide, _menushell);
390 		}
391 	}
392 
393 	void delegate(MenuShell)[] onCancelListeners;
394 	/**
395 	 * An action signal which cancels the selection within the menu shell.
396 	 * Causes the #GtkMenuShell::selection-done signal to be emitted.
397 	 */
398 	void addOnCancel(void delegate(MenuShell) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
399 	{
400 		if ( "cancel" !in connectedSignals )
401 		{
402 			Signals.connectData(
403 				this,
404 				"cancel",
405 				cast(GCallback)&callBackCancel,
406 				cast(void*)this,
407 				null,
408 				connectFlags);
409 			connectedSignals["cancel"] = 1;
410 		}
411 		onCancelListeners ~= dlg;
412 	}
413 	extern(C) static void callBackCancel(GtkMenuShell* menushellStruct, MenuShell _menushell)
414 	{
415 		foreach ( void delegate(MenuShell) dlg; _menushell.onCancelListeners )
416 		{
417 			dlg(_menushell);
418 		}
419 	}
420 
421 	void delegate(GtkDirectionType, MenuShell)[] onCycleFocusListeners;
422 	/**
423 	 * A keybinding signal which moves the focus in the
424 	 * given @direction.
425 	 *
426 	 * Params:
427 	 *     direction = the direction to cycle in
428 	 */
429 	void addOnCycleFocus(void delegate(GtkDirectionType, MenuShell) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
430 	{
431 		if ( "cycle-focus" !in connectedSignals )
432 		{
433 			Signals.connectData(
434 				this,
435 				"cycle-focus",
436 				cast(GCallback)&callBackCycleFocus,
437 				cast(void*)this,
438 				null,
439 				connectFlags);
440 			connectedSignals["cycle-focus"] = 1;
441 		}
442 		onCycleFocusListeners ~= dlg;
443 	}
444 	extern(C) static void callBackCycleFocus(GtkMenuShell* menushellStruct, GtkDirectionType direction, MenuShell _menushell)
445 	{
446 		foreach ( void delegate(GtkDirectionType, MenuShell) dlg; _menushell.onCycleFocusListeners )
447 		{
448 			dlg(direction, _menushell);
449 		}
450 	}
451 
452 	void delegate(MenuShell)[] onDeactivateListeners;
453 	/**
454 	 * This signal is emitted when a menu shell is deactivated.
455 	 */
456 	void addOnDeactivate(void delegate(MenuShell) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
457 	{
458 		if ( "deactivate" !in connectedSignals )
459 		{
460 			Signals.connectData(
461 				this,
462 				"deactivate",
463 				cast(GCallback)&callBackDeactivate,
464 				cast(void*)this,
465 				null,
466 				connectFlags);
467 			connectedSignals["deactivate"] = 1;
468 		}
469 		onDeactivateListeners ~= dlg;
470 	}
471 	extern(C) static void callBackDeactivate(GtkMenuShell* menushellStruct, MenuShell _menushell)
472 	{
473 		foreach ( void delegate(MenuShell) dlg; _menushell.onDeactivateListeners )
474 		{
475 			dlg(_menushell);
476 		}
477 	}
478 
479 	void delegate(Widget, int, MenuShell)[] onInsertListeners;
480 	/**
481 	 * The ::insert signal is emitted when a new #GtkMenuItem is added to
482 	 * a #GtkMenuShell.  A separate signal is used instead of
483 	 * GtkContainer::add because of the need for an additional position
484 	 * parameter.
485 	 *
486 	 * The inverse of this signal is the GtkContainer::removed signal.
487 	 *
488 	 * Params:
489 	 *     child = the #GtkMenuItem that is being inserted
490 	 *     position = the position at which the insert occurs
491 	 *
492 	 * Since: 3.2
493 	 */
494 	void addOnInsert(void delegate(Widget, int, MenuShell) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
495 	{
496 		if ( "insert" !in connectedSignals )
497 		{
498 			Signals.connectData(
499 				this,
500 				"insert",
501 				cast(GCallback)&callBackInsert,
502 				cast(void*)this,
503 				null,
504 				connectFlags);
505 			connectedSignals["insert"] = 1;
506 		}
507 		onInsertListeners ~= dlg;
508 	}
509 	extern(C) static void callBackInsert(GtkMenuShell* menushellStruct, GtkWidget* child, int position, MenuShell _menushell)
510 	{
511 		foreach ( void delegate(Widget, int, MenuShell) dlg; _menushell.onInsertListeners )
512 		{
513 			dlg(ObjectG.getDObject!(Widget)(child), position, _menushell);
514 		}
515 	}
516 
517 	void delegate(GtkMenuDirectionType, MenuShell)[] onMoveCurrentListeners;
518 	/**
519 	 * An keybinding signal which moves the current menu item
520 	 * in the direction specified by @direction.
521 	 *
522 	 * Params:
523 	 *     direction = the direction to move
524 	 */
525 	void addOnMoveCurrent(void delegate(GtkMenuDirectionType, MenuShell) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
526 	{
527 		if ( "move-current" !in connectedSignals )
528 		{
529 			Signals.connectData(
530 				this,
531 				"move-current",
532 				cast(GCallback)&callBackMoveCurrent,
533 				cast(void*)this,
534 				null,
535 				connectFlags);
536 			connectedSignals["move-current"] = 1;
537 		}
538 		onMoveCurrentListeners ~= dlg;
539 	}
540 	extern(C) static void callBackMoveCurrent(GtkMenuShell* menushellStruct, GtkMenuDirectionType direction, MenuShell _menushell)
541 	{
542 		foreach ( void delegate(GtkMenuDirectionType, MenuShell) dlg; _menushell.onMoveCurrentListeners )
543 		{
544 			dlg(direction, _menushell);
545 		}
546 	}
547 
548 	bool delegate(int, MenuShell)[] onMoveSelectedListeners;
549 	/**
550 	 * The ::move-selected signal is emitted to move the selection to
551 	 * another item.
552 	 *
553 	 * Params:
554 	 *     distance = +1 to move to the next item, -1 to move to the previous
555 	 *
556 	 * Return: %TRUE to stop the signal emission, %FALSE to continue
557 	 *
558 	 * Since: 2.12
559 	 */
560 	void addOnMoveSelected(bool delegate(int, MenuShell) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
561 	{
562 		if ( "move-selected" !in connectedSignals )
563 		{
564 			Signals.connectData(
565 				this,
566 				"move-selected",
567 				cast(GCallback)&callBackMoveSelected,
568 				cast(void*)this,
569 				null,
570 				connectFlags);
571 			connectedSignals["move-selected"] = 1;
572 		}
573 		onMoveSelectedListeners ~= dlg;
574 	}
575 	extern(C) static int callBackMoveSelected(GtkMenuShell* menushellStruct, int distance, MenuShell _menushell)
576 	{
577 		foreach ( bool delegate(int, MenuShell) dlg; _menushell.onMoveSelectedListeners )
578 		{
579 			if ( dlg(distance, _menushell) )
580 			{
581 				return 1;
582 			}
583 		}
584 		
585 		return 0;
586 	}
587 
588 	void delegate(MenuShell)[] onSelectionDoneListeners;
589 	/**
590 	 * This signal is emitted when a selection has been
591 	 * completed within a menu shell.
592 	 */
593 	void addOnSelectionDone(void delegate(MenuShell) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
594 	{
595 		if ( "selection-done" !in connectedSignals )
596 		{
597 			Signals.connectData(
598 				this,
599 				"selection-done",
600 				cast(GCallback)&callBackSelectionDone,
601 				cast(void*)this,
602 				null,
603 				connectFlags);
604 			connectedSignals["selection-done"] = 1;
605 		}
606 		onSelectionDoneListeners ~= dlg;
607 	}
608 	extern(C) static void callBackSelectionDone(GtkMenuShell* menushellStruct, MenuShell _menushell)
609 	{
610 		foreach ( void delegate(MenuShell) dlg; _menushell.onSelectionDoneListeners )
611 		{
612 			dlg(_menushell);
613 		}
614 	}
615 }