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.Paned; 26 27 private import gdk.Window; 28 private import glib.ConstructionException; 29 private import gobject.ObjectG; 30 private import gobject.Signals; 31 private import gtk.Container; 32 private import gtk.OrientableIF; 33 private import gtk.OrientableT; 34 private import gtk.Widget; 35 private import gtk.c.functions; 36 public import gtk.c.types; 37 public import gtkc.gtktypes; 38 private import std.algorithm; 39 40 41 /** 42 * #GtkPaned has two panes, arranged either 43 * horizontally or vertically. The division between 44 * the two panes is adjustable by the user by dragging 45 * a handle. 46 * 47 * Child widgets are 48 * added to the panes of the widget with gtk_paned_pack1() and 49 * gtk_paned_pack2(). The division between the two children is set by default 50 * from the size requests of the children, but it can be adjusted by the 51 * user. 52 * 53 * A paned widget draws a separator between the two child widgets and a 54 * small handle that the user can drag to adjust the division. It does not 55 * draw any relief around the children or around the separator. (The space 56 * in which the separator is called the gutter.) Often, it is useful to put 57 * each child inside a #GtkFrame with the shadow type set to %GTK_SHADOW_IN 58 * so that the gutter appears as a ridge. No separator is drawn if one of 59 * the children is missing. 60 * 61 * Each child has two options that can be set, @resize and @shrink. If 62 * @resize is true, then when the #GtkPaned is resized, that child will 63 * expand or shrink along with the paned widget. If @shrink is true, then 64 * that child can be made smaller than its requisition by the user. 65 * Setting @shrink to %FALSE allows the application to set a minimum size. 66 * If @resize is false for both children, then this is treated as if 67 * @resize is true for both children. 68 * 69 * The application can set the position of the slider as if it were set 70 * by the user, by calling gtk_paned_set_position(). 71 * 72 * # CSS nodes 73 * 74 * |[<!-- language="plain" --> 75 * paned 76 * ├── <child> 77 * ├── separator[.wide] 78 * ╰── <child> 79 * ]| 80 * 81 * GtkPaned has a main CSS node with name paned, and a subnode for 82 * the separator with name separator. The subnode gets a .wide style 83 * class when the paned is supposed to be wide. 84 * 85 * In horizontal orientation, the nodes of the children are always arranged 86 * from left to right. So :first-child will always select the leftmost child, 87 * regardless of text direction. 88 * 89 * ## Creating a paned widget with minimum sizes. 90 * 91 * |[<!-- language="C" --> 92 * GtkWidget *hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); 93 * GtkWidget *frame1 = gtk_frame_new (NULL); 94 * GtkWidget *frame2 = gtk_frame_new (NULL); 95 * gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN); 96 * gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN); 97 * 98 * gtk_widget_set_size_request (hpaned, 200, -1); 99 * 100 * gtk_paned_pack1 (GTK_PANED (hpaned), frame1, TRUE, FALSE); 101 * gtk_widget_set_size_request (frame1, 50, -1); 102 * 103 * gtk_paned_pack2 (GTK_PANED (hpaned), frame2, FALSE, FALSE); 104 * gtk_widget_set_size_request (frame2, 50, -1); 105 * ]| 106 */ 107 public class Paned : Container, OrientableIF 108 { 109 /** the main Gtk struct */ 110 protected GtkPaned* gtkPaned; 111 112 /** Get the main Gtk struct */ 113 public GtkPaned* getPanedStruct(bool transferOwnership = false) 114 { 115 if (transferOwnership) 116 ownedRef = false; 117 return gtkPaned; 118 } 119 120 /** the main Gtk struct as a void* */ 121 protected override void* getStruct() 122 { 123 return cast(void*)gtkPaned; 124 } 125 126 protected override void setStruct(GObject* obj) 127 { 128 gtkPaned = cast(GtkPaned*)obj; 129 super.setStruct(obj); 130 } 131 132 /** 133 * Sets our main struct and passes it to the parent class. 134 */ 135 public this (GtkPaned* gtkPaned, bool ownedRef = false) 136 { 137 this.gtkPaned = gtkPaned; 138 super(cast(GtkContainer*)gtkPaned, ownedRef); 139 } 140 141 // add the Orientable capabilities 142 mixin OrientableT!(GtkPaned); 143 144 /** */ 145 public void add(Widget child1, Widget child2) 146 { 147 add1(child1); 148 add2(child2); 149 } 150 151 /** 152 */ 153 154 /** */ 155 public static GType getType() 156 { 157 return gtk_paned_get_type(); 158 } 159 160 /** 161 * Creates a new #GtkPaned widget. 162 * 163 * Params: 164 * orientation = the paned’s orientation. 165 * 166 * Returns: a new #GtkPaned. 167 * 168 * Since: 3.0 169 * 170 * Throws: ConstructionException GTK+ fails to create the object. 171 */ 172 public this(GtkOrientation orientation) 173 { 174 auto p = gtk_paned_new(orientation); 175 176 if(p is null) 177 { 178 throw new ConstructionException("null returned by new"); 179 } 180 181 this(cast(GtkPaned*) p); 182 } 183 184 /** 185 * Adds a child to the top or left pane with default parameters. This is 186 * equivalent to 187 * `gtk_paned_pack1 (paned, child, FALSE, TRUE)`. 188 * 189 * Params: 190 * child = the child to add 191 */ 192 public void add1(Widget child) 193 { 194 gtk_paned_add1(gtkPaned, (child is null) ? null : child.getWidgetStruct()); 195 } 196 197 /** 198 * Adds a child to the bottom or right pane with default parameters. This 199 * is equivalent to 200 * `gtk_paned_pack2 (paned, child, TRUE, TRUE)`. 201 * 202 * Params: 203 * child = the child to add 204 */ 205 public void add2(Widget child) 206 { 207 gtk_paned_add2(gtkPaned, (child is null) ? null : child.getWidgetStruct()); 208 } 209 210 /** 211 * Obtains the first child of the paned widget. 212 * 213 * Returns: first child, or %NULL if it is not set. 214 * 215 * Since: 2.4 216 */ 217 public Widget getChild1() 218 { 219 auto p = gtk_paned_get_child1(gtkPaned); 220 221 if(p is null) 222 { 223 return null; 224 } 225 226 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 227 } 228 229 /** 230 * Obtains the second child of the paned widget. 231 * 232 * Returns: second child, or %NULL if it is not set. 233 * 234 * Since: 2.4 235 */ 236 public Widget getChild2() 237 { 238 auto p = gtk_paned_get_child2(gtkPaned); 239 240 if(p is null) 241 { 242 return null; 243 } 244 245 return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p); 246 } 247 248 /** 249 * Returns the #GdkWindow of the handle. This function is 250 * useful when handling button or motion events because it 251 * enables the callback to distinguish between the window 252 * of the paned, a child and the handle. 253 * 254 * Returns: the paned’s handle window. 255 * 256 * Since: 2.20 257 */ 258 public Window getHandleWindow() 259 { 260 auto p = gtk_paned_get_handle_window(gtkPaned); 261 262 if(p is null) 263 { 264 return null; 265 } 266 267 return ObjectG.getDObject!(Window)(cast(GdkWindow*) p); 268 } 269 270 /** 271 * Obtains the position of the divider between the two panes. 272 * 273 * Returns: position of the divider 274 */ 275 public int getPosition() 276 { 277 return gtk_paned_get_position(gtkPaned); 278 } 279 280 /** 281 * Gets the #GtkPaned:wide-handle property. 282 * 283 * Returns: %TRUE if the paned should have a wide handle 284 * 285 * Since: 3.16 286 */ 287 public bool getWideHandle() 288 { 289 return gtk_paned_get_wide_handle(gtkPaned) != 0; 290 } 291 292 /** 293 * Adds a child to the top or left pane. 294 * 295 * Params: 296 * child = the child to add 297 * resize = should this child expand when the paned widget is resized. 298 * shrink = can this child be made smaller than its requisition. 299 */ 300 public void pack1(Widget child, bool resize, bool shrink) 301 { 302 gtk_paned_pack1(gtkPaned, (child is null) ? null : child.getWidgetStruct(), resize, shrink); 303 } 304 305 /** 306 * Adds a child to the bottom or right pane. 307 * 308 * Params: 309 * child = the child to add 310 * resize = should this child expand when the paned widget is resized. 311 * shrink = can this child be made smaller than its requisition. 312 */ 313 public void pack2(Widget child, bool resize, bool shrink) 314 { 315 gtk_paned_pack2(gtkPaned, (child is null) ? null : child.getWidgetStruct(), resize, shrink); 316 } 317 318 /** 319 * Sets the position of the divider between the two panes. 320 * 321 * Params: 322 * position = pixel position of divider, a negative value means that the position 323 * is unset. 324 */ 325 public void setPosition(int position) 326 { 327 gtk_paned_set_position(gtkPaned, position); 328 } 329 330 /** 331 * Sets the #GtkPaned:wide-handle property. 332 * 333 * Params: 334 * wide = the new value for the #GtkPaned:wide-handle property 335 * 336 * Since: 3.16 337 */ 338 public void setWideHandle(bool wide) 339 { 340 gtk_paned_set_wide_handle(gtkPaned, wide); 341 } 342 343 protected class OnAcceptPositionDelegateWrapper 344 { 345 bool delegate(Paned) dlg; 346 gulong handlerId; 347 348 this(bool delegate(Paned) dlg) 349 { 350 this.dlg = dlg; 351 onAcceptPositionListeners ~= this; 352 } 353 354 void remove(OnAcceptPositionDelegateWrapper source) 355 { 356 foreach(index, wrapper; onAcceptPositionListeners) 357 { 358 if (wrapper.handlerId == source.handlerId) 359 { 360 onAcceptPositionListeners[index] = null; 361 onAcceptPositionListeners = std.algorithm.remove(onAcceptPositionListeners, index); 362 break; 363 } 364 } 365 } 366 } 367 OnAcceptPositionDelegateWrapper[] onAcceptPositionListeners; 368 369 /** 370 * The ::accept-position signal is a 371 * [keybinding signal][GtkBindingSignal] 372 * which gets emitted to accept the current position of the handle when 373 * moving it using key bindings. 374 * 375 * The default binding for this signal is Return or Space. 376 * 377 * Since: 2.0 378 */ 379 gulong addOnAcceptPosition(bool delegate(Paned) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 380 { 381 auto wrapper = new OnAcceptPositionDelegateWrapper(dlg); 382 wrapper.handlerId = Signals.connectData( 383 this, 384 "accept-position", 385 cast(GCallback)&callBackAcceptPosition, 386 cast(void*)wrapper, 387 cast(GClosureNotify)&callBackAcceptPositionDestroy, 388 connectFlags); 389 return wrapper.handlerId; 390 } 391 392 extern(C) static int callBackAcceptPosition(GtkPaned* panedStruct, OnAcceptPositionDelegateWrapper wrapper) 393 { 394 return wrapper.dlg(wrapper.outer); 395 } 396 397 extern(C) static void callBackAcceptPositionDestroy(OnAcceptPositionDelegateWrapper wrapper, GClosure* closure) 398 { 399 wrapper.remove(wrapper); 400 } 401 402 protected class OnCancelPositionDelegateWrapper 403 { 404 bool delegate(Paned) dlg; 405 gulong handlerId; 406 407 this(bool delegate(Paned) dlg) 408 { 409 this.dlg = dlg; 410 onCancelPositionListeners ~= this; 411 } 412 413 void remove(OnCancelPositionDelegateWrapper source) 414 { 415 foreach(index, wrapper; onCancelPositionListeners) 416 { 417 if (wrapper.handlerId == source.handlerId) 418 { 419 onCancelPositionListeners[index] = null; 420 onCancelPositionListeners = std.algorithm.remove(onCancelPositionListeners, index); 421 break; 422 } 423 } 424 } 425 } 426 OnCancelPositionDelegateWrapper[] onCancelPositionListeners; 427 428 /** 429 * The ::cancel-position signal is a 430 * [keybinding signal][GtkBindingSignal] 431 * which gets emitted to cancel moving the position of the handle using key 432 * bindings. The position of the handle will be reset to the value prior to 433 * moving it. 434 * 435 * The default binding for this signal is Escape. 436 * 437 * Since: 2.0 438 */ 439 gulong addOnCancelPosition(bool delegate(Paned) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 440 { 441 auto wrapper = new OnCancelPositionDelegateWrapper(dlg); 442 wrapper.handlerId = Signals.connectData( 443 this, 444 "cancel-position", 445 cast(GCallback)&callBackCancelPosition, 446 cast(void*)wrapper, 447 cast(GClosureNotify)&callBackCancelPositionDestroy, 448 connectFlags); 449 return wrapper.handlerId; 450 } 451 452 extern(C) static int callBackCancelPosition(GtkPaned* panedStruct, OnCancelPositionDelegateWrapper wrapper) 453 { 454 return wrapper.dlg(wrapper.outer); 455 } 456 457 extern(C) static void callBackCancelPositionDestroy(OnCancelPositionDelegateWrapper wrapper, GClosure* closure) 458 { 459 wrapper.remove(wrapper); 460 } 461 462 protected class OnCycleChildFocusDelegateWrapper 463 { 464 bool delegate(bool, Paned) dlg; 465 gulong handlerId; 466 467 this(bool delegate(bool, Paned) dlg) 468 { 469 this.dlg = dlg; 470 onCycleChildFocusListeners ~= this; 471 } 472 473 void remove(OnCycleChildFocusDelegateWrapper source) 474 { 475 foreach(index, wrapper; onCycleChildFocusListeners) 476 { 477 if (wrapper.handlerId == source.handlerId) 478 { 479 onCycleChildFocusListeners[index] = null; 480 onCycleChildFocusListeners = std.algorithm.remove(onCycleChildFocusListeners, index); 481 break; 482 } 483 } 484 } 485 } 486 OnCycleChildFocusDelegateWrapper[] onCycleChildFocusListeners; 487 488 /** 489 * The ::cycle-child-focus signal is a 490 * [keybinding signal][GtkBindingSignal] 491 * which gets emitted to cycle the focus between the children of the paned. 492 * 493 * The default binding is f6. 494 * 495 * Params: 496 * reversed = whether cycling backward or forward 497 * 498 * Since: 2.0 499 */ 500 gulong addOnCycleChildFocus(bool delegate(bool, Paned) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 501 { 502 auto wrapper = new OnCycleChildFocusDelegateWrapper(dlg); 503 wrapper.handlerId = Signals.connectData( 504 this, 505 "cycle-child-focus", 506 cast(GCallback)&callBackCycleChildFocus, 507 cast(void*)wrapper, 508 cast(GClosureNotify)&callBackCycleChildFocusDestroy, 509 connectFlags); 510 return wrapper.handlerId; 511 } 512 513 extern(C) static int callBackCycleChildFocus(GtkPaned* panedStruct, bool reversed, OnCycleChildFocusDelegateWrapper wrapper) 514 { 515 return wrapper.dlg(reversed, wrapper.outer); 516 } 517 518 extern(C) static void callBackCycleChildFocusDestroy(OnCycleChildFocusDelegateWrapper wrapper, GClosure* closure) 519 { 520 wrapper.remove(wrapper); 521 } 522 523 protected class OnCycleHandleFocusDelegateWrapper 524 { 525 bool delegate(bool, Paned) dlg; 526 gulong handlerId; 527 528 this(bool delegate(bool, Paned) dlg) 529 { 530 this.dlg = dlg; 531 onCycleHandleFocusListeners ~= this; 532 } 533 534 void remove(OnCycleHandleFocusDelegateWrapper source) 535 { 536 foreach(index, wrapper; onCycleHandleFocusListeners) 537 { 538 if (wrapper.handlerId == source.handlerId) 539 { 540 onCycleHandleFocusListeners[index] = null; 541 onCycleHandleFocusListeners = std.algorithm.remove(onCycleHandleFocusListeners, index); 542 break; 543 } 544 } 545 } 546 } 547 OnCycleHandleFocusDelegateWrapper[] onCycleHandleFocusListeners; 548 549 /** 550 * The ::cycle-handle-focus signal is a 551 * [keybinding signal][GtkBindingSignal] 552 * which gets emitted to cycle whether the paned should grab focus to allow 553 * the user to change position of the handle by using key bindings. 554 * 555 * The default binding for this signal is f8. 556 * 557 * Params: 558 * reversed = whether cycling backward or forward 559 * 560 * Since: 2.0 561 */ 562 gulong addOnCycleHandleFocus(bool delegate(bool, Paned) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 563 { 564 auto wrapper = new OnCycleHandleFocusDelegateWrapper(dlg); 565 wrapper.handlerId = Signals.connectData( 566 this, 567 "cycle-handle-focus", 568 cast(GCallback)&callBackCycleHandleFocus, 569 cast(void*)wrapper, 570 cast(GClosureNotify)&callBackCycleHandleFocusDestroy, 571 connectFlags); 572 return wrapper.handlerId; 573 } 574 575 extern(C) static int callBackCycleHandleFocus(GtkPaned* panedStruct, bool reversed, OnCycleHandleFocusDelegateWrapper wrapper) 576 { 577 return wrapper.dlg(reversed, wrapper.outer); 578 } 579 580 extern(C) static void callBackCycleHandleFocusDestroy(OnCycleHandleFocusDelegateWrapper wrapper, GClosure* closure) 581 { 582 wrapper.remove(wrapper); 583 } 584 585 protected class OnMoveHandleDelegateWrapper 586 { 587 bool delegate(GtkScrollType, Paned) dlg; 588 gulong handlerId; 589 590 this(bool delegate(GtkScrollType, Paned) dlg) 591 { 592 this.dlg = dlg; 593 onMoveHandleListeners ~= this; 594 } 595 596 void remove(OnMoveHandleDelegateWrapper source) 597 { 598 foreach(index, wrapper; onMoveHandleListeners) 599 { 600 if (wrapper.handlerId == source.handlerId) 601 { 602 onMoveHandleListeners[index] = null; 603 onMoveHandleListeners = std.algorithm.remove(onMoveHandleListeners, index); 604 break; 605 } 606 } 607 } 608 } 609 OnMoveHandleDelegateWrapper[] onMoveHandleListeners; 610 611 /** 612 * The ::move-handle signal is a 613 * [keybinding signal][GtkBindingSignal] 614 * which gets emitted to move the handle when the user is using key bindings 615 * to move it. 616 * 617 * Params: 618 * scrollType = a #GtkScrollType 619 * 620 * Since: 2.0 621 */ 622 gulong addOnMoveHandle(bool delegate(GtkScrollType, Paned) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 623 { 624 auto wrapper = new OnMoveHandleDelegateWrapper(dlg); 625 wrapper.handlerId = Signals.connectData( 626 this, 627 "move-handle", 628 cast(GCallback)&callBackMoveHandle, 629 cast(void*)wrapper, 630 cast(GClosureNotify)&callBackMoveHandleDestroy, 631 connectFlags); 632 return wrapper.handlerId; 633 } 634 635 extern(C) static int callBackMoveHandle(GtkPaned* panedStruct, GtkScrollType scrollType, OnMoveHandleDelegateWrapper wrapper) 636 { 637 return wrapper.dlg(scrollType, wrapper.outer); 638 } 639 640 extern(C) static void callBackMoveHandleDestroy(OnMoveHandleDelegateWrapper wrapper, GClosure* closure) 641 { 642 wrapper.remove(wrapper); 643 } 644 645 protected class OnToggleHandleFocusDelegateWrapper 646 { 647 bool delegate(Paned) dlg; 648 gulong handlerId; 649 650 this(bool delegate(Paned) dlg) 651 { 652 this.dlg = dlg; 653 onToggleHandleFocusListeners ~= this; 654 } 655 656 void remove(OnToggleHandleFocusDelegateWrapper source) 657 { 658 foreach(index, wrapper; onToggleHandleFocusListeners) 659 { 660 if (wrapper.handlerId == source.handlerId) 661 { 662 onToggleHandleFocusListeners[index] = null; 663 onToggleHandleFocusListeners = std.algorithm.remove(onToggleHandleFocusListeners, index); 664 break; 665 } 666 } 667 } 668 } 669 OnToggleHandleFocusDelegateWrapper[] onToggleHandleFocusListeners; 670 671 /** 672 * The ::toggle-handle-focus is a 673 * [keybinding signal][GtkBindingSignal] 674 * which gets emitted to accept the current position of the handle and then 675 * move focus to the next widget in the focus chain. 676 * 677 * The default binding is Tab. 678 * 679 * Since: 2.0 680 */ 681 gulong addOnToggleHandleFocus(bool delegate(Paned) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 682 { 683 auto wrapper = new OnToggleHandleFocusDelegateWrapper(dlg); 684 wrapper.handlerId = Signals.connectData( 685 this, 686 "toggle-handle-focus", 687 cast(GCallback)&callBackToggleHandleFocus, 688 cast(void*)wrapper, 689 cast(GClosureNotify)&callBackToggleHandleFocusDestroy, 690 connectFlags); 691 return wrapper.handlerId; 692 } 693 694 extern(C) static int callBackToggleHandleFocus(GtkPaned* panedStruct, OnToggleHandleFocusDelegateWrapper wrapper) 695 { 696 return wrapper.dlg(wrapper.outer); 697 } 698 699 extern(C) static void callBackToggleHandleFocusDestroy(OnToggleHandleFocusDelegateWrapper wrapper, GClosure* closure) 700 { 701 wrapper.remove(wrapper); 702 } 703 }