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.Screen; 29 private import gio.MenuModel; 30 private import glib.ConstructionException; 31 private import glib.ListG; 32 private import glib.Str; 33 private import gobject.ObjectG; 34 private import gobject.Signals; 35 private import gtk.AccelGroup; 36 private import gtk.MenuItem; 37 private import gtk.MenuShell; 38 private import gtk.Widget; 39 public import gtkc.gdktypes; 40 private import gtkc.gtk; 41 public import gtkc.gtktypes; 42 43 44 /** 45 * A #GtkMenu is a #GtkMenuShell that implements a drop down menu 46 * consisting of a list of #GtkMenuItem objects which can be navigated 47 * and activated by the user to perform application functions. 48 * 49 * A #GtkMenu is most commonly dropped down by activating a 50 * #GtkMenuItem in a #GtkMenuBar or popped up by activating a 51 * #GtkMenuItem in another #GtkMenu. 52 * 53 * A #GtkMenu can also be popped up by activating a #GtkComboBox. 54 * Other composite widgets such as the #GtkNotebook can pop up a 55 * #GtkMenu as well. 56 * 57 * Applications can display a #GtkMenu as a popup menu by calling the 58 * gtk_menu_popup() function. The example below shows how an application 59 * can pop up a menu when the 3rd mouse button is pressed. 60 * 61 * ## Connecting the popup signal handler. 62 * 63 * |[<!-- language="C" --> 64 * // connect our handler which will popup the menu 65 * g_signal_connect_swapped (window, "button_press_event", 66 * G_CALLBACK (my_popup_handler), menu); 67 * ]| 68 * 69 * ## Signal handler which displays a popup menu. 70 * 71 * |[<!-- language="C" --> 72 * static gint 73 * my_popup_handler (GtkWidget *widget, GdkEvent *event) 74 * { 75 * GtkMenu *menu; 76 * GdkEventButton *event_button; 77 * 78 * g_return_val_if_fail (widget != NULL, FALSE); 79 * g_return_val_if_fail (GTK_IS_MENU (widget), FALSE); 80 * g_return_val_if_fail (event != NULL, FALSE); 81 * 82 * // The "widget" is the menu that was supplied when 83 * // g_signal_connect_swapped() was called. 84 * menu = GTK_MENU (widget); 85 * 86 * if (event->type == GDK_BUTTON_PRESS) 87 * { 88 * event_button = (GdkEventButton *) event; 89 * if (event_button->button == GDK_BUTTON_SECONDARY) 90 * { 91 * gtk_menu_popup (menu, NULL, NULL, NULL, NULL, 92 * event_button->button, event_button->time); 93 * return TRUE; 94 * } 95 * } 96 * 97 * return FALSE; 98 * } 99 * ]| 100 */ 101 public class Menu : MenuShell 102 { 103 /** the main Gtk struct */ 104 protected GtkMenu* gtkMenu; 105 106 /** Get the main Gtk struct */ 107 public GtkMenu* getMenuStruct() 108 { 109 return gtkMenu; 110 } 111 112 /** the main Gtk struct as a void* */ 113 protected override void* getStruct() 114 { 115 return cast(void*)gtkMenu; 116 } 117 118 protected override void setStruct(GObject* obj) 119 { 120 gtkMenu = cast(GtkMenu*)obj; 121 super.setStruct(obj); 122 } 123 124 /** 125 * Sets our main struct and passes it to the parent class. 126 */ 127 public this (GtkMenu* gtkMenu, bool ownedRef = false) 128 { 129 this.gtkMenu = gtkMenu; 130 super(cast(GtkMenuShell*)gtkMenu, ownedRef); 131 } 132 133 /** 134 * Popups up this menu 135 * Params: 136 * button = you can pass a button number here 137 * activateTime = you can pass the time from an event here 138 */ 139 void popup(uint button, uint activateTime) 140 { 141 popup(null, null, null, null, button, activateTime); 142 } 143 144 /** 145 * Creates and append a submenu to this menu. 146 * This menu item that actualy has the sub menu is also created. 147 * Params: 148 * label = the sub menu item label 149 * Returns: the new menu 150 */ 151 Menu appendSubmenu(string label) 152 { 153 MenuItem item = new MenuItem(label); 154 append(item); 155 Menu submenu = new Menu(); 156 item.setSubmenu(submenu); 157 return submenu; 158 } 159 160 /** */ 161 void appendSubmenu(string label, Menu submenu) 162 { 163 MenuItem item = new MenuItem(label); 164 append(item); 165 item.setSubmenu(submenu); 166 } 167 168 /** */ 169 Menu prependSubmenu(string label) 170 { 171 MenuItem item = new MenuItem(label); 172 prepend(item); 173 Menu submenu = new Menu(); 174 item.setSubmenu(submenu); 175 return submenu; 176 } 177 178 /** 179 */ 180 181 /** */ 182 public static GType getType() 183 { 184 return gtk_menu_get_type(); 185 } 186 187 /** 188 * Creates a new #GtkMenu 189 * 190 * Return: a new #GtkMenu 191 * 192 * Throws: ConstructionException GTK+ fails to create the object. 193 */ 194 public this() 195 { 196 auto p = gtk_menu_new(); 197 198 if(p is null) 199 { 200 throw new ConstructionException("null returned by new"); 201 } 202 203 this(cast(GtkMenu*) p); 204 } 205 206 /** 207 * Creates a #GtkMenu and populates it with menu items and 208 * submenus according to @model. 209 * 210 * The created menu items are connected to actions found in the 211 * #GtkApplicationWindow to which the menu belongs - typically 212 * by means of being attached to a widget (see gtk_menu_attach_to_widget()) 213 * that is contained within the #GtkApplicationWindows widget hierarchy. 214 * 215 * Actions can also be added using gtk_widget_insert_action_group() on the menu's 216 * attach widget or on any of its parent widgets. 217 * 218 * Params: 219 * model = a #GMenuModel 220 * 221 * Return: a new #GtkMenu 222 * 223 * Since: 3.4 224 * 225 * Throws: ConstructionException GTK+ fails to create the object. 226 */ 227 public this(MenuModel model) 228 { 229 auto p = gtk_menu_new_from_model((model is null) ? null : model.getMenuModelStruct()); 230 231 if(p is null) 232 { 233 throw new ConstructionException("null returned by new_from_model"); 234 } 235 236 this(cast(GtkMenu*) p); 237 } 238 239 /** 240 * Returns a list of the menus which are attached to this widget. 241 * This list is owned by GTK+ and must not be modified. 242 * 243 * Params: 244 * widget = a #GtkWidget 245 * 246 * Return: the list 247 * of menus attached to his widget. 248 * 249 * Since: 2.6 250 */ 251 public static ListG getForAttachWidget(Widget widget) 252 { 253 auto p = gtk_menu_get_for_attach_widget((widget is null) ? null : widget.getWidgetStruct()); 254 255 if(p is null) 256 { 257 return null; 258 } 259 260 return new ListG(cast(GList*) p); 261 } 262 263 /** 264 * Adds a new #GtkMenuItem to a (table) menu. The number of “cells” that 265 * an item will occupy is specified by @left_attach, @right_attach, 266 * @top_attach and @bottom_attach. These each represent the leftmost, 267 * rightmost, uppermost and lower column and row numbers of the table. 268 * (Columns and rows are indexed from zero). 269 * 270 * Note that this function is not related to gtk_menu_detach(). 271 * 272 * Params: 273 * child = a #GtkMenuItem 274 * leftAttach = The column number to attach the left side of the item to 275 * rightAttach = The column number to attach the right side of the item to 276 * topAttach = The row number to attach the top of the item to 277 * bottomAttach = The row number to attach the bottom of the item to 278 * 279 * Since: 2.4 280 */ 281 public void attach(Widget child, uint leftAttach, uint rightAttach, uint topAttach, uint bottomAttach) 282 { 283 gtk_menu_attach(gtkMenu, (child is null) ? null : child.getWidgetStruct(), leftAttach, rightAttach, topAttach, bottomAttach); 284 } 285 286 /** 287 * Attaches the menu to the widget and provides a callback function 288 * that will be invoked when the menu calls gtk_menu_detach() during 289 * its destruction. 290 * 291 * If the menu is attached to the widget then it will be destroyed 292 * when the widget is destroyed, as if it was a child widget. 293 * An attached menu will also move between screens correctly if the 294 * widgets moves between screens. 295 * 296 * Params: 297 * attachWidget = the #GtkWidget that the menu will be attached to 298 * detacher = the user supplied callback function 299 * that will be called when the menu calls gtk_menu_detach() 300 */ 301 public void attachToWidget(Widget attachWidget, GtkMenuDetachFunc detacher) 302 { 303 gtk_menu_attach_to_widget(gtkMenu, (attachWidget is null) ? null : attachWidget.getWidgetStruct(), detacher); 304 } 305 306 /** 307 * Detaches the menu from the widget to which it had been attached. 308 * This function will call the callback function, @detacher, provided 309 * when the gtk_menu_attach_to_widget() function was called. 310 */ 311 public void detach() 312 { 313 gtk_menu_detach(gtkMenu); 314 } 315 316 /** 317 * Gets the #GtkAccelGroup which holds global accelerators for the 318 * menu. See gtk_menu_set_accel_group(). 319 * 320 * Return: the #GtkAccelGroup associated with the menu 321 */ 322 public AccelGroup getAccelGroup() 323 { 324 auto p = gtk_menu_get_accel_group(gtkMenu); 325 326 if(p is null) 327 { 328 return null; 329 } 330 331 return ObjectG.getDObject!(AccelGroup)(cast(GtkAccelGroup*) p); 332 } 333 334 /** 335 * Retrieves the accelerator path set on the menu. 336 * 337 * Return: the accelerator path set on the menu. 338 * 339 * Since: 2.14 340 */ 341 public string getAccelPath() 342 { 343 return Str.toString(gtk_menu_get_accel_path(gtkMenu)); 344 } 345 346 /** 347 * Returns the selected menu item from the menu. This is used by the 348 * #GtkComboBox. 349 * 350 * Return: the #GtkMenuItem that was last selected 351 * in the menu. If a selection has not yet been made, the 352 * first menu item is selected. 353 */ 354 public Widget getActive() 355 { 356 auto p = gtk_menu_get_active(gtkMenu); 357 358 if(p is null) 359 { 360 return null; 361 } 362 363 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 364 } 365 366 /** 367 * Returns the #GtkWidget that the menu is attached to. 368 * 369 * Return: the #GtkWidget that the menu is attached to 370 */ 371 public Widget getAttachWidget() 372 { 373 auto p = gtk_menu_get_attach_widget(gtkMenu); 374 375 if(p is null) 376 { 377 return null; 378 } 379 380 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 381 } 382 383 /** 384 * Retrieves the number of the monitor on which to show the menu. 385 * 386 * Return: the number of the monitor on which the menu should 387 * be popped up or -1, if no monitor has been set 388 * 389 * Since: 2.14 390 */ 391 public int getMonitor() 392 { 393 return gtk_menu_get_monitor(gtkMenu); 394 } 395 396 /** 397 * Returns whether the menu reserves space for toggles and 398 * icons, regardless of their actual presence. 399 * 400 * Return: Whether the menu reserves toggle space 401 * 402 * Since: 2.18 403 */ 404 public bool getReserveToggleSize() 405 { 406 return gtk_menu_get_reserve_toggle_size(gtkMenu) != 0; 407 } 408 409 /** 410 * Returns whether the menu is torn off. 411 * See gtk_menu_set_tearoff_state(). 412 * 413 * Return: %TRUE if the menu is currently torn off. 414 */ 415 public bool getTearoffState() 416 { 417 return gtk_menu_get_tearoff_state(gtkMenu) != 0; 418 } 419 420 /** 421 * Returns the title of the menu. See gtk_menu_set_title(). 422 * 423 * Return: the title of the menu, or %NULL if the menu 424 * has no title set on it. This string is owned by GTK+ 425 * and should not be modified or freed. 426 */ 427 public string getTitle() 428 { 429 return Str.toString(gtk_menu_get_title(gtkMenu)); 430 } 431 432 /** 433 * Removes the menu from the screen. 434 */ 435 public void popdown() 436 { 437 gtk_menu_popdown(gtkMenu); 438 } 439 440 /** 441 * Displays a menu and makes it available for selection. 442 * 443 * Applications can use this function to display context-sensitive 444 * menus, and will typically supply %NULL for the @parent_menu_shell, 445 * @parent_menu_item, @func and @data parameters. The default menu 446 * positioning function will position the menu at the current mouse 447 * cursor position. 448 * 449 * The @button parameter should be the mouse button pressed to initiate 450 * the menu popup. If the menu popup was initiated by something other 451 * than a mouse button press, such as a mouse button release or a keypress, 452 * @button should be 0. 453 * 454 * The @activate_time parameter is used to conflict-resolve initiation 455 * of concurrent requests for mouse/keyboard grab requests. To function 456 * properly, this needs to be the timestamp of the user event (such as 457 * a mouse click or key press) that caused the initiation of the popup. 458 * Only if no such event is available, gtk_get_current_event_time() can 459 * be used instead. 460 * 461 * Params: 462 * parentMenuShell = the menu shell containing the 463 * triggering menu item, or %NULL 464 * parentMenuItem = the menu item whose activation 465 * triggered the popup, or %NULL 466 * func = a user supplied function used to position 467 * the menu, or %NULL 468 * data = user supplied data to be passed to @func. 469 * button = the mouse button which was pressed to initiate the event. 470 * activateTime = the time at which the activation event occurred. 471 */ 472 public void popup(Widget parentMenuShell, Widget parentMenuItem, GtkMenuPositionFunc func, void* data, uint button, uint activateTime) 473 { 474 gtk_menu_popup(gtkMenu, (parentMenuShell is null) ? null : parentMenuShell.getWidgetStruct(), (parentMenuItem is null) ? null : parentMenuItem.getWidgetStruct(), func, data, button, activateTime); 475 } 476 477 /** 478 * Displays a menu and makes it available for selection. 479 * 480 * Applications can use this function to display context-sensitive menus, 481 * and will typically supply %NULL for the @parent_menu_shell, 482 * @parent_menu_item, @func, @data and @destroy parameters. The default 483 * menu positioning function will position the menu at the current position 484 * of @device (or its corresponding pointer). 485 * 486 * The @button parameter should be the mouse button pressed to initiate 487 * the menu popup. If the menu popup was initiated by something other than 488 * a mouse button press, such as a mouse button release or a keypress, 489 * @button should be 0. 490 * 491 * The @activate_time parameter is used to conflict-resolve initiation of 492 * concurrent requests for mouse/keyboard grab requests. To function 493 * properly, this needs to be the time stamp of the user event (such as 494 * a mouse click or key press) that caused the initiation of the popup. 495 * Only if no such event is available, gtk_get_current_event_time() can 496 * be used instead. 497 * 498 * Params: 499 * device = a #GdkDevice 500 * parentMenuShell = the menu shell containing the triggering 501 * menu item, or %NULL 502 * parentMenuItem = the menu item whose activation triggered 503 * the popup, or %NULL 504 * func = a user supplied function used to position the menu, 505 * or %NULL 506 * data = user supplied data to be passed to @func 507 * destroy = destroy notify for @data 508 * button = the mouse button which was pressed to initiate the event 509 * activateTime = the time at which the activation event occurred 510 * 511 * Since: 3.0 512 */ 513 public void popupForDevice(Device device, Widget parentMenuShell, Widget parentMenuItem, GtkMenuPositionFunc func, void* data, GDestroyNotify destroy, uint button, uint activateTime) 514 { 515 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); 516 } 517 518 /** 519 * Moves @child to a new @position in the list of @menu 520 * children. 521 * 522 * Params: 523 * child = the #GtkMenuItem to move 524 * position = the new position to place @child. 525 * Positions are numbered from 0 to n - 1 526 */ 527 public void reorderChild(Widget child, int position) 528 { 529 gtk_menu_reorder_child(gtkMenu, (child is null) ? null : child.getWidgetStruct(), position); 530 } 531 532 /** 533 * Repositions the menu according to its position function. 534 */ 535 public void reposition() 536 { 537 gtk_menu_reposition(gtkMenu); 538 } 539 540 /** 541 * Set the #GtkAccelGroup which holds global accelerators for the 542 * menu. This accelerator group needs to also be added to all windows 543 * that this menu is being used in with gtk_window_add_accel_group(), 544 * in order for those windows to support all the accelerators 545 * contained in this group. 546 * 547 * Params: 548 * accelGroup = the #GtkAccelGroup to be associated 549 * with the menu. 550 */ 551 public void setAccelGroup(AccelGroup accelGroup) 552 { 553 gtk_menu_set_accel_group(gtkMenu, (accelGroup is null) ? null : accelGroup.getAccelGroupStruct()); 554 } 555 556 /** 557 * Sets an accelerator path for this menu from which accelerator paths 558 * for its immediate children, its menu items, can be constructed. 559 * The main purpose of this function is to spare the programmer the 560 * inconvenience of having to call gtk_menu_item_set_accel_path() on 561 * each menu item that should support runtime user changable accelerators. 562 * Instead, by just calling gtk_menu_set_accel_path() on their parent, 563 * each menu item of this menu, that contains a label describing its 564 * purpose, automatically gets an accel path assigned. 565 * 566 * For example, a menu containing menu items “New” and “Exit”, will, after 567 * `gtk_menu_set_accel_path (menu, "<Gnumeric-Sheet>/File");` has been 568 * called, assign its items the accel paths: `"<Gnumeric-Sheet>/File/New"` 569 * and `"<Gnumeric-Sheet>/File/Exit"`. 570 * 571 * Assigning accel paths to menu items then enables the user to change 572 * their accelerators at runtime. More details about accelerator paths 573 * and their default setups can be found at gtk_accel_map_add_entry(). 574 * 575 * Note that @accel_path string will be stored in a #GQuark. Therefore, 576 * if you pass a static string, you can save some memory by interning 577 * it first with g_intern_static_string(). 578 * 579 * Params: 580 * accelPath = a valid accelerator path 581 */ 582 public void setAccelPath(string accelPath) 583 { 584 gtk_menu_set_accel_path(gtkMenu, Str.toStringz(accelPath)); 585 } 586 587 /** 588 * Selects the specified menu item within the menu. This is used by 589 * the #GtkComboBox and should not be used by anyone else. 590 * 591 * Params: 592 * index = the index of the menu item to select. Index values are 593 * from 0 to n-1 594 */ 595 public void setActive(uint index) 596 { 597 gtk_menu_set_active(gtkMenu, index); 598 } 599 600 /** 601 * Informs GTK+ on which monitor a menu should be popped up. 602 * See gdk_screen_get_monitor_geometry(). 603 * 604 * This function should be called from a #GtkMenuPositionFunc 605 * if the menu should not appear on the same monitor as the pointer. 606 * This information can’t be reliably inferred from the coordinates 607 * returned by a #GtkMenuPositionFunc, since, for very long menus, 608 * these coordinates may extend beyond the monitor boundaries or even 609 * the screen boundaries. 610 * 611 * Params: 612 * monitorNum = the number of the monitor on which the menu should 613 * be popped up 614 * 615 * Since: 2.4 616 */ 617 public void setMonitor(int monitorNum) 618 { 619 gtk_menu_set_monitor(gtkMenu, monitorNum); 620 } 621 622 /** 623 * Sets whether the menu should reserve space for drawing toggles 624 * or icons, regardless of their actual presence. 625 * 626 * Params: 627 * reserveToggleSize = whether to reserve size for toggles 628 * 629 * Since: 2.18 630 */ 631 public void setReserveToggleSize(bool reserveToggleSize) 632 { 633 gtk_menu_set_reserve_toggle_size(gtkMenu, reserveToggleSize); 634 } 635 636 /** 637 * Sets the #GdkScreen on which the menu will be displayed. 638 * 639 * Params: 640 * screen = a #GdkScreen, or %NULL if the screen should be 641 * determined by the widget the menu is attached to 642 * 643 * Since: 2.2 644 */ 645 public void setScreen(Screen screen) 646 { 647 gtk_menu_set_screen(gtkMenu, (screen is null) ? null : screen.getScreenStruct()); 648 } 649 650 /** 651 * Changes the tearoff state of the menu. A menu is normally 652 * displayed as drop down menu which persists as long as the menu is 653 * active. It can also be displayed as a tearoff menu which persists 654 * until it is closed or reattached. 655 * 656 * Params: 657 * tornOff = If %TRUE, menu is displayed as a tearoff menu. 658 */ 659 public void setTearoffState(bool tornOff) 660 { 661 gtk_menu_set_tearoff_state(gtkMenu, tornOff); 662 } 663 664 /** 665 * Sets the title string for the menu. 666 * 667 * The title is displayed when the menu is shown as a tearoff 668 * menu. If @title is %NULL, the menu will see if it is attached 669 * to a parent menu item, and if so it will try to use the same 670 * text as that menu item’s label. 671 * 672 * Params: 673 * title = a string containing the title for the menu 674 */ 675 public void setTitle(string title) 676 { 677 gtk_menu_set_title(gtkMenu, Str.toStringz(title)); 678 } 679 680 int[string] connectedSignals; 681 682 void delegate(GtkScrollType, Menu)[] onMoveScrollListeners; 683 /** */ 684 void addOnMoveScroll(void delegate(GtkScrollType, Menu) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 685 { 686 if ( "move-scroll" !in connectedSignals ) 687 { 688 Signals.connectData( 689 this, 690 "move-scroll", 691 cast(GCallback)&callBackMoveScroll, 692 cast(void*)this, 693 null, 694 connectFlags); 695 connectedSignals["move-scroll"] = 1; 696 } 697 onMoveScrollListeners ~= dlg; 698 } 699 extern(C) static void callBackMoveScroll(GtkMenu* menuStruct, GtkScrollType scrollType, Menu _menu) 700 { 701 foreach ( void delegate(GtkScrollType, Menu) dlg; _menu.onMoveScrollListeners ) 702 { 703 dlg(scrollType, _menu); 704 } 705 } 706 }