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