Support duplicating and moving new walls
This commit is contained in:
@@ -14,7 +14,7 @@ import {
|
||||
StairSegmentNode,
|
||||
sceneRegistry,
|
||||
useScene,
|
||||
type WallNode,
|
||||
WallNode,
|
||||
WindowNode,
|
||||
} from '@pascal-app/core'
|
||||
import { useViewer } from '@pascal-app/viewer'
|
||||
@@ -210,6 +210,8 @@ export function FloatingActionMenu() {
|
||||
duplicate = WindowNode.parse(duplicateInfo)
|
||||
} else if (node.type === 'item') {
|
||||
duplicate = ItemNode.parse(duplicateInfo)
|
||||
} else if (node.type === 'wall') {
|
||||
duplicate = WallNode.parse(duplicateInfo)
|
||||
} else if (node.type === 'fence') {
|
||||
duplicate = FenceNode.parse(duplicateInfo)
|
||||
duplicate.start = [duplicate.start[0] + 1, duplicate.start[1] + 1]
|
||||
@@ -241,6 +243,8 @@ export function FloatingActionMenu() {
|
||||
if (duplicate) {
|
||||
if (duplicate.type === 'door' || duplicate.type === 'window') {
|
||||
useScene.getState().createNode(duplicate, duplicate.parentId as AnyNodeId)
|
||||
} else if (duplicate.type === 'wall') {
|
||||
useScene.getState().createNode(duplicate, duplicate.parentId as AnyNodeId)
|
||||
} else if (duplicate.type === 'fence') {
|
||||
useScene.getState().createNode(duplicate, duplicate.parentId as AnyNodeId)
|
||||
} else if (
|
||||
@@ -310,6 +314,7 @@ export function FloatingActionMenu() {
|
||||
}
|
||||
if (
|
||||
duplicate.type === 'item' ||
|
||||
duplicate.type === 'wall' ||
|
||||
duplicate.type === 'fence' ||
|
||||
duplicate.type === 'window' ||
|
||||
duplicate.type === 'door' ||
|
||||
|
||||
@@ -19,6 +19,16 @@ function samePoint(a: [number, number], b: [number, number]) {
|
||||
return a[0] === b[0] && a[1] === b[1]
|
||||
}
|
||||
|
||||
function stripWallIsNewMetadata(meta: WallNode['metadata']): WallNode['metadata'] {
|
||||
if (!meta || typeof meta !== 'object' || Array.isArray(meta)) {
|
||||
return meta
|
||||
}
|
||||
|
||||
const nextMeta = { ...(meta as Record<string, unknown>) }
|
||||
delete nextMeta.isNew
|
||||
return nextMeta
|
||||
}
|
||||
|
||||
type LinkedWallSnapshot = {
|
||||
id: WallNode['id']
|
||||
start: [number, number]
|
||||
@@ -86,6 +96,11 @@ function getLinkedWallUpdates(
|
||||
}
|
||||
|
||||
export const MoveWallTool: React.FC<{ node: WallNode }> = ({ node }) => {
|
||||
const meta =
|
||||
typeof node.metadata === 'object' && node.metadata !== null && !Array.isArray(node.metadata)
|
||||
? (node.metadata as Record<string, unknown>)
|
||||
: {}
|
||||
const isNew = !!meta.isNew
|
||||
const activatedAtRef = useRef<number>(Date.now())
|
||||
const previousGridPosRef = useRef<[number, number] | null>(null)
|
||||
const originalStartRef = useRef<[number, number]>([...node.start] as [number, number])
|
||||
@@ -99,7 +114,9 @@ export const MoveWallTool: React.FC<{ node: WallNode }> = ({ node }) => {
|
||||
(node.end[1] - node.start[1]) / 2,
|
||||
])
|
||||
const linkedOriginalsRef = useRef(
|
||||
getLinkedWallSnapshots({
|
||||
isNew
|
||||
? []
|
||||
: getLinkedWallSnapshots({
|
||||
wallId: node.id,
|
||||
wallParentId: node.parentId ?? null,
|
||||
originalStart: node.start,
|
||||
@@ -223,6 +240,11 @@ export const MoveWallTool: React.FC<{ node: WallNode }> = ({ node }) => {
|
||||
preview.end,
|
||||
),
|
||||
])
|
||||
if (isNew) {
|
||||
useScene.getState().updateNode(nodeId, {
|
||||
metadata: stripWallIsNewMetadata(node.metadata),
|
||||
})
|
||||
}
|
||||
useScene.temporal.getState().pause()
|
||||
|
||||
sfxEmitter.emit('sfx:item-place')
|
||||
@@ -295,7 +317,7 @@ export const MoveWallTool: React.FC<{ node: WallNode }> = ({ node }) => {
|
||||
window.removeEventListener('keydown', onKeyDown)
|
||||
window.removeEventListener('keyup', onKeyUp)
|
||||
}
|
||||
}, [exitMoveMode])
|
||||
}, [exitMoveMode, isNew, node.metadata])
|
||||
|
||||
return (
|
||||
<group>
|
||||
|
||||
Reference in New Issue
Block a user