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.Menu; 26 27 private import gdk.Device; 28 private import gdk.Event; 29 private import gdk.MonitorG; 30 private import gdk.Screen; 31 private import gdk.Window; 32 private import gio.MenuModel; 33 private import glib.ConstructionException; 34 private import glib.ListG; 35 private import glib.Str; 36 private import gobject.ObjectG; 37 private import gobject.Signals; 38 private import gtk.AccelGroup; 39 private import gtk.MenuItem; 40 private import gtk.MenuShell; 41 private import gtk.Widget; 42 private import gtk.c.functions; 43 public import gtk.c.types; 44 public import gtkc.gtktypes; 45 private import std.algorithm; 46 47 48 /** 49 * A #GtkMenu is a #GtkMenuShell that implements a drop down menu 50 * consisting of a list of #GtkMenuItem objects which can be navigated 51 * and activated by the user to perform application functions. 52 * 53 * A #GtkMenu is most commonly dropped down by activating a 54 * #GtkMenuItem in a #GtkMenuBar or popped up by activating a 55 * #GtkMenuItem in another #GtkMenu. 56 * 57 * A #GtkMenu can also be popped up by activating a #GtkComboBox. 58 * Other composite widgets such as the #GtkNotebook can pop up a 59 * #GtkMenu as well. 60 * 61 * Applications can display a #GtkMenu as a popup menu by calling the 62 * gtk_menu_popup() function. The example below shows how an application 63 * can pop up a menu when the 3rd mouse button is pressed. 64 * 65 * ## Connecting the popup signal handler. 66 * 67 * |[<!-- language="C" --> 68 * // connect our handler which will popup the menu 69 * g_signal_connect_swapped (window, "button_press_event", 70 * G_CALLBACK (my_popup_handler), menu); 71 * ]| 72 * 73 * ## Signal handler which displays a popup menu. 74 * 75 * |[<!-- language="C" --> 76 * static gint 77 * my_popup_handler (GtkWidget *widget, GdkEvent *event) 78 * { 79 * GtkMenu *menu; 80 * GdkEventButton *event_button; 81 * 82 * g_return_val_if_fail (widget != NULL, FALSE); 83 * g_return_val_if_fail (GTK_IS_MENU (widget), FALSE); 84 * g_return_val_if_fail (event != NULL, FALSE); 85 * 86 * // The "widget" is the menu that was supplied when 87 * // g_signal_connect_swapped() was called. 88 * menu = GTK_MENU (widget); 89 * 90 * if (event->type == GDK_BUTTON_PRESS) 91 * { 92 * event_button = (GdkEventButton *) event; 93 * if (event_button->button == GDK_BUTTON_SECONDARY) 94 * { 95 * gtk_menu_popup (menu, NULL, NULL, NULL, NULL, 96 * event_button->button, event_button->time); 97 * return TRUE; 98 * } 99 * } 100 * 101 * return FALSE; 102 * } 103 * ]| 104 * 105 * # CSS nodes 106 * 107 * |[<!-- language="plain" --> 108 * menu 109 * ├── arrow.top 110 * ├── <child> 111 * ┊ 112 * ├── <child> 113 * ╰── arrow.bottom 114 * ]| 115 * 116 * The main CSS node of GtkMenu has name menu, and there are two subnodes 117 * with name arrow, for scrolling menu arrows. These subnodes get the 118 * .top and .bottom style classes. 119 */ 120 public class Menu : MenuShell 121 { 122 /** the main Gtk struct */ 123 protected GtkMenu* gtkMenu; 124 125 /** Get the main Gtk struct */ 126 public GtkMenu* getMenuStruct(bool transferOwnership = false) 127 { 128 if (transferOwnership) 129 ownedRef = false; 130 return gtkMenu; 131 } 132 133 /** the main Gtk struct as a void* */ 134 protected override void* getStruct() 135 { 136 return cast(void*)gtkMenu; 137 } 138 139 protected override void setStruct(GObject* obj) 140 { 141 gtkMenu = cast(GtkMenu*)obj; 142 super.setStruct(obj); 143 } 144 145 /** 146 * Sets our main struct and passes it to the parent class. 147 */ 148 public this (GtkMenu* gtkMenu, bool ownedRef = false) 149 { 150 this.gtkMenu = gtkMenu; 151 super(cast(GtkMenuShell*)gtkMenu, ownedRef); 152 } 153 154 /** 155 * Popups up this menu 156 * Params: 157 * button = you can pass a button number here 158 * activateTime = you can pass the time from an event here 159 */ 160 void popup(uint button, uint activateTime) 161 { 162 popup(null, null, null, null, button, activateTime); 163 } 164 165 /** 166 * Creates and append a submenu to this menu. 167 * This menu item that actualy has the sub menu is also created. 168 * Params: 169 * label = the sub menu item label 170 * Returns: the new menu 171 */ 172 Menu appendSubmenu(string label) 173 { 174 MenuItem item = new MenuItem(label); 175 append(item); 176 Menu submenu = new Menu(); 177 item.setSubmenu(submenu); 178 return submenu; 179 } 180 181 /** */ 182 void appendSubmenu(string label, Menu submenu) 183 { 184 MenuItem item = new MenuItem(label); 185 append(item); 186 item.setSubmenu(submenu); 187 } 188 189 /** */ 190 Menu prependSubmenu(string label) 191 { 192 MenuItem item = new MenuItem(label); 193 prepend(item); 194 Menu submenu = new Menu(); 195 item.setSubmenu(submenu); 196 return submenu; 197 } 198 199 /** 200 */ 201 202 /** */ 203 public static GType getType() 204 { 205 return gtk_menu_get_type(); 206 } 207 208 /** 209 * Creates a new #GtkMenu 210 * 211 * Returns: a new #GtkMenu 212 * 213 * Throws: ConstructionException GTK+ fails to create the object. 214 */ 215 public this() 216 { 217 auto p = gtk_menu_new(); 218 219 if(p is null) 220 { 221 throw new ConstructionException("null returned by new"); 222 } 223 224 this(cast(GtkMenu*) p); 225 } 226 227 /** 228 * Creates a #GtkMenu and populates it with menu items and 229 * submenus according to @model. 230 * 231 * The created menu items are connected to actions found in the 232 * #GtkApplicationWindow to which the menu belongs - typically 233 * by means of being attached to a widget (see gtk_menu_attach_to_widget()) 234 * that is contained within the #GtkApplicationWindows widget hierarchy. 235 * 236 * Actions can also be added using gtk_widget_insert_action_group() on the menu's 237 * attach widget or on any of its parent widgets. 238 * 239 * Params: 240 * model = a #GMenuModel 241 * 242 * Returns: a new #GtkMenu 243 * 244 * Since: 3.4 245 * 246 * Throws: ConstructionException GTK+ fails to create the object. 247 */ 248 public this(MenuModel model) 249 { 250 auto p = gtk_menu_new_from_model((model is null) ? null : model.getMenuModelStruct()); 251 252 if(p is null) 253 { 254 throw new ConstructionException("null returned by new_from_model"); 255 } 256 257 this(cast(GtkMenu*) p); 258 } 259 260 /** 261 * Returns a list of the menus which are attached to this widget. 262 * This list is owned by GTK+ and must not be modified. 263 * 264 * Params: 265 * widget = a #GtkWidget 266 * 267 * Returns: the list 268 * of menus attached to his widget. 269 * 270 * Since: 2.6 271 */ 272 public static ListG getForAttachWidget(Widget widget) 273 { 274 auto p = gtk_menu_get_for_attach_widget((widget is null) ? null : widget.getWidgetStruct()); 275 276 if(p is null) 277 { 278 return null; 279 } 280 281 return new ListG(cast(GList*) p); 282 } 283 284 /** 285 * Adds a new #GtkMenuItem to a (table) menu. The number of “cells” that 286 * an item will occupy is specified by @left_attach, @right_attach, 287 * @top_attach and @bottom_attach. These each represent the leftmost, 288 * rightmost, uppermost and lower column and row numbers of the table. 289 * (Columns and rows are indexed from zero). 290 * 291 * Note that this function is not related to gtk_menu_detach(). 292 * 293 * Params: 294 * child = a #GtkMenuItem 295 * leftAttach = The column number to attach the left side of the item to 296 * rightAttach = The column number to attach the right side of the item to 297 * topAttach = The row number to attach the top of the item to 298 * bottomAttach = The row number to attach the bottom of the item to 299 * 300 * Since: 2.4 301 */ 302 public void attach(Widget child, uint leftAttach, uint rightAttach, uint topAttach, uint bottomAttach) 303 { 304 gtk_menu_attach(gtkMenu, (child is null) ? null : child.getWidgetStruct(), leftAttach, rightAttach, topAttach, bottomAttach); 305 } 306 307 /** 308 * Attaches the menu to the widget and provides a callback function 309 * that will be invoked when the menu calls gtk_menu_detach() during 310 * its destruction. 311 * 312 * If the menu is attached to the widget then it will be destroyed 313 * when the widget is destroyed, as if it was a child widget. 314 * An attached menu will also move between screens correctly if the 315 * widgets moves between screens. 316 * 317 * Params: 318 * attachWidget = the #GtkWidget that the menu will be attached to 319 * detacher = the user supplied callback function 320 * that will be called when the menu calls gtk_menu_detach() 321 */ 322 public void attachToWidget(Widget attachWidget, GtkMenuDetachFunc detacher) 323 { 324 gtk_menu_attach_to_widget(gtkMenu, (attachWidget is null) ? null : attachWidget.getWidgetStruct(), detacher); 325 } 326 327 /** 328 * Detaches the menu from the widget to which it had been attached. 329 * This function will call the callback function, @detacher, provided 330 * when the gtk_menu_attach_to_widget() function was called. 331 */ 332 public void detach() 333 { 334 gtk_menu_detach(gtkMenu); 335 } 336 337 /** 338 * Gets the #GtkAccelGroup which holds global accelerators for the 339 * menu. See gtk_menu_set_accel_group(). 340 * 341 * Returns: the #GtkAccelGroup associated with the menu 342 */ 343 public AccelGroup getAccelGroup() 344 { 345 auto p = gtk_menu_get_accel_group(gtkMenu); 346 347 if(p is null) 348 { 349 return null; 350 } 351 352 return ObjectG.getDObject!(AccelGroup)(cast(GtkAccelGroup*) p); 353 } 354 355 /** 356 * Retrieves the accelerator path set on the menu. 357 * 358 * Returns: the accelerator path set on the menu. 359 * 360 * Since: 2.14 361 */ 362 public string getAccelPath() 363 { 364 return Str.toString(gtk_menu_get_accel_path(gtkMenu)); 365 } 366 367 /** 368 * Returns the selected menu item from the menu. This is used by the 369 * #GtkComboBox. 370 * 371 * Returns: the #GtkMenuItem that was last selected 372 * in the menu. If a selection has not yet been made, the 373 * first menu item is selected. 374 */ 375 public Widget getActive() 376 { 377 auto p = gtk_menu_get_active(gtkMenu); 378 379 if(p is null) 380 { 381 return null; 382 } 383 384 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 385 } 386 387 /** 388 * Returns the #GtkWidget that the menu is attached to. 389 * 390 * Returns: the #GtkWidget that the menu is attached to 391 */ 392 public Widget getAttachWidget() 393 { 394 auto p = gtk_menu_get_attach_widget(gtkMenu); 395 396 if(p is null) 397 { 398 return null; 399 } 400 401 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 402 } 403 404 /** 405 * Retrieves the number of the monitor on which to show the menu. 406 * 407 * Returns: the number of the monitor on which the menu should 408 * be popped up or -1, if no monitor has been set 409 * 410 * Since: 2.14 411 */ 412 public int getMonitor() 413 { 414 return gtk_menu_get_monitor(gtkMenu); 415 } 416 417 /** 418 * Returns whether the menu reserves space for toggles and 419 * icons, regardless of their actual presence. 420 * 421 * Returns: Whether the menu reserves toggle space 422 * 423 * Since: 2.18 424 */ 425 public bool getReserveToggleSize() 426 { 427 return gtk_menu_get_reserve_toggle_size(gtkMenu) != 0; 428 } 429 430 /** 431 * Returns whether the menu is torn off. 432 * See gtk_menu_set_tearoff_state(). 433 * 434 * Returns: %TRUE if the menu is currently torn off. 435 */ 436 public bool getTearoffState() 437 { 438 return gtk_menu_get_tearoff_state(gtkMenu) != 0; 439 } 440 441 /** 442 * Returns the title of the menu. See gtk_menu_set_title(). 443 * 444 * Returns: the title of the menu, or %NULL if the menu 445 * has no title set on it. This string is owned by GTK+ 446 * and should not be modified or freed. 447 */ 448 public string getTitle() 449 { 450 return Str.toString(gtk_menu_get_title(gtkMenu)); 451 } 452 453 /** 454 * Places @menu on the given monitor. 455 * 456 * Params: 457 * monitor = the monitor to place the menu on 458 * 459 * Since: 3.22 460 */ 461 public void placeOnMonitor(MonitorG monitor) 462 { 463 gtk_menu_place_on_monitor(gtkMenu, (monitor is null) ? null : monitor.getMonitorGStruct()); 464 } 465 466 /** 467 * Removes the menu from the screen. 468 */ 469 public void popdown() 470 { 471 gtk_menu_popdown(gtkMenu); 472 } 473 474 /** 475 * Displays a menu and makes it available for selection. 476 * 477 * Applications can use this function to display context-sensitive 478 * menus, and will typically supply %NULL for the @parent_menu_shell, 479 * @parent_menu_item, @func and @data parameters. The default menu 480 * positioning function will position the menu at the current mouse 481 * cursor position. 482 * 483 * The @button parameter should be the mouse button pressed to initiate 484 * the menu popup. If the menu popup was initiated by something other 485 * than a mouse button press, such as a mouse button release or a keypress, 486 * @button should be 0. 487 * 488 * The @activate_time parameter is used to conflict-resolve initiation 489 * of concurrent requests for mouse/keyboard grab requests. To function 490 * properly, this needs to be the timestamp of the user event (such as 491 * a mouse click or key press) that caused the initiation of the popup. 492 * Only if no such event is available, gtk_get_current_event_time() can 493 * be used instead. 494 * 495 * Note that this function does not work very well on GDK backends that 496 * do not have global coordinates, such as Wayland or Mir. You should 497 * probably use one of the gtk_menu_popup_at_ variants, which do not 498 * have this problem. 499 * 500 * Deprecated: Please use gtk_menu_popup_at_widget(), 501 * gtk_menu_popup_at_pointer(). or gtk_menu_popup_at_rect() instead 502 * 503 * Params: 504 * parentMenuShell = the menu shell containing the 505 * triggering menu item, or %NULL 506 * parentMenuItem = the menu item whose activation 507 * triggered the popup, or %NULL 508 * func = a user supplied function used to position 509 * the menu, or %NULL 510 * data = user supplied data to be passed to @func. 511 * button = the mouse button which was pressed to initiate the event. 512 * activateTime = the time at which the activation event occurred. 513 */ 514 public void popup(Widget parentMenuShell, Widget parentMenuItem, GtkMenuPositionFunc func, void* data, uint button, uint activateTime) 515 { 516 gtk_menu_popup(gtkMenu, (parentMenuShell is null) ? null : parentMenuShell.getWidgetStruct(), (parentMenuItem is null) ? null : parentMenuItem.getWidgetStruct(), func, data, button, activateTime); 517 } 518 519 /** 520 * Displays @menu and makes it available for selection. 521 * 522 * See gtk_menu_popup_at_widget () to pop up a menu at a widget. 523 * gtk_menu_popup_at_rect () also allows you to position a menu at an arbitrary 524 * rectangle. 525 * 526 * @menu will be positioned at the pointer associated with @trigger_event. 527 * 528 * Properties that influence the behaviour of this function are 529 * #GtkMenu:anchor-hints, #GtkMenu:rect-anchor-dx, #GtkMenu:rect-anchor-dy, and 530 * #GtkMenu:menu-type-hint. Connect to the #GtkMenu::popped-up signal to find 531 * out how it was actually positioned. 532 * 533 * Params: 534 * triggerEvent = the #GdkEvent that initiated this request or 535 * %NULL if it's the current event 536 * 537 * Since: 3.22 538 */ 539 public void popupAtPointer(Event triggerEvent) 540 { 541 gtk_menu_popup_at_pointer(gtkMenu, (triggerEvent is null) ? null : triggerEvent.getEventStruct()); 542 } 543 544 /** 545 * Displays @menu and makes it available for selection. 546 * 547 * See gtk_menu_popup_at_widget () and gtk_menu_popup_at_pointer (), which 548 * handle more common cases for popping up menus. 549 * 550 * @menu will be positioned at @rect, aligning their anchor points. @rect is 551 * relative to the top-left corner of @rect_window. @rect_anchor and 552 * @menu_anchor determine anchor points on @rect and @menu to pin together. 553 * @menu can optionally be offset by #GtkMenu:rect-anchor-dx and 554 * #GtkMenu:rect-anchor-dy. 555 * 556 * Anchors should be specified under the assumption that the text direction is 557 * left-to-right; they will be flipped horizontally automatically if the text 558 * direction is right-to-left. 559 * 560 * Other properties that influence the behaviour of this function are 561 * #GtkMenu:anchor-hints and #GtkMenu:menu-type-hint. Connect to the 562 * #GtkMenu::popped-up signal to find out how it was actually positioned. 563 * 564 * Params: 565 * rectWindow = the #GdkWindow @rect is relative to 566 * rect = the #GdkRectangle to align @menu with 567 * rectAnchor = the point on @rect to align with @menu's anchor point 568 * menuAnchor = the point on @menu to align with @rect's anchor point 569 * triggerEvent = the #GdkEvent that initiated this request or 570 * %NULL if it's the current event 571 * 572 * Since: 3.22 573 */ 574 public void popupAtRect(Window rectWindow, GdkRectangle* rect, GdkGravity rectAnchor, GdkGravity menuAnchor, Event triggerEvent) 575 { 576 gtk_menu_popup_at_rect(gtkMenu, (rectWindow is null) ? null : rectWindow.getWindowStruct(), rect, rectAnchor, menuAnchor, (triggerEvent is null) ? null : triggerEvent.getEventStruct()); 577 } 578 579 /** 580 * Displays @menu and makes it available for selection. 581 * 582 * See gtk_menu_popup_at_pointer () to pop up a menu at the master pointer. 583 * gtk_menu_popup_at_rect () also allows you to position a menu at an arbitrary 584 * rectangle. 585 * 586 * ![](popup-anchors.png) 587 * 588 * @menu will be positioned at @widget, aligning their anchor points. 589 * @widget_anchor and @menu_anchor determine anchor points on @widget and @menu 590 * to pin together. @menu can optionally be offset by #GtkMenu:rect-anchor-dx 591 * and #GtkMenu:rect-anchor-dy. 592 * 593 * Anchors should be specified under the assumption that the text direction is 594 * left-to-right; they will be flipped horizontally automatically if the text 595 * direction is right-to-left. 596 * 597 * Other properties that influence the behaviour of this function are 598 * #GtkMenu:anchor-hints and #GtkMenu:menu-type-hint. Connect to the 599 * #GtkMenu::popped-up signal to find out how it was actually positioned. 600 * 601 * Params: 602 * widget = the #GtkWidget to align @menu with 603 * widgetAnchor = the point on @widget to align with @menu's anchor point 604 * menuAnchor = the point on @menu to align with @widget's anchor point 605 * triggerEvent = the #GdkEvent that initiated this request or 606 * %NULL if it's the current event 607 * 608 * Since: 3.22 609 */ 610 public void popupAtWidget(Widget widget, GdkGravity widgetAnchor, GdkGravity menuAnchor, Event triggerEvent) 611 { 612 gtk_menu_popup_at_widget(gtkMenu, (widget is null) ? null : widget.getWidgetStruct(), widgetAnchor, menuAnchor, (triggerEvent is null) ? null : triggerEvent.getEventStruct()); 613 } 614 615 /** 616 * Displays a menu and makes it available for selection. 617 * 618 * Applications can use this function to display context-sensitive menus, 619 * and will typically supply %NULL for the @parent_menu_shell, 620 * @parent_menu_item, @func, @data and @destroy parameters. The default 621 * menu positioning function will position the menu at the current position 622 * of @device (or its corresponding pointer). 623 * 624 * The @button parameter should be the mouse button pressed to initiate 625 * the menu popup. If the menu popup was initiated by something other than 626 * a mouse button press, such as a mouse button release or a keypress, 627 * @button should be 0. 628 * 629 * The @activate_time parameter is used to conflict-resolve initiation of 630 * concurrent requests for mouse/keyboard grab requests. To function 631 * properly, this needs to be the time stamp of the user event (such as 632 * a mouse click or key press) that caused the initiation of the popup. 633 * Only if no such event is available, gtk_get_current_event_time() can 634 * be used instead. 635 * 636 * Note that this function does not work very well on GDK backends that 637 * do not have global coordinates, such as Wayland or Mir. You should 638 * probably use one of the gtk_menu_popup_at_ variants, which do not 639 * have this problem. 640 * 641 * Deprecated: Please use gtk_menu_popup_at_widget(), 642 * gtk_menu_popup_at_pointer(). or gtk_menu_popup_at_rect() instead 643 * 644 * Params: 645 * device = a #GdkDevice 646 * parentMenuShell = the menu shell containing the triggering 647 * menu item, or %NULL 648 * parentMenuItem = the menu item whose activation triggered 649 * the popup, or %NULL 650 * func = a user supplied function used to position the menu, 651 * or %NULL 652 * data = user supplied data to be passed to @func 653 * destroy = destroy notify for @data 654 * button = the mouse button which was pressed to initiate the event 655 * activateTime = the time at which the activation event occurred 656 * 657 * Since: 3.0 658 */ 659 public void popupForDevice(Device device, Widget parentMenuShell, Widget parentMenuItem, GtkMenuPositionFunc func, void* data, GDestroyNotify destroy, uint button, uint activateTime) 660 { 661 gtk_menu_popup_for_device(gtkMenu, (device is null) ? null : device.getDeviceStruct(), (parentMenuShell is null) ? null : parentMenuShell.getWidgetStruct(), (parentMenuItem is null) ? null : parentMenuItem.getWidgetStruct(), func, data, destroy, button, activateTime); 662 } 663 664 /** 665 * Moves @child to a new @position in the list of @menu 666 * children. 667 * 668 * Params: 669 * child = the #GtkMenuItem to move 670 * position = the new position to place @child. 671 * Positions are numbered from 0 to n - 1 672 */ 673 public void reorderChild(Widget child, int position) 674 { 675 gtk_menu_reorder_child(gtkMenu, (child is null) ? null : child.getWidgetStruct(), position); 676 } 677 678 /** 679 * Repositions the menu according to its position function. 680 */ 681 public void reposition() 682 { 683 gtk_menu_reposition(gtkMenu); 684 } 685 686 /** 687 * Set the #GtkAccelGroup which holds global accelerators for the 688 * menu. This accelerator group needs to also be added to all windows 689 * that this menu is being used in with gtk_window_add_accel_group(), 690 * in order for those windows to support all the accelerators 691 * contained in this group. 692 * 693 * Params: 694 * accelGroup = the #GtkAccelGroup to be associated 695 * with the menu. 696 */ 697 public void setAccelGroup(AccelGroup accelGroup) 698 { 699 gtk_menu_set_accel_group(gtkMenu, (accelGroup is null) ? null : accelGroup.getAccelGroupStruct()); 700 } 701 702 /** 703 * Sets an accelerator path for this menu from which accelerator paths 704 * for its immediate children, its menu items, can be constructed. 705 * The main purpose of this function is to spare the programmer the 706 * inconvenience of having to call gtk_menu_item_set_accel_path() on 707 * each menu item that should support runtime user changable accelerators. 708 * Instead, by just calling gtk_menu_set_accel_path() on their parent, 709 * each menu item of this menu, that contains a label describing its 710 * purpose, automatically gets an accel path assigned. 711 * 712 * For example, a menu containing menu items “New” and “Exit”, will, after 713 * `gtk_menu_set_accel_path (menu, "<Gnumeric-Sheet>/File");` has been 714 * called, assign its items the accel paths: `"<Gnumeric-Sheet>/File/New"` 715 * and `"<Gnumeric-Sheet>/File/Exit"`. 716 * 717 * Assigning accel paths to menu items then enables the user to change 718 * their accelerators at runtime. More details about accelerator paths 719 * and their default setups can be found at gtk_accel_map_add_entry(). 720 * 721 * Note that @accel_path string will be stored in a #GQuark. Therefore, 722 * if you pass a static string, you can save some memory by interning 723 * it first with g_intern_static_string(). 724 * 725 * Params: 726 * accelPath = a valid accelerator path 727 */ 728 public void setAccelPath(string accelPath) 729 { 730 gtk_menu_set_accel_path(gtkMenu, Str.toStringz(accelPath)); 731 } 732 733 /** 734 * Selects the specified menu item within the menu. This is used by 735 * the #GtkComboBox and should not be used by anyone else. 736 * 737 * Params: 738 * index = the index of the menu item to select. Index values are 739 * from 0 to n-1 740 */ 741 public void setActive(uint index) 742 { 743 gtk_menu_set_active(gtkMenu, index); 744 } 745 746 /** 747 * Informs GTK+ on which monitor a menu should be popped up. 748 * See gdk_monitor_get_geometry(). 749 * 750 * This function should be called from a #GtkMenuPositionFunc 751 * if the menu should not appear on the same monitor as the pointer. 752 * This information can’t be reliably inferred from the coordinates 753 * returned by a #GtkMenuPositionFunc, since, for very long menus, 754 * these coordinates may extend beyond the monitor boundaries or even 755 * the screen boundaries. 756 * 757 * Params: 758 * monitorNum = the number of the monitor on which the menu should 759 * be popped up 760 * 761 * Since: 2.4 762 */ 763 public void setMonitor(int monitorNum) 764 { 765 gtk_menu_set_monitor(gtkMenu, monitorNum); 766 } 767 768 /** 769 * Sets whether the menu should reserve space for drawing toggles 770 * or icons, regardless of their actual presence. 771 * 772 * Params: 773 * reserveToggleSize = whether to reserve size for toggles 774 * 775 * Since: 2.18 776 */ 777 public void setReserveToggleSize(bool reserveToggleSize) 778 { 779 gtk_menu_set_reserve_toggle_size(gtkMenu, reserveToggleSize); 780 } 781 782 /** 783 * Sets the #GdkScreen on which the menu will be displayed. 784 * 785 * Params: 786 * screen = a #GdkScreen, or %NULL if the screen should be 787 * determined by the widget the menu is attached to 788 * 789 * Since: 2.2 790 */ 791 public void setScreen(Screen screen) 792 { 793 gtk_menu_set_screen(gtkMenu, (screen is null) ? null : screen.getScreenStruct()); 794 } 795 796 /** 797 * Changes the tearoff state of the menu. A menu is normally 798 * displayed as drop down menu which persists as long as the menu is 799 * active. It can also be displayed as a tearoff menu which persists 800 * until it is closed or reattached. 801 * 802 * Params: 803 * tornOff = If %TRUE, menu is displayed as a tearoff menu. 804 */ 805 public void setTearoffState(bool tornOff) 806 { 807 gtk_menu_set_tearoff_state(gtkMenu, tornOff); 808 } 809 810 /** 811 * Sets the title string for the menu. 812 * 813 * The title is displayed when the menu is shown as a tearoff 814 * menu. If @title is %NULL, the menu will see if it is attached 815 * to a parent menu item, and if so it will try to use the same 816 * text as that menu item’s label. 817 * 818 * Params: 819 * title = a string containing the title for the menu 820 */ 821 public void setTitle(string title) 822 { 823 gtk_menu_set_title(gtkMenu, Str.toStringz(title)); 824 } 825 826 protected class OnMoveScrollDelegateWrapper 827 { 828 void delegate(GtkScrollType, Menu) dlg; 829 gulong handlerId; 830 831 this(void delegate(GtkScrollType, Menu) dlg) 832 { 833 this.dlg = dlg; 834 onMoveScrollListeners ~= this; 835 } 836 837 void remove(OnMoveScrollDelegateWrapper source) 838 { 839 foreach(index, wrapper; onMoveScrollListeners) 840 { 841 if (wrapper.handlerId == source.handlerId) 842 { 843 onMoveScrollListeners[index] = null; 844 onMoveScrollListeners = std.algorithm.remove(onMoveScrollListeners, index); 845 break; 846 } 847 } 848 } 849 } 850 OnMoveScrollDelegateWrapper[] onMoveScrollListeners; 851 852 /** */ 853 gulong addOnMoveScroll(void delegate(GtkScrollType, Menu) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 854 { 855 auto wrapper = new OnMoveScrollDelegateWrapper(dlg); 856 wrapper.handlerId = Signals.connectData( 857 this, 858 "move-scroll", 859 cast(GCallback)&callBackMoveScroll, 860 cast(void*)wrapper, 861 cast(GClosureNotify)&callBackMoveScrollDestroy, 862 connectFlags); 863 return wrapper.handlerId; 864 } 865 866 extern(C) static void callBackMoveScroll(GtkMenu* menuStruct, GtkScrollType scrollType, OnMoveScrollDelegateWrapper wrapper) 867 { 868 wrapper.dlg(scrollType, wrapper.outer); 869 } 870 871 extern(C) static void callBackMoveScrollDestroy(OnMoveScrollDelegateWrapper wrapper, GClosure* closure) 872 { 873 wrapper.remove(wrapper); 874 } 875 876 protected class OnPoppedUpDelegateWrapper 877 { 878 void delegate(void*, void*, bool, bool, Menu) dlg; 879 gulong handlerId; 880 881 this(void delegate(void*, void*, bool, bool, Menu) dlg) 882 { 883 this.dlg = dlg; 884 onPoppedUpListeners ~= this; 885 } 886 887 void remove(OnPoppedUpDelegateWrapper source) 888 { 889 foreach(index, wrapper; onPoppedUpListeners) 890 { 891 if (wrapper.handlerId == source.handlerId) 892 { 893 onPoppedUpListeners[index] = null; 894 onPoppedUpListeners = std.algorithm.remove(onPoppedUpListeners, index); 895 break; 896 } 897 } 898 } 899 } 900 OnPoppedUpDelegateWrapper[] onPoppedUpListeners; 901 902 /** 903 * Emitted when the position of @menu is finalized after being popped up 904 * using gtk_menu_popup_at_rect (), gtk_menu_popup_at_widget (), or 905 * gtk_menu_popup_at_pointer (). 906 * 907 * @menu might be flipped over the anchor rectangle in order to keep it 908 * on-screen, in which case @flipped_x and @flipped_y will be set to %TRUE 909 * accordingly. 910 * 911 * @flipped_rect is the ideal position of @menu after any possible flipping, 912 * but before any possible sliding. @final_rect is @flipped_rect, but possibly 913 * translated in the case that flipping is still ineffective in keeping @menu 914 * on-screen. 915 * 916 * ![](popup-slide.png) 917 * 918 * The blue menu is @menu's ideal position, the green menu is @flipped_rect, 919 * and the red menu is @final_rect. 920 * 921 * See gtk_menu_popup_at_rect (), gtk_menu_popup_at_widget (), 922 * gtk_menu_popup_at_pointer (), #GtkMenu:anchor-hints, 923 * #GtkMenu:rect-anchor-dx, #GtkMenu:rect-anchor-dy, and 924 * #GtkMenu:menu-type-hint. 925 * 926 * Params: 927 * flippedRect = the position of @menu after any possible 928 * flipping or %NULL if the backend can't obtain it 929 * finalRect = the final position of @menu or %NULL if the 930 * backend can't obtain it 931 * flippedX = %TRUE if the anchors were flipped horizontally 932 * flippedY = %TRUE if the anchors were flipped vertically 933 * 934 * Since: 3.22 935 */ 936 gulong addOnPoppedUp(void delegate(void*, void*, bool, bool, Menu) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 937 { 938 auto wrapper = new OnPoppedUpDelegateWrapper(dlg); 939 wrapper.handlerId = Signals.connectData( 940 this, 941 "popped-up", 942 cast(GCallback)&callBackPoppedUp, 943 cast(void*)wrapper, 944 cast(GClosureNotify)&callBackPoppedUpDestroy, 945 connectFlags); 946 return wrapper.handlerId; 947 } 948 949 extern(C) static void callBackPoppedUp(GtkMenu* menuStruct, void* flippedRect, void* finalRect, bool flippedX, bool flippedY, OnPoppedUpDelegateWrapper wrapper) 950 { 951 wrapper.dlg(flippedRect, finalRect, flippedX, flippedY, wrapper.outer); 952 } 953 954 extern(C) static void callBackPoppedUpDestroy(OnPoppedUpDelegateWrapper wrapper, GClosure* closure) 955 { 956 wrapper.remove(wrapper); 957 } 958 }