Class SplitPane
SplitPane split = SplitPane.horizontal(sidebar, editor).setRatio(0.25f);
split.setMinimums(180, 320); // neither pane below this
split.onRatioChange(app::rememberLayout);
The orientation names the axis the panes are arranged along, not the
divider: horizontal(limn.scene.Widget, limn.scene.Widget) puts them side by side, so the divider is the
vertical line between them.
The first pane takes the leading edge. Reading left to right that is the left, and reading right to left it is the right; the ratio, the minimums and the divider's position are all magnitudes along the divided axis and mean the same thing either way. A stacked split has no reading axis at all and is untouched by the layout direction.
The split is a ratio, not a width, so growing the window grows both panes. An application that wants a sidebar to keep its width while the other pane absorbs every new pixel re-sets the ratio from its own resize handling; there is no weight knob, because which pane absorbs a change is a per-layout decision rather than a per-splitter one.
setMinimums(float, float) keeps a pane from being dragged away entirely; the default
floor is a hit target's worth on each side. Pass 0 for a pane that is allowed
to collapse to nothing, such as a preview the user is meant to be able to dismiss.
The divider is thin to look at and thick to hit: it paints a hairline that thickens into the accent on hover, and catches a band a few points wider than the gutter, overlapping both panes. Focus, hover and drag are the same mark in three tints of the accent, each lighter than the one before.
The divider is not a tab stop unless asked; see
setDividerFocusable(boolean), which is what turns on the keyboard: arrows by a
visible step, by one point with Shift, Home and End to the minimum on either side.
Three panes are two splitters: nest one in the other.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumWhich axis the two panes are arranged along. -
Method Summary
Modifier and TypeMethodDescriptionstatic SplitPanehorizontal(Widget left, Widget right) Two panes side by side, divided by a vertical line.booleanprotected voidonLayout()Containers position children here (measure +Widget.layoutBox(float, float, float, float)per child).protected SizeonMeasure(Constraints constraints) Reports the size this widget wants withinconstraints.onRatioChange(Consumer<Float> listener) Fires while the user drags or keys the divider, never onsetRatio(float).Which axis the panes are arranged along.floatratio()setDividerFocusable(boolean focusable) Makes the divider a tab stop, off by default.setMinimums(float first, float second) Floors, in points, under which neither pane may be dragged.setRatio(float newRatio) Sets the share of the space given to the first pane,0..1.static SplitPaneTwo panes stacked, divided by a horizontal line.Methods inherited from class limn.scene.Widget
acceptsTextInput, add, baselineOffset, baselineOffsetOf, caretRect, children, clipboard, clipsChildren, controlSize, cursor, declaredControlSize, declaredLayoutDirection, declaredLocale, focusArrivedByTraversal, height, hitTest, imageCursor, invalidate, invalidate, isEnabled, isFocusable, isFocused, isShowing, isVisible, layoutBox, layoutDirection, locale, localToSceneX, localToSceneY, markNeedsContainedLayout, markNeedsLayout, measure, moveChild, neutralBase, onAttached, onCharTyped, onDetached, onFileDrop, onFocusGained, onFocusLost, onKeyEvent, onMouseEvent, onPaint, onPaintOverlay, onPreedit, overlayPassesPointer, paintChildren, paintOutset, paintWidget, parent, remove, requestFocus, revealInView, scene, sceneToLocalX, sceneToLocalY, setControlSize, setCursor, setEnabled, setFocusable, setImageCursor, setInheritanceHost, setLayoutDirection, setLocale, setTooltip, setTooltip, setVisible, shapeText, textRuler, tooltip, width, x, y
-
Method Details
-
horizontal
Two panes side by side, divided by a vertical line. The first takes the leading edge, so the parameter names describe the default reading direction and not the screen: in a right-to-left layoutleftis the pane on the right. -
vertical
Two panes stacked, divided by a horizontal line. -
setRatio
Sets the share of the space given to the first pane,0..1. Clamped bysetMinimums(float, float)at layout, not here: the minimums are in points and the space is not known until there is a box to divide. Programmatic, so it does not fireonRatioChange. -
ratio
public float ratio()- Returns:
- the requested share of the first pane, before any minimum applies
-
setMinimums
Floors, in points, under which neither pane may be dragged.0lets that pane collapse entirely. When the box is too small for both floors the first one wins and the second pane takes what is left: a split that cannot honour both still has to lay out.firstis the leading pane's floor andsecondthe trailing one's, whichever way the layout reads; both are extents along the divided axis, so neither swaps when the direction does. -
onRatioChange
Fires while the user drags or keys the divider, never onsetRatio(float). -
setDividerFocusable
Makes the divider a tab stop, off by default. A split is reached with the pointer, and a tab stop that only moves a boundary costs every keyboard user a stop on the way to the panes' own controls, so the keyboard support is here to be turned on by a layout that wants it, not to be paid for by one that does not.On, the divider takes focus by Tab and by a click on its band, shows the accent at its focus tint, and answers the arrows, Shift+arrow, Home and End. Off, nothing else changes: dragging, the cursor, the hover tint and the grab band are the pointer's, and none of them asks about focus.
The flag is the divider's rather than the split's, because the divider is what focus would land on; the split itself is a container and never a tab stop. UI thread only.
-
isDividerFocusable
public boolean isDividerFocusable()- Returns:
- whether the divider takes keyboard focus (
falseby default)
-
orientation
Which axis the panes are arranged along. -
onMeasure
Description copied from class:WidgetReports the size this widget wants withinconstraints. Called once per layout pass, and the result is cached against the constraints and the resolved axes (size step, layout direction, locale), so it must be a pure function of them and of this widget's own state.Resolve the
ControlSizeand theLayoutDirectiononce each here and thread them down; never read either in a constructor. The locale needs no threading: it is in scope, andI18n.locale()answers it wherever text is resolved. -
onLayout
protected void onLayout()Description copied from class:WidgetContainers position children here (measure +Widget.layoutBox(float, float, float, float)per child).
-