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.ActionGroup; 26 27 private import glib.ConstructionException; 28 private import glib.ListG; 29 private import glib.Str; 30 private import gobject.ObjectG; 31 private import gobject.Signals; 32 private import gtk.AccelGroup; 33 private import gtk.Action; 34 private import gtk.BuildableIF; 35 private import gtk.BuildableT; 36 private import gtk.Widget; 37 public import gtkc.gdktypes; 38 private import gtkc.gtk; 39 public import gtkc.gtktypes; 40 private import std.algorithm; 41 42 43 /** 44 * Actions are organised into groups. An action group is essentially a 45 * map from names to #GtkAction objects. 46 * 47 * All actions that would make sense to use in a particular context 48 * should be in a single group. Multiple action groups may be used for a 49 * particular user interface. In fact, it is expected that most nontrivial 50 * applications will make use of multiple groups. For example, in an 51 * application that can edit multiple documents, one group holding global 52 * actions (e.g. quit, about, new), and one group per document holding 53 * actions that act on that document (eg. save, cut/copy/paste, etc). Each 54 * window’s menus would be constructed from a combination of two action 55 * groups. 56 * 57 * ## Accelerators ## {#Action-Accel} 58 * 59 * Accelerators are handled by the GTK+ accelerator map. All actions are 60 * assigned an accelerator path (which normally has the form 61 * `<Actions>/group-name/action-name`) and a shortcut is associated with 62 * this accelerator path. All menuitems and toolitems take on this accelerator 63 * path. The GTK+ accelerator map code makes sure that the correct shortcut 64 * is displayed next to the menu item. 65 * 66 * # GtkActionGroup as GtkBuildable # {#GtkActionGroup-BUILDER-UI} 67 * 68 * The #GtkActionGroup implementation of the #GtkBuildable interface accepts 69 * #GtkAction objects as <child> elements in UI definitions. 70 * 71 * Note that it is probably more common to define actions and action groups 72 * in the code, since they are directly related to what the code can do. 73 * 74 * The GtkActionGroup implementation of the GtkBuildable interface supports 75 * a custom <accelerator> element, which has attributes named “key“ and 76 * “modifiers“ and allows to specify accelerators. This is similar to the 77 * <accelerator> element of #GtkWidget, the main difference is that 78 * it doesn’t allow you to specify a signal. 79 * 80 * ## A #GtkDialog UI definition fragment. ## 81 * |[ 82 * <object class="GtkActionGroup" id="actiongroup"> 83 * <child> 84 * <object class="GtkAction" id="About"> 85 * <property name="name">About</property> 86 * <property name="stock_id">gtk-about</property> 87 * <signal handler="about_activate" name="activate"/> 88 * </object> 89 * <accelerator key="F1" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK"/> 90 * </child> 91 * </object> 92 * ]| 93 */ 94 public class ActionGroup : ObjectG, BuildableIF 95 { 96 /** the main Gtk struct */ 97 protected GtkActionGroup* gtkActionGroup; 98 99 /** Get the main Gtk struct */ 100 public GtkActionGroup* getActionGroupStruct() 101 { 102 return gtkActionGroup; 103 } 104 105 /** the main Gtk struct as a void* */ 106 protected override void* getStruct() 107 { 108 return cast(void*)gtkActionGroup; 109 } 110 111 protected override void setStruct(GObject* obj) 112 { 113 gtkActionGroup = cast(GtkActionGroup*)obj; 114 super.setStruct(obj); 115 } 116 117 /** 118 * Sets our main struct and passes it to the parent class. 119 */ 120 public this (GtkActionGroup* gtkActionGroup, bool ownedRef = false) 121 { 122 this.gtkActionGroup = gtkActionGroup; 123 super(cast(GObject*)gtkActionGroup, ownedRef); 124 } 125 126 // add the Buildable capabilities 127 mixin BuildableT!(GtkActionGroup); 128 129 130 /** */ 131 public static GType getType() 132 { 133 return gtk_action_group_get_type(); 134 } 135 136 /** 137 * Creates a new #GtkActionGroup object. The name of the action group 138 * is used when associating [keybindings][Action-Accel] 139 * with the actions. 140 * 141 * Params: 142 * name = the name of the action group. 143 * 144 * Return: the new #GtkActionGroup 145 * 146 * Since: 2.4 147 * 148 * Throws: ConstructionException GTK+ fails to create the object. 149 */ 150 public this(string name) 151 { 152 auto p = gtk_action_group_new(Str.toStringz(name)); 153 154 if(p is null) 155 { 156 throw new ConstructionException("null returned by new"); 157 } 158 159 this(cast(GtkActionGroup*) p, true); 160 } 161 162 /** 163 * Adds an action object to the action group. Note that this function 164 * does not set up the accel path of the action, which can lead to problems 165 * if a user tries to modify the accelerator of a menuitem associated with 166 * the action. Therefore you must either set the accel path yourself with 167 * gtk_action_set_accel_path(), or use 168 * `gtk_action_group_add_action_with_accel (..., NULL)`. 169 * 170 * Params: 171 * action = an action 172 * 173 * Since: 2.4 174 */ 175 public void addAction(Action action) 176 { 177 gtk_action_group_add_action(gtkActionGroup, (action is null) ? null : action.getActionStruct()); 178 } 179 180 /** 181 * Adds an action object to the action group and sets up the accelerator. 182 * 183 * If @accelerator is %NULL, attempts to use the accelerator associated 184 * with the stock_id of the action. 185 * 186 * Accel paths are set to `<Actions>/group-name/action-name`. 187 * 188 * Params: 189 * action = the action to add 190 * accelerator = the accelerator for the action, in 191 * the format understood by gtk_accelerator_parse(), or "" for no accelerator, or 192 * %NULL to use the stock accelerator 193 * 194 * Since: 2.4 195 */ 196 public void addActionWithAccel(Action action, string accelerator) 197 { 198 gtk_action_group_add_action_with_accel(gtkActionGroup, (action is null) ? null : action.getActionStruct(), Str.toStringz(accelerator)); 199 } 200 201 /** 202 * This is a convenience function to create a number of actions and add them 203 * to the action group. 204 * 205 * The “activate” signals of the actions are connected to the callbacks 206 * and their accel paths are set to `<Actions>/group-name/action-name`. 207 * 208 * Params: 209 * entries = an array of action descriptions 210 * nEntries = the number of entries 211 * userData = data to pass to the action callbacks 212 * 213 * Since: 2.4 214 */ 215 public void addActions(GtkActionEntry[] entries, void* userData) 216 { 217 gtk_action_group_add_actions(gtkActionGroup, entries.ptr, cast(uint)entries.length, userData); 218 } 219 220 /** 221 * This variant of gtk_action_group_add_actions() adds a #GDestroyNotify 222 * callback for @user_data. 223 * 224 * Params: 225 * entries = an array of action descriptions 226 * nEntries = the number of entries 227 * userData = data to pass to the action callbacks 228 * destroy = destroy notification callback for @user_data 229 * 230 * Since: 2.4 231 */ 232 public void addActionsFull(GtkActionEntry[] entries, void* userData, GDestroyNotify destroy) 233 { 234 gtk_action_group_add_actions_full(gtkActionGroup, entries.ptr, cast(uint)entries.length, userData, destroy); 235 } 236 237 /** 238 * This is a convenience routine to create a group of radio actions and 239 * add them to the action group. 240 * 241 * The “changed” signal of the first radio action is connected to the 242 * @on_change callback and the accel paths of the actions are set to 243 * `<Actions>/group-name/action-name`. 244 * 245 * Params: 246 * entries = an array of radio action descriptions 247 * nEntries = the number of entries 248 * value = the value of the action to activate initially, or -1 if 249 * no action should be activated 250 * onChange = the callback to connect to the changed signal 251 * userData = data to pass to the action callbacks 252 * 253 * Since: 2.4 254 */ 255 public void addRadioActions(GtkRadioActionEntry[] entries, int value, GCallback onChange, void* userData) 256 { 257 gtk_action_group_add_radio_actions(gtkActionGroup, entries.ptr, cast(uint)entries.length, value, onChange, userData); 258 } 259 260 /** 261 * This variant of gtk_action_group_add_radio_actions() adds a 262 * #GDestroyNotify callback for @user_data. 263 * 264 * Params: 265 * entries = an array of radio action descriptions 266 * nEntries = the number of entries 267 * value = the value of the action to activate initially, or -1 if 268 * no action should be activated 269 * onChange = the callback to connect to the changed signal 270 * userData = data to pass to the action callbacks 271 * destroy = destroy notification callback for @user_data 272 * 273 * Since: 2.4 274 */ 275 public void addRadioActionsFull(GtkRadioActionEntry[] entries, int value, GCallback onChange, void* userData, GDestroyNotify destroy) 276 { 277 gtk_action_group_add_radio_actions_full(gtkActionGroup, entries.ptr, cast(uint)entries.length, value, onChange, userData, destroy); 278 } 279 280 /** 281 * This is a convenience function to create a number of toggle actions and add them 282 * to the action group. 283 * 284 * The “activate” signals of the actions are connected to the callbacks 285 * and their accel paths are set to `<Actions>/group-name/action-name`. 286 * 287 * Params: 288 * entries = an array of toggle action descriptions 289 * nEntries = the number of entries 290 * userData = data to pass to the action callbacks 291 * 292 * Since: 2.4 293 */ 294 public void addToggleActions(GtkToggleActionEntry[] entries, void* userData) 295 { 296 gtk_action_group_add_toggle_actions(gtkActionGroup, entries.ptr, cast(uint)entries.length, userData); 297 } 298 299 /** 300 * This variant of gtk_action_group_add_toggle_actions() adds a 301 * #GDestroyNotify callback for @user_data. 302 * 303 * Params: 304 * entries = an array of toggle action descriptions 305 * nEntries = the number of entries 306 * userData = data to pass to the action callbacks 307 * destroy = destroy notification callback for @user_data 308 * 309 * Since: 2.4 310 */ 311 public void addToggleActionsFull(GtkToggleActionEntry[] entries, void* userData, GDestroyNotify destroy) 312 { 313 gtk_action_group_add_toggle_actions_full(gtkActionGroup, entries.ptr, cast(uint)entries.length, userData, destroy); 314 } 315 316 /** 317 * Gets the accelerator group. 318 * 319 * Return: the accelerator group associated with this action 320 * group or %NULL if there is none. 321 * 322 * Since: 3.6 323 */ 324 public AccelGroup getAccelGroup() 325 { 326 auto p = gtk_action_group_get_accel_group(gtkActionGroup); 327 328 if(p is null) 329 { 330 return null; 331 } 332 333 return ObjectG.getDObject!(AccelGroup)(cast(GtkAccelGroup*) p); 334 } 335 336 /** 337 * Looks up an action in the action group by name. 338 * 339 * Params: 340 * actionName = the name of the action 341 * 342 * Return: the action, or %NULL if no action by that name exists 343 * 344 * Since: 2.4 345 */ 346 public Action getAction(string actionName) 347 { 348 auto p = gtk_action_group_get_action(gtkActionGroup, Str.toStringz(actionName)); 349 350 if(p is null) 351 { 352 return null; 353 } 354 355 return ObjectG.getDObject!(Action)(cast(GtkAction*) p); 356 } 357 358 /** 359 * Gets the name of the action group. 360 * 361 * Return: the name of the action group. 362 * 363 * Since: 2.4 364 */ 365 public string getName() 366 { 367 return Str.toString(gtk_action_group_get_name(gtkActionGroup)); 368 } 369 370 /** 371 * Returns %TRUE if the group is sensitive. The constituent actions 372 * can only be logically sensitive (see gtk_action_is_sensitive()) if 373 * they are sensitive (see gtk_action_get_sensitive()) and their group 374 * is sensitive. 375 * 376 * Return: %TRUE if the group is sensitive. 377 * 378 * Since: 2.4 379 */ 380 public bool getSensitive() 381 { 382 return gtk_action_group_get_sensitive(gtkActionGroup) != 0; 383 } 384 385 /** 386 * Returns %TRUE if the group is visible. The constituent actions 387 * can only be logically visible (see gtk_action_is_visible()) if 388 * they are visible (see gtk_action_get_visible()) and their group 389 * is visible. 390 * 391 * Return: %TRUE if the group is visible. 392 * 393 * Since: 2.4 394 */ 395 public bool getVisible() 396 { 397 return gtk_action_group_get_visible(gtkActionGroup) != 0; 398 } 399 400 /** 401 * Lists the actions in the action group. 402 * 403 * Return: an allocated list of the action objects in the action group 404 * 405 * Since: 2.4 406 */ 407 public ListG listActions() 408 { 409 auto p = gtk_action_group_list_actions(gtkActionGroup); 410 411 if(p is null) 412 { 413 return null; 414 } 415 416 return new ListG(cast(GList*) p); 417 } 418 419 /** 420 * Removes an action object from the action group. 421 * 422 * Params: 423 * action = an action 424 * 425 * Since: 2.4 426 */ 427 public void removeAction(Action action) 428 { 429 gtk_action_group_remove_action(gtkActionGroup, (action is null) ? null : action.getActionStruct()); 430 } 431 432 /** 433 * Sets the accelerator group to be used by every action in this group. 434 * 435 * Params: 436 * accelGroup = a #GtkAccelGroup to set or %NULL 437 * 438 * Since: 3.6 439 */ 440 public void setAccelGroup(AccelGroup accelGroup) 441 { 442 gtk_action_group_set_accel_group(gtkActionGroup, (accelGroup is null) ? null : accelGroup.getAccelGroupStruct()); 443 } 444 445 /** 446 * Changes the sensitivity of @action_group 447 * 448 * Params: 449 * sensitive = new sensitivity 450 * 451 * Since: 2.4 452 */ 453 public void setSensitive(bool sensitive) 454 { 455 gtk_action_group_set_sensitive(gtkActionGroup, sensitive); 456 } 457 458 /** 459 * Sets a function to be used for translating the @label and @tooltip of 460 * #GtkActionEntrys added by gtk_action_group_add_actions(). 461 * 462 * If you’re using gettext(), it is enough to set the translation domain 463 * with gtk_action_group_set_translation_domain(). 464 * 465 * Params: 466 * func = a #GtkTranslateFunc 467 * data = data to be passed to @func and @notify 468 * notify = a #GDestroyNotify function to be called when @action_group is 469 * destroyed and when the translation function is changed again 470 * 471 * Since: 2.4 472 */ 473 public void setTranslateFunc(GtkTranslateFunc func, void* data, GDestroyNotify notify) 474 { 475 gtk_action_group_set_translate_func(gtkActionGroup, func, data, notify); 476 } 477 478 /** 479 * Sets the translation domain and uses g_dgettext() for translating the 480 * @label and @tooltip of #GtkActionEntrys added by 481 * gtk_action_group_add_actions(). 482 * 483 * If you’re not using gettext() for localization, see 484 * gtk_action_group_set_translate_func(). 485 * 486 * Params: 487 * domain = the translation domain to use for g_dgettext() 488 * calls, or %NULL to use the domain set with textdomain() 489 * 490 * Since: 2.4 491 */ 492 public void setTranslationDomain(string domain) 493 { 494 gtk_action_group_set_translation_domain(gtkActionGroup, Str.toStringz(domain)); 495 } 496 497 /** 498 * Changes the visible of @action_group. 499 * 500 * Params: 501 * visible = new visiblity 502 * 503 * Since: 2.4 504 */ 505 public void setVisible(bool visible) 506 { 507 gtk_action_group_set_visible(gtkActionGroup, visible); 508 } 509 510 /** 511 * Translates a string using the function set with 512 * gtk_action_group_set_translate_func(). This 513 * is mainly intended for language bindings. 514 * 515 * Params: 516 * str = a string 517 * 518 * Return: the translation of @string 519 * 520 * Since: 2.6 521 */ 522 public string translateString(string str) 523 { 524 return Str.toString(gtk_action_group_translate_string(gtkActionGroup, Str.toStringz(str))); 525 } 526 527 protected class OnConnectProxyDelegateWrapper 528 { 529 void delegate(Action, Widget, ActionGroup) dlg; 530 gulong handlerId; 531 ConnectFlags flags; 532 this(void delegate(Action, Widget, ActionGroup) dlg, gulong handlerId, ConnectFlags flags) 533 { 534 this.dlg = dlg; 535 this.handlerId = handlerId; 536 this.flags = flags; 537 } 538 } 539 protected OnConnectProxyDelegateWrapper[] onConnectProxyListeners; 540 541 /** 542 * The ::connect-proxy signal is emitted after connecting a proxy to 543 * an action in the group. Note that the proxy may have been connected 544 * to a different action before. 545 * 546 * This is intended for simple customizations for which a custom action 547 * class would be too clumsy, e.g. showing tooltips for menuitems in the 548 * statusbar. 549 * 550 * #GtkUIManager proxies the signal and provides global notification 551 * just before any action is connected to a proxy, which is probably more 552 * convenient to use. 553 * 554 * Params: 555 * action = the action 556 * proxy = the proxy 557 * 558 * Since: 2.4 559 */ 560 gulong addOnConnectProxy(void delegate(Action, Widget, ActionGroup) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 561 { 562 onConnectProxyListeners ~= new OnConnectProxyDelegateWrapper(dlg, 0, connectFlags); 563 onConnectProxyListeners[onConnectProxyListeners.length - 1].handlerId = Signals.connectData( 564 this, 565 "connect-proxy", 566 cast(GCallback)&callBackConnectProxy, 567 cast(void*)onConnectProxyListeners[onConnectProxyListeners.length - 1], 568 cast(GClosureNotify)&callBackConnectProxyDestroy, 569 connectFlags); 570 return onConnectProxyListeners[onConnectProxyListeners.length - 1].handlerId; 571 } 572 573 extern(C) static void callBackConnectProxy(GtkActionGroup* actiongroupStruct, GtkAction* action, GtkWidget* proxy,OnConnectProxyDelegateWrapper wrapper) 574 { 575 wrapper.dlg(ObjectG.getDObject!(Action)(action), ObjectG.getDObject!(Widget)(proxy), wrapper.outer); 576 } 577 578 extern(C) static void callBackConnectProxyDestroy(OnConnectProxyDelegateWrapper wrapper, GClosure* closure) 579 { 580 wrapper.outer.internalRemoveOnConnectProxy(wrapper); 581 } 582 583 protected void internalRemoveOnConnectProxy(OnConnectProxyDelegateWrapper source) 584 { 585 foreach(index, wrapper; onConnectProxyListeners) 586 { 587 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 588 { 589 onConnectProxyListeners[index] = null; 590 onConnectProxyListeners = std.algorithm.remove(onConnectProxyListeners, index); 591 break; 592 } 593 } 594 } 595 596 597 protected class OnDisconnectProxyDelegateWrapper 598 { 599 void delegate(Action, Widget, ActionGroup) dlg; 600 gulong handlerId; 601 ConnectFlags flags; 602 this(void delegate(Action, Widget, ActionGroup) dlg, gulong handlerId, ConnectFlags flags) 603 { 604 this.dlg = dlg; 605 this.handlerId = handlerId; 606 this.flags = flags; 607 } 608 } 609 protected OnDisconnectProxyDelegateWrapper[] onDisconnectProxyListeners; 610 611 /** 612 * The ::disconnect-proxy signal is emitted after disconnecting a proxy 613 * from an action in the group. 614 * 615 * #GtkUIManager proxies the signal and provides global notification 616 * just before any action is connected to a proxy, which is probably more 617 * convenient to use. 618 * 619 * Params: 620 * action = the action 621 * proxy = the proxy 622 * 623 * Since: 2.4 624 */ 625 gulong addOnDisconnectProxy(void delegate(Action, Widget, ActionGroup) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 626 { 627 onDisconnectProxyListeners ~= new OnDisconnectProxyDelegateWrapper(dlg, 0, connectFlags); 628 onDisconnectProxyListeners[onDisconnectProxyListeners.length - 1].handlerId = Signals.connectData( 629 this, 630 "disconnect-proxy", 631 cast(GCallback)&callBackDisconnectProxy, 632 cast(void*)onDisconnectProxyListeners[onDisconnectProxyListeners.length - 1], 633 cast(GClosureNotify)&callBackDisconnectProxyDestroy, 634 connectFlags); 635 return onDisconnectProxyListeners[onDisconnectProxyListeners.length - 1].handlerId; 636 } 637 638 extern(C) static void callBackDisconnectProxy(GtkActionGroup* actiongroupStruct, GtkAction* action, GtkWidget* proxy,OnDisconnectProxyDelegateWrapper wrapper) 639 { 640 wrapper.dlg(ObjectG.getDObject!(Action)(action), ObjectG.getDObject!(Widget)(proxy), wrapper.outer); 641 } 642 643 extern(C) static void callBackDisconnectProxyDestroy(OnDisconnectProxyDelegateWrapper wrapper, GClosure* closure) 644 { 645 wrapper.outer.internalRemoveOnDisconnectProxy(wrapper); 646 } 647 648 protected void internalRemoveOnDisconnectProxy(OnDisconnectProxyDelegateWrapper source) 649 { 650 foreach(index, wrapper; onDisconnectProxyListeners) 651 { 652 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 653 { 654 onDisconnectProxyListeners[index] = null; 655 onDisconnectProxyListeners = std.algorithm.remove(onDisconnectProxyListeners, index); 656 break; 657 } 658 } 659 } 660 661 662 protected class OnPostActivateDelegateWrapper 663 { 664 void delegate(Action, ActionGroup) dlg; 665 gulong handlerId; 666 ConnectFlags flags; 667 this(void delegate(Action, ActionGroup) dlg, gulong handlerId, ConnectFlags flags) 668 { 669 this.dlg = dlg; 670 this.handlerId = handlerId; 671 this.flags = flags; 672 } 673 } 674 protected OnPostActivateDelegateWrapper[] onPostActivateListeners; 675 676 /** 677 * The ::post-activate signal is emitted just after the @action in the 678 * @action_group is activated 679 * 680 * This is intended for #GtkUIManager to proxy the signal and provide global 681 * notification just after any action is activated. 682 * 683 * Params: 684 * action = the action 685 * 686 * Since: 2.4 687 */ 688 gulong addOnPostActivate(void delegate(Action, ActionGroup) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 689 { 690 onPostActivateListeners ~= new OnPostActivateDelegateWrapper(dlg, 0, connectFlags); 691 onPostActivateListeners[onPostActivateListeners.length - 1].handlerId = Signals.connectData( 692 this, 693 "post-activate", 694 cast(GCallback)&callBackPostActivate, 695 cast(void*)onPostActivateListeners[onPostActivateListeners.length - 1], 696 cast(GClosureNotify)&callBackPostActivateDestroy, 697 connectFlags); 698 return onPostActivateListeners[onPostActivateListeners.length - 1].handlerId; 699 } 700 701 extern(C) static void callBackPostActivate(GtkActionGroup* actiongroupStruct, GtkAction* action,OnPostActivateDelegateWrapper wrapper) 702 { 703 wrapper.dlg(ObjectG.getDObject!(Action)(action), wrapper.outer); 704 } 705 706 extern(C) static void callBackPostActivateDestroy(OnPostActivateDelegateWrapper wrapper, GClosure* closure) 707 { 708 wrapper.outer.internalRemoveOnPostActivate(wrapper); 709 } 710 711 protected void internalRemoveOnPostActivate(OnPostActivateDelegateWrapper source) 712 { 713 foreach(index, wrapper; onPostActivateListeners) 714 { 715 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 716 { 717 onPostActivateListeners[index] = null; 718 onPostActivateListeners = std.algorithm.remove(onPostActivateListeners, index); 719 break; 720 } 721 } 722 } 723 724 725 protected class OnPreActivateDelegateWrapper 726 { 727 void delegate(Action, ActionGroup) dlg; 728 gulong handlerId; 729 ConnectFlags flags; 730 this(void delegate(Action, ActionGroup) dlg, gulong handlerId, ConnectFlags flags) 731 { 732 this.dlg = dlg; 733 this.handlerId = handlerId; 734 this.flags = flags; 735 } 736 } 737 protected OnPreActivateDelegateWrapper[] onPreActivateListeners; 738 739 /** 740 * The ::pre-activate signal is emitted just before the @action in the 741 * @action_group is activated 742 * 743 * This is intended for #GtkUIManager to proxy the signal and provide global 744 * notification just before any action is activated. 745 * 746 * Params: 747 * action = the action 748 * 749 * Since: 2.4 750 */ 751 gulong addOnPreActivate(void delegate(Action, ActionGroup) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 752 { 753 onPreActivateListeners ~= new OnPreActivateDelegateWrapper(dlg, 0, connectFlags); 754 onPreActivateListeners[onPreActivateListeners.length - 1].handlerId = Signals.connectData( 755 this, 756 "pre-activate", 757 cast(GCallback)&callBackPreActivate, 758 cast(void*)onPreActivateListeners[onPreActivateListeners.length - 1], 759 cast(GClosureNotify)&callBackPreActivateDestroy, 760 connectFlags); 761 return onPreActivateListeners[onPreActivateListeners.length - 1].handlerId; 762 } 763 764 extern(C) static void callBackPreActivate(GtkActionGroup* actiongroupStruct, GtkAction* action,OnPreActivateDelegateWrapper wrapper) 765 { 766 wrapper.dlg(ObjectG.getDObject!(Action)(action), wrapper.outer); 767 } 768 769 extern(C) static void callBackPreActivateDestroy(OnPreActivateDelegateWrapper wrapper, GClosure* closure) 770 { 771 wrapper.outer.internalRemoveOnPreActivate(wrapper); 772 } 773 774 protected void internalRemoveOnPreActivate(OnPreActivateDelegateWrapper source) 775 { 776 foreach(index, wrapper; onPreActivateListeners) 777 { 778 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 779 { 780 onPreActivateListeners[index] = null; 781 onPreActivateListeners = std.algorithm.remove(onPreActivateListeners, index); 782 break; 783 } 784 } 785 } 786 787 }