| Safe Haskell | None |
|---|---|
| Language | GHC2024 |
NanoUI.Widgets.SplitPane
Description
Pure pane-grid tree model and geometry, modelled on iced's PaneGrid.
A GridNode is a binary split tree of panes. Each split stores an axis
(AxisV = vertical divider splitting width, AxisH = horizontal divider
splitting height), a ratio in [0,1] for the first (A) side, and the two
child subtrees. Every pane and split has a globally unique Word64 id so
pane state can be keyed by pane id regardless of position in the tree.
All functions here are pure; the interactive wrapper in
NanoUI.Widgets.PaneGrid persists a GridNode as a Data.Dynamic value
in the widget store.
Synopsis
- data GridAxis
- data GridNode
- data PaneDrop
- treePanes :: GridNode -> [Word64]
- treeSize :: GridNode -> Int
- paneExist :: GridNode -> Word64 -> Bool
- subtreeMin :: Float -> Float -> GridNode -> (Float, Float)
- mainMins :: GridAxis -> (Float, Float) -> (Float, Float) -> (Float, Float)
- mainLen :: GridAxis -> Rect -> Float
- splitLength :: Float -> Float -> Float -> Float -> Float -> Float
- layoutNode :: Float -> Float -> GridNode -> Rect -> (Map Word64 Rect, [DividerInfo])
- data DividerInfo = DividerInfo {}
- treeSplit :: Word64 -> Word64 -> GridAxis -> Bool -> Word64 -> GridNode -> GridNode
- treeSetRatio :: Word64 -> Float -> GridNode -> GridNode
- treeRemovePane :: Word64 -> GridNode -> Maybe GridNode
- treeMovePane :: Word64 -> Word64 -> PaneDrop -> GridNode -> Maybe GridNode
- clampTreeRatio :: GridNode -> Word64 -> Rect -> Float -> Float -> Float -> Float
- dropPreview :: Float -> Float -> GridNode -> Word64 -> Rect -> PaneDrop -> Maybe (Rect, PaneDrop)
- dropTargetForPane :: Rect -> V2 -> Word64 -> PaneDrop
- topLevelDropTarget :: Float -> Rect -> V2 -> Maybe PaneDrop
Documentation
Divider orientation. AxisV draws a vertical divider (panes left/right),
AxisH draws a horizontal divider (panes stacked top/bottom).
Instances
| Eq GridAxis Source # | |
| Ord GridAxis Source # | |
Defined in NanoUI.Widgets.SplitPane | |
| Bounded GridAxis Source # | |
| Enum GridAxis Source # | |
Defined in NanoUI.Widgets.SplitPane | |
| Show GridAxis Source # | |
Binary split tree node. Pane and split ids share one monotonic counter. Positional (non-record) so the multi-constructor type keeps total fields.
Result of dropping a dragged pane on a target pane.
Constructors
| DropSwap Word64 | Drop on the center of the pane: the two panes swap places. |
| DropSplit Word64 GridAxis Bool | Drop near an edge: the target pane splits along the axis and the
dragged pane moves into the new child. |
| DropTop GridAxis Bool | Drop on the outer edge of the whole grid: the entire tree is wrapped
in a new top-level split and the dragged pane takes one side, so the
rest of the grid collapses onto the other. |
subtreeMin :: Float -> Float -> GridNode -> (Float, Float) Source #
Minimum (width, height) that must be reserved for a subtree under a
minSize per-pane floor and spacing between every split level.
splitLength :: Float -> Float -> Float -> Float -> Float -> Float Source #
A-side extent for a split along its main axis, honouring the subtree minima. The ratio shares out the extent left after the gutter between the sides, so a 0.5 split gives both sides the same length. Falls back to the raw share when the region is too small to satisfy both minima.
layoutNode :: Float -> Float -> GridNode -> Rect -> (Map Word64 Rect, [DividerInfo]) Source #
Lay out a tree into per-pane regions and divider bands within Rect.
Dividers are reported parent-before-child so dragging a divider resizes its
immediate subtrees relative to the same region.
data DividerInfo Source #
Per-split divider information: the split's own region (where the ratio applies), the exact spacing band, and the axis ratio id.
Constructors
| DividerInfo | |
Instances
| Eq DividerInfo Source # | |
Defined in NanoUI.Widgets.SplitPane | |
| Show DividerInfo Source # | |
Defined in NanoUI.Widgets.SplitPane Methods showsPrec :: Int -> DividerInfo -> ShowS # show :: DividerInfo -> String # showList :: [DividerInfo] -> ShowS # | |
treeSplit :: Word64 -> Word64 -> GridAxis -> Bool -> Word64 -> GridNode -> GridNode Source #
Split the pane (first arg) along the axis with a 0.5 ratio, inserting the
new pane. newOnA places the new pane on the A (left/top) side of the new
split; False puts it on the B (right/bottom) side. Returns the updated
tree (unchanged if the pane does not exist).
treeSetRatio :: Word64 -> Float -> GridNode -> GridNode Source #
Set the raw ratio of a split (clamped to [0,1]).
treeRemovePane :: Word64 -> GridNode -> Maybe GridNode Source #
Remove a pane. The sibling subtree absorbs its space. Nothing if the
pane does not exist or removing it would empty the tree.
treeMovePane :: Word64 -> Word64 -> PaneDrop -> GridNode -> Maybe GridNode Source #
Move a pane onto a drop target. Center drops swap the two panes; edge drops split the target pane with the given fresh split id and move the dragged pane into the new child; top-level drops wrap the whole tree in a new root split with the dragged pane on one side.
clampTreeRatio :: GridNode -> Word64 -> Rect -> Float -> Float -> Float -> Float Source #
Clamp a proposed ratio for a split so both subtrees keep at least their minimum size within the given region.
dropPreview :: Float -> Float -> GridNode -> Word64 -> Rect -> PaneDrop -> Maybe (Rect, PaneDrop) Source #
Drop preview for a drop target: the rect to highlight and the
PaneDrop the drop performs. The highlight is found by simulating the
drop (treeMovePane with a throwaway split id) and laying the resulting
tree out (layoutNode) into the grid rect, so it is exactly the region the
dragged pane will occupy after the drop, accounting for the restructuring
that removing the pane causes (its parent split collapses and sibling
subtrees expand) and for spacing and min-size floors. Estimating the rect
from the target's pre-drop bounds goes wrong wherever mixed AxisV /
AxisH splits make those two layouts diverge. spacing must be the gutter
actually laid out between panes: PaneGrid passes
pgSpacing + 2 * pgLeeway, not pgSpacing, or the preview regions drift
from the on-screen layout. Nothing when the drop cannot be performed
(unknown pane ids, DropTop on a single-pane grid).
dropTargetForPane :: Rect -> V2 -> Word64 -> PaneDrop Source #
Classify a drop point on a target pane into the PaneDrop the drop
performs: the pane's center swaps the two panes, an edge zone splits the
target along that edge's axis with the dragged pane on the near side.