SelectionManager: route item to furnish phase before registry fallback
User report: items needed a double click to select after the item kind
registered (Phase 5). Root cause: `getSelectionTarget` checked
`isRegistrySelectable(node.type)` as part of the FIRST branch (which
routes to structure phase), matching `item` before the item-specific
branch below could route door/window-category items to structure +
everything else to furnish.
Effect: clicking an item triggered phase switch (structure ← furnish),
then the next click selected. Hence the double click.
Fix:
1. Item-specific case moved to the TOP of getSelectionTarget. Its
asset.category-driven routing (door/window items → structure;
everything else → furnish) beats any generic registry fallback.
2. Generic registry fallback at the bottom now reads `def.category`
to pick the phase — `category: 'furnish'` → furnish phase,
everything else → structure/elements. Future furnish-category
kinds (only shelf right now) route correctly without a special
case.
3. `isRegistrySelectable(node.type)` clause removed from the
structure branch — replaced by the def.category check at the
bottom.
Net: single-click selection works for items again, and the routing
logic is now cleanly capability/category-driven instead of "all
registered kinds → structure" which was a Stage A simplification
that broke as soon as a furnish-category kind registered.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
8d65be17fa
commit
df07f7bcb2
@@ -11,6 +11,7 @@ import {
|
||||
type ItemNode,
|
||||
isRegistrySelectable,
|
||||
type NodeEvent,
|
||||
nodeRegistry,
|
||||
type RoofEvent,
|
||||
type RoofNode,
|
||||
type RoofSegmentEvent,
|
||||
@@ -691,6 +692,25 @@ const SELECTION_STRATEGIES: Record<string, SelectionStrategy> = {
|
||||
}
|
||||
|
||||
const getSelectionTarget = (node: AnyNode): SelectionTarget | null => {
|
||||
// Item is checked FIRST so its asset.category-driven routing (door/
|
||||
// window items land in structure phase, everything else in furnish)
|
||||
// beats the generic registry fallback below. Without this, registering
|
||||
// `item` (Phase 5) made isRegistrySelectable('item') match the
|
||||
// structure branch first, breaking single-click selection: first click
|
||||
// switched the editor to structure phase, second click selected.
|
||||
if (node.type === 'item') {
|
||||
const item = node as ItemNode
|
||||
if (item.asset.category === 'door' || item.asset.category === 'window') {
|
||||
return {
|
||||
phase: 'structure',
|
||||
structureLayer: 'elements',
|
||||
}
|
||||
}
|
||||
return {
|
||||
phase: 'furnish',
|
||||
}
|
||||
}
|
||||
|
||||
if (node.type === 'zone') {
|
||||
return {
|
||||
phase: 'structure',
|
||||
@@ -711,10 +731,7 @@ const getSelectionTarget = (node: AnyNode): SelectionTarget | null => {
|
||||
node.type === 'stair-segment' ||
|
||||
node.type === 'spawn' ||
|
||||
node.type === 'window' ||
|
||||
node.type === 'door' ||
|
||||
// Registry-driven kinds default to structure/elements (Phase 4 reads
|
||||
// `definition.presentation.paletteSection` to route correctly).
|
||||
isRegistrySelectable(node.type)
|
||||
node.type === 'door'
|
||||
) {
|
||||
return {
|
||||
phase: 'structure',
|
||||
@@ -722,18 +739,16 @@ const getSelectionTarget = (node: AnyNode): SelectionTarget | null => {
|
||||
}
|
||||
}
|
||||
|
||||
if (node.type === 'item') {
|
||||
const item = node as ItemNode
|
||||
if (item.asset.category === 'door' || item.asset.category === 'window') {
|
||||
return {
|
||||
phase: 'structure',
|
||||
structureLayer: 'elements',
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
phase: 'furnish',
|
||||
// Registry-driven kinds (Phase 5+): route by `def.category`. Built-ins
|
||||
// above match before this fallback. Furnish-category kinds (shelf,
|
||||
// item — already handled above) land on the furnish phase; structure-
|
||||
// category kinds (everything else) on structure/elements.
|
||||
const def = nodeRegistry.get(node.type)
|
||||
if (def) {
|
||||
if (def.category === 'furnish') {
|
||||
return { phase: 'furnish' }
|
||||
}
|
||||
return { phase: 'structure', structureLayer: 'elements' }
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
Reference in New Issue
Block a user