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.MenuItem; 26 27 private import glib.ConstructionException; 28 private import glib.Str; 29 private import gobject.ObjectG; 30 private import gobject.Signals; 31 private import gtk.AccelGroup; 32 private import gtk.ActionableIF; 33 private import gtk.ActionableT; 34 private import gtk.ActivatableIF; 35 private import gtk.ActivatableT; 36 private import gtk.Bin; 37 private import gtk.Menu; 38 private import gtk.Widget; 39 public import gtkc.gdktypes; 40 private import gtkc.gtk; 41 public import gtkc.gtktypes; 42 private import std.algorithm; 43 44 45 /** 46 * The #GtkMenuItem widget and the derived widgets are the only valid 47 * children for menus. Their function is to correctly handle highlighting, 48 * alignment, events and submenus. 49 * 50 * As a GtkMenuItem derives from #GtkBin it can hold any valid child widget, 51 * although only a few are really useful. 52 * 53 * By default, a GtkMenuItem sets a #GtkAccelLabel as its child. 54 * GtkMenuItem has direct functions to set the label and its mnemonic. 55 * For more advanced label settings, you can fetch the child widget from the GtkBin. 56 * 57 * An example for setting markup and accelerator on a MenuItem: 58 * |[<!-- language="C" --> 59 * GtkWidget *child = gtk_bin_get_child (GTK_BIN (menu_item)); 60 * gtk_label_set_markup (GTK_LABEL (child), "<i>new label</i> with <b>markup</b>"); 61 * gtk_accel_label_set_accel (GTK_ACCEL_LABEL (child), GDK_KEY_1, 0); 62 * ]| 63 * 64 * # GtkMenuItem as GtkBuildable 65 * 66 * The GtkMenuItem implementation of the #GtkBuildable interface supports 67 * adding a submenu by specifying “submenu” as the “type” attribute of 68 * a <child> element. 69 * 70 * An example of UI definition fragment with submenus: 71 * |[ 72 * <object class="GtkMenuItem"> 73 * <child type="submenu"> 74 * <object class="GtkMenu"/> 75 * </child> 76 * </object> 77 * ]| 78 * 79 * # CSS nodes 80 * 81 * |[<!-- language="plain" --> 82 * menuitem 83 * ├── <child> 84 * ╰── [arrow.right] 85 * ]| 86 * 87 * GtkMenuItem has a single CSS node with name menuitem. If the menuitem 88 * has a submenu, it gets another CSS node with name arrow, which has 89 * the .left or .right style class. 90 */ 91 public class MenuItem : Bin, ActionableIF, ActivatableIF 92 { 93 /** the main Gtk struct */ 94 protected GtkMenuItem* gtkMenuItem; 95 96 /** Get the main Gtk struct */ 97 public GtkMenuItem* getMenuItemStruct() 98 { 99 return gtkMenuItem; 100 } 101 102 /** the main Gtk struct as a void* */ 103 protected override void* getStruct() 104 { 105 return cast(void*)gtkMenuItem; 106 } 107 108 protected override void setStruct(GObject* obj) 109 { 110 gtkMenuItem = cast(GtkMenuItem*)obj; 111 super.setStruct(obj); 112 } 113 114 /** 115 * Sets our main struct and passes it to the parent class. 116 */ 117 public this (GtkMenuItem* gtkMenuItem, bool ownedRef = false) 118 { 119 this.gtkMenuItem = gtkMenuItem; 120 super(cast(GtkBin*)gtkMenuItem, ownedRef); 121 } 122 123 // add the Actionable capabilities 124 mixin ActionableT!(GtkMenuItem); 125 126 // add the Activatable capabilities 127 mixin ActivatableT!(GtkMenuItem); 128 129 /** store the action code passed in by the applcation */ 130 private string actionLabel; 131 132 /** Gets the application set action code */ 133 public string getActionName() 134 { 135 if ( actionLabel is null ) 136 { 137 actionLabel = ""; 138 } 139 return actionLabel; 140 } 141 142 /** 143 * Creates a new menu item with a label and a listener and a action. 144 * used for backward compatibily with DUI. 145 */ 146 this(string label, void delegate(MenuItem)dlg, string action) 147 { 148 this(label); 149 this.actionLabel = action; 150 addOnActivate(dlg); 151 } 152 153 /** 154 * Creates a new Item associated with a "activate" delegate and with a action code 155 * and optionally accelGroup 156 */ 157 public this(void delegate(MenuItem) dlg, string label, string action, 158 bool mnemonic=true, 159 AccelGroup accelGroup=null, 160 char accelKey='\0', 161 GdkModifierType modifierType=GdkModifierType.CONTROL_MASK, 162 GtkAccelFlags accelFlags=GtkAccelFlags.VISIBLE 163 ) 164 { 165 this(label, mnemonic); 166 this.actionLabel = action; 167 addOnActivate(dlg); 168 if ( accelGroup !is null && accelKey != '\0' ) 169 { 170 addAccelerator("activate",accelGroup,accelKey,modifierType,accelFlags); 171 } 172 } 173 174 /** 175 * Creates a new Item associated with a "activate" delegate 176 */ 177 public this(void delegate(MenuItem) dlg, string label, bool mnemonic=true) 178 { 179 this(label, mnemonic); 180 addOnActivate(dlg); 181 } 182 183 /** 184 * Creates a new GtkMenuItem whose child is a GtkLabel. 185 * Params: 186 * label = the text for the label 187 * mnemonic = if true the label 188 * will be created using gtk_label_new_with_mnemonic(), so underscores 189 * in label indicate the mnemonic for the menu item. 190 * Throws: ConstructionException GTK+ fails to create the object. 191 */ 192 public this (string label, bool mnemonic=true) 193 { 194 GtkMenuItem* p; 195 196 if ( mnemonic ) 197 { 198 // GtkWidget* gtk_menu_item_new_with_mnemonic (const gchar *label); 199 p = cast(GtkMenuItem*)gtk_menu_item_new_with_mnemonic(Str.toStringz(label)); 200 } 201 else 202 { 203 // GtkWidget* gtk_menu_item_new_with_label (const gchar *label); 204 p = cast(GtkMenuItem*)gtk_menu_item_new_with_label(Str.toStringz(label)); 205 } 206 207 if(p is null) 208 { 209 throw new ConstructionException("null returned by gtk_menu_item_new_with_"); 210 } 211 212 this(p); 213 214 setName(label); 215 } 216 217 /** 218 */ 219 220 /** */ 221 public static GType getType() 222 { 223 return gtk_menu_item_get_type(); 224 } 225 226 /** 227 * Creates a new #GtkMenuItem. 228 * 229 * Return: the newly created #GtkMenuItem 230 * 231 * Throws: ConstructionException GTK+ fails to create the object. 232 */ 233 public this() 234 { 235 auto p = gtk_menu_item_new(); 236 237 if(p is null) 238 { 239 throw new ConstructionException("null returned by new"); 240 } 241 242 this(cast(GtkMenuItem*) p); 243 } 244 245 /** 246 * Emits the #GtkMenuItem::activate signal on the given item 247 */ 248 public void itemActivate() 249 { 250 gtk_menu_item_activate(gtkMenuItem); 251 } 252 253 /** 254 * Emits the #GtkMenuItem::deselect signal on the given item. 255 */ 256 public void deselect() 257 { 258 gtk_menu_item_deselect(gtkMenuItem); 259 } 260 261 /** 262 * Retrieve the accelerator path that was previously set on @menu_item. 263 * 264 * See gtk_menu_item_set_accel_path() for details. 265 * 266 * Return: the accelerator path corresponding to 267 * this menu item’s functionality, or %NULL if not set 268 * 269 * Since: 2.14 270 */ 271 public string getAccelPath() 272 { 273 return Str.toString(gtk_menu_item_get_accel_path(gtkMenuItem)); 274 } 275 276 /** 277 * Sets @text on the @menu_item label 278 * 279 * Return: The text in the @menu_item label. This is the internal 280 * string used by the label, and must not be modified. 281 * 282 * Since: 2.16 283 */ 284 public string getLabel() 285 { 286 return Str.toString(gtk_menu_item_get_label(gtkMenuItem)); 287 } 288 289 /** 290 * Returns whether the @menu_item reserves space for 291 * the submenu indicator, regardless if it has a submenu 292 * or not. 293 * 294 * Return: %TRUE if @menu_item always reserves space for the 295 * submenu indicator 296 * 297 * Since: 3.0 298 */ 299 public bool getReserveIndicator() 300 { 301 return gtk_menu_item_get_reserve_indicator(gtkMenuItem) != 0; 302 } 303 304 /** 305 * Gets whether the menu item appears justified at the right 306 * side of the menu bar. 307 * 308 * Deprecated: See gtk_menu_item_set_right_justified() 309 * 310 * Return: %TRUE if the menu item will appear at the 311 * far right if added to a menu bar. 312 */ 313 public bool getRightJustified() 314 { 315 return gtk_menu_item_get_right_justified(gtkMenuItem) != 0; 316 } 317 318 /** 319 * Gets the submenu underneath this menu item, if any. 320 * See gtk_menu_item_set_submenu(). 321 * 322 * Return: submenu for this menu item, or %NULL if none 323 */ 324 public Widget getSubmenu() 325 { 326 auto p = gtk_menu_item_get_submenu(gtkMenuItem); 327 328 if(p is null) 329 { 330 return null; 331 } 332 333 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 334 } 335 336 /** 337 * Checks if an underline in the text indicates the next character 338 * should be used for the mnemonic accelerator key. 339 * 340 * Return: %TRUE if an embedded underline in the label 341 * indicates the mnemonic accelerator key. 342 * 343 * Since: 2.16 344 */ 345 public bool getUseUnderline() 346 { 347 return gtk_menu_item_get_use_underline(gtkMenuItem) != 0; 348 } 349 350 /** 351 * Emits the #GtkMenuItem::select signal on the given item. 352 */ 353 public void select() 354 { 355 gtk_menu_item_select(gtkMenuItem); 356 } 357 358 /** 359 * Set the accelerator path on @menu_item, through which runtime 360 * changes of the menu item’s accelerator caused by the user can be 361 * identified and saved to persistent storage (see gtk_accel_map_save() 362 * on this). To set up a default accelerator for this menu item, call 363 * gtk_accel_map_add_entry() with the same @accel_path. See also 364 * gtk_accel_map_add_entry() on the specifics of accelerator paths, 365 * and gtk_menu_set_accel_path() for a more convenient variant of 366 * this function. 367 * 368 * This function is basically a convenience wrapper that handles 369 * calling gtk_widget_set_accel_path() with the appropriate accelerator 370 * group for the menu item. 371 * 372 * Note that you do need to set an accelerator on the parent menu with 373 * gtk_menu_set_accel_group() for this to work. 374 * 375 * Note that @accel_path string will be stored in a #GQuark. 376 * Therefore, if you pass a static string, you can save some memory 377 * by interning it first with g_intern_static_string(). 378 * 379 * Params: 380 * accelPath = accelerator path, corresponding to this menu 381 * item’s functionality, or %NULL to unset the current path. 382 */ 383 public void setAccelPath(string accelPath) 384 { 385 gtk_menu_item_set_accel_path(gtkMenuItem, Str.toStringz(accelPath)); 386 } 387 388 /** 389 * Sets @text on the @menu_item label 390 * 391 * Params: 392 * label = the text you want to set 393 * 394 * Since: 2.16 395 */ 396 public void setLabel(string label) 397 { 398 gtk_menu_item_set_label(gtkMenuItem, Str.toStringz(label)); 399 } 400 401 /** 402 * Sets whether the @menu_item should reserve space for 403 * the submenu indicator, regardless if it actually has 404 * a submenu or not. 405 * 406 * There should be little need for applications to call 407 * this functions. 408 * 409 * Params: 410 * reserve = the new value 411 * 412 * Since: 3.0 413 */ 414 public void setReserveIndicator(bool reserve) 415 { 416 gtk_menu_item_set_reserve_indicator(gtkMenuItem, reserve); 417 } 418 419 /** 420 * Sets whether the menu item appears justified at the right 421 * side of a menu bar. This was traditionally done for “Help” 422 * menu items, but is now considered a bad idea. (If the widget 423 * layout is reversed for a right-to-left language like Hebrew 424 * or Arabic, right-justified-menu-items appear at the left.) 425 * 426 * Deprecated: If you insist on using it, use 427 * gtk_widget_set_hexpand() and gtk_widget_set_halign(). 428 * 429 * Params: 430 * rightJustified = if %TRUE the menu item will appear at the 431 * far right if added to a menu bar 432 */ 433 public void setRightJustified(bool rightJustified) 434 { 435 gtk_menu_item_set_right_justified(gtkMenuItem, rightJustified); 436 } 437 438 /** 439 * Sets or replaces the menu item’s submenu, or removes it when a %NULL 440 * submenu is passed. 441 * 442 * Params: 443 * submenu = the submenu, or %NULL 444 */ 445 public void setSubmenu(Menu submenu) 446 { 447 gtk_menu_item_set_submenu(gtkMenuItem, (submenu is null) ? null : cast(GtkWidget*)submenu.getMenuStruct()); 448 } 449 450 /** 451 * If true, an underline in the text indicates the next character 452 * should be used for the mnemonic accelerator key. 453 * 454 * Params: 455 * setting = %TRUE if underlines in the text indicate mnemonics 456 * 457 * Since: 2.16 458 */ 459 public void setUseUnderline(bool setting) 460 { 461 gtk_menu_item_set_use_underline(gtkMenuItem, setting); 462 } 463 464 /** 465 * Emits the #GtkMenuItem::toggle-size-allocate signal on the given item. 466 * 467 * Params: 468 * allocation = the allocation to use as signal data. 469 */ 470 public void toggleSizeAllocate(int allocation) 471 { 472 gtk_menu_item_toggle_size_allocate(gtkMenuItem, allocation); 473 } 474 475 /** 476 * Emits the #GtkMenuItem::toggle-size-request signal on the given item. 477 * 478 * Params: 479 * requisition = the requisition to use as signal data. 480 */ 481 public void toggleSizeRequest(ref int requisition) 482 { 483 gtk_menu_item_toggle_size_request(gtkMenuItem, &requisition); 484 } 485 486 protected class OnActivateDelegateWrapper 487 { 488 void delegate(MenuItem) dlg; 489 gulong handlerId; 490 ConnectFlags flags; 491 this(void delegate(MenuItem) dlg, gulong handlerId, ConnectFlags flags) 492 { 493 this.dlg = dlg; 494 this.handlerId = handlerId; 495 this.flags = flags; 496 } 497 } 498 protected OnActivateDelegateWrapper[] onActivateListeners; 499 500 /** 501 * Emitted when the item is activated. 502 */ 503 gulong addOnActivate(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 504 { 505 onActivateListeners ~= new OnActivateDelegateWrapper(dlg, 0, connectFlags); 506 onActivateListeners[onActivateListeners.length - 1].handlerId = Signals.connectData( 507 this, 508 "activate", 509 cast(GCallback)&callBackActivate, 510 cast(void*)onActivateListeners[onActivateListeners.length - 1], 511 cast(GClosureNotify)&callBackActivateDestroy, 512 connectFlags); 513 return onActivateListeners[onActivateListeners.length - 1].handlerId; 514 } 515 516 extern(C) static void callBackActivate(GtkMenuItem* menuitemStruct,OnActivateDelegateWrapper wrapper) 517 { 518 wrapper.dlg(wrapper.outer); 519 } 520 521 extern(C) static void callBackActivateDestroy(OnActivateDelegateWrapper wrapper, GClosure* closure) 522 { 523 wrapper.outer.internalRemoveOnActivate(wrapper); 524 } 525 526 protected void internalRemoveOnActivate(OnActivateDelegateWrapper source) 527 { 528 foreach(index, wrapper; onActivateListeners) 529 { 530 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 531 { 532 onActivateListeners[index] = null; 533 onActivateListeners = std.algorithm.remove(onActivateListeners, index); 534 break; 535 } 536 } 537 } 538 539 540 protected class OnActivateItemDelegateWrapper 541 { 542 void delegate(MenuItem) dlg; 543 gulong handlerId; 544 ConnectFlags flags; 545 this(void delegate(MenuItem) dlg, gulong handlerId, ConnectFlags flags) 546 { 547 this.dlg = dlg; 548 this.handlerId = handlerId; 549 this.flags = flags; 550 } 551 } 552 protected OnActivateItemDelegateWrapper[] onActivateItemListeners; 553 554 /** 555 * Emitted when the item is activated, but also if the menu item has a 556 * submenu. For normal applications, the relevant signal is 557 * #GtkMenuItem::activate. 558 */ 559 gulong addOnActivateItem(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 560 { 561 onActivateItemListeners ~= new OnActivateItemDelegateWrapper(dlg, 0, connectFlags); 562 onActivateItemListeners[onActivateItemListeners.length - 1].handlerId = Signals.connectData( 563 this, 564 "activate-item", 565 cast(GCallback)&callBackActivateItem, 566 cast(void*)onActivateItemListeners[onActivateItemListeners.length - 1], 567 cast(GClosureNotify)&callBackActivateItemDestroy, 568 connectFlags); 569 return onActivateItemListeners[onActivateItemListeners.length - 1].handlerId; 570 } 571 572 extern(C) static void callBackActivateItem(GtkMenuItem* menuitemStruct,OnActivateItemDelegateWrapper wrapper) 573 { 574 wrapper.dlg(wrapper.outer); 575 } 576 577 extern(C) static void callBackActivateItemDestroy(OnActivateItemDelegateWrapper wrapper, GClosure* closure) 578 { 579 wrapper.outer.internalRemoveOnActivateItem(wrapper); 580 } 581 582 protected void internalRemoveOnActivateItem(OnActivateItemDelegateWrapper source) 583 { 584 foreach(index, wrapper; onActivateItemListeners) 585 { 586 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 587 { 588 onActivateItemListeners[index] = null; 589 onActivateItemListeners = std.algorithm.remove(onActivateItemListeners, index); 590 break; 591 } 592 } 593 } 594 595 596 protected class OnDeselectDelegateWrapper 597 { 598 void delegate(MenuItem) dlg; 599 gulong handlerId; 600 ConnectFlags flags; 601 this(void delegate(MenuItem) dlg, gulong handlerId, ConnectFlags flags) 602 { 603 this.dlg = dlg; 604 this.handlerId = handlerId; 605 this.flags = flags; 606 } 607 } 608 protected OnDeselectDelegateWrapper[] onDeselectListeners; 609 610 /** */ 611 gulong addOnDeselect(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 612 { 613 onDeselectListeners ~= new OnDeselectDelegateWrapper(dlg, 0, connectFlags); 614 onDeselectListeners[onDeselectListeners.length - 1].handlerId = Signals.connectData( 615 this, 616 "deselect", 617 cast(GCallback)&callBackDeselect, 618 cast(void*)onDeselectListeners[onDeselectListeners.length - 1], 619 cast(GClosureNotify)&callBackDeselectDestroy, 620 connectFlags); 621 return onDeselectListeners[onDeselectListeners.length - 1].handlerId; 622 } 623 624 extern(C) static void callBackDeselect(GtkMenuItem* menuitemStruct,OnDeselectDelegateWrapper wrapper) 625 { 626 wrapper.dlg(wrapper.outer); 627 } 628 629 extern(C) static void callBackDeselectDestroy(OnDeselectDelegateWrapper wrapper, GClosure* closure) 630 { 631 wrapper.outer.internalRemoveOnDeselect(wrapper); 632 } 633 634 protected void internalRemoveOnDeselect(OnDeselectDelegateWrapper source) 635 { 636 foreach(index, wrapper; onDeselectListeners) 637 { 638 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 639 { 640 onDeselectListeners[index] = null; 641 onDeselectListeners = std.algorithm.remove(onDeselectListeners, index); 642 break; 643 } 644 } 645 } 646 647 648 protected class OnSelectDelegateWrapper 649 { 650 void delegate(MenuItem) dlg; 651 gulong handlerId; 652 ConnectFlags flags; 653 this(void delegate(MenuItem) dlg, gulong handlerId, ConnectFlags flags) 654 { 655 this.dlg = dlg; 656 this.handlerId = handlerId; 657 this.flags = flags; 658 } 659 } 660 protected OnSelectDelegateWrapper[] onSelectListeners; 661 662 /** */ 663 gulong addOnSelect(void delegate(MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 664 { 665 onSelectListeners ~= new OnSelectDelegateWrapper(dlg, 0, connectFlags); 666 onSelectListeners[onSelectListeners.length - 1].handlerId = Signals.connectData( 667 this, 668 "select", 669 cast(GCallback)&callBackSelect, 670 cast(void*)onSelectListeners[onSelectListeners.length - 1], 671 cast(GClosureNotify)&callBackSelectDestroy, 672 connectFlags); 673 return onSelectListeners[onSelectListeners.length - 1].handlerId; 674 } 675 676 extern(C) static void callBackSelect(GtkMenuItem* menuitemStruct,OnSelectDelegateWrapper wrapper) 677 { 678 wrapper.dlg(wrapper.outer); 679 } 680 681 extern(C) static void callBackSelectDestroy(OnSelectDelegateWrapper wrapper, GClosure* closure) 682 { 683 wrapper.outer.internalRemoveOnSelect(wrapper); 684 } 685 686 protected void internalRemoveOnSelect(OnSelectDelegateWrapper source) 687 { 688 foreach(index, wrapper; onSelectListeners) 689 { 690 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 691 { 692 onSelectListeners[index] = null; 693 onSelectListeners = std.algorithm.remove(onSelectListeners, index); 694 break; 695 } 696 } 697 } 698 699 700 protected class OnToggleSizeAllocateDelegateWrapper 701 { 702 void delegate(int, MenuItem) dlg; 703 gulong handlerId; 704 ConnectFlags flags; 705 this(void delegate(int, MenuItem) dlg, gulong handlerId, ConnectFlags flags) 706 { 707 this.dlg = dlg; 708 this.handlerId = handlerId; 709 this.flags = flags; 710 } 711 } 712 protected OnToggleSizeAllocateDelegateWrapper[] onToggleSizeAllocateListeners; 713 714 /** */ 715 gulong addOnToggleSizeAllocate(void delegate(int, MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 716 { 717 onToggleSizeAllocateListeners ~= new OnToggleSizeAllocateDelegateWrapper(dlg, 0, connectFlags); 718 onToggleSizeAllocateListeners[onToggleSizeAllocateListeners.length - 1].handlerId = Signals.connectData( 719 this, 720 "toggle-size-allocate", 721 cast(GCallback)&callBackToggleSizeAllocate, 722 cast(void*)onToggleSizeAllocateListeners[onToggleSizeAllocateListeners.length - 1], 723 cast(GClosureNotify)&callBackToggleSizeAllocateDestroy, 724 connectFlags); 725 return onToggleSizeAllocateListeners[onToggleSizeAllocateListeners.length - 1].handlerId; 726 } 727 728 extern(C) static void callBackToggleSizeAllocate(GtkMenuItem* menuitemStruct, int object,OnToggleSizeAllocateDelegateWrapper wrapper) 729 { 730 wrapper.dlg(object, wrapper.outer); 731 } 732 733 extern(C) static void callBackToggleSizeAllocateDestroy(OnToggleSizeAllocateDelegateWrapper wrapper, GClosure* closure) 734 { 735 wrapper.outer.internalRemoveOnToggleSizeAllocate(wrapper); 736 } 737 738 protected void internalRemoveOnToggleSizeAllocate(OnToggleSizeAllocateDelegateWrapper source) 739 { 740 foreach(index, wrapper; onToggleSizeAllocateListeners) 741 { 742 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 743 { 744 onToggleSizeAllocateListeners[index] = null; 745 onToggleSizeAllocateListeners = std.algorithm.remove(onToggleSizeAllocateListeners, index); 746 break; 747 } 748 } 749 } 750 751 752 protected class OnToggleSizeRequestDelegateWrapper 753 { 754 void delegate(void*, MenuItem) dlg; 755 gulong handlerId; 756 ConnectFlags flags; 757 this(void delegate(void*, MenuItem) dlg, gulong handlerId, ConnectFlags flags) 758 { 759 this.dlg = dlg; 760 this.handlerId = handlerId; 761 this.flags = flags; 762 } 763 } 764 protected OnToggleSizeRequestDelegateWrapper[] onToggleSizeRequestListeners; 765 766 /** */ 767 gulong addOnToggleSizeRequest(void delegate(void*, MenuItem) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 768 { 769 onToggleSizeRequestListeners ~= new OnToggleSizeRequestDelegateWrapper(dlg, 0, connectFlags); 770 onToggleSizeRequestListeners[onToggleSizeRequestListeners.length - 1].handlerId = Signals.connectData( 771 this, 772 "toggle-size-request", 773 cast(GCallback)&callBackToggleSizeRequest, 774 cast(void*)onToggleSizeRequestListeners[onToggleSizeRequestListeners.length - 1], 775 cast(GClosureNotify)&callBackToggleSizeRequestDestroy, 776 connectFlags); 777 return onToggleSizeRequestListeners[onToggleSizeRequestListeners.length - 1].handlerId; 778 } 779 780 extern(C) static void callBackToggleSizeRequest(GtkMenuItem* menuitemStruct, void* object,OnToggleSizeRequestDelegateWrapper wrapper) 781 { 782 wrapper.dlg(object, wrapper.outer); 783 } 784 785 extern(C) static void callBackToggleSizeRequestDestroy(OnToggleSizeRequestDelegateWrapper wrapper, GClosure* closure) 786 { 787 wrapper.outer.internalRemoveOnToggleSizeRequest(wrapper); 788 } 789 790 protected void internalRemoveOnToggleSizeRequest(OnToggleSizeRequestDelegateWrapper source) 791 { 792 foreach(index, wrapper; onToggleSizeRequestListeners) 793 { 794 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 795 { 796 onToggleSizeRequestListeners[index] = null; 797 onToggleSizeRequestListeners = std.algorithm.remove(onToggleSizeRequestListeners, index); 798 break; 799 } 800 } 801 } 802 803 }