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,
|
type ItemNode,
|
||||||
isRegistrySelectable,
|
isRegistrySelectable,
|
||||||
type NodeEvent,
|
type NodeEvent,
|
||||||
|
nodeRegistry,
|
||||||
type RoofEvent,
|
type RoofEvent,
|
||||||
type RoofNode,
|
type RoofNode,
|
||||||
type RoofSegmentEvent,
|
type RoofSegmentEvent,
|
||||||
@@ -691,6 +692,25 @@ const SELECTION_STRATEGIES: Record<string, SelectionStrategy> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getSelectionTarget = (node: AnyNode): SelectionTarget | null => {
|
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') {
|
if (node.type === 'zone') {
|
||||||
return {
|
return {
|
||||||
phase: 'structure',
|
phase: 'structure',
|
||||||
@@ -711,10 +731,7 @@ const getSelectionTarget = (node: AnyNode): SelectionTarget | null => {
|
|||||||
node.type === 'stair-segment' ||
|
node.type === 'stair-segment' ||
|
||||||
node.type === 'spawn' ||
|
node.type === 'spawn' ||
|
||||||
node.type === 'window' ||
|
node.type === 'window' ||
|
||||||
node.type === 'door' ||
|
node.type === 'door'
|
||||||
// Registry-driven kinds default to structure/elements (Phase 4 reads
|
|
||||||
// `definition.presentation.paletteSection` to route correctly).
|
|
||||||
isRegistrySelectable(node.type)
|
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
phase: 'structure',
|
phase: 'structure',
|
||||||
@@ -722,18 +739,16 @@ const getSelectionTarget = (node: AnyNode): SelectionTarget | null => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.type === 'item') {
|
// Registry-driven kinds (Phase 5+): route by `def.category`. Built-ins
|
||||||
const item = node as ItemNode
|
// above match before this fallback. Furnish-category kinds (shelf,
|
||||||
if (item.asset.category === 'door' || item.asset.category === 'window') {
|
// item — already handled above) land on the furnish phase; structure-
|
||||||
return {
|
// category kinds (everything else) on structure/elements.
|
||||||
phase: 'structure',
|
const def = nodeRegistry.get(node.type)
|
||||||
structureLayer: 'elements',
|
if (def) {
|
||||||
}
|
if (def.category === 'furnish') {
|
||||||
}
|
return { phase: 'furnish' }
|
||||||
|
|
||||||
return {
|
|
||||||
phase: 'furnish',
|
|
||||||
}
|
}
|
||||||
|
return { phase: 'structure', structureLayer: 'elements' }
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
|||||||
Reference in New Issue
Block a user