Implemtation in progress, UIX working , replacing in ContainerOperations.ts working but not properly need fix

This commit is contained in:
Carl Fuchs 2023-02-06 16:45:34 +01:00
parent 62abd3ff03
commit e789300090
9 changed files with 139 additions and 98 deletions

View file

@ -8,7 +8,8 @@ import Swal from 'sweetalert2';
import { PropertyType } from '../../../Enums/PropertyType';
import { TransformX, TransformY } from '../../../utils/svg';
import { Orientation } from '../../../Enums/Orientation';
import { AddContainers, AddContainerToSelectedContainer } from './AddContainer';
import { AddContainerToSelectedContainer } from './AddContainer';
import { IConfiguration } from '../../../Interfaces/IConfiguration';
/**
* Select a container
@ -113,64 +114,44 @@ export function DeleteContainer(
/**
* Replace a container
* @param containerId containerId of the container to delete
* @param newContainerId
* @param configuration
* @param fullHistory History of the editor
* @param historyCurrentStep Current step
* @returns New history
*/
// export function ReplaceByContainer(
// containerId: string,
// newContainerId: string,
// fullHistory: IHistoryState[],
// historyCurrentStep: number
// ): IHistoryState[] {
// const history = GetCurrentHistory(fullHistory, historyCurrentStep);
// const current = history[history.length - 1];
//
//
// const containers = structuredClone(current.containers);
// const container = FindContainerById(containers, containerId);
// if (container === undefined) {
// throw new Error(`[ReplaceContainer] Tried to delete a container that is not present in the main container: ${containerId}`);
// }
// ///
// const parent = FindContainerById(containers, container.properties.parentId);
// if (parent === undefined || parent === null) {
// throw new Error('[ReplaceContainer] Cannot replace a container that does not exists');
// }
//
// const index = parent.children.indexOf(container.properties.id);
//
// const newHistoryAfterDelete = DeleteContainer(
// container.properties.id,
// history,
// historyCurrentStep
// );
//
// const newContainer = FindContainerById(containers, container.properties.parentId);
//
// AddContainerToSelectedContainer(
// ne,
// selected,
// configuration,
// history,
// historyCurrentStep
// );
//
//
// /// /
//
//
// history.push({
// lastAction: `Replace ${containerId} By InsertnewId`,
// mainContainer: current.mainContainer,
// containers,
// newContainerId,
// typeCounters: Object.assign({}, current.typeCounters),
// symbols: newSymbols,
// selectedSymbolId: current.selectedSymbolId
// });
// return history;
// }
export function ReplaceByContainer(
containerId: string,
newContainerId: string,
configuration: IConfiguration,
fullHistory: IHistoryState[],
historyCurrentStep: number
): IHistoryState[] {
const history = GetCurrentHistory(fullHistory, historyCurrentStep);
const current = history[history.length - 1];
const historyDelete = DeleteContainer(containerId, fullHistory, historyCurrentStep);
const currentDelete = historyDelete[historyDelete.length - 1];
const selectedContainer = FindContainerById(currentDelete.containers, currentDelete.selectedContainerId);
if (selectedContainer != null) {
const historyAdd = AddContainerToSelectedContainer(newContainerId, selectedContainer, configuration, fullHistory, historyCurrentStep);
const currentAdd = historyAdd[historyAdd.length - 1];
fullHistory.push({
lastAction: `Replace ${containerId} by ${newContainerId}`,
mainContainer: currentAdd.mainContainer,
containers: currentAdd.containers,
selectedContainerId: currentAdd.selectedContainerId,
typeCounters: Object.assign({}, currentAdd.typeCounters),
symbols: current.symbols,
selectedSymbolId: current.selectedSymbolId
});
return fullHistory;
}
return history;
}
/**
* Returns the next container that will be selected
@ -178,7 +159,7 @@ export function DeleteContainer(
* If the selected container is removed, select the sibling after,
* If there is no sibling, select the parent,
*
* @param mainContainerClone Main container
* @param containers
* @param selectedContainerId Current selected container
* @param parent Parent of the selected/deleted container
* @param index Index of the selected/deleted container
@ -190,11 +171,10 @@ function GetSelectedContainerOnDelete(
parent: IContainerModel,
index: number
): string {
const newSelectedContainerId = FindContainerById(containers, selectedContainerId)?.properties.id ??
parent.children.at(index) ??
parent.children.at(index - 1) ??
parent.properties.id;
return newSelectedContainerId;
return FindContainerById(containers, selectedContainerId)?.properties.id ??
parent.children.at(index) ??
parent.children.at(index - 1) ??
parent.properties.id;
}
/**
@ -220,11 +200,15 @@ function UnlinkContainerFromSymbols(
}
/**
* Handled the property change event in the properties form
* @param key Property name
* @param value New value of the property
* @returns void
*/
* Handled the property change event in the properties form
* @param key Property name
* @param value New value of the property
* @param type
* @param selected
* @param fullHistory
* @param historyCurrentStep
* @returns void
*/
export function OnPropertyChange(
key: string,
value: string | number | boolean | number[],
@ -264,6 +248,7 @@ export function OnPropertyChange(
/**
* Sort the parent children by x
* @param containers
* @param parent The clone used for the sort
* @returns void
*/
@ -328,6 +313,7 @@ export function SortChildren(
/**
* Set the container with properties and behaviors (mutate)
* @param containers
* @param container Container to update
* @param key Key of the property to update
* @param value Value of the property to update

View file

@ -16,6 +16,7 @@ import { AddContainers } from './AddContainer';
import { DeleteContainer } from './ContainerOperations';
import { DeleteSymbol } from './SymbolOperations';
import { Text } from '../../Text/Text';
import { IReplaceContainer } from '../../../Interfaces/IReplaceContainer';
export function InitActions(
menuActions: Map<string, IMenuAction[]>,
@ -23,7 +24,8 @@ export function InitActions(
history: IHistoryState[],
historyCurrentStep: number,
setNewHistory: (newHistory: IHistoryState[]) => void,
setHistoryCurrentStep: Dispatch<SetStateAction<number>>
setHistoryCurrentStep: Dispatch<SetStateAction<number>>,
setIsReplacingContainer: Dispatch<SetStateAction<IReplaceContainer>>
): void {
menuActions.set(
'',
@ -60,8 +62,14 @@ export function InitActions(
title: Text({ textId: '@ReplaceByContainerTitle' }),
shortcut: '<kbd>R</kbd>',
action: (target: HTMLElement) => {
const id = target.id;
console.log('replace');
const targetContainer = FindContainerById(history[historyCurrentStep].containers, target.id);
const targetAvailableContainer = configuration.AvailableContainers.find((availableContainer) => availableContainer.Type === targetContainer?.properties.type);
if (targetAvailableContainer === undefined) {
return;
}
setIsReplacingContainer({ isReplacing: true, id: target.id, category: targetAvailableContainer.Category });
}
}, {
text: Text({ textId: '@DeleteContainer' }),

View file

@ -3,7 +3,7 @@ import './Editor.scss';
import { IConfiguration } from '../../Interfaces/IConfiguration';
import { IHistoryState } from '../../Interfaces/IHistoryState';
import { UI } from '../UI/UI';
import { SelectContainer, DeleteContainer, OnPropertyChange } from './Actions/ContainerOperations';
import { SelectContainer, DeleteContainer, OnPropertyChange, ReplaceByContainer } from './Actions/ContainerOperations';
import { SaveEditorAsJSON, SaveEditorAsSVG } from './Actions/Save';
import { OnKey } from './Actions/Shortcuts';
import { UseCustomEvents, UseEditorListener } from '../../Events/EditorEvents';
@ -13,6 +13,7 @@ import { FindContainerById } from '../../utils/itertools';
import { Menu } from '../Menu/Menu';
import { InitActions } from './Actions/ContextMenuActions';
import { AddContainerToSelectedContainer, AddContainer } from './Actions/AddContainer';
import { IReplaceContainer } from '../../Interfaces/IReplaceContainer';
interface IEditorProps {
root: Element | Document
@ -66,6 +67,8 @@ export function Editor(props: IEditorProps): JSX.Element {
// States
const [history, setHistory] = React.useState<IHistoryState[]>(structuredClone(props.history));
const [historyCurrentStep, setHistoryCurrentStep] = React.useState<number>(props.historyCurrentStep);
const [replaceContainer, setReplaceContainer] = React.useState<IReplaceContainer>({ isReplacing: false, id: undefined, category: undefined });
const editorRef = useRef<HTMLDivElement>(null);
const setNewHistory = UseNewHistoryState(setHistory, setHistoryCurrentStep);
@ -104,7 +107,8 @@ export function Editor(props: IEditorProps): JSX.Element {
history,
historyCurrentStep,
setNewHistory,
setHistoryCurrentStep
setHistoryCurrentStep,
setReplaceContainer
);
// Render
@ -113,7 +117,7 @@ export function Editor(props: IEditorProps): JSX.Element {
const selected = FindContainerById(current.containers, current.selectedContainerId);
return (
<div ref={editorRef} className="Editor font-sans h-full">
<div ref={editorRef} className="Editor font-sans h-full ">
<UI
editorState={{
configuration: props.configuration,
@ -139,18 +143,29 @@ export function Editor(props: IEditorProps): JSX.Element {
history,
historyCurrentStep
))}
addContainer={(type) => {
addOrReplaceContainer={(type) => {
if (selected === null || selected === undefined) {
return;
}
setNewHistory(AddContainerToSelectedContainer(
type,
selected,
configuration,
history,
historyCurrentStep
));
if (replaceContainer.isReplacing && replaceContainer.id !== undefined) {
const newHistory = ReplaceByContainer(
replaceContainer.id,
type,
configuration,
history,
historyCurrentStep
);
setReplaceContainer({ isReplacing: false, id: undefined, category: undefined });
setNewHistory(newHistory);
} else {
setNewHistory(AddContainerToSelectedContainer(
type,
selected,
configuration,
history,
historyCurrentStep
));
}
}}
addContainerAt={(index, type, parent) => setNewHistory(
AddContainer(
@ -194,9 +209,10 @@ export function Editor(props: IEditorProps): JSX.Element {
)}
saveEditorAsSVG={() => SaveEditorAsSVG()}
loadState={(move) => setHistoryCurrentStep(move)}
/>
replaceContainer ={replaceContainer} setReplaceContainer={setReplaceContainer}/>
<Menu
getListener={() => editorRef.current}
configuration={configuration}
actions={menuActions}
className="z-30 transition-opacity rounded bg-slate-200 drop-shadow-xl"
/>