added zone selection
This commit is contained in:
@@ -96,25 +96,10 @@ const Outline: React.FC = () => {
|
|||||||
) : (
|
) : (
|
||||||
<div className="outline-content-container">
|
<div className="outline-content-container">
|
||||||
{/* <section className="outline-section">
|
{/* <section className="outline-section">
|
||||||
<DropDownList
|
<DropDownList value="Layers" items={dropdownItems} isOpen={isLayersOpen} onToggle={() => setIsLayersOpen((prev) => !prev)} showKebabMenu={false} showFocusIcon={true} remove />
|
||||||
value="Layers"
|
</section> */}
|
||||||
items={dropdownItems}
|
|
||||||
isOpen={isLayersOpen}
|
|
||||||
onToggle={() => setIsLayersOpen((prev) => !prev)}
|
|
||||||
showKebabMenu={false}
|
|
||||||
showFocusIcon={true}
|
|
||||||
remove
|
|
||||||
/>
|
|
||||||
</section> */}
|
|
||||||
<section className="outline-section overflow">
|
<section className="outline-section overflow">
|
||||||
{/* <DropDownList
|
{/* <DropDownList value="Buildings" items={buildingsList} isOpen={isBuildingsOpen} onToggle={() => setIsBuildingsOpen((prev) => !prev)} showKebabMenu={false} showAddIcon={false} /> */}
|
||||||
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} />
|
<DropDownList value="Zones" items={sceneAssetsDataList} isOpen={isZonesOpen} onToggle={() => setIsZonesOpen((prev) => !prev)} showKebabMenu={false} showAddIcon={false} />
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,70 +4,65 @@ import KebabMenuListMultiSelect from "./KebebMenuListMultiSelect";
|
|||||||
import List from "./OutlineList/ListNew";
|
import List from "./OutlineList/ListNew";
|
||||||
|
|
||||||
interface DropDownListProps {
|
interface DropDownListProps {
|
||||||
value?: string;
|
value?: string;
|
||||||
items?: { id: string; name: string }[];
|
items?: { id: string; name: string }[];
|
||||||
showFocusIcon?: boolean;
|
showFocusIcon?: boolean;
|
||||||
showAddIcon?: boolean;
|
showAddIcon?: boolean;
|
||||||
showKebabMenu?: boolean;
|
showKebabMenu?: boolean;
|
||||||
kebabMenuItems?: { id: string; name: string }[];
|
kebabMenuItems?: { id: string; name: string }[];
|
||||||
remove?: boolean;
|
remove?: boolean;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onToggle: () => void;
|
onToggle: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DropDownList: React.FC<DropDownListProps> = ({
|
const DropDownList: React.FC<DropDownListProps> = ({
|
||||||
value = "Dropdown",
|
value = "Dropdown",
|
||||||
items = [],
|
items = [],
|
||||||
showFocusIcon = false,
|
showFocusIcon = false,
|
||||||
showAddIcon = true,
|
showAddIcon = true,
|
||||||
showKebabMenu = true,
|
showKebabMenu = true,
|
||||||
kebabMenuItems = [
|
kebabMenuItems = [
|
||||||
{ id: "Buildings", name: "Buildings" },
|
{ id: "Buildings", name: "Buildings" },
|
||||||
{ id: "Paths", name: "Paths" },
|
{ id: "Paths", name: "Paths" },
|
||||||
{ id: "Zones", name: "Zones" },
|
{ id: "Zones", name: "Zones" },
|
||||||
],
|
],
|
||||||
remove,
|
remove,
|
||||||
isOpen,
|
isOpen,
|
||||||
onToggle,
|
onToggle,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="dropdown-list-container">
|
<div className="dropdown-list-container">
|
||||||
<div className="head" onClick={onToggle}>
|
<div className="head" onClick={onToggle}>
|
||||||
<div className="value">{value}</div>
|
<div className="value">{value}</div>
|
||||||
<div className="options">
|
<div className="options">
|
||||||
{showFocusIcon && (
|
{showFocusIcon && (
|
||||||
<div className="focus option">
|
<div className="focus option">
|
||||||
<FocusIcon />
|
<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>
|
</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 && (
|
{isOpen && (
|
||||||
<div className="lists-container">
|
<div className="lists-container">
|
||||||
<List items={items} remove={remove} />
|
<List items={items} remove={remove} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
);
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DropDownList;
|
export default DropDownList;
|
||||||
|
|||||||
@@ -6,44 +6,39 @@ import { useZoneAssetHandlers } from "../../../../functions/outlineHelpers/useZo
|
|||||||
import { useZonesExpansion } from "../../../../functions/outlineHelpers/useZonesExpansion";
|
import { useZonesExpansion } from "../../../../functions/outlineHelpers/useZonesExpansion";
|
||||||
|
|
||||||
const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
||||||
const { selectedZone } = useSelectedZoneStore();
|
const { selectedZone } = useSelectedZoneStore();
|
||||||
const { zoneAssetId } = useZoneAssetId();
|
const { zoneAssetId } = useZoneAssetId();
|
||||||
const { expandedZones, toggleZoneExpansion } = useZonesExpansion(items);
|
const { expandedZones, toggleZoneExpansion } = useZonesExpansion(items);
|
||||||
|
|
||||||
const {
|
const { handleSelectZone, handleZoneNameChange, handleAssetClick, handleZoneAssetName } = useZoneAssetHandlers();
|
||||||
handleSelectZone,
|
|
||||||
handleZoneNameChange,
|
if (items.length === 0) {
|
||||||
handleAssetClick,
|
return (
|
||||||
handleZoneAssetName,
|
<div className="list-wrapper">
|
||||||
} = useZoneAssetHandlers();
|
<div className="no-item">No items to display</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (items.length === 0) {
|
|
||||||
return (
|
return (
|
||||||
<div className="list-wrapper">
|
<ul className="list-wrapper">
|
||||||
<div className="no-item">No items to display</div>
|
{items.map((item) => (
|
||||||
</div>
|
<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;
|
export default List;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { useBuilderStore } from "../../../../../store/builder/useBuilderStore";
|
|||||||
import { useToggleView } from "../../../../../store/builder/store";
|
import { useToggleView } from "../../../../../store/builder/store";
|
||||||
import * as Constants from "../../../../../types/world/worldConstants";
|
import * as Constants from "../../../../../types/world/worldConstants";
|
||||||
|
|
||||||
|
import ExtrudePolygon from "../../../wrappers/geomentry/extrudePolygon";
|
||||||
import DecalInstance from "../../../Decal/decalInstance/decalInstance";
|
import DecalInstance from "../../../Decal/decalInstance/decalInstance";
|
||||||
|
|
||||||
import texturePath from "../../../../../assets/textures/floor/white.png";
|
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 material4RoughnessMap from "../../../../../assets/textures/floor/tex3/metal_plate_rough_1k.png";
|
||||||
import material4MetalicMap from "../../../../../assets/textures/floor/tex3/metal_plate_metal_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 material4NormalMap from "../../../../../assets/textures/floor/tex3/metal_plate_nor_gl_1k.png";
|
||||||
import ExtrudePolygon from "../../../wrappers/geomentry/extrudePolygon";
|
|
||||||
|
|
||||||
function FloorInstance({ floor }: { readonly floor: Floor }) {
|
function FloorInstance({ floor }: { readonly floor: Floor }) {
|
||||||
const { toggleView } = useToggleView();
|
const { toggleView } = useToggleView();
|
||||||
|
|||||||
@@ -1,14 +1,37 @@
|
|||||||
import { Vector3 } from "three";
|
import { useRef } from "react";
|
||||||
import ZoneCornerReference from "./zoneCornerReference";
|
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 ExtrudePolygon from "../../../wrappers/geomentry/extrudePolygon";
|
||||||
import PlaneMaterial from "../../../wrappers/materials/planeMaterial";
|
import PlaneMaterial from "../../../wrappers/materials/planeMaterial";
|
||||||
import PolygonMaterial from "../../../wrappers/materials/polygonMaterial";
|
import PolygonMaterial from "../../../wrappers/materials/polygonMaterial";
|
||||||
|
import ZoneCornerReference from "./zoneCornerReference";
|
||||||
|
|
||||||
function ZoneInstance({ zone }: { readonly zone: Zone }) {
|
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;
|
const zoneLayer = zone.points[0].layer;
|
||||||
|
|
||||||
return (
|
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}>
|
<ExtrudePolygon options={{ depth: 0, bevelEnabled: false }} points={zone.points}>
|
||||||
<PolygonMaterial
|
<PolygonMaterial
|
||||||
transparent
|
transparent
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ function OutlineInstances() {
|
|||||||
const { deletableEventSphere } = useDeletableEventSphere();
|
const { deletableEventSphere } = useDeletableEventSphere();
|
||||||
const {assetStore} = useSceneContext();
|
const {assetStore} = useSceneContext();
|
||||||
const {selectedAssets} = assetStore();
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -56,6 +56,11 @@ function OutlineInstances() {
|
|||||||
selection={selectedFloor?.floorMesh ? [selectedFloor.floorMesh] : null}
|
selection={selectedFloor?.floorMesh ? [selectedFloor.floorMesh] : null}
|
||||||
color={CONSTANTS.outlineConfig.assetSelectColor}
|
color={CONSTANTS.outlineConfig.assetSelectColor}
|
||||||
/>
|
/>
|
||||||
|
<OutlineInstance
|
||||||
|
key="selectedZone"
|
||||||
|
selection={selectedZone?.zoneMesh ? flattenChildren(selectedZone.zoneMesh.children) : null}
|
||||||
|
color={CONSTANTS.outlineConfig.assetSelectColor}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Decals */}
|
{/* Decals */}
|
||||||
<OutlineInstance
|
<OutlineInstance
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ interface BuilderState {
|
|||||||
topMaterial: string;
|
topMaterial: string;
|
||||||
|
|
||||||
// Zone Settings
|
// Zone Settings
|
||||||
selectedZone: Object3D | null;
|
selectedZone: { zoneMesh: Object3D | null; zoneData: Zone } | null;
|
||||||
zoneHeight: number;
|
zoneHeight: number;
|
||||||
zoneColor: string;
|
zoneColor: string;
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ interface BuilderState {
|
|||||||
setFloorMaterial: (material: string, side: "side" | "top") => void;
|
setFloorMaterial: (material: string, side: "side" | "top") => void;
|
||||||
|
|
||||||
// Setters - Zone
|
// Setters - Zone
|
||||||
setSelectedZone: (zone: Object3D | null) => void;
|
setSelectedZone: (zone: { zoneMesh: Object3D | null; zoneData: Zone } | null) => void;
|
||||||
setZoneHeight: (height: number) => void;
|
setZoneHeight: (height: number) => void;
|
||||||
setZoneColor: (color: string) => void;
|
setZoneColor: (color: string) => void;
|
||||||
|
|
||||||
@@ -292,7 +292,7 @@ export const useBuilderStore = create<BuilderState>()(
|
|||||||
|
|
||||||
// === Setters: Zone ===
|
// === Setters: Zone ===
|
||||||
|
|
||||||
setSelectedZone: (zone: Object3D | null) => {
|
setSelectedZone: (zone: { zoneMesh: Object3D | null; zoneData: Zone } | null) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.selectedZone = zone;
|
state.selectedZone = zone;
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user