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.UIManager; 26 27 private import glib.ConstructionException; 28 private import glib.ErrorG; 29 private import glib.GException; 30 private import glib.ListG; 31 private import glib.ListSG; 32 private import glib.Str; 33 private import gobject.ObjectG; 34 private import gobject.Signals; 35 private import gobject.Type; 36 private import gtk.AccelGroup; 37 private import gtk.Action; 38 private import gtk.ActionGroup; 39 private import gtk.BuildableIF; 40 private import gtk.BuildableT; 41 private import gtk.CheckMenuItem; 42 private import gtk.ImageMenuItem; 43 private import gtk.Menu; 44 private import gtk.MenuBar; 45 private import gtk.MenuItem; 46 private import gtk.MenuToolButton; 47 private import gtk.RadioMenuItem; 48 private import gtk.RadioToolButton; 49 private import gtk.SeparatorMenuItem; 50 private import gtk.SeparatorToolItem; 51 private import gtk.TearoffMenuItem; 52 private import gtk.ToggleToolButton; 53 private import gtk.ToolButton; 54 private import gtk.ToolItem; 55 private import gtk.Toolbar; 56 private import gtk.Widget; 57 private import gtkc.gtk; 58 public import gtkc.gtktypes; 59 private import std.algorithm; 60 61 62 /** 63 * A #GtkUIManager constructs a user interface (menus and toolbars) from 64 * one or more UI definitions, which reference actions from one or more 65 * action groups. 66 * 67 * # UI Definitions # {#XML-UI} 68 * 69 * The UI definitions are specified in an XML format which can be 70 * roughly described by the following DTD. 71 * 72 * > Do not confuse the GtkUIManager UI Definitions described here with 73 * > the similarly named [GtkBuilder UI Definitions][BUILDER-UI]. 74 * 75 * |[ 76 * <!ELEMENT ui (menubar|toolbar|popup|accelerator)* > 77 * <!ELEMENT menubar (menuitem|separator|placeholder|menu)* > 78 * <!ELEMENT menu (menuitem|separator|placeholder|menu)* > 79 * <!ELEMENT popup (menuitem|separator|placeholder|menu)* > 80 * <!ELEMENT toolbar (toolitem|separator|placeholder)* > 81 * <!ELEMENT placeholder (menuitem|toolitem|separator|placeholder|menu)* > 82 * <!ELEMENT menuitem EMPTY > 83 * <!ELEMENT toolitem (menu?) > 84 * <!ELEMENT separator EMPTY > 85 * <!ELEMENT accelerator EMPTY > 86 * <!ATTLIST menubar name #IMPLIED 87 * action #IMPLIED > 88 * <!ATTLIST toolbar name #IMPLIED 89 * action #IMPLIED > 90 * <!ATTLIST popup name #IMPLIED 91 * action #IMPLIED 92 * accelerators (true|false) #IMPLIED > 93 * <!ATTLIST placeholder name #IMPLIED 94 * action #IMPLIED > 95 * <!ATTLIST separator name #IMPLIED 96 * action #IMPLIED 97 * expand (true|false) #IMPLIED > 98 * <!ATTLIST menu name #IMPLIED 99 * action #REQUIRED 100 * position (top|bot) #IMPLIED > 101 * <!ATTLIST menuitem name #IMPLIED 102 * action #REQUIRED 103 * position (top|bot) #IMPLIED 104 * always-show-image (true|false) #IMPLIED > 105 * <!ATTLIST toolitem name #IMPLIED 106 * action #REQUIRED 107 * position (top|bot) #IMPLIED > 108 * <!ATTLIST accelerator name #IMPLIED 109 * action #REQUIRED > 110 * ]| 111 * 112 * There are some additional restrictions beyond those specified in the 113 * DTD, e.g. every toolitem must have a toolbar in its anchestry and 114 * every menuitem must have a menubar or popup in its anchestry. Since 115 * a #GMarkupParser is used to parse the UI description, it must not only 116 * be valid XML, but valid markup. 117 * 118 * If a name is not specified, it defaults to the action. If an action is 119 * not specified either, the element name is used. The name and action 120 * attributes must not contain “/” characters after parsing (since that 121 * would mess up path lookup) and must be usable as XML attributes when 122 * enclosed in doublequotes, thus they must not “"” characters or references 123 * to the " entity. 124 * 125 * # A UI definition # 126 * 127 * |[ 128 * <ui> 129 * <menubar> 130 * <menu name="FileMenu" action="FileMenuAction"> 131 * <menuitem name="New" action="New2Action" /> 132 * <placeholder name="FileMenuAdditions" /> 133 * </menu> 134 * <menu name="JustifyMenu" action="JustifyMenuAction"> 135 * <menuitem name="Left" action="justify-left"/> 136 * <menuitem name="Centre" action="justify-center"/> 137 * <menuitem name="Right" action="justify-right"/> 138 * <menuitem name="Fill" action="justify-fill"/> 139 * </menu> 140 * </menubar> 141 * <toolbar action="toolbar1"> 142 * <placeholder name="JustifyToolItems"> 143 * <separator/> 144 * <toolitem name="Left" action="justify-left"/> 145 * <toolitem name="Centre" action="justify-center"/> 146 * <toolitem name="Right" action="justify-right"/> 147 * <toolitem name="Fill" action="justify-fill"/> 148 * <separator/> 149 * </placeholder> 150 * </toolbar> 151 * </ui> 152 * ]| 153 * 154 * The constructed widget hierarchy is very similar to the element tree 155 * of the XML, with the exception that placeholders are merged into their 156 * parents. The correspondence of XML elements to widgets should be 157 * almost obvious: 158 * 159 * - menubar 160 * 161 * a #GtkMenuBar 162 * 163 * - toolbar 164 * 165 * a #GtkToolbar 166 * 167 * - popup 168 * 169 * a toplevel #GtkMenu 170 * 171 * - menu 172 * 173 * a #GtkMenu attached to a menuitem 174 * 175 * - menuitem 176 * 177 * a #GtkMenuItem subclass, the exact type depends on the action 178 * 179 * - toolitem 180 * 181 * a #GtkToolItem subclass, the exact type depends on the 182 * action. Note that toolitem elements may contain a menu element, 183 * but only if their associated action specifies a 184 * #GtkMenuToolButton as proxy. 185 * 186 * - separator 187 * 188 * a #GtkSeparatorMenuItem or #GtkSeparatorToolItem 189 * 190 * - accelerator 191 * 192 * a keyboard accelerator 193 * 194 * The “position” attribute determines where a constructed widget is positioned 195 * wrt. to its siblings in the partially constructed tree. If it is 196 * “top”, the widget is prepended, otherwise it is appended. 197 * 198 * # UI Merging # {#UI-Merging} 199 * 200 * The most remarkable feature of #GtkUIManager is that it can overlay a set 201 * of menuitems and toolitems over another one, and demerge them later. 202 * 203 * Merging is done based on the names of the XML elements. Each element is 204 * identified by a path which consists of the names of its anchestors, separated 205 * by slashes. For example, the menuitem named “Left” in the example above 206 * has the path `/ui/menubar/JustifyMenu/Left` and the 207 * toolitem with the same name has path 208 * `/ui/toolbar1/JustifyToolItems/Left`. 209 * 210 * # Accelerators # 211 * 212 * Every action has an accelerator path. Accelerators are installed together 213 * with menuitem proxies, but they can also be explicitly added with 214 * <accelerator> elements in the UI definition. This makes it possible to 215 * have accelerators for actions even if they have no visible proxies. 216 * 217 * # Smart Separators # {#Smart-Separators} 218 * 219 * The separators created by #GtkUIManager are “smart”, i.e. they do not show up 220 * in the UI unless they end up between two visible menu or tool items. Separators 221 * which are located at the very beginning or end of the menu or toolbar 222 * containing them, or multiple separators next to each other, are hidden. This 223 * is a useful feature, since the merging of UI elements from multiple sources 224 * can make it hard or impossible to determine in advance whether a separator 225 * will end up in such an unfortunate position. 226 * 227 * For separators in toolbars, you can set `expand="true"` to 228 * turn them from a small, visible separator to an expanding, invisible one. 229 * Toolitems following an expanding separator are effectively right-aligned. 230 * 231 * # Empty Menus 232 * 233 * Submenus pose similar problems to separators inconnection with merging. It is 234 * impossible to know in advance whether they will end up empty after merging. 235 * #GtkUIManager offers two ways to treat empty submenus: 236 * 237 * - make them disappear by hiding the menu item they’re attached to 238 * 239 * - add an insensitive “Empty” item 240 * 241 * The behaviour is chosen based on the “hide_if_empty” property of the action 242 * to which the submenu is associated. 243 * 244 * # GtkUIManager as GtkBuildable # {#GtkUIManager-BUILDER-UI} 245 * 246 * The GtkUIManager implementation of the GtkBuildable interface accepts 247 * GtkActionGroup objects as <child> elements in UI definitions. 248 * 249 * A GtkUIManager UI definition as described above can be embedded in 250 * an GtkUIManager <object> element in a GtkBuilder UI definition. 251 * 252 * The widgets that are constructed by a GtkUIManager can be embedded in 253 * other parts of the constructed user interface with the help of the 254 * “constructor” attribute. See the example below. 255 * 256 * ## An embedded GtkUIManager UI definition 257 * 258 * |[ 259 * <object class="GtkUIManager" id="uiman"> 260 * <child> 261 * <object class="GtkActionGroup" id="actiongroup"> 262 * <child> 263 * <object class="GtkAction" id="file"> 264 * <property name="label">_File</property> 265 * </object> 266 * </child> 267 * </object> 268 * </child> 269 * <ui> 270 * <menubar name="menubar1"> 271 * <menu action="file"> 272 * </menu> 273 * </menubar> 274 * </ui> 275 * </object> 276 * <object class="GtkWindow" id="main-window"> 277 * <child> 278 * <object class="GtkMenuBar" id="menubar1" constructor="uiman"/> 279 * </child> 280 * </object> 281 * ]| 282 */ 283 public class UIManager : ObjectG, BuildableIF 284 { 285 /** the main Gtk struct */ 286 protected GtkUIManager* gtkUIManager; 287 288 /** Get the main Gtk struct */ 289 public GtkUIManager* getUIManagerStruct(bool transferOwnership = false) 290 { 291 if (transferOwnership) 292 ownedRef = false; 293 return gtkUIManager; 294 } 295 296 /** the main Gtk struct as a void* */ 297 protected override void* getStruct() 298 { 299 return cast(void*)gtkUIManager; 300 } 301 302 protected override void setStruct(GObject* obj) 303 { 304 gtkUIManager = cast(GtkUIManager*)obj; 305 super.setStruct(obj); 306 } 307 308 /** 309 * Sets our main struct and passes it to the parent class. 310 */ 311 public this (GtkUIManager* gtkUIManager, bool ownedRef = false) 312 { 313 this.gtkUIManager = gtkUIManager; 314 super(cast(GObject*)gtkUIManager, ownedRef); 315 } 316 317 // add the Buildable capabilities 318 mixin BuildableT!(GtkUIManager); 319 320 /** 321 * Warning: getWidget is deprecated and should not be used in newly-written code. 3.10 322 * 323 * Looks up a widget by following a path. 324 * The path consists of the names specified in the XML description of the UI. 325 * separated by '/'. Elements which don't have a name or action attribute in 326 * the XML (e.g. <popup>) can be addressed by their XML element name 327 * (e.g. "popup"). The root element ("/ui") can be omitted in the path. 328 * 329 * Note that the widget found by following a path that ends in a <menu> 330 * element is the menuitem to which the menu is attached, not the menu itself. 331 * 332 * Also note that the widgets constructed by a ui manager are not tied to 333 * the lifecycle of the ui manager. If you add the widgets returned by this 334 * function to some container or explicitly ref them, they will survive the 335 * destruction of the ui manager. 336 * 337 * Since 2.4 338 * 339 * Params: 340 * path = a path 341 * 342 * Returns: the widget found by following the path, or null if no widget was found. 343 */ 344 public Widget getWidget(string path) 345 { 346 // GtkWidget * gtk_ui_manager_get_widget (GtkUIManager *manager, const gchar *path); 347 auto p = gtk_ui_manager_get_widget(gtkUIManager, Str.toStringz(path)); 348 349 if(p is null) 350 { 351 return null; 352 } 353 354 string typeName = Type.name((cast(GTypeInstance*)p).gClass.gType); 355 356 switch(typeName) 357 { 358 case "GtkCheckMenuItem": 359 return ObjectG.getDObject!(CheckMenuItem)(cast(GtkCheckMenuItem*) p); 360 case "GtkImageMenuItem": 361 return ObjectG.getDObject!(ImageMenuItem)(cast(GtkImageMenuItem*) p); 362 case "GtkMenu": 363 return ObjectG.getDObject!(Menu)(cast(GtkMenu*) p); 364 case "GtkMenuBar": 365 return ObjectG.getDObject!(MenuBar)(cast(GtkMenuBar*) p); 366 case "GtkMenuItem": 367 return ObjectG.getDObject!(MenuItem)(cast(GtkMenuItem*) p); 368 case "GtkMenuToolButton": 369 return ObjectG.getDObject!(MenuToolButton)(cast(GtkMenuToolButton*) p); 370 case "GtkRadioMenuItem": 371 return ObjectG.getDObject!(RadioMenuItem)(cast(GtkRadioMenuItem*) p); 372 case "GtkRadioToolButton": 373 return ObjectG.getDObject!(RadioToolButton)(cast(GtkRadioToolButton*) p); 374 case "GtkSeparatorMenuItem": 375 return ObjectG.getDObject!(SeparatorMenuItem)(cast(GtkSeparatorMenuItem*) p); 376 case "GtkSeparatorToolItem": 377 return ObjectG.getDObject!(SeparatorToolItem)(cast(GtkSeparatorToolItem*) p); 378 case "GtkTearoffMenuItem": 379 return ObjectG.getDObject!(TearoffMenuItem)(cast(GtkTearoffMenuItem*) p); 380 case "GtkToggleToolButton": 381 return ObjectG.getDObject!(ToggleToolButton)(cast(GtkToggleToolButton*) p); 382 case "GtkToolbar": 383 return ObjectG.getDObject!(Toolbar)(cast(GtkToolbar*) p); 384 case "GtkToolButton": 385 return ObjectG.getDObject!(ToolButton)(cast(GtkToolButton*) p); 386 case "GtkToolItem": 387 return ObjectG.getDObject!(ToolItem)(cast(GtkToolItem*) p); 388 default: 389 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 390 } 391 } 392 393 /** 394 */ 395 396 /** */ 397 public static GType getType() 398 { 399 return gtk_ui_manager_get_type(); 400 } 401 402 /** 403 * Creates a new ui manager object. 404 * 405 * Returns: a new ui manager object. 406 * 407 * Since: 2.4 408 * 409 * Throws: ConstructionException GTK+ fails to create the object. 410 */ 411 public this() 412 { 413 auto p = gtk_ui_manager_new(); 414 415 if(p is null) 416 { 417 throw new ConstructionException("null returned by new"); 418 } 419 420 this(cast(GtkUIManager*) p, true); 421 } 422 423 /** 424 * Adds a UI element to the current contents of @manager. 425 * 426 * If @type is %GTK_UI_MANAGER_AUTO, GTK+ inserts a menuitem, toolitem or 427 * separator if such an element can be inserted at the place determined by 428 * @path. Otherwise @type must indicate an element that can be inserted at 429 * the place determined by @path. 430 * 431 * If @path points to a menuitem or toolitem, the new element will be inserted 432 * before or after this item, depending on @top. 433 * 434 * Params: 435 * mergeId = the merge id for the merged UI, see gtk_ui_manager_new_merge_id() 436 * path = a path 437 * name = the name for the added UI element 438 * action = the name of the action to be proxied, or %NULL to add a separator 439 * type = the type of UI element to add. 440 * top = if %TRUE, the UI element is added before its siblings, otherwise it 441 * is added after its siblings. 442 * 443 * Since: 2.4 444 */ 445 public void addUi(uint mergeId, string path, string name, string action, GtkUIManagerItemType type, bool top) 446 { 447 gtk_ui_manager_add_ui(gtkUIManager, mergeId, Str.toStringz(path), Str.toStringz(name), Str.toStringz(action), type, top); 448 } 449 450 /** 451 * Parses a file containing a [UI definition][XML-UI] and 452 * merges it with the current contents of @manager. 453 * 454 * Params: 455 * filename = the name of the file to parse 456 * 457 * Returns: The merge id for the merged UI. The merge id can be used 458 * to unmerge the UI with gtk_ui_manager_remove_ui(). If an error occurred, 459 * the return value is 0. 460 * 461 * Since: 2.4 462 * 463 * Throws: GException on failure. 464 */ 465 public uint addUiFromFile(string filename) 466 { 467 GError* err = null; 468 469 auto p = gtk_ui_manager_add_ui_from_file(gtkUIManager, Str.toStringz(filename), &err); 470 471 if (err !is null) 472 { 473 throw new GException( new ErrorG(err) ); 474 } 475 476 return p; 477 } 478 479 /** 480 * Parses a resource file containing a [UI definition][XML-UI] and 481 * merges it with the current contents of @manager. 482 * 483 * Params: 484 * resourcePath = the resource path of the file to parse 485 * 486 * Returns: The merge id for the merged UI. The merge id can be used 487 * to unmerge the UI with gtk_ui_manager_remove_ui(). If an error occurred, 488 * the return value is 0. 489 * 490 * Since: 3.4 491 * 492 * Throws: GException on failure. 493 */ 494 public uint addUiFromResource(string resourcePath) 495 { 496 GError* err = null; 497 498 auto p = gtk_ui_manager_add_ui_from_resource(gtkUIManager, Str.toStringz(resourcePath), &err); 499 500 if (err !is null) 501 { 502 throw new GException( new ErrorG(err) ); 503 } 504 505 return p; 506 } 507 508 /** 509 * Parses a string containing a [UI definition][XML-UI] and merges it with 510 * the current contents of @manager. An enclosing <ui> element is added if 511 * it is missing. 512 * 513 * Params: 514 * buffer = the string to parse 515 * length = the length of @buffer (may be -1 if @buffer is nul-terminated) 516 * 517 * Returns: The merge id for the merged UI. The merge id can be used 518 * to unmerge the UI with gtk_ui_manager_remove_ui(). If an error occurred, 519 * the return value is 0. 520 * 521 * Since: 2.4 522 * 523 * Throws: GException on failure. 524 */ 525 public uint addUiFromString(string buffer, ptrdiff_t length) 526 { 527 GError* err = null; 528 529 auto p = gtk_ui_manager_add_ui_from_string(gtkUIManager, Str.toStringz(buffer), length, &err); 530 531 if (err !is null) 532 { 533 throw new GException( new ErrorG(err) ); 534 } 535 536 return p; 537 } 538 539 /** 540 * Makes sure that all pending updates to the UI have been completed. 541 * 542 * This may occasionally be necessary, since #GtkUIManager updates the 543 * UI in an idle function. A typical example where this function is 544 * useful is to enforce that the menubar and toolbar have been added to 545 * the main window before showing it: 546 * |[<!-- language="C" --> 547 * gtk_container_add (GTK_CONTAINER (window), vbox); 548 * g_signal_connect (merge, "add-widget", 549 * G_CALLBACK (add_widget), vbox); 550 * gtk_ui_manager_add_ui_from_file (merge, "my-menus"); 551 * gtk_ui_manager_add_ui_from_file (merge, "my-toolbars"); 552 * gtk_ui_manager_ensure_update (merge); 553 * gtk_widget_show (window); 554 * ]| 555 * 556 * Since: 2.4 557 */ 558 public void ensureUpdate() 559 { 560 gtk_ui_manager_ensure_update(gtkUIManager); 561 } 562 563 /** 564 * Returns the #GtkAccelGroup associated with @manager. 565 * 566 * Returns: the #GtkAccelGroup. 567 * 568 * Since: 2.4 569 */ 570 public AccelGroup getAccelGroup() 571 { 572 auto p = gtk_ui_manager_get_accel_group(gtkUIManager); 573 574 if(p is null) 575 { 576 return null; 577 } 578 579 return ObjectG.getDObject!(AccelGroup)(cast(GtkAccelGroup*) p); 580 } 581 582 /** 583 * Looks up an action by following a path. See gtk_ui_manager_get_widget() 584 * for more information about paths. 585 * 586 * Params: 587 * path = a path 588 * 589 * Returns: the action whose proxy widget is found by following the path, 590 * or %NULL if no widget was found. 591 * 592 * Since: 2.4 593 */ 594 public Action getAction(string path) 595 { 596 auto p = gtk_ui_manager_get_action(gtkUIManager, Str.toStringz(path)); 597 598 if(p is null) 599 { 600 return null; 601 } 602 603 return ObjectG.getDObject!(Action)(cast(GtkAction*) p); 604 } 605 606 /** 607 * Returns the list of action groups associated with @manager. 608 * 609 * Returns: a #GList of 610 * action groups. The list is owned by GTK+ 611 * and should not be modified. 612 * 613 * Since: 2.4 614 */ 615 public ListG getActionGroups() 616 { 617 auto p = gtk_ui_manager_get_action_groups(gtkUIManager); 618 619 if(p is null) 620 { 621 return null; 622 } 623 624 return new ListG(cast(GList*) p); 625 } 626 627 /** 628 * Returns whether menus generated by this #GtkUIManager 629 * will have tearoff menu items. 630 * 631 * Deprecated: Tearoff menus are deprecated and should not 632 * be used in newly written code. 633 * 634 * Returns: whether tearoff menu items are added 635 * 636 * Since: 2.4 637 */ 638 public bool getAddTearoffs() 639 { 640 return gtk_ui_manager_get_add_tearoffs(gtkUIManager) != 0; 641 } 642 643 /** 644 * Obtains a list of all toplevel widgets of the requested types. 645 * 646 * Params: 647 * types = specifies the types of toplevel widgets to include. Allowed 648 * types are #GTK_UI_MANAGER_MENUBAR, #GTK_UI_MANAGER_TOOLBAR and 649 * #GTK_UI_MANAGER_POPUP. 650 * 651 * Returns: a newly-allocated #GSList of 652 * all toplevel widgets of the requested types. Free the returned list with g_slist_free(). 653 * 654 * Since: 2.4 655 */ 656 public ListSG getToplevels(GtkUIManagerItemType types) 657 { 658 auto p = gtk_ui_manager_get_toplevels(gtkUIManager, types); 659 660 if(p is null) 661 { 662 return null; 663 } 664 665 return new ListSG(cast(GSList*) p); 666 } 667 668 /** 669 * Creates a [UI definition][XML-UI] of the merged UI. 670 * 671 * Returns: A newly allocated string containing an XML representation of 672 * the merged UI. 673 * 674 * Since: 2.4 675 */ 676 public string getUi() 677 { 678 auto retStr = gtk_ui_manager_get_ui(gtkUIManager); 679 680 scope(exit) Str.freeString(retStr); 681 return Str.toString(retStr); 682 } 683 684 /** 685 * Inserts an action group into the list of action groups associated 686 * with @manager. Actions in earlier groups hide actions with the same 687 * name in later groups. 688 * 689 * If @pos is larger than the number of action groups in @manager, or 690 * negative, @action_group will be inserted at the end of the internal 691 * list. 692 * 693 * Params: 694 * actionGroup = the action group to be inserted 695 * pos = the position at which the group will be inserted. 696 * 697 * Since: 2.4 698 */ 699 public void insertActionGroup(ActionGroup actionGroup, int pos) 700 { 701 gtk_ui_manager_insert_action_group(gtkUIManager, (actionGroup is null) ? null : actionGroup.getActionGroupStruct(), pos); 702 } 703 704 /** 705 * Returns an unused merge id, suitable for use with 706 * gtk_ui_manager_add_ui(). 707 * 708 * Returns: an unused merge id. 709 * 710 * Since: 2.4 711 */ 712 public uint newMergeId() 713 { 714 return gtk_ui_manager_new_merge_id(gtkUIManager); 715 } 716 717 /** 718 * Removes an action group from the list of action groups associated 719 * with @manager. 720 * 721 * Params: 722 * actionGroup = the action group to be removed 723 * 724 * Since: 2.4 725 */ 726 public void removeActionGroup(ActionGroup actionGroup) 727 { 728 gtk_ui_manager_remove_action_group(gtkUIManager, (actionGroup is null) ? null : actionGroup.getActionGroupStruct()); 729 } 730 731 /** 732 * Unmerges the part of @manager's content identified by @merge_id. 733 * 734 * Params: 735 * mergeId = a merge id as returned by gtk_ui_manager_add_ui_from_string() 736 * 737 * Since: 2.4 738 */ 739 public void removeUi(uint mergeId) 740 { 741 gtk_ui_manager_remove_ui(gtkUIManager, mergeId); 742 } 743 744 /** 745 * Sets the “add_tearoffs” property, which controls whether menus 746 * generated by this #GtkUIManager will have tearoff menu items. 747 * 748 * Note that this only affects regular menus. Generated popup 749 * menus never have tearoff menu items. 750 * 751 * Deprecated: Tearoff menus are deprecated and should not 752 * be used in newly written code. 753 * 754 * Params: 755 * addTearoffs = whether tearoff menu items are added 756 * 757 * Since: 2.4 758 */ 759 public void setAddTearoffs(bool addTearoffs) 760 { 761 gtk_ui_manager_set_add_tearoffs(gtkUIManager, addTearoffs); 762 } 763 764 protected class OnActionsChangedDelegateWrapper 765 { 766 static OnActionsChangedDelegateWrapper[] listeners; 767 void delegate(UIManager) dlg; 768 gulong handlerId; 769 770 this(void delegate(UIManager) dlg) 771 { 772 this.dlg = dlg; 773 this.listeners ~= this; 774 } 775 776 void remove(OnActionsChangedDelegateWrapper source) 777 { 778 foreach(index, wrapper; listeners) 779 { 780 if (wrapper.handlerId == source.handlerId) 781 { 782 listeners[index] = null; 783 listeners = std.algorithm.remove(listeners, index); 784 break; 785 } 786 } 787 } 788 } 789 790 /** 791 * The ::actions-changed signal is emitted whenever the set of actions 792 * changes. 793 * 794 * Since: 2.4 795 */ 796 gulong addOnActionsChanged(void delegate(UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 797 { 798 auto wrapper = new OnActionsChangedDelegateWrapper(dlg); 799 wrapper.handlerId = Signals.connectData( 800 this, 801 "actions-changed", 802 cast(GCallback)&callBackActionsChanged, 803 cast(void*)wrapper, 804 cast(GClosureNotify)&callBackActionsChangedDestroy, 805 connectFlags); 806 return wrapper.handlerId; 807 } 808 809 extern(C) static void callBackActionsChanged(GtkUIManager* uimanagerStruct, OnActionsChangedDelegateWrapper wrapper) 810 { 811 wrapper.dlg(wrapper.outer); 812 } 813 814 extern(C) static void callBackActionsChangedDestroy(OnActionsChangedDelegateWrapper wrapper, GClosure* closure) 815 { 816 wrapper.remove(wrapper); 817 } 818 819 protected class OnAddWidgetDelegateWrapper 820 { 821 static OnAddWidgetDelegateWrapper[] listeners; 822 void delegate(Widget, UIManager) dlg; 823 gulong handlerId; 824 825 this(void delegate(Widget, UIManager) dlg) 826 { 827 this.dlg = dlg; 828 this.listeners ~= this; 829 } 830 831 void remove(OnAddWidgetDelegateWrapper source) 832 { 833 foreach(index, wrapper; listeners) 834 { 835 if (wrapper.handlerId == source.handlerId) 836 { 837 listeners[index] = null; 838 listeners = std.algorithm.remove(listeners, index); 839 break; 840 } 841 } 842 } 843 } 844 845 /** 846 * The ::add-widget signal is emitted for each generated menubar and toolbar. 847 * It is not emitted for generated popup menus, which can be obtained by 848 * gtk_ui_manager_get_widget(). 849 * 850 * Params: 851 * widget = the added widget 852 * 853 * Since: 2.4 854 */ 855 gulong addOnAddWidget(void delegate(Widget, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 856 { 857 auto wrapper = new OnAddWidgetDelegateWrapper(dlg); 858 wrapper.handlerId = Signals.connectData( 859 this, 860 "add-widget", 861 cast(GCallback)&callBackAddWidget, 862 cast(void*)wrapper, 863 cast(GClosureNotify)&callBackAddWidgetDestroy, 864 connectFlags); 865 return wrapper.handlerId; 866 } 867 868 extern(C) static void callBackAddWidget(GtkUIManager* uimanagerStruct, GtkWidget* widget, OnAddWidgetDelegateWrapper wrapper) 869 { 870 wrapper.dlg(ObjectG.getDObject!(Widget)(widget), wrapper.outer); 871 } 872 873 extern(C) static void callBackAddWidgetDestroy(OnAddWidgetDelegateWrapper wrapper, GClosure* closure) 874 { 875 wrapper.remove(wrapper); 876 } 877 878 protected class OnConnectProxyDelegateWrapper 879 { 880 static OnConnectProxyDelegateWrapper[] listeners; 881 void delegate(Action, Widget, UIManager) dlg; 882 gulong handlerId; 883 884 this(void delegate(Action, Widget, UIManager) dlg) 885 { 886 this.dlg = dlg; 887 this.listeners ~= this; 888 } 889 890 void remove(OnConnectProxyDelegateWrapper source) 891 { 892 foreach(index, wrapper; listeners) 893 { 894 if (wrapper.handlerId == source.handlerId) 895 { 896 listeners[index] = null; 897 listeners = std.algorithm.remove(listeners, index); 898 break; 899 } 900 } 901 } 902 } 903 904 /** 905 * The ::connect-proxy signal is emitted after connecting a proxy to 906 * an action in the group. 907 * 908 * This is intended for simple customizations for which a custom action 909 * class would be too clumsy, e.g. showing tooltips for menuitems in the 910 * statusbar. 911 * 912 * Params: 913 * action = the action 914 * proxy = the proxy 915 * 916 * Since: 2.4 917 */ 918 gulong addOnConnectProxy(void delegate(Action, Widget, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 919 { 920 auto wrapper = new OnConnectProxyDelegateWrapper(dlg); 921 wrapper.handlerId = Signals.connectData( 922 this, 923 "connect-proxy", 924 cast(GCallback)&callBackConnectProxy, 925 cast(void*)wrapper, 926 cast(GClosureNotify)&callBackConnectProxyDestroy, 927 connectFlags); 928 return wrapper.handlerId; 929 } 930 931 extern(C) static void callBackConnectProxy(GtkUIManager* uimanagerStruct, GtkAction* action, GtkWidget* proxy, OnConnectProxyDelegateWrapper wrapper) 932 { 933 wrapper.dlg(ObjectG.getDObject!(Action)(action), ObjectG.getDObject!(Widget)(proxy), wrapper.outer); 934 } 935 936 extern(C) static void callBackConnectProxyDestroy(OnConnectProxyDelegateWrapper wrapper, GClosure* closure) 937 { 938 wrapper.remove(wrapper); 939 } 940 941 protected class OnDisconnectProxyDelegateWrapper 942 { 943 static OnDisconnectProxyDelegateWrapper[] listeners; 944 void delegate(Action, Widget, UIManager) dlg; 945 gulong handlerId; 946 947 this(void delegate(Action, Widget, UIManager) dlg) 948 { 949 this.dlg = dlg; 950 this.listeners ~= this; 951 } 952 953 void remove(OnDisconnectProxyDelegateWrapper source) 954 { 955 foreach(index, wrapper; listeners) 956 { 957 if (wrapper.handlerId == source.handlerId) 958 { 959 listeners[index] = null; 960 listeners = std.algorithm.remove(listeners, index); 961 break; 962 } 963 } 964 } 965 } 966 967 /** 968 * The ::disconnect-proxy signal is emitted after disconnecting a proxy 969 * from an action in the group. 970 * 971 * Params: 972 * action = the action 973 * proxy = the proxy 974 * 975 * Since: 2.4 976 */ 977 gulong addOnDisconnectProxy(void delegate(Action, Widget, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 978 { 979 auto wrapper = new OnDisconnectProxyDelegateWrapper(dlg); 980 wrapper.handlerId = Signals.connectData( 981 this, 982 "disconnect-proxy", 983 cast(GCallback)&callBackDisconnectProxy, 984 cast(void*)wrapper, 985 cast(GClosureNotify)&callBackDisconnectProxyDestroy, 986 connectFlags); 987 return wrapper.handlerId; 988 } 989 990 extern(C) static void callBackDisconnectProxy(GtkUIManager* uimanagerStruct, GtkAction* action, GtkWidget* proxy, OnDisconnectProxyDelegateWrapper wrapper) 991 { 992 wrapper.dlg(ObjectG.getDObject!(Action)(action), ObjectG.getDObject!(Widget)(proxy), wrapper.outer); 993 } 994 995 extern(C) static void callBackDisconnectProxyDestroy(OnDisconnectProxyDelegateWrapper wrapper, GClosure* closure) 996 { 997 wrapper.remove(wrapper); 998 } 999 1000 protected class OnPostActivateDelegateWrapper 1001 { 1002 static OnPostActivateDelegateWrapper[] listeners; 1003 void delegate(Action, UIManager) dlg; 1004 gulong handlerId; 1005 1006 this(void delegate(Action, UIManager) dlg) 1007 { 1008 this.dlg = dlg; 1009 this.listeners ~= this; 1010 } 1011 1012 void remove(OnPostActivateDelegateWrapper source) 1013 { 1014 foreach(index, wrapper; listeners) 1015 { 1016 if (wrapper.handlerId == source.handlerId) 1017 { 1018 listeners[index] = null; 1019 listeners = std.algorithm.remove(listeners, index); 1020 break; 1021 } 1022 } 1023 } 1024 } 1025 1026 /** 1027 * The ::post-activate signal is emitted just after the @action 1028 * is activated. 1029 * 1030 * This is intended for applications to get notification 1031 * just after any action is activated. 1032 * 1033 * Params: 1034 * action = the action 1035 * 1036 * Since: 2.4 1037 */ 1038 gulong addOnPostActivate(void delegate(Action, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1039 { 1040 auto wrapper = new OnPostActivateDelegateWrapper(dlg); 1041 wrapper.handlerId = Signals.connectData( 1042 this, 1043 "post-activate", 1044 cast(GCallback)&callBackPostActivate, 1045 cast(void*)wrapper, 1046 cast(GClosureNotify)&callBackPostActivateDestroy, 1047 connectFlags); 1048 return wrapper.handlerId; 1049 } 1050 1051 extern(C) static void callBackPostActivate(GtkUIManager* uimanagerStruct, GtkAction* action, OnPostActivateDelegateWrapper wrapper) 1052 { 1053 wrapper.dlg(ObjectG.getDObject!(Action)(action), wrapper.outer); 1054 } 1055 1056 extern(C) static void callBackPostActivateDestroy(OnPostActivateDelegateWrapper wrapper, GClosure* closure) 1057 { 1058 wrapper.remove(wrapper); 1059 } 1060 1061 protected class OnPreActivateDelegateWrapper 1062 { 1063 static OnPreActivateDelegateWrapper[] listeners; 1064 void delegate(Action, UIManager) dlg; 1065 gulong handlerId; 1066 1067 this(void delegate(Action, UIManager) dlg) 1068 { 1069 this.dlg = dlg; 1070 this.listeners ~= this; 1071 } 1072 1073 void remove(OnPreActivateDelegateWrapper source) 1074 { 1075 foreach(index, wrapper; listeners) 1076 { 1077 if (wrapper.handlerId == source.handlerId) 1078 { 1079 listeners[index] = null; 1080 listeners = std.algorithm.remove(listeners, index); 1081 break; 1082 } 1083 } 1084 } 1085 } 1086 1087 /** 1088 * The ::pre-activate signal is emitted just before the @action 1089 * is activated. 1090 * 1091 * This is intended for applications to get notification 1092 * just before any action is activated. 1093 * 1094 * Params: 1095 * action = the action 1096 * 1097 * Since: 2.4 1098 */ 1099 gulong addOnPreActivate(void delegate(Action, UIManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1100 { 1101 auto wrapper = new OnPreActivateDelegateWrapper(dlg); 1102 wrapper.handlerId = Signals.connectData( 1103 this, 1104 "pre-activate", 1105 cast(GCallback)&callBackPreActivate, 1106 cast(void*)wrapper, 1107 cast(GClosureNotify)&callBackPreActivateDestroy, 1108 connectFlags); 1109 return wrapper.handlerId; 1110 } 1111 1112 extern(C) static void callBackPreActivate(GtkUIManager* uimanagerStruct, GtkAction* action, OnPreActivateDelegateWrapper wrapper) 1113 { 1114 wrapper.dlg(ObjectG.getDObject!(Action)(action), wrapper.outer); 1115 } 1116 1117 extern(C) static void callBackPreActivateDestroy(OnPreActivateDelegateWrapper wrapper, GClosure* closure) 1118 { 1119 wrapper.remove(wrapper); 1120 } 1121 }