199 lines
8.3 KiB
TypeScript
199 lines
8.3 KiB
TypeScript
// Importing React and useEffect from React library
|
|
import React, { useEffect } from "react";
|
|
|
|
// 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 { 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 = () => {
|
|
// 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
|
|
|
|
// 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;
|
|
|
|
// 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; // Skip shortcut handling while typing
|
|
}
|
|
|
|
// Detect the combination of keys pressed
|
|
const keyCombination = detectModifierKeys(event);
|
|
|
|
// Allow browser default behavior for specific keys (e.g., F5 for refresh)
|
|
if (["F5", "F11", "F12"].includes(event.key) || keyCombination === "Ctrl+R") {
|
|
return;
|
|
}
|
|
|
|
// Prevent the default browser action for other handled key presses
|
|
event.preventDefault();
|
|
|
|
if (keyCombination) {
|
|
// Switch between different modules (e.g., builder, simulation)
|
|
if (keyCombination === "1" && !toggleView) {
|
|
setActiveTool("cursor");
|
|
setActiveSubTool("cursor");
|
|
setActiveModule("builder");
|
|
}
|
|
if (keyCombination === "2" && !toggleView) {
|
|
setActiveTool("cursor");
|
|
setActiveSubTool("cursor");
|
|
setActiveModule("simulation");
|
|
}
|
|
if (keyCombination === "3" && !toggleView) {
|
|
setActiveTool("cursor");
|
|
setActiveSubTool("cursor");
|
|
setActiveModule("visualization");
|
|
}
|
|
if (keyCombination === "4" && !toggleView) {
|
|
setActiveTool("cursor");
|
|
setActiveSubTool("cursor");
|
|
setToggleUI(false);
|
|
setActiveModule("market");
|
|
}
|
|
|
|
// Toggle UI visibility
|
|
if (keyCombination === "Ctrl+." && activeModule !== "market") {
|
|
setToggleUI(!toggleUI);
|
|
}
|
|
|
|
// Tool selection shortcuts
|
|
if (keyCombination === "V") {
|
|
setActiveTool("cursor");
|
|
setActiveSubTool("cursor");
|
|
}
|
|
if (keyCombination === "X") {
|
|
setActiveTool("delete");
|
|
setActiveSubTool("delete");
|
|
}
|
|
if (keyCombination === "H") {
|
|
setActiveTool("free-hand");
|
|
setActiveSubTool("free-hand");
|
|
}
|
|
|
|
// Toggle play mode
|
|
if (keyCombination === "Ctrl+P" && !toggleView) {
|
|
setIsPlaying(true);
|
|
}
|
|
|
|
// Builder-specific shortcuts
|
|
if (activeModule === "builder") {
|
|
if (keyCombination === "TAB") {
|
|
// Switch between 2D and 3D views
|
|
if (toggleView) {
|
|
setToggleView(false);
|
|
setToggleThreeD(true);
|
|
setActiveTool("cursor");
|
|
} else {
|
|
setSelectedWallItem(null);
|
|
setDeleteTool(false);
|
|
setAddAction(null);
|
|
setToggleView(true);
|
|
setToggleThreeD(false);
|
|
setActiveTool("cursor");
|
|
}
|
|
}
|
|
|
|
// Wall-related tools
|
|
if (toggleView) {
|
|
if (keyCombination === "Q" || keyCombination === "6") {
|
|
setActiveTool("draw-wall");
|
|
setToolMode("Wall");
|
|
}
|
|
if (keyCombination === "R" || keyCombination === "7") {
|
|
setActiveTool("draw-aisle");
|
|
setToolMode("Aisle");
|
|
}
|
|
if (keyCombination === "E" || keyCombination === "8") {
|
|
setActiveTool("draw-zone");
|
|
setToolMode("Zone");
|
|
}
|
|
if (keyCombination === "T" || keyCombination === "9") {
|
|
setActiveTool("draw-floor");
|
|
setToolMode("Floor");
|
|
}
|
|
}
|
|
|
|
// Measurement tool
|
|
if (keyCombination === "M") {
|
|
setActiveTool("measure");
|
|
setToolMode("MeasurementScale");
|
|
}
|
|
}
|
|
|
|
// Undo and redo actions
|
|
if (keyCombination === "Ctrl+Z") {
|
|
// Handle undo action
|
|
}
|
|
if (keyCombination === "Ctrl+Y" || keyCombination === "Ctrl+Shift+Z") {
|
|
// Handle redo action
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
};
|
|
|
|
// Add keydown event listener
|
|
window.addEventListener("keydown", handleKeyPress);
|
|
|
|
// Cleanup function to remove the event listener
|
|
return () => {
|
|
window.removeEventListener("keydown", handleKeyPress);
|
|
};
|
|
}, [activeModule, toggleUI, toggleView]); // Dependencies to reapply effect if these values change
|
|
|
|
return null; // This component does not render any UI
|
|
};
|
|
|
|
export default KeyPressListener;
|