svg-layout-designer-react/src/Components/Editor/PropertiesOperations.ts
Siklos 5f8e011bc6
All checks were successful
continuous-integration/drone/push Build is passing
Unrefactor Properties form to allow more freedom on the input types and form (#32)
- The css style is now in IProperties.Style again.
- Forms are divided in DynamicForm and StaticForm
- Faster because less logic
- Add RadioGroupButton
- Add InputGroup
- Fix Children Dimensions not using x for their origin

Co-authored-by: Eric NGUYEN <enguyen@techform.fr>
Reviewed-on: https://git.siklos-chaneru.duckdns.org/Siklos/svg-layout-designer-react/pulls/32
2022-08-16 08:57:54 -04:00

147 lines
5.3 KiB
TypeScript

import { Dispatch, SetStateAction } from 'react';
import { IContainerModel, ContainerModel } from '../../Interfaces/IContainerModel';
import { IHistoryState } from '../../Interfaces/IHistoryState';
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,
isStyle: boolean = false,
fullHistory: IHistoryState[],
historyCurrentStep: number,
setHistory: Dispatch<SetStateAction<IHistoryState[]>>,
setHistoryCurrentStep: Dispatch<SetStateAction<number>>
): 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 (isStyle) {
(container.properties.style as any)[key] = value;
} else {
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<HTMLFormElement>,
fullHistory: IHistoryState[],
historyCurrentStep: number,
setHistory: Dispatch<SetStateAction<IHistoryState[]>>,
setHistoryCurrentStep: Dispatch<SetStateAction<number>>
): 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!');
}
// Assign container properties
for (const property in container.properties) {
const input: HTMLInputElement | HTMLDivElement | null = (event.target as HTMLFormElement).querySelector(`#${property}`);
if (input === null) {
continue;
}
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 if (input instanceof HTMLDivElement) {
const radiobutton: HTMLInputElement | null = input.querySelector(`input[name="${property}"]:checked`);
if (radiobutton === null) {
continue;
}
(container.properties as any)[property] = radiobutton.value;
if (INPUT_TYPES[property] === 'number') {
(container.properties as any)[property] = Number(radiobutton.value);
}
}
}
// Assign cssproperties
for (const styleProperty in container.properties.style) {
const input: HTMLInputElement | null = (event.target as HTMLFormElement).querySelector(`#${styleProperty}`);
if (input === null) {
continue;
}
(container.properties.style as any)[styleProperty] = 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);
}