feat: measure distance between two selected views - #39
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 typeRectRelationclassifies two rects, fully unit-tested without a window scene.Behavior
gapX/gapY) — the axis whose projections overlap is omitted, so stacked elements show onlygapYand side-by-side elements onlygapX;0means flushoverlapX/overlapY)top/left/bottom/right), direction-agnostichide()clears it explicitlyAlso in this PR
InfoRowBuilder's duplicated 8-title lists consolidated into one (deferred cleanup from the 2.1.0 review)MonitorOverlayTestscovering the selection flow end-to-end, including the previously untested nil-targetViewdefensive pathVerification
RectRelationTests×8,InfoRowBuilderTests+5,MonitorOverlayTests×5),swiftlint --strictat 0 violationsgapY, side-by-side →gapX, label-in-parent → insets, no distance section on first selection) — to be confirmed on this PR🤖 Generated with Claude Code