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