Say which node a click selects, before and after the click - #122
Merged
Conversation
Selecting geometry was legible only to whoever wrote the picker. A click resolved to a leaf primitive somewhere deep in the tree, and the sole visible result was a row highlighting in a side panel — which on a narrow window or on mobile is not on screen at all. The model itself looked identical before and after. So "what did I just select, and why that?" had no answer in the viewport, and clicking was a guess you checked afterwards. Four parts, all aimed at that one gap: - Hover preview. The node under the pointer is outlined and named before you commit to a click. Throttled to 50ms, skipped mid-drag, and it will not force a frame to answer — a stale preview beats a full sphere-march per pointer move. - Selection is visible in the 3D view. The bounding box used to belong to DimensionLabels and was gated on the Dimensions toggle, which is off by default; SelectionOverlay now owns every wireframe and draws the selection in the accent colour whether or not dimensions are showing. - A breadcrumb naming the chain. Clicking the flat face left by a subtract selects the cylinder that cut it — correct, and arbitrary until something says `Subtract > Move > Cylinder`. Crumbs are clickable, which is also the only way to reach an ancestor, since picking can only ever land on a leaf. Alt-click does the same one level up. - Tree and viewport hover are the same state, so pointing at a surface lights its row and pointing at a row lights its geometry. One real bug fell out of it: `mesh` was missing from the picker's leaf set, so a click on an imported STL matched no branch, returned null, and was read as a miss — clicking an imported mesh *cleared* the selection. That is the one node kind you cannot drag in from the palette, and so the one you most need to find by clicking it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
🚀 Preview deployed: https://worktree-selection-ux.sinter.pages.dev (updates on every push to this PR) |
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.
The problem
Selecting geometry was legible only to whoever wrote the picker. A click resolved to a leaf primitive somewhere deep in the tree, and the sole visible result was a row highlighting in a side panel — which on a narrow window or on mobile is not on screen at all. The model itself looked identical before and after. So "what did I just select, and why that?" had no answer in the viewport, and clicking was a guess you checked afterwards.
What changed
Hover preview — the node under the pointer is outlined and named before you commit to a click. Throttled to 50ms, skipped mid-drag, and it will not force a frame to answer: a stale preview beats a full sphere-march per pointer move. Clicks still force a frame, because a wrong selection is worse than a hitch.
Selection is visible in the 3D view — the bounding box used to belong to
DimensionLabelsand was gated on the Dimensions toggle, which is off by default. A newSelectionOverlayowns every wireframe in the scene and draws the selection in the accent colour whether or not dimensions are showing.A breadcrumb naming the chain — clicking the flat face left by a subtract selects the cylinder that cut it. That is correct, and reads as arbitrary until something says
Subtract › Move › Cylinder. Crumbs are clickable, which is also the only way to reach an ancestor, since picking can only ever land on a leaf.Alt+Clickdoes the same one level up. Deep chains collapse to root +…+ last three.Tree and viewport hover are the same state — pointing at a surface lights up its row, and pointing at a row lights up its geometry.
One real bug fixed
meshwas missing from the picker's leaf set, so a click on an imported STL matched no branch, fell through to the childless tail, and returnednull— which the viewport reads as "the click missed the model". Clicking an imported mesh cleared the selection. That is the one node kind you cannot drag in from the palette, and so the one you most need to be able to find by clicking it.Verification
tsc --noEmitcleansdfPicking,SelectionBreadcrumb,viewportStore)viewport-frames.spec.tsagainst real WebGL, including 3 new ones covering hover preview, the breadcrumb, and alt-clicksetTreeclears the selection, so no box is drawn in those scenes)fitPrimitive.test.tstiming out at 60s — passes in isolation, and was contending with a separatevitest runin the main checkout. Pre-existing load flake the vitest config comments already describe; unrelated to this change.Notes
A design bug surfaced during testing and is fixed here: hovering a breadcrumb crumb flipped the chip into preview mode, which disabled the very button the pointer was reaching for. Hover now records its source (
viewportvsui), and only a hover over geometry counts as "a click here would select this".🤖 Generated with Claude Code