Expand/Shrink

gSplit

Definition: include xpGUI.e

gdx id = gSplit(gdx child1, child2, string orientation="VERTICAL")
Description: Creates a gH/Vbox with three children, the middle one being a (private) movable resizer.

child1/2, orientation: should be fairly self explanatory, see notes below.

Returns: the identifier of the created element.
pwa/p2js: [DEV] Not yet supported. (but have got meself E:\downloads\misc\js\simpledrag.htm/js as a fairly simple proof of concept)
Example:
-- demo\xpGUI\gSplit.exw
include xpGUI.e
procedure edge(gdx canvas, integer w,h)
    gCanvasRect(canvas,1,w-2,1,h-2)
    string txt = sprintf("%d",canvas) -- "1"/"2"/"3"
    gCanvasText(canvas,w/2,h/2,txt,XPG_C)
end procedure

gdx c1 = gCanvas(edge), 
    c2 = gCanvas(edge), 
    c3 = gCanvas(edge),
    sv = gSplit(c2,c3),--"VERTICAL"),
    sh = gSplit(c1,sv,"HORIZONTAL"),
    dlg = gDialog(sh,"gSplit","SIZE=240x80")
gSetAttribute({c1,c2,c3},"BGCLR",XPG_PARCHMENT)
gSetAttribute({c1,c2,c3},"FGCLR",XPG_OLIVE)
gShow(dlg)
gMainLoop()
gSplit
Notes: The whole point of a gSplit() is to draw, set the mouse pointer, and handle drag/drop of the separator.
It is just a gH/Vbox({child1,<private canvas>,child2}) masquerading as a builtin/native control, but one that handles all the resizing, display, cursors, and mouse handling automatically for you.
The initial position is based on the initial natural/user sizes of the two children, both of which must of course be expandable in the appropriate direction, and is appropriately limited by both the MINSIZE and MAXSIZE of both children. (DEV: the latter (ie MIN/MAX) not yet - dragging on WinAPI is also still very flickery... might work much better with a timer)

The default orientation is VERTICAL, ie a gVbox() containing a horizontal splitter, whereby the two main halves are stacked vertically, as shown for '2'/'3' above, whereas (obviously) a HORIZONTAL orientation gets a gHbox() containing a vertical splitter, as shown for '1'/pair, with the two children side-by-side. I suppose it would not be entirely unfair to say that VERTICAL is shorthand for VERTICALLY_STACKED_CHILDREN_WITH_A_HORIZONTAL_SPLITTER, and I’ll not bore you with the other one.

Failing to set EXPAND on either child may lead to unpredictable results, probably crashing in the primary orientation, and something no doubt downright weird in the cross orientation.
Attributes:
GAP,
MARGIN,
PADDING,
SPACE
Not supported and in fact specifically prohibited.
A MARGIN should instead be specified on a parent container, perhaps one specifically introduced for that purpose. Likewise SPACE, which should have no effect in the primary orientation anyway, may need a child container (also expanding in the cross orientation) or two to be deliberately/explicitly introduced. Further the internal workings of a gSplit are already complicated enough and handled specially and unlikely to honour any margins set on child1/2: you may need to "double-nest" and specify a margin on the grand-children instead to achieve the effect you want.
FRAC A fraction of the sizes of the two children which is occupied by child1, ranging between 0.0 (splitter dragged fully left/up) and 1.0 (splitter dragged fully right/down).
Default: -1, meaning "not yet in use", aka "use the natural sizes" - for example were the latter 20 and 30, a window size of 100 would make them 40 and 60.

You might save/restore this to mimic hiding or showing one of the children, such as a side panel or message area.
(DEV: currently not:)
Note that any MIN/MAX are applied automatically, and you would have to remove any and all such in order to hide a child.
Suppose that fl and fh are the minimum and maximum values of f that would honour any MIN/MAX: dragging is limited to fl..fh, however resizing or explicitly setting it simply clamps f to fl..fh at the point of use, but without actually changing it.
The value must always be an atom in the range 0.0..1.0, or -1.
also ? ACTIVE, ? VISIBLE.