From e1e730560d218fa6a689776a88f5c647557ca067 Mon Sep 17 00:00:00 2001 From: Matysh Date: Tue, 28 Jul 2026 22:28:40 +0300 Subject: [PATCH] fix: the migrated viewport must be the whole square, not the old rectangle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seen on the live instance: in the editors the dot grid covered only part of the canvas. The grid is drawn over the space's view_box, and I transformed that box along with everything else — so it still described the old plan area, and the margins the square canvas had just added were outside it. Nothing to draw on, which is precisely the room the change exists to give. The viewport is now reset to the full square. It is also what 'fit to screen' fits, so the whole canvas is reachable. --- custom_components/houseplan/geometry_migration.py | 12 ++++++------ tests_backend/test_validation.py | 13 ++++++++++++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/custom_components/houseplan/geometry_migration.py b/custom_components/houseplan/geometry_migration.py index b4281cb..48e8d97 100644 --- a/custom_components/houseplan/geometry_migration.py +++ b/custom_components/houseplan/geometry_migration.py @@ -82,12 +82,12 @@ def migrate_space(space: dict[str, Any]) -> bool: if shape.get("h") is not None: shape["h"] = float(shape["h"]) * ky - vb = space.get("view_box") - if isinstance(vb, list) and len(vb) == 4: - space["view_box"] = [ - dx + float(vb[0]) * kx, dy + float(vb[1]) * ky, - float(vb[2]) * kx, float(vb[3]) * ky, - ] + # The viewport becomes the whole square rather than the transformed old + # rectangle. It is what the grid is drawn over and what "fit to screen" + # fits, so keeping the old box would leave the new margins outside the + # canvas — no dots, nothing to draw on — which is exactly the room this + # change was meant to give. + space["view_box"] = [0.0, 0.0, 1.0, 1.0] # The grid pitch is a fraction of the WIDTH. A tall plan just got a wider # canvas, so a wall now covers fewer cells; without this every measurement diff --git a/tests_backend/test_validation.py b/tests_backend/test_validation.py index 6d83b21..38e5b4b 100644 --- a/tests_backend/test_validation.py +++ b/tests_backend/test_validation.py @@ -688,6 +688,17 @@ def _sq(space, layout=None): return cfg["spaces"][0] +def test_the_viewport_becomes_the_whole_square(): + """The grid is drawn over the view box, and the fit fits it. + + Transforming the old rectangle instead would leave the new margins outside + the canvas — no grid there and nothing to draw on — which is the room the + square canvas was meant to add. + """ + sp = _sq({"id": "f1", "aspect": 0.5, "view_box": [0.1, 0.2, 0.5, 0.5], "rooms": []}) + assert sp["view_box"] == [0.0, 0.0, 1.0, 1.0] + + def test_a_wide_plan_gains_margins_above_and_below(): sp = _sq({ "id": "f1", "aspect": 2.0, "cell_cm": 5, "view_box": [0, 0, 1, 1], @@ -718,7 +729,7 @@ def test_a_square_plan_is_left_alone(): } sp = _sq({**before, "rooms": [dict(before["rooms"][0])]}) assert sp["rooms"][0] == before["rooms"][0] - assert sp["cell_cm"] == 5 and sp["view_box"] == [0, 0, 1, 1] + assert sp["cell_cm"] == 5 and sp["view_box"] == [0.0, 0.0, 1.0, 1.0] def test_migration_preserves_real_lengths_and_shapes():