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