It would be useful to have an Arbitrary Layout Widget in Gtk+ for creating user-rearrangable widgets. This would make it possible to drag-and-drop rearrange the layout at runtime and store it in a configuration file for later recreation. The exact nature of this needs to be discussed.
JohnMoser suggests a GtkPaned derivative called GtkPanedArbitraryArea where both vertical and horizontal panes can exist in one widget. These panes would then be said to "span" eachother vertically or horizontally; most simply put, if a pane "spans" another pane, its border ends on and is bound to the matching border for that pane. Using a modifier key, these bindings can be broken, and spanning can be changed.
Thunderbird interfaces. A: Mail folders B: Messages C: Message body ===================== TITLE BAR ===================== Menus --------------------- |A |B | |_________________ | |C |__|_________________ |Status bar Fig. 0-0: A basic layout. C spans B horizontally; A spans B and C vertically. we know we can resize A, B, or C by dragging the separators.
JohnMoser notes that "spanning" is really much more complex. A group of adjacent panes in a horizontal or vertical line can be grouped so that they span multiple panes around them; this would be constituted by the panes spanning eachother in a related manner. As a simple example, three panes arranged horrizontally with their upper and lower borders matching would be a group, and could span across the panes above and below them.
===================== TITLE BAR ===================== Menus --------------------- |A |B |__|_________________ |C |____________________ |Status bar Fig. 0-1: A different layout; C now Spans A and B horizontally. A only Spans B vertically. A and B are a group; they both together span C. ===================== TITLE BAR ===================== Menus --------------------- |C | |____________________ |B________________|A_ |Status bar Fig. 0-2: An even more different layout. C is placed at the top and spans B and A; A only spans next to B, and is to the right. C has also been enlarged. B and A are a group spanning C horizontally.
JohnMoser describes a modifier-keyed method for rearranging objects inside an arbitrary layout widget. For example, right-click dragging the borders could be used. The below diagrams show this; note that Fig. 0-7 through Fig. 0-9 show that a small area in the lower-right of a pane can be right-clicked to drag a whole widget around.
=============================================== TITLE BAR =============================================== Menus ----------------------------------------------- |A |B | |____________________________________ | |C | | | | |_________|____________________________________ |Status bar Fig. 0-3: Initial layout. =============================================== TITLE BAR =============================================== Menus ----------------------------------------------- |A |B | |_______________________________________ | |C | | | |<-- Left-click, drag left |______|_______________________________________ |Status bar Fig. 0-4: Initial layout, we just dragged the pane left. =============================================== TITLE BAR =============================================== Menus ----------------------------------------------- |A |B |______|_______________________________________ | |C | | | |<-- Right-click, drag left within threshold |______|_______________________________________ |Status bar Fig. 0-5: Right-click and drag a little, it "previews" by resizing Pane A up and leaving the left area blank. =============================================== TITLE BAR =============================================== Menus ----------------------------------------------- |A |B |______|_______________________________________ |C | |<-- Right-click, drag left |______________________________________________ |Status bar Fig. 0-6: Right-click and drag more, Pane C snaps left by 1 widget. =============================================== TITLE BAR =============================================== Menus ----------------------------------------------- |A |B |_____X|_______________________________________ |C ^ | |-- Right-click at X and drag | |______________________________________________ |Status bar Fig. 0-7: Right-click and drag here. . . =============================================== TITLE BAR =============================================== Menus ----------------------------------------------- |B |______________________________________________ |A |C | | | | We're still holding onto X. . . |_____X|_______________________________________ |Status bar Fig. 0-8: Down. . . . =============================================== TITLE BAR =============================================== Menus ----------------------------------------------- |B |______________________________________________ |C |A | | | | |_______________________________________|______ |Status bar Fig. 0-9: And right!
JohnMoser illustrates a complex layout as well. In this layout, A and D are a group A-D; B and C are a group B-C; E and F are a group E-F; A-D and B-C are a group AD-BC. A-D spans B-C vertically; B-C spans A-D vertically; E-F spans AD-BC horizontally; AD-BC spans E-F horizontally. By forcing (with a modifier) the separator between A and D to properly bind to the separator between B and C, groups A-B and D-C can be formed; with the same modifier, A-D or B-C could force their borders to decouple from the compliment and create the freeform design shown in Fig. 0-10.
=============================================== TITLE BAR =============================================== Menus ----------------------------------------------- |A |B | |____________________________________ |_________|C |D | | | |_________|____________________________________ |E |F |______|_______________________________________ |Status bar Fig. 0-10: A pain.
JohnMoser shows a very complex design which would require much work to create in a reusable widget. This design also does not address simple two-pane layouts where the user may want to switch from vertical to horizontal layouts; nor does it address hinting at toolbars and menus in case they're made narrow or placed at the side. It does not, however, forbid such things inherantly.
Tristan suggests a much simpler method where a GtkBin subclass called GtkWidgetPort is used. This contains a single child, and can be drag and dropped to another GtkWidgetPort; upon drop the widgets are swapped. This is a much simpler layout, but does not supply a variadic layout of horizontal/vertical panes as with GtkPanedArbitraryArea.
MurrayCumming: Isn't this basically "docking panels" as seen on Windows in MS Visual Studio, or half the copy-cat apps that use the Stingray toolkit, and in KDevelop (with insanely complex modes). It is difficult to get right - getting something to dock in the right is generally mysterious for the user.