added zone selection

This commit is contained in:
2025-09-26 16:44:37 +05:30
parent 9f4eb40d1d
commit 6ee922a760
7 changed files with 120 additions and 117 deletions

View File

@@ -96,25 +96,10 @@ const Outline: React.FC = () => {
) : (
<div className="outline-content-container">
{/* <section className="outline-section">
<DropDownList
value="Layers"
items={dropdownItems}
isOpen={isLayersOpen}
onToggle={() => setIsLayersOpen((prev) => !prev)}
showKebabMenu={false}
showFocusIcon={true}
remove
/>
</section> */}
<DropDownList value="Layers" items={dropdownItems} isOpen={isLayersOpen} onToggle={() => setIsLayersOpen((prev) => !prev)} showKebabMenu={false} showFocusIcon={true} remove />
</section> */}
<section className="outline-section overflow">
{/* <DropDownList
value="Buildings"
items={buildingsList}
isOpen={isBuildingsOpen}
onToggle={() => setIsBuildingsOpen((prev) => !prev)}
showKebabMenu={false}
showAddIcon={false}
/> */}
{/* <DropDownList value="Buildings" items={buildingsList} isOpen={isBuildingsOpen} onToggle={() => setIsBuildingsOpen((prev) => !prev)} showKebabMenu={false} showAddIcon={false} /> */}
<DropDownList value="Zones" items={sceneAssetsDataList} isOpen={isZonesOpen} onToggle={() => setIsZonesOpen((prev) => !prev)} showKebabMenu={false} showAddIcon={false} />
</section>
</div>

View File

@@ -4,70 +4,65 @@ import KebabMenuListMultiSelect from "./KebebMenuListMultiSelect";
import List from "./OutlineList/ListNew";
interface DropDownListProps {
value?: string;
items?: { id: string; name: string }[];
showFocusIcon?: boolean;
showAddIcon?: boolean;
showKebabMenu?: boolean;
kebabMenuItems?: { id: string; name: string }[];
remove?: boolean;
isOpen: boolean;
onToggle: () => void;
value?: string;
items?: { id: string; name: string }[];
showFocusIcon?: boolean;
showAddIcon?: boolean;
showKebabMenu?: boolean;
kebabMenuItems?: { id: string; name: string }[];
remove?: boolean;
isOpen: boolean;
onToggle: () => void;
}
const DropDownList: React.FC<DropDownListProps> = ({
value = "Dropdown",
items = [],
showFocusIcon = false,
showAddIcon = true,
showKebabMenu = true,
kebabMenuItems = [
{ id: "Buildings", name: "Buildings" },
{ id: "Paths", name: "Paths" },
{ id: "Zones", name: "Zones" },
],
remove,
isOpen,
onToggle,
value = "Dropdown",
items = [],
showFocusIcon = false,
showAddIcon = true,
showKebabMenu = true,
kebabMenuItems = [
{ id: "Buildings", name: "Buildings" },
{ id: "Paths", name: "Paths" },
{ id: "Zones", name: "Zones" },
],
remove,
isOpen,
onToggle,
}) => {
return (
<div className="dropdown-list-container">
<div className="head" onClick={onToggle}>
<div className="value">{value}</div>
<div className="options">
{showFocusIcon && (
<div className="focus option">
<FocusIcon />
return (
<div className="dropdown-list-container">
<div className="head" onClick={onToggle}>
<div className="value">{value}</div>
<div className="options">
{showFocusIcon && (
<div className="focus option">
<FocusIcon />
</div>
)}
{showAddIcon && (
<div className="add option">
<AddIcon />
</div>
)}
{showKebabMenu && (
<div className="kebab-menu option">
<KebabMenuListMultiSelect items={kebabMenuItems} />
</div>
)}
<button id="collapse-btn" title="collapse-btn" className="collapse-icon option" style={{ transform: isOpen ? "rotate(0deg)" : "rotate(-90deg)" }}>
<ArrowIcon />
</button>
</div>
</div>
)}
{showAddIcon && (
<div className="add option">
<AddIcon />
</div>
)}
{showKebabMenu && (
<div className="kebab-menu option">
<KebabMenuListMultiSelect items={kebabMenuItems} />
</div>
)}
<button
id="collapse-btn"
title="collapse-btn"
className="collapse-icon option"
style={{ transform: isOpen ? "rotate(0deg)" : "rotate(-90deg)" }}
>
<ArrowIcon />
</button>
</div>
</div>
{isOpen && (
<div className="lists-container">
<List items={items} remove={remove} />
{isOpen && (
<div className="lists-container">
<List items={items} remove={remove} />
</div>
)}
</div>
)}
</div>
);
);
};
export default DropDownList;

View File

@@ -6,44 +6,39 @@ import { useZoneAssetHandlers } from "../../../../functions/outlineHelpers/useZo
import { useZonesExpansion } from "../../../../functions/outlineHelpers/useZonesExpansion";
const List: React.FC<ListProps> = ({ items = [], remove }) => {
const { selectedZone } = useSelectedZoneStore();
const { zoneAssetId } = useZoneAssetId();
const { expandedZones, toggleZoneExpansion } = useZonesExpansion(items);
const { selectedZone } = useSelectedZoneStore();
const { zoneAssetId } = useZoneAssetId();
const { expandedZones, toggleZoneExpansion } = useZonesExpansion(items);
const {
handleSelectZone,
handleZoneNameChange,
handleAssetClick,
handleZoneAssetName,
} = useZoneAssetHandlers();
const { handleSelectZone, handleZoneNameChange, handleAssetClick, handleZoneAssetName } = useZoneAssetHandlers();
if (items.length === 0) {
return (
<div className="list-wrapper">
<div className="no-item">No items to display</div>
</div>
);
}
if (items.length === 0) {
return (
<div className="list-wrapper">
<div className="no-item">No items to display</div>
</div>
<ul className="list-wrapper">
{items.map((item) => (
<ZoneItemComponent
key={item.id}
item={item}
remove={remove}
expanded={expandedZones[item.id]}
isActive={selectedZone.zoneUuid === item.id}
activeAssetId={zoneAssetId?.id}
onSelect={handleSelectZone}
onRename={handleZoneNameChange}
onToggleExpand={toggleZoneExpansion}
onAssetClick={handleAssetClick}
onAssetRename={handleZoneAssetName}
/>
))}
</ul>
);
}
return (
<ul className="list-wrapper">
{items.map((item) => (
<ZoneItemComponent
key={item.id}
item={item}
remove={remove}
expanded={expandedZones[item.id]}
isActive={selectedZone.zoneUuid === item.id}
activeAssetId={zoneAssetId?.id}
onSelect={handleSelectZone}
onRename={handleZoneNameChange}
onToggleExpand={toggleZoneExpansion}
onAssetClick={handleAssetClick}
onAssetRename={handleZoneAssetName}
/>
))}
</ul>
);
};
export default List;

View File

@@ -5,6 +5,7 @@ import { useBuilderStore } from "../../../../../store/builder/useBuilderStore";
import { useToggleView } from "../../../../../store/builder/store";
import * as Constants from "../../../../../types/world/worldConstants";
import ExtrudePolygon from "../../../wrappers/geomentry/extrudePolygon";
import DecalInstance from "../../../Decal/decalInstance/decalInstance";
import texturePath from "../../../../../assets/textures/floor/white.png";
@@ -26,7 +27,6 @@ import material4Map from "../../../../../assets/textures/floor/tex3/metal_plate_
import material4RoughnessMap from "../../../../../assets/textures/floor/tex3/metal_plate_rough_1k.png";
import material4MetalicMap from "../../../../../assets/textures/floor/tex3/metal_plate_metal_1k.png";
import material4NormalMap from "../../../../../assets/textures/floor/tex3/metal_plate_nor_gl_1k.png";
import ExtrudePolygon from "../../../wrappers/geomentry/extrudePolygon";
function FloorInstance({ floor }: { readonly floor: Floor }) {
const { toggleView } = useToggleView();

View File

@@ -1,14 +1,37 @@
import { Vector3 } from "three";
import ZoneCornerReference from "./zoneCornerReference";
import { useRef } from "react";
import { Group, Vector3 } from "three";
import useModuleStore from "../../../../../store/ui/useModuleStore";
import { useToggleView } from "../../../../../store/builder/store";
import { useBuilderStore } from "../../../../../store/builder/useBuilderStore";
import ExtrudePolygon from "../../../wrappers/geomentry/extrudePolygon";
import PlaneMaterial from "../../../wrappers/materials/planeMaterial";
import PolygonMaterial from "../../../wrappers/materials/polygonMaterial";
import ZoneCornerReference from "./zoneCornerReference";
function ZoneInstance({ zone }: { readonly zone: Zone }) {
const { toggleView } = useToggleView();
const { activeModule } = useModuleStore();
const { selectedZone, setSelectedZone } = useBuilderStore();
const groupRef = useRef<Group>(null);
const zoneLayer = zone.points[0].layer;
return (
<group name={`Zone-${zone.zoneUuid}`} userData={zone}>
<group
ref={groupRef}
name={`Zone-${zone.zoneUuid}`}
userData={zone}
onDoubleClick={(e) => {
if (!toggleView && activeModule === "builder") {
e.stopPropagation();
setSelectedZone({ zoneData: zone, zoneMesh: groupRef.current });
}
}}
onPointerMissed={() => {
if (selectedZone && selectedZone.zoneMesh?.userData.zoneUuid === zone.zoneUuid) {
setSelectedZone(null);
}
}}
>
<ExtrudePolygon options={{ depth: 0, bevelEnabled: false }} points={zone.points}>
<PolygonMaterial
transparent

View File

@@ -14,7 +14,7 @@ function OutlineInstances() {
const { deletableEventSphere } = useDeletableEventSphere();
const {assetStore} = useSceneContext();
const {selectedAssets} = assetStore();
const { selectedAisle, selectedWall, selectedDecal, selectedFloor, selectedWallAsset, deletableWallAsset, deletableFloorAsset, deletableDecal } = useBuilderStore();
const { selectedAisle, selectedWall, selectedDecal, selectedFloor, selectedWallAsset, selectedZone, deletableWallAsset, deletableFloorAsset, deletableDecal } = useBuilderStore();
return (
<>
@@ -56,6 +56,11 @@ function OutlineInstances() {
selection={selectedFloor?.floorMesh ? [selectedFloor.floorMesh] : null}
color={CONSTANTS.outlineConfig.assetSelectColor}
/>
<OutlineInstance
key="selectedZone"
selection={selectedZone?.zoneMesh ? flattenChildren(selectedZone.zoneMesh.children) : null}
color={CONSTANTS.outlineConfig.assetSelectColor}
/>
{/* Decals */}
<OutlineInstance

View File

@@ -33,7 +33,7 @@ interface BuilderState {
topMaterial: string;
// Zone Settings
selectedZone: Object3D | null;
selectedZone: { zoneMesh: Object3D | null; zoneData: Zone } | null;
zoneHeight: number;
zoneColor: string;
@@ -94,7 +94,7 @@ interface BuilderState {
setFloorMaterial: (material: string, side: "side" | "top") => void;
// Setters - Zone
setSelectedZone: (zone: Object3D | null) => void;
setSelectedZone: (zone: { zoneMesh: Object3D | null; zoneData: Zone } | null) => void;
setZoneHeight: (height: number) => void;
setZoneColor: (color: string) => void;
@@ -292,7 +292,7 @@ export const useBuilderStore = create<BuilderState>()(
// === Setters: Zone ===
setSelectedZone: (zone: Object3D | null) => {
setSelectedZone: (zone: { zoneMesh: Object3D | null; zoneData: Zone } | null) => {
set((state) => {
state.selectedZone = zone;
});