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