Skip to content

feat: measure distance between two selected views - #39

Merged
daisuke0131 merged 8 commits into
masterfrom
feat/distance-measurement
Aug 6, 2026
Merged

feat: measure distance between two selected views#39
daisuke0131 merged 8 commits into
masterfrom
feat/distance-measurement

Conversation

@daisuke0131

@daisuke0131 daisuke0131 commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Summary

Selecting a view, then selecting another one, now appends a distance section to the InfoView panel: the reference view's class name plus rows describing the geometric relation between the two frames.

Data flow stays one-directional: ViewInspector → ViewInspection ×2 → InfoRowBuilder → InfoView. A new pure type RectRelation classifies two rects, fully unit-tested without a window scene.

Behavior

  • Separated: nearest-edge gaps (gapX / gapY) — the axis whose projections overlap is omitted, so stacked elements show only gapY and side-by-side elements only gapX; 0 means flush
  • Overlapping: overlap widths (overlapX / overlapY)
  • Contained: insets of the inner view within the outer (top / left / bottom / right), direction-agnostic
  • The reference is simply the previously selected view — the interaction model is unchanged single-tap selection
  • While a distance section is shown, the reference view keeps a blue border (the current selection stays red), so it's always visible which two views are being compared — added after device-testing feedback that the pair was hard to identify
  • The reference is dropped (no distance section) unless it still lives in the same window as the current selection; screen transitions reset it automatically via the existing reload path, and hide() clears it explicitly

Also in this PR

  • InfoRowBuilder's duplicated 8-title lists consolidated into one (deferred cleanup from the 2.1.0 review)
  • New MonitorOverlayTests covering the selection flow end-to-end, including the previously untested nil-targetView defensive path

Verification

  • Full suite green: 84 test declarations in 15 suites (new: RectRelationTests ×8, InfoRowBuilderTests +5, MonitorOverlayTests ×5), swiftlint --strict at 0 violations
  • Example app launched on the iPhone 17 simulator (screenshot below); the distance rows themselves are exercised by the overlay tests against real window coordinates
  • Pre-merge gate: manual tap-through on the Example app (stacked pair → gapY, side-by-side → gapX, label-in-parent → insets, no distance section on first selection) — to be confirmed on this PR

🤖 Generated with Claude Code

daisuke0131 and others added 8 commits August 5, 2026 23:14
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Eliminates nil guard branching by using optional chaining and map operations.
Consolidates title list definition to a single location, improving maintainability.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds comparedTo parameter to rows(from:comparedTo:) with default nil for
backward compatibility. Distance section includes vs row plus relational
rows (gapX/gapY for separated, overlapX/overlapY for overlapping, or top/
left/bottom/right for contained).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Track the previously selected MonitorButton (lastSelectedButton, weak)
in MonitorOverlay and pass its inspection as the comparedTo reference
to InfoRowBuilder.rows(from:comparedTo:), so selecting a second view
appends the vs/gap/overlap/inset rows. select(sender:) is loosened
from private to internal as a test seam for the new MonitorOverlayTests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ation

Update RectRelation.between doc comment to accurately reflect that CGRect.contains
returns true when a zero-size rectangle is inside the outer bounds, making them
treated as contained. Previously documented behavior was inverted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…erence reset

Improve reference tracking robustness in MonitorOverlay:
- Enhance window reference guard to require reference and measurement targets to be
  in the same window instance (referenceWindow === window), preventing mixed coordinate
  system measurements when views move between windows
- Explicitly reset lastSelectedButton in hide() for lifetime-independent cleanup instead
  of relying on dealloc

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Real-device feedback: users couldn't tell which view the distance
section was comparing against, since the reference (previous
selection) only showed up as a class name in the "vs" row. Keep a
2pt systemBlue border on the reference button for as long as the
distance section is shown, alongside the existing 2pt red border on
the current selection.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@daisuke0131
daisuke0131 merged commit ea145d8 into master Aug 6, 2026
4 checks passed
@daisuke0131
daisuke0131 deleted the feat/distance-measurement branch August 6, 2026 13:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant