Merge branch 'main' into simulation-animation

This commit is contained in:
SreeNath14
2025-04-10 17:52:30 +05:30
25 changed files with 441 additions and 217 deletions

View File

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

View File

@@ -1,16 +1,20 @@
import React, { useEffect, useMemo, useState } from "react";
import Search from "../../ui/inputs/Search";
import vehicle from "../../../assets/image/vehicles.png";
import workStation from "../../../assets/image/workStation.png";
import machines from "../../../assets/image/machines.png";
import feneration from "../../../assets/image/feneration.png";
import worker from "../../../assets/image/worker.png";
import { getCategoryAsset } from "../../../services/factoryBuilder/assest/assets/getCategoryAsset";
import arch from "../../../assets/gltf-glb/arch.glb";
import door from "../../../assets/gltf-glb/door.glb";
import window from "../../../assets/gltf-glb/window.glb";
import { fetchAssets } from "../../../services/marketplace/fetchAssets";
import { useSelectedItem } from "../../../store/store";
// images -------------------
import vehicle from "../../../assets/image/categories/vehicles.png";
import workStation from "../../../assets/image/categories/workStation.png";
import machines from "../../../assets/image/categories/machines.png";
import feneration from "../../../assets/image/categories/feneration.png";
import worker from "../../../assets/image/categories/worker.png";
// -------------------------------------
interface AssetProp {
filename: string;
thumbnail?: string;

View File

@@ -115,17 +115,10 @@ const Tools: React.FC = () => {
setOpenDrop(false); // Close the dropdown
}
};
const handleEscKeyPress = (event: KeyboardEvent) => {
if (event.key === "Escape") {
setIsPlaying(false); // Set isPlaying to false when Escape key is pressed
}
};
document.addEventListener("mousedown", handleOutsideClick);
document.addEventListener("keydown", handleEscKeyPress); // Listen for ESC key
return () => {
document.removeEventListener("mousedown", handleOutsideClick);
document.removeEventListener("keydown", handleEscKeyPress); // Clean up the event listener
};
}, []);
useEffect(() => {

View File

@@ -5,6 +5,7 @@ import { useCamMode, useToggleView } from '../../../store/store';
import { useKeyboardControls } from '@react-three/drei';
import switchToThirdPerson from './switchToThirdPerson';
import switchToFirstPerson from './switchToFirstPerson';
import { detectModifierKeys } from '../../../utils/shortcutkeys/detectModifierKeys';
const CamMode: React.FC = () => {
const { camMode, setCamMode } = useCamMode();
@@ -37,7 +38,9 @@ const CamMode: React.FC = () => {
const handleKeyPress = async (event: any) => {
if (!state.controls) return;
if (event.key === "/" && !isTransitioning && !toggleView) {
const keyCombination = detectModifierKeys(event);
if (keyCombination === "/" && !isTransitioning && !toggleView) {
setIsTransitioning(true);
state.controls.mouseButtons.left = CONSTANTS.controlsTransition.leftMouse;
state.controls.mouseButtons.right = CONSTANTS.controlsTransition.rightMouse;
@@ -81,9 +84,7 @@ const CamMode: React.FC = () => {
}
});
return (
<></>
);
return null; // This component does not render any UI
};
export default CamMode;

View File

@@ -5,6 +5,7 @@ import { useFloorItems, useSelectedAssets, useSimulationStates, useSocketStore,
import { toast } from "react-toastify";
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
import * as Types from "../../../../types/world/worldTypes";
import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys";
const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, selectionGroup, setDuplicatedObjects, movedObjects, setMovedObjects, rotatedObjects, setRotatedObjects, boundingBoxRef }: any) => {
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
@@ -38,10 +39,12 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
};
const onKeyDown = (event: KeyboardEvent) => {
if (event.ctrlKey && event.key.toLowerCase() === "c" && movedObjects.length === 0 && rotatedObjects.length === 0) {
const keyCombination = detectModifierKeys(event);
if (keyCombination === "Ctrl+C" && movedObjects.length === 0 && rotatedObjects.length === 0) {
copySelection();
}
if (event.ctrlKey && event.key.toLowerCase() === "v" && copiedObjects.length > 0 && pastedObjects.length === 0 && movedObjects.length === 0 && rotatedObjects.length === 0) {
if (keyCombination === "Ctrl+V" && copiedObjects.length > 0 && pastedObjects.length === 0 && movedObjects.length === 0 && rotatedObjects.length === 0) {
pasteCopiedObjects();
}
};
@@ -570,9 +573,7 @@ const CopyPasteControls = ({ itemsGroupRef, copiedObjects, setCopiedObjects, pas
setSelectedAssets([]);
}
return (
<></>
);
return null; // No visible output, but the component handles copy-paste functionality
};
export default CopyPasteControls;

View File

@@ -6,6 +6,7 @@ import { toast } from "react-toastify";
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
import * as Types from "../../../../types/world/worldTypes";
import { setFloorItemApi } from "../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi";
import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys";
const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedObjects, setpastedObjects, selectionGroup, movedObjects, setMovedObjects, rotatedObjects, setRotatedObjects, boundingBoxRef }: any) => {
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
@@ -39,12 +40,11 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
};
const onKeyDown = (event: KeyboardEvent) => {
if (event.key.toLowerCase() === "d") {
event.preventDefault();
if (event.ctrlKey && event.key.toLowerCase() === "d" && selectedAssets.length > 0 && duplicatedObjects.length === 0 && movedObjects.length === 0 && rotatedObjects.length === 0) {
const keyCombination = detectModifierKeys(event);
if (keyCombination === "Ctrl+D" && selectedAssets.length > 0 && duplicatedObjects.length === 0 && movedObjects.length === 0 && rotatedObjects.length === 0) {
duplicateSelection();
}
}
};
if (!toggleView) {
@@ -552,9 +552,7 @@ const DuplicationControls = ({ itemsGroupRef, duplicatedObjects, setDuplicatedOb
setSelectedAssets([]);
}
return (
<></>
);
return null; // This component does not render any UI
};
export default DuplicationControls;

View File

@@ -5,6 +5,7 @@ import { useFloorItems, useSelectedAssets, useSimulationStates, useSocketStore,
// import { setFloorItemApi } from '../../../../services/factoryBuilder/assest/floorAsset/setFloorItemApi';
import { toast } from "react-toastify";
import * as Types from "../../../../types/world/worldTypes";
import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys";
function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObjects, setCopiedObjects, pastedObjects, setpastedObjects, duplicatedObjects, setDuplicatedObjects, selectionGroup, rotatedObjects, setRotatedObjects, boundingBoxRef }: any) {
const { camera, controls, gl, scene, pointer, raycaster } = useThree();
@@ -56,14 +57,16 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
};
const onKeyDown = (event: KeyboardEvent) => {
const keyCombination = detectModifierKeys(event);
if (pastedObjects.length > 0 || duplicatedObjects.length > 0 || rotatedObjects.length > 0) return;
if (event.key.toLowerCase() === "g") {
if (keyCombination === "G") {
if (selectedAssets.length > 0) {
moveAssets();
itemsData.current = floorItems.filter((item: { modeluuid: string }) => selectedAssets.some((asset: any) => asset.uuid === item.modeluuid));
}
}
if (event.key.toLowerCase() === "escape") {
if (keyCombination === "ESCAPE") {
event.preventDefault();
clearSelection();
@@ -453,9 +456,7 @@ function MoveControls({ movedObjects, setMovedObjects, itemsGroupRef, copiedObje
setSelectedAssets([]);
}
return (
<></>
)
return null; // No need to return anything, as this component is used for its side effects
}
export default MoveControls

View File

@@ -457,9 +457,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
setSelectedAssets([]);
}
return (
<></>
)
return null; // No need to return anything, as this component is used for its side effects
}
export default RotateControls

View File

@@ -14,6 +14,7 @@ import CopyPasteControls from "./copyPasteControls";
import MoveControls from "./moveControls";
import RotateControls from "./rotateControls";
import useModuleStore from "../../../../store/useModuleStore";
import { detectModifierKeys } from "../../../../utils/shortcutkeys/detectModifierKeys";
const SelectionControls: React.FC = () => {
const { camera, controls, gl, scene, pointer } = useThree();
@@ -101,12 +102,13 @@ const SelectionControls: React.FC = () => {
};
const onKeyDown = (event: KeyboardEvent) => {
const keyCombination = detectModifierKeys(event);
if (movedObjects.length > 0 || rotatedObjects.length > 0) return;
if (event.key.toLowerCase() === "escape") {
if (keyCombination === "ESCAPE") {
event.preventDefault();
clearSelection();
}
if (event.key.toLowerCase() === "delete") {
if (keyCombination === "DELETE") {
event.preventDefault();
deleteSelection();
}

View File

@@ -16,6 +16,7 @@ import { useFrame, useThree } from "@react-three/fiber";
import { useSubModuleStore } from "../../../store/useModuleStore";
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
import { setEventApi } from "../../../services/factoryBuilder/assest/floorAsset/setEventsApt";
import { detectModifierKeys } from "../../../utils/shortcutkeys/detectModifierKeys";
function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObject<THREE.Group>; }) {
const { isPlaying } = usePlayButtonStore();
@@ -40,11 +41,12 @@ function PathCreation({ pathsGroupRef, }: { pathsGroupRef: React.MutableRefObjec
useEffect(() => {
setTransformMode(null);
const handleKeyDown = (e: KeyboardEvent) => {
const keyCombination = detectModifierKeys(e);
if (!selectedActionSphere) return;
if (e.key === "g") {
if (keyCombination === "G") {
setTransformMode((prev) => (prev === "translate" ? null : "translate"));
}
if (e.key === "r") {
if (keyCombination === "R") {
setTransformMode((prev) => (prev === "rotate" ? null : "rotate"));
}
};

View File

@@ -9,3 +9,25 @@
justify-content: space-between;
align-items: center;
}
// Array of base colors
$colors: (
#f5550b,
#1bac1b,
#0099ff,
#d4c927,
#8400ff,
#13e9b3,
#df1dcf
);
@mixin gradient-by-child($index) {
// Get the color based on the index passed
$base-color: nth($colors, $index);
// Apply gradient using the same color with different alpha values
background: linear-gradient(
144.19deg,
rgba($base-color, 0.2) 16.62%, // 20% opacity
rgba($base-color, 0.08) 85.81% // 80% opacity
);
}

View File

@@ -7,14 +7,28 @@ input {
width: 100%;
padding: 2px 4px;
border-radius: #{$border-radius-small};
border: 1px solid var(--border-color);
outline: none;
outline: 2px solid var(--border-color);
outline-offset: -2px;
border: none;
background: transparent;
color: var(--input-text-color);
&:focus,
&:active {
border: 1px solid var(--accent-color);
outline: 1px solid var(--accent-color);
}
&:-webkit-autofill,
&:-webkit-autofill:hover,
&:-webkit-autofill:focus,
&:-webkit-autofill:active {
// Text styles
-webkit-text-fill-color: var(--input-text-color) !important;
caret-color: var(--input-text-color);
// Background styles
background-color: var(--background-color) !important;
-webkit-box-shadow: 0 0 0px 1000px var(--background-color) inset !important;
}
}
@@ -615,6 +629,7 @@ input {
input {
border: none;
outline: none;
background: transparent;
&::placeholder {

View File

@@ -78,19 +78,19 @@
min-height: 50vh;
max-height: 60vh;
}
.template-item {
border: 1px solid #e0e0e0;
border-radius: 8px;
padding: 1rem;
transition: box-shadow 0.3s ease;
}
.template-image-container {
position: relative;
padding-bottom: 56.25%; // 16:9 aspect ratio
}
.template-image {
position: absolute;
width: 100%;
@@ -100,19 +100,19 @@
cursor: pointer;
transition: transform 0.3s ease;
}
.template-details {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 0.5rem;
}
.template-name {
cursor: pointer;
font-weight: 500;
}
.delete-button {
padding: 0.25rem 0.5rem;
background: #ff4444;
@@ -122,14 +122,13 @@
cursor: pointer;
transition: opacity 0.3s ease;
}
.no-templates {
text-align: center;
color: #666;
padding: 2rem;
grid-column: 1 / -1;
}
.widget-left-sideBar {
min-height: 50vh;
@@ -538,7 +537,6 @@
.floating {
width: 100%;
}
}
@@ -1070,24 +1068,62 @@
.category-name {
position: relative;
z-index: 3;
font-size: var(--font-size-large);
font-size: var(--font-size-regular);
// -webkit-text-fill-color: transparent;
// -webkit-text-stroke: 1px black;
}
&::after {
content: "";
width: 50px;
height: 50px;
width: 60px;
height: 60px;
border-radius: 50%;
background-color: var(--circle-color, #000);
position: absolute;
top: 50%;
top: 60%;
right: -10px;
transform: translate(0, -50%);
background: linear-gradient(144.19deg,
#f1e7cd 16.62%,
#fffaef 85.81%);
}
&:nth-child(1), &:nth-child(9) {
&::after {
@include gradient-by-child(1); // First child uses the first color
}
}
&:nth-child(2), &:nth-child(10) {
&::after {
@include gradient-by-child(2); // Second child uses the second color
}
}
&:nth-child(3), &:nth-child(11) {
&::after {
@include gradient-by-child(3); // Third child uses the third color
}
}
&:nth-child(4), &:nth-child(12) {
&::after {
@include gradient-by-child(4); // Fourth child uses the fourth color
}
}
&:nth-child(5), &:nth-child(13) {
&::after {
@include gradient-by-child(5); // Fifth child uses the fifth color
}
}
&:nth-child(6), &:nth-child(14) {
&::after {
@include gradient-by-child(6); // Fifth child uses the fifth color
}
}
&:nth-child(7), &:nth-child(15) {
&::after {
@include gradient-by-child(7); // Fifth child uses the fifth color
}
}
.category-image {
@@ -1114,30 +1150,47 @@
.assets {
width: 117px;
height: 95px;
border-radius: 3.59px;
border-radius: #{$border-radius-small};
background-color: var(--background-color-gray);
padding: 8px;
padding-top: 12px;
font-weight: $medium-weight;
position: relative;
overflow: hidden;
padding: 0;
&:hover {
.asset-name {
opacity: 1;
}
}
.asset-name {
position: relative;
position: absolute;
top: 0;
z-index: 3;
padding: 8px;
width: 100%;
font-size: var(--font-size-regular);
background: color-mix(
in srgb,
var(--background-color) 40%,
transparent
);
backdrop-filter: blur(5px);
opacity: 0;
transition: opacity 0.3s ease;
/* Added properties for ellipsis */
display: -webkit-box; /* Necessary for multiline truncation */
-webkit-line-clamp: 2; /* Number of lines to show */
-webkit-box-orient: vertical; /* Box orientation for the ellipsis */
overflow: hidden; /* Hide overflowing content */
text-overflow: ellipsis; /* Add ellipsis for truncated content */
}
.asset-image {
height: 100%;
width: 100%;
position: absolute;
// top: 50%;
// right: 5px;
// transform: translate(0, -50%);
top: 0;
left: 0;
z-index: 2;
object-fit: cover;
}
}
}
@@ -1200,4 +1253,4 @@
.assets-wrapper {
margin: 0;
}
}
}

View File

@@ -765,20 +765,19 @@
.editWidgetOptions {
position: absolute;
// top: 50%;
// left: 50%;
// transform: translate(-50%, -50%);
background-color: var(--background-color);
z-index: 3;
display: flex;
flex-direction: column;
border-radius: 6px;
overflow: hidden;
padding: 4px;
min-width: 150px;
.option {
padding: 8px 10px;
padding: 4px 10px;
border-radius: #{$border-radius-small};
color: var(--text-color);
cursor: pointer;
@@ -791,7 +790,8 @@
color: #f65648;
&:hover {
background-color: #ffe3e0;
background-color: #f65648;
color: white;
}
}
}

View File

@@ -0,0 +1,30 @@
// Function to detect if Shift, Ctrl, Alt, or combinations are pressed
// and return the corresponding key combination string
export const detectModifierKeys = (event: KeyboardEvent): string => {
const modifiers = [
event.ctrlKey ? "Ctrl" : "",
event.altKey ? "Alt" : "",
event.shiftKey ? "Shift" : "",
event.metaKey ? "Meta" : "" // Add support for Command/Win key
].filter(Boolean);
// Ignore modifier keys when they're pressed alone
const isModifierKey = [
"Control", "Shift", "Alt", "Meta",
"Ctrl", "AltGraph", "OS" // Additional modifier key aliases
].includes(event.key);
const mainKey = isModifierKey ? "" : event.key.toUpperCase();
// Handle special cases for keys with different representations
const normalizedKey = mainKey === " " ? "Space" : mainKey;
// Build the combination string
if (modifiers.length > 0 && normalizedKey) {
return `${modifiers.join("+")}+${normalizedKey}`;
} else if (modifiers.length > 0) {
return modifiers.join("+");
} else {
return normalizedKey;
}
};

View File

@@ -1,85 +1,70 @@
// Importing React and useEffect from React library
import React, { useEffect } from "react";
// Importing the necessary hooks and types from React and TypeScript
// Importing the necessary hooks and types from the application's state management stores
import useModuleStore, { useThreeDStore } from "../../store/useModuleStore";
import useToggleStore from "../../store/useUIToggleStore";
import { useActiveSubTool, useActiveTool, useAddAction, useDeleteTool, useSelectedWallItem, useToggleView, useToolMode } from "../../store/store";
import {
useActiveSubTool,
useActiveTool,
useAddAction,
useDeleteTool,
useSelectedWallItem,
useToggleView,
useToolMode,
} from "../../store/store";
import { usePlayButtonStore } from "../../store/usePlayButtonStore";
// Utility function to detect modifier keys (Ctrl, Alt, Shift) and key combinations
import { detectModifierKeys } from "./detectModifierKeys";
// KeyPressListener component to handle global keyboard shortcuts
const KeyPressListener: React.FC = () => {
// Function to detect if Shift, Ctrl, Alt, or combinations are pressed
const detectModifierKeys = (event: KeyboardEvent): string => {
const modifiers = [
event.ctrlKey ? "Ctrl" : "",
event.altKey ? "Alt" : "",
event.shiftKey ? "Shift" : "",
event.metaKey ? "Meta" : "" // Add support for Command/Win key
].filter(Boolean);
// Accessing state and actions from different stores
const { activeModule, setActiveModule } = useModuleStore(); // Module management (e.g., builder, simulation, visualization)
const { setActiveSubTool } = useActiveSubTool(); // Sub-tool management
const { toggleUI, setToggleUI } = useToggleStore(); // UI visibility toggle
const { setToggleThreeD } = useThreeDStore(); // 3D view toggle
const { setToolMode } = useToolMode(); // Tool mode management
const { setIsPlaying } = usePlayButtonStore(); // Play button state management
// Ignore modifier keys when they're pressed alone
const isModifierKey = [
"Control", "Shift", "Alt", "Meta",
"Ctrl", "AltGraph", "OS" // Additional modifier key aliases
].includes(event.key);
const mainKey = isModifierKey ? "" : event.key.toUpperCase();
// Handle special cases for keys with different representations
const normalizedKey = mainKey === " " ? "Space" : mainKey;
// Build the combination string
if (modifiers.length > 0 && normalizedKey) {
return `${modifiers.join("+")}+${normalizedKey}`;
} else if (modifiers.length > 0) {
return modifiers.join("+");
} else {
return normalizedKey;
}
};
// Importing the necessary hooks from the store
const { activeModule, setActiveModule } = useModuleStore();
const { setActiveSubTool } = useActiveSubTool();
const { toggleUI, setToggleUI } = useToggleStore();
const { setToggleThreeD } = useThreeDStore();
const { setToolMode } = useToolMode();
const { setIsPlaying } = usePlayButtonStore();
// wall options
const { toggleView, setToggleView } = useToggleView();
const { setDeleteTool } = useDeleteTool();
const { setAddAction } = useAddAction();
const { setSelectedWallItem } = useSelectedWallItem();
const { setActiveTool } = useActiveTool();
// Wall and tool-related actions
const { toggleView, setToggleView } = useToggleView(); // 2D/3D toggle state
const { setDeleteTool } = useDeleteTool(); // Delete tool action
const { setAddAction } = useAddAction(); // Add action management
const { setSelectedWallItem } = useSelectedWallItem(); // Selected wall item management
const { setActiveTool } = useActiveTool(); // Active tool management
// useEffect to manage global keyboard shortcuts
useEffect(() => {
// Function to handle keydown events
const handleKeyPress = (event: KeyboardEvent) => {
// Identify the currently focused element
const activeElement = document.activeElement;
const isTyping =
activeElement instanceof HTMLInputElement ||
activeElement instanceof HTMLTextAreaElement ||
(activeElement && activeElement.getAttribute('contenteditable') === 'true');
// Check if the user is typing in an input field, textarea, or contenteditable element
const isTyping =
activeElement instanceof HTMLInputElement ||
activeElement instanceof HTMLTextAreaElement ||
(activeElement && activeElement.getAttribute("contenteditable") === "true");
if (isTyping) {
return; // Don't trigger shortcuts while typing
return; // Skip shortcut handling while typing
}
// Detect the combination of keys pressed
const keyCombination = detectModifierKeys(event);
// Allow default behavior for F5 and F12
// Allow browser default behavior for specific keys (e.g., F5 for refresh)
if (["F5", "F11", "F12"].includes(event.key) || keyCombination === "Ctrl+R") {
return;
}
// Prevent default action for the key press
// Prevent the default browser action for other handled key presses
event.preventDefault();
// Detect the key combination pressed
if (keyCombination) {
// Check for specific key combinations to switch modules
// Switch between different modules (e.g., builder, simulation)
if (keyCombination === "1" && !toggleView) {
setActiveTool("cursor");
setActiveSubTool("cursor");
@@ -102,12 +87,12 @@ const KeyPressListener: React.FC = () => {
setActiveModule("market");
}
// sidebar toggle
// Toggle UI visibility
if (keyCombination === "Ctrl+." && activeModule !== "market") {
setToggleUI(!toggleUI);
}
// tools toggle
// Tool selection shortcuts
if (keyCombination === "V") {
setActiveTool("cursor");
setActiveSubTool("cursor");
@@ -121,14 +106,15 @@ const KeyPressListener: React.FC = () => {
setActiveSubTool("free-hand");
}
// player toggle
// Toggle play mode
if (keyCombination === "Ctrl+P" && !toggleView) {
setIsPlaying(true);
}
// builder key combination
// Builder-specific shortcuts
if (activeModule === "builder") {
if (keyCombination === "TAB") {
// Switch between 2D and 3D views
if (toggleView) {
setToggleView(false);
setToggleThreeD(true);
@@ -142,7 +128,8 @@ const KeyPressListener: React.FC = () => {
setActiveTool("cursor");
}
}
// builder tools
// Wall-related tools
if (toggleView) {
if (keyCombination === "Q" || keyCombination === "6") {
setActiveTool("draw-wall");
@@ -161,21 +148,34 @@ const KeyPressListener: React.FC = () => {
setToolMode("Floor");
}
}
// Measurement tool
if (keyCombination === "M") {
setActiveTool("measure");
setToolMode("MeasurementScale");
}
}
// Undo redo
// Undo and redo actions
if (keyCombination === "Ctrl+Z") {
// Handle undo action here
// Handle undo action
}
if (keyCombination === "Ctrl+Y" || keyCombination === "Ctrl+Shift+Z") {
// Handle redo action here
// Handle redo action
}
// cleanup function to remove event listener
// Helper actions
if (keyCombination === "Ctrl+H") {
// Open help
}
if (keyCombination === "Ctrl+F") {
// Open find functionality
}
if (keyCombination === "Ctrl+?") {
// Show shortcuts info
}
// Reset to cursor tool and stop play mode
if (keyCombination === "ESCAPE") {
setActiveTool("cursor");
setIsPlaying(false);
@@ -183,16 +183,16 @@ const KeyPressListener: React.FC = () => {
}
};
// Add event listener for keydown
// Add keydown event listener
window.addEventListener("keydown", handleKeyPress);
// Cleanup function to remove event listener
// Cleanup function to remove the event listener
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, [activeModule, toggleUI, toggleView]); // Empty dependency array ensures this runs only once
}, [activeModule, toggleUI, toggleView]); // Dependencies to reapply effect if these values change
return null; // No UI component to render, so return null
return null; // This component does not render any UI
};
export default KeyPressListener;