class

TUI::HSplit

Inherits TUI::Widget < Reference < Object

Positions two widgets side by side with a vertical divider between them, replacing the pattern of hand-computing a split width and drawing the divider with manual absolute-coordinate calls. Owns only the children's geometry and the divider — each child still renders itself.

The split is either a fixed column count (#left_width) or a proportion of the total width (#left_ratio) — the latter keeps both panes expanding or shrinking together, relative to each other, across resizes, since #layout re-derives #left_width from #left_ratio on every #composite. Only one is active at a time; setting one clears the other.

Tab toggles which pane is active and routes keys to it — the same convention SplitWindow uses for its two Scrollables, generalized here to two full Widgets. Each child's focus_if is driven from the active pane each render, so a widget like TableView can style its own cursor row accordingly, exactly as it would hosted standalone or in SplitWindow.

Constructors

full_screen(screen : Screen, left : Widget, right : Widget, left_width : Int32 | Nil = nil, left_ratio : Float64 | Nil = nil, bordered : Bool = true) : HSplit

Sizes and positions an HSplit to fill the screen below the status bar row — see Window.full_screen for the same reasoning. left_width defaults to an even split when neither it nor left_ratio is given.

Source
full_screen_scrollables(screen : Screen, left : Scrollable, right : Scrollable, left_width : Int32 | Nil = nil, left_ratio : Float64 | Nil = nil) : HSplit

Convenience wrapper for the common case of two Scrollables placed side by side without a shared border — HSplit itself only accepts full Widgets (see full_screen above), since each pane may be an arbitrary composite widget, not just a bare Scrollable. Wraps each Scrollable in its own borderless Window before delegating to full_screen, replacing the pattern of hand-computing left_width and building two matching Window.new calls.

Source
new(x : Int32, y : Int32, width : Int32, height : Int32, left : Widget, right : Widget, left_width : Int32 | Nil = nil, left_ratio : Float64 | Nil = nil, bordered : Bool = true)
Source

Instance methods

border_style

Applied to the divider line drawn by #render when #bordered? is true.

Source
border_style=(border_style : Style)

Applied to the divider line drawn by #render when #bordered? is true.

Source
bordered=(bordered : Bool)

Whether to draw the vertical divider between panes — false to leave the gap column blank, e.g. when each pane supplies its own visual separation. Mirrors Window#bordered?.

Source
bordered?

Whether to draw the vertical divider between panes — false to leave the gap column blank, e.g. when each pane supplies its own visual separation. Mirrors Window#bordered?.

Source
composite(screen : Screen) : Nil

Children are separate widgets with their own buffers — composite them directly onto the screen rather than drawing them into HSplit's own buffer, then draw just the divider into HSplit's buffer as usual.

Order matters: super (Widget#composite) blits HSplit's OWN buffer — blank except for the divider column — over its entire bounding box. If that ran after the children, it would wipe out everything they just drew except the one divider column. Draw the divider first, so each child's later blit wins for its own region and only the actual divider column (never touched by either child) is left showing it.

Source
focus_left

Resets which pane is active back to the left one — for a host app that reuses the same HSplit instance across appearances and wants a consistent starting focus each time it reappears, rather than carrying over whatever pane was last active before it was hidden. Mirrors SplitWindow#focus_left.

Source
handle_key(ev : KeyEvent) : Bool

Returns true if the key was consumed.

Source
left

The two hosted panes. Read-only from outside — HSplit itself owns their geometry (see #layout, driven from HSplit's own x/y/width/ height/#left_width or #left_ratio); mutate #left_width/#left_ratio rather than these directly.

Source
left_ratio

Fraction (0.0-1.0) of total width the left pane occupies, re-derived every #layout so both panes expand/shrink together, proportionally to each other, across resizes — nil when in fixed-#left_width mode.

Source
left_ratio=(r : Float64) : Nil

Switches to ratio mode: the left pane's width becomes r * width, recomputed on every #layout (including resizes) instead of staying pinned to an absolute column count. Re-runs #layout immediately.

Source
left_width

Width in columns of the left pane, excluding the divider column. When #left_ratio is set, this reflects the ratio's current column count as of the last #layout, but is a derived value, not the source of truth.

Source
left_width=(w : Int32) : Nil

Sets a fixed column width for the left pane and switches out of ratio mode (clears #left_ratio) — the two are mutually exclusive. Re-runs #layout immediately so both panes' geometry stays consistent with the new split.

Source
render

Draw into @buffer using LOCAL coordinates (0, 0 = this widget's own top-left). Widgets never need to know their own x/y offset to draw themselves — that arithmetic is handled entirely by composite.

Source
right
Source
status_hint

Plain text describing the actions available in the widget's current state. Rendered by the App in the global status bar at the bottom of the screen — widgets must NOT draw their own hint lines.

Source