A binary split tree for interactive window tiling. More...
#include <phosphor-tiles/include/PhosphorTiles/SplitTree.h>
Public Member Functions | |
| SplitTree () | |
| Construct an empty tree (no root) | |
| SplitTree (SplitTree &&other) noexcept | |
| Move constructor. | |
| SplitTree & | operator= (SplitTree &&other) noexcept |
| Move assignment. | |
| ~SplitTree () | |
| SplitTree (const SplitTree &)=delete | |
| SplitTree & | operator= (const SplitTree &)=delete |
| const SplitNode * | root () const noexcept |
| Get the root node of the tree. | |
| SplitNode * | root () noexcept |
| bool | isEmpty () const noexcept |
| Check if the tree has no nodes. | |
| int | leafCount () const noexcept |
| Count the number of leaf nodes (windows) | |
| int | treeHeight () const noexcept |
| Get the maximum height of the tree. | |
| const SplitNode * | leafForWindow (const QString &windowId) const |
| Find the leaf node for a given window ID. | |
| SplitNode * | leafForWindow (const QString &windowId) |
| QStringList | leafOrder () const |
| Get window IDs in depth-first left-to-right order. | |
| void | insertAtFocused (const QString &windowId, const QString &focusedWindowId, qreal initialRatio=0.0) |
| Insert a window by splitting the focused window's leaf. | |
| void | insertAtEnd (const QString &windowId, qreal initialRatio=0.0) |
| Insert a window by splitting the rightmost leaf. | |
| void | insertAtPosition (const QString &windowId, int position, qreal initialRatio=0.0) |
| Insert a window by splitting the leaf at a given position. | |
| void | remove (const QString &windowId) |
| Remove a window, collapsing its parent and promoting its sibling. | |
| void | swap (const QString &windowId1, const QString &windowId2) |
| Swap two windows' positions in the tree. | |
| bool | swapLeaves (const QString &a, const QString &b) |
| Swap the stored window ids on two existing leaves. | |
| void | resizeSplit (const QString &windowId, qreal newRatio) |
| Adjust the split ratio of a window's parent node. | |
| QVector< QRect > | applyGeometry (const QRect &area, int innerGap) const |
| Compute zone rectangles by recursively splitting the area. | |
| bool | rebuildFromOrder (const QStringList &tiledWindows, qreal defaultSplitRatio=AutotileDefaults::DefaultSplitRatio) |
| Rebuild tree from a new window order, preserving split ratios where possible. | |
| QJsonObject | toJson () const |
| Serialize the tree to JSON. | |
Static Public Member Functions | |
| static std::unique_ptr< SplitTree > | fromJson (const QJsonObject &json) |
| Deserialize a tree from JSON. | |
A binary split tree for interactive window tiling.
SplitTree manages a binary tree of split nodes where each leaf represents a tiled window and each internal node defines how its area is divided between two children. This enables per-split ratio adjustment and interactive insert/remove operations (similar to bspwm).
Unlike BSPAlgorithm (which rebuilds the tree from scratch each frame), SplitTree is a persistent data structure that is mutated incrementally as windows are added, removed, swapped, or resized.
This class is NOT a QObject. It is movable via unique_ptr members.
| PhosphorTiles::SplitTree::SplitTree | ( | ) |
Construct an empty tree (no root)
|
noexcept |
Move constructor.
| PhosphorTiles::SplitTree::~SplitTree | ( | ) |
|
delete |
| QVector< QRect > PhosphorTiles::SplitTree::applyGeometry | ( | const QRect & | area, |
| int | innerGap | ||
| ) | const |
Compute zone rectangles by recursively splitting the area.
| area | Available screen area |
| innerGap | Gap between adjacent zones in pixels |
first subtree receives the full parent rect and each leaf of the second subtree is emitted as a 1×1 rect anchored at the parent's origin. This preserves the invariant that the returned rect count equals leafCount, which downstream code relies on to map tiled windows to zones by position. Windows under the degenerate second subtree land effectively offscreen; this is intentional. A warning is logged via lcTilesLib.
|
static |
Deserialize a tree from JSON.
| json | Serialized tree |
| void PhosphorTiles::SplitTree::insertAtEnd | ( | const QString & | windowId, |
| qreal | initialRatio = 0.0 |
||
| ) |
Insert a window by splitting the rightmost leaf.
If the tree is empty, creates a root leaf.
| windowId | New window to insert |
| initialRatio | Split ratio for the new split (0 = use DefaultSplitRatio) |
| void PhosphorTiles::SplitTree::insertAtFocused | ( | const QString & | windowId, |
| const QString & | focusedWindowId, | ||
| qreal | initialRatio = 0.0 |
||
| ) |
Insert a window by splitting the focused window's leaf.
If the tree is empty, creates a root leaf. If the focused window is not found, falls back to insertAtEnd.
| windowId | New window to insert |
| focusedWindowId | Currently focused window to split |
| void PhosphorTiles::SplitTree::insertAtPosition | ( | const QString & | windowId, |
| int | position, | ||
| qreal | initialRatio = 0.0 |
||
| ) |
Insert a window by splitting the leaf at a given position.
Position is a depth-first index. If position >= leafCount, falls back to insertAtEnd.
| windowId | New window to insert |
| position | Depth-first leaf index to split |
| initialRatio | Split ratio for the new split (0 = use DefaultSplitRatio) |
|
noexcept |
Check if the tree has no nodes.
|
noexcept |
Count the number of leaf nodes (windows)
| SplitNode * PhosphorTiles::SplitTree::leafForWindow | ( | const QString & | windowId | ) |
| const SplitNode * PhosphorTiles::SplitTree::leafForWindow | ( | const QString & | windowId | ) | const |
Find the leaf node for a given window ID.
| windowId | Window to search for |
| QStringList PhosphorTiles::SplitTree::leafOrder | ( | ) | const |
Get window IDs in depth-first left-to-right order.
| bool PhosphorTiles::SplitTree::rebuildFromOrder | ( | const QStringList & | tiledWindows, |
| qreal | defaultSplitRatio = AutotileDefaults::DefaultSplitRatio |
||
| ) |
Rebuild tree from a new window order, preserving split ratios where possible.
| tiledWindows | Ordered list of tiled window IDs |
| defaultSplitRatio | Default split ratio for new internal nodes |
true if all windows were preserved, false if the input had to be truncated (size exceeded MaxRuntimeTreeDepth). Callers that care about lossless round-tripping should observe the return value and clamp their own state to match. | void PhosphorTiles::SplitTree::remove | ( | const QString & | windowId | ) |
Remove a window, collapsing its parent and promoting its sibling.
| windowId | Window to remove |
| void PhosphorTiles::SplitTree::resizeSplit | ( | const QString & | windowId, |
| qreal | newRatio | ||
| ) |
Adjust the split ratio of a window's parent node.
| windowId | Window whose parent split to resize |
| newRatio | New split ratio (clamped to MinSplitRatio..MaxSplitRatio) |
|
noexcept |
Get the root node of the tree.
|
noexcept |
| void PhosphorTiles::SplitTree::swap | ( | const QString & | windowId1, |
| const QString & | windowId2 | ||
| ) |
Swap two windows' positions in the tree.
Only swaps the windowId strings on the leaf nodes; tree structure remains unchanged.
| windowId1 | First window |
| windowId2 | Second window |
| bool PhosphorTiles::SplitTree::swapLeaves | ( | const QString & | a, |
| const QString & | b | ||
| ) |
Swap the stored window ids on two existing leaves.
Fast-path variant of swap that reports whether both leaves were actually found. Callers can use the return value to decide whether the swap succeeded or whether a fallback rebuild is required.
Tree structure, split ratios, split directions, and child ordering are left untouched; only the windowId strings on the two leaf nodes are exchanged.
| a | First window id |
| b | Second window id |
true if both leaves were located and their ids swapped; false otherwise (tree is left unchanged in the false case). Swapping an id with itself returns true as a no-op when the leaf exists, and false when it doesn't. | QJsonObject PhosphorTiles::SplitTree::toJson | ( | ) | const |
Serialize the tree to JSON.
|
noexcept |
Get the maximum height of the tree.