From d2a555896e11a315084a00c34ef0ec77b25dcf70 Mon Sep 17 00:00:00 2001 From: Christian Kolset Date: Thu, 4 Jun 2026 12:13:47 -0600 Subject: Fix split zone detection and canvas-edge squeeze behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split zone was unreachable: squeezed between outer squeeze (1/6) and center (1/3), leaving a 1/6-wide band impossible to target reliably. Users hitting the tile edge always triggered squeeze instead of split. - Remove squeeze from inside-tile detection entirely. Split now owns the outer 1/3 of each tile edge — large, easy to target. Center keeps the inner 1/3. Squeeze remains gap-detection only (second pass). - Fix canvas-edge squeeze (no adjacent neighbor): instead of bisecting the edge tile, wrap the entire remaining tree in a new directional split with the dragged tile placed at the outer position, then equalize — all tiles end up equal size. Co-Authored-By: Claude Sonnet 4.6 --- ui/windows/plot_window.py | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'ui/windows/plot_window.py') diff --git a/ui/windows/plot_window.py b/ui/windows/plot_window.py index 95b9fea..bc8823f 100644 --- a/ui/windows/plot_window.py +++ b/ui/windows/plot_window.py @@ -599,8 +599,8 @@ class LayoutCanvas(QFrame): def _zone_at(self, pos: QPoint) -> Optional[Tuple[int, str]]: """ Returns (pane_idx, zone) where zone is one of: - squeeze_left/right/top/bottom — outer 1/6 of tile OR gap between tiles, insert between - split_left/right/top/bottom — 1/6 to 1/3, bisect tile + split_left/right/top/bottom — outer 1/3 of tile, bisect tile + squeeze_left/right/top/bottom — gap between tiles only (second pass) center — inner 1/3, swap/move """ dragging_idx = self._drag_tile.pane_index if self._drag_tile else -1 @@ -612,22 +612,16 @@ class LayoutCanvas(QFrame): rx = pos.x() - rect.x() ry = pos.y() - rect.y() w, h = rect.width(), rect.height() - sq_w = max(1, w // 6) sp_w = max(1, w // 3) - sq_h = max(1, h // 6) sp_h = max(1, h // 3) - # X-axis zone - if rx < sq_w: x_zone = "squeeze_left" - elif rx < sp_w: x_zone = "split_left" - elif rx > w - sq_w: x_zone = "squeeze_right" + # X-axis zone — outer 1/3 = split, inner 1/3 = center + if rx < sp_w: x_zone = "split_left" elif rx > w - sp_w: x_zone = "split_right" else: x_zone = "center" # Y-axis zone - if ry < sq_h: y_zone = "squeeze_top" - elif ry < sp_h: y_zone = "split_top" - elif ry > h - sq_h: y_zone = "squeeze_bottom" + if ry < sp_h: y_zone = "split_top" elif ry > h - sp_h: y_zone = "split_bottom" else: y_zone = "center" @@ -781,9 +775,28 @@ class LayoutCanvas(QFrame): self._reposition_tiles() self.arrangement_changed.emit() return - # No neighbor (canvas edge) — bisect the edge tile outward + # No neighbor — insert dragged at outer edge of full layout + new_tree = _tree_remove(self._tree, dragged_idx) + if new_tree is None: + self._reposition_tiles(); return + dragged_leaf = {"kind": "leaf", "pane": dragged_idx} + if direction == "left": + new_tree = {"kind": "hsplit", "ratio": 0.5, "first": dragged_leaf, "second": new_tree} + elif direction == "right": + new_tree = {"kind": "hsplit", "ratio": 0.5, "first": new_tree, "second": dragged_leaf} + elif direction == "top": + new_tree = {"kind": "vsplit", "ratio": 0.5, "first": dragged_leaf, "second": new_tree} + else: + new_tree = {"kind": "vsplit", "ratio": 0.5, "first": new_tree, "second": dragged_leaf} + new_tree = _tree_equalize_ratios(new_tree) + self._tree = new_tree + if self._cfg_ref is not None: + self._cfg_ref.tree = new_tree + self._reposition_tiles() + self.arrangement_changed.emit() + return - # split, or squeeze at canvas edge with no neighbor + # split — bisect target tile new_tree = _tree_remove(self._tree, dragged_idx) if new_tree is None: self._reposition_tiles() -- cgit v1.2.3