working ceiling items
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
type CeilingEvent,
|
||||
type CeilingNode,
|
||||
emitter,
|
||||
type GridEvent,
|
||||
ItemNode,
|
||||
@@ -112,7 +113,7 @@ export const ItemTool: React.FC = () => {
|
||||
const draftItem = useRef<ItemNode | null>(null)
|
||||
const gridPosition = useRef(new Vector3(0, 0, 0))
|
||||
const selectedItem = useEditor((state) => state.selectedItem)
|
||||
const { canPlaceOnFloor, canPlaceOnWall } = useSpatialQuery()
|
||||
const { canPlaceOnFloor, canPlaceOnWall, canPlaceOnCeiling } = useSpatialQuery()
|
||||
const isOnWall = useRef(false)
|
||||
const isOnCeiling = useRef(false)
|
||||
|
||||
@@ -129,7 +130,18 @@ export const ItemTool: React.FC = () => {
|
||||
if (currentLevelId && draftItem.current) {
|
||||
let placeable = true
|
||||
if (draftItem.current.asset.attachTo === 'ceiling') {
|
||||
placeable = isOnCeiling.current && !!currentCeilingId
|
||||
if (!isOnCeiling.current || !currentCeilingId) {
|
||||
placeable = false
|
||||
} else {
|
||||
const result = canPlaceOnCeiling(
|
||||
currentCeilingId as CeilingNode['id'],
|
||||
[gridPosition.current.x, gridPosition.current.y, gridPosition.current.z],
|
||||
draftItem.current.asset.dimensions,
|
||||
draftItem.current.rotation,
|
||||
[draftItem.current.id],
|
||||
)
|
||||
placeable = result.valid
|
||||
}
|
||||
} else if (draftItem.current.asset.attachTo) {
|
||||
if (!isOnWall.current || !currentWallId) {
|
||||
placeable = false
|
||||
@@ -541,7 +553,7 @@ export const ItemTool: React.FC = () => {
|
||||
emitter.off('ceiling:leave', onCeilingLeave)
|
||||
window.removeEventListener('keydown', onKeyDown)
|
||||
}
|
||||
}, [selectedItem, canPlaceOnFloor, canPlaceOnWall])
|
||||
}, [selectedItem, canPlaceOnFloor, canPlaceOnWall, canPlaceOnCeiling])
|
||||
|
||||
useFrame((_, delta) => {
|
||||
if (draftItem.current && !isOnWall.current && !isOnCeiling.current) {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { CeilingNode } from "@pascal-app/core";
|
||||
import { useViewer } from "@pascal-app/viewer";
|
||||
import { Square } from "lucide-react";
|
||||
import { TreeNodeWrapper } from "./tree-node";
|
||||
import { useState } from "react";
|
||||
import { TreeNode, TreeNodeWrapper } from "./tree-node";
|
||||
import { TreeNodeActions } from "./tree-node-actions";
|
||||
|
||||
interface CeilingTreeNodeProps {
|
||||
@@ -10,6 +11,7 @@ interface CeilingTreeNodeProps {
|
||||
}
|
||||
|
||||
export function CeilingTreeNode({ node, depth }: CeilingTreeNodeProps) {
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const isSelected = useViewer((state) => state.selection.selectedIds.includes(node.id));
|
||||
const isHovered = useViewer((state) => state.hoveredId === node.id);
|
||||
const setSelection = useViewer((state) => state.setSelection);
|
||||
@@ -35,16 +37,20 @@ export function CeilingTreeNode({ node, depth }: CeilingTreeNodeProps) {
|
||||
icon={<Square className="w-3.5 h-3.5" />}
|
||||
label={node.name || `Ceiling (${area}m²)`}
|
||||
depth={depth}
|
||||
hasChildren={false}
|
||||
expanded={false}
|
||||
onToggle={() => {}}
|
||||
hasChildren={node.children.length > 0}
|
||||
expanded={expanded}
|
||||
onToggle={() => setExpanded(!expanded)}
|
||||
onClick={handleClick}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
isSelected={isSelected}
|
||||
isHovered={isHovered}
|
||||
actions={<TreeNodeActions node={node} />}
|
||||
/>
|
||||
>
|
||||
{node.children.map((childId) => (
|
||||
<TreeNode key={childId} nodeId={childId} depth={depth + 1} />
|
||||
))}
|
||||
</TreeNodeWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user