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