import { Dispatch, SetStateAction } from 'react'; import { IContainerModel, ContainerModel } from '../../Interfaces/IContainerModel'; import { IHistoryState } from '../../Interfaces/IHistoryState'; import IProperties from '../../Interfaces/IProperties'; import { findContainerById } from '../../utils/itertools'; import { getCurrentHistory } from './Editor'; import { RecalculatePhysics } from './Behaviors/RigidBodyBehaviors'; import { INPUT_TYPES } from '../Properties/PropertiesInputTypes'; import { ImposePosition } from './Behaviors/AnchorBehaviors'; /** * Handled the property change event in the properties form * @param key Property name * @param value New value of the property * @returns void */ export function OnPropertyChange( key: string, value: string | number | boolean, fullHistory: IHistoryState[], historyCurrentStep: number, setHistory: Dispatch>, setHistoryCurrentStep: Dispatch> ): void { const history = getCurrentHistory(fullHistory, historyCurrentStep); const current = history[history.length - 1]; if (current.SelectedContainer === null || current.SelectedContainer === undefined) { throw new Error('[OnPropertyChange] Property was changed before selecting a Container'); } const mainContainerClone: IContainerModel = structuredClone(current.MainContainer); const container: ContainerModel | undefined = findContainerById(mainContainerClone, current.SelectedContainer.properties.id); if (container === null || container === undefined) { throw new Error('[OnPropertyChange] Container model was not found among children of the main container!'); } if (INPUT_TYPES[key] === 'number') { (container.properties as any)[key] = Number(value); } else { (container.properties as any)[key] = value; } if (container.properties.isAnchor) { ImposePosition(container); } if (container.properties.isRigidBody) { RecalculatePhysics(container); } history.push({ LastAction: `Change ${key} of ${container.properties.id}`, MainContainer: mainContainerClone, SelectedContainer: container, SelectedContainerId: container.properties.id, TypeCounters: Object.assign({}, current.TypeCounters) }); setHistory(history); setHistoryCurrentStep(history.length - 1); } /** * Handled the property change event in the properties form * @param key Property name * @param properties Properties of the selected container * @returns void */ export function OnPropertiesSubmit( event: React.SyntheticEvent, properties: IProperties, fullHistory: IHistoryState[], historyCurrentStep: number, setHistory: Dispatch>, setHistoryCurrentStep: Dispatch> ): void { event.preventDefault(); const history = getCurrentHistory(fullHistory, historyCurrentStep); const current = history[history.length - 1]; if (current.SelectedContainer === null || current.SelectedContainer === undefined) { throw new Error('[OnPropertyChange] Property was changed before selecting a Container'); } const mainContainerClone: IContainerModel = structuredClone(current.MainContainer); const container: ContainerModel | undefined = findContainerById(mainContainerClone, current.SelectedContainer.properties.id); if (container === null || container === undefined) { throw new Error('[OnPropertyChange] Container model was not found among children of the main container!'); } for (const property in properties) { const input = (event.target as HTMLFormElement).querySelector(`#${property}`); if (input instanceof HTMLInputElement) { (container.properties as any)[property] = input.value; if (INPUT_TYPES[property] === 'number') { (container.properties as any)[property] = Number(input.value); } else { (container.properties as any)[property] = input.value; } } } if (container.properties.isRigidBody) { RecalculatePhysics(container); } history.push({ LastAction: `Change properties of ${container.properties.id}`, MainContainer: mainContainerClone, SelectedContainer: container, SelectedContainerId: container.properties.id, TypeCounters: Object.assign({}, current.TypeCounters) }); setHistory(history); setHistoryCurrentStep(history.length - 1); }