diff options
| author | Christian Kolset <christian.kolset@gmail.com> | 2026-06-03 15:20:45 -0600 |
|---|---|---|
| committer | Christian Kolset <christian.kolset@gmail.com> | 2026-06-03 15:20:45 -0600 |
| commit | 216a278102e3f63f155d76d62790a3ca60fcec02 (patch) | |
| tree | 57bf860d06bbb99a5c3ec17912e32278df7cb5e0 /ui/strip_chart.py | |
| parent | 7b926faab3dcd52e45fc1b4b24f955a4dcf66959 (diff) | |
Replace grid-snap canvas with BSP-tree drag-to-split tiling
Dragging a tile to the edge (left/right/top/bottom) of another tile
splits that tile's space and inserts the dragged tile on that side.
Drop zones occupy the outer third of each tile edge; center has no zone.
Ghost overlay shows the split target during drag.
Data model: LayoutConfig.tree (BSP tree as nested dict). PaneSpec.row/col
removed. strip_chart uses tree_to_grid() → rowspan/colspan for pyqtgraph.
Backward compat: tree=None falls back to layout_mode stacking path.
Example: 3 stacked → drag Tile 3 to left of Tile 1 → Tile 3|Tile 1 on
top (side-by-side), Tile 2 spans full bottom.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'ui/strip_chart.py')
| -rw-r--r-- | ui/strip_chart.py | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/ui/strip_chart.py b/ui/strip_chart.py index d855038..5a1d1e9 100644 --- a/ui/strip_chart.py +++ b/ui/strip_chart.py @@ -42,7 +42,8 @@ if _HAS_PG: from devices.device_registry import DeviceRegistry from core.acquisition import AcquisitionEngine from core.signal_processor import SignalProcessor -from ui.windows.plot_window import LayoutConfig, PaneSpec, TraceSpec, build_default_layout +from ui.windows.plot_window import (LayoutConfig, PaneSpec, TraceSpec, + build_default_layout, tree_to_grid, _tree_grid_size) _STYLES = { "solid": Qt.PenStyle.SolidLine, @@ -94,20 +95,26 @@ class StripChartWidget(QWidget): mf = QFont("IBM Plex Mono", 8) n = len(cfg.panes) - # Determine row/col for each pane - if cfg.layout_mode == "free": - positions = [(spec.row or 0, spec.col or 0) for spec in cfg.panes] + # Determine row/col/rowspan/colspan for each pane + if cfg.layout_mode == "free" and cfg.tree is not None: + gs = _tree_grid_size(cfg.tree) + grid_pos: dict = {} + tree_to_grid(cfg.tree, 0, 0, gs, gs, grid_pos) + # grid_pos[pane_idx] = (row, col, rowspan, colspan) elif cfg.layout_mode == "sidebyside": - positions = [(0, c) for c in range(n)] + grid_pos = {i: (0, i, 1, 1) for i in range(n)} elif cfg.layout_mode == "grid": cols = max(1, cfg.grid_cols) - positions = [(i // cols, i % cols) for i in range(n)] + grid_pos = {i: (i // cols, i % cols, 1, 1) for i in range(n)} else: # stacked (legacy default) - positions = [(r, 0) for r in range(n)] + grid_pos = {i: (i, 0, 1, 1) for i in range(n)} ref_plot = None - for idx, (spec, (row, col)) in enumerate(zip(cfg.panes, positions)): - plot = self._gw.addPlot(row=row, col=col) + for idx, spec in enumerate(cfg.panes): + if idx not in grid_pos: + continue + row, col, rowspan, colspan = grid_pos[idx] + plot = self._gw.addPlot(row=row, col=col, rowspan=rowspan, colspan=colspan) plot.setLabel("left", spec.y_label or spec.title) plot.setLabel("bottom", spec.x_label or "Elapsed (s)") plot.showGrid(x=spec.grid, y=spec.grid, alpha=0.12) @@ -135,7 +142,6 @@ class StripChartWidget(QWidget): else: plot.enableAutoRange(axis="y") - # Apply weight to row and column stretch self._gw.ci.layout.setColumnStretchFactor(col, spec.weight) self._gw.ci.layout.setRowStretchFactor(row, spec.weight) |
