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 }