Merged PR 173: Implements API methods through right click + more (read desc)
- Implements API methods through right click - Refactor events - Refactor usage of setHistory and setHistoryCurrentStep into a single function - Update ContainerOperations documentations - Added AddContainers in order to add multiple containers + refactor AddContainer to use it - Fix regression - Fix AddContainer at index
This commit is contained in:
parent
79c6874240
commit
57e6c9a156
20 changed files with 652 additions and 291 deletions
|
@ -4,15 +4,16 @@ import { IConfiguration } from '../../Interfaces/IConfiguration';
|
|||
import { SVG } from '../SVG/SVG';
|
||||
import { IHistoryState } from '../../Interfaces/IHistoryState';
|
||||
import { UI } from '../UI/UI';
|
||||
import { SelectContainer, DeleteContainer, AddContainerToSelectedContainer, OnPropertyChange } from './Actions/ContainerOperations';
|
||||
import { SelectContainer, DeleteContainer, AddContainerToSelectedContainer, OnPropertyChange, AddContainers } from './Actions/ContainerOperations';
|
||||
import { SaveEditorAsJSON, SaveEditorAsSVG } from './Actions/Save';
|
||||
import { OnKey } from './Actions/Shortcuts';
|
||||
import EditorEvents from '../../Events/EditorEvents';
|
||||
import { events as EVENTS } from '../../Events/EditorEvents';
|
||||
import { IEditorState } from '../../Interfaces/IEditorState';
|
||||
import { MAX_HISTORY } from '../../utils/default';
|
||||
import { AddSymbol, OnPropertyChange as OnSymbolPropertyChange, DeleteSymbol, SelectSymbol } from './Actions/SymbolOperations';
|
||||
import { FindContainerById } from '../../utils/itertools';
|
||||
import { Menu } from '../Menu/Menu';
|
||||
import { IMenuAction, Menu } from '../Menu/Menu';
|
||||
import { GetAction } from './Actions/ContextMenuActions';
|
||||
|
||||
interface IEditorProps {
|
||||
root: Element | Document
|
||||
|
@ -22,11 +23,11 @@ interface IEditorProps {
|
|||
}
|
||||
|
||||
function InitActions(
|
||||
menuActions: Map<any, any>,
|
||||
menuActions: Map<string, IMenuAction[]>,
|
||||
configuration: IConfiguration,
|
||||
history: IHistoryState[],
|
||||
historyCurrentStep: number,
|
||||
setHistory: React.Dispatch<React.SetStateAction<IHistoryState[]>>,
|
||||
setHistoryCurrentStep: React.Dispatch<React.SetStateAction<number>>
|
||||
setNewHistory: (newHistory: IHistoryState[]) => void
|
||||
): void {
|
||||
menuActions.set(
|
||||
'elements-sidebar-row',
|
||||
|
@ -34,13 +35,12 @@ function InitActions(
|
|||
text: 'Delete',
|
||||
action: (target: HTMLElement) => {
|
||||
const id = target.id;
|
||||
DeleteContainer(
|
||||
const newHistory = DeleteContainer(
|
||||
id,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
historyCurrentStep
|
||||
);
|
||||
setNewHistory(newHistory);
|
||||
}
|
||||
}]
|
||||
);
|
||||
|
@ -50,16 +50,43 @@ function InitActions(
|
|||
text: 'Delete',
|
||||
action: (target: HTMLElement) => {
|
||||
const id = target.id;
|
||||
DeleteSymbol(
|
||||
const newHistory = DeleteSymbol(
|
||||
id,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
historyCurrentStep
|
||||
);
|
||||
setNewHistory(newHistory);
|
||||
}
|
||||
}]
|
||||
);
|
||||
|
||||
// API Actions
|
||||
for (const availableContainer of configuration.AvailableContainers) {
|
||||
if (availableContainer.Actions === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const action of availableContainer.Actions) {
|
||||
if (menuActions.get(availableContainer.Type) === undefined) {
|
||||
menuActions.set(availableContainer.Type, []);
|
||||
}
|
||||
|
||||
const currentState = GetCurrentHistoryState(history, historyCurrentStep);
|
||||
const newAction: IMenuAction = {
|
||||
text: action.Label,
|
||||
action: GetAction(
|
||||
action,
|
||||
currentState,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
setNewHistory
|
||||
)
|
||||
};
|
||||
|
||||
menuActions.get(availableContainer.Type)?.push(newAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function UseShortcuts(
|
||||
|
@ -90,11 +117,9 @@ function UseWindowEvents(
|
|||
historyCurrentStep: number,
|
||||
configuration: IConfiguration,
|
||||
editorRef: React.RefObject<HTMLDivElement>,
|
||||
setHistory: Dispatch<SetStateAction<IHistoryState[]>>,
|
||||
setHistoryCurrentStep: Dispatch<SetStateAction<number>>
|
||||
setNewHistory: (newHistory: IHistoryState[]) => void
|
||||
): void {
|
||||
useEffect(() => {
|
||||
const events = EditorEvents;
|
||||
const editorState: IEditorState = {
|
||||
history,
|
||||
historyCurrentStep,
|
||||
|
@ -102,13 +127,12 @@ function UseWindowEvents(
|
|||
};
|
||||
|
||||
const funcs = new Map<string, () => void>();
|
||||
for (const event of events) {
|
||||
for (const event of EVENTS) {
|
||||
function Func(eventInitDict?: CustomEventInit): void {
|
||||
return event.func(
|
||||
root,
|
||||
editorState,
|
||||
setHistory,
|
||||
setHistoryCurrentStep,
|
||||
setNewHistory,
|
||||
eventInitDict
|
||||
);
|
||||
}
|
||||
|
@ -116,7 +140,7 @@ function UseWindowEvents(
|
|||
funcs.set(event.name, Func);
|
||||
}
|
||||
return () => {
|
||||
for (const event of events) {
|
||||
for (const event of EVENTS) {
|
||||
const func = funcs.get(event.name);
|
||||
if (func === undefined) {
|
||||
continue;
|
||||
|
@ -127,11 +151,29 @@ function UseWindowEvents(
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a macro function to use both setHistory
|
||||
* and setHistoryCurrentStep at the same time
|
||||
* @param setHistory
|
||||
* @param setHistoryCurrentStep
|
||||
* @returns
|
||||
*/
|
||||
function UseNewHistoryState(
|
||||
setHistory: Dispatch<SetStateAction<IHistoryState[]>>,
|
||||
setHistoryCurrentStep: Dispatch<SetStateAction<number>>
|
||||
): (newHistory: IHistoryState[]) => void {
|
||||
return (newHistory) => {
|
||||
setHistory(newHistory);
|
||||
setHistoryCurrentStep(newHistory.length - 1);
|
||||
};
|
||||
}
|
||||
|
||||
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 editorRef = useRef<HTMLDivElement>(null);
|
||||
const setNewHistory = UseNewHistoryState(setHistory, setHistoryCurrentStep);
|
||||
|
||||
// Events
|
||||
UseShortcuts(history, historyCurrentStep, setHistoryCurrentStep);
|
||||
|
@ -141,13 +183,18 @@ export function Editor(props: IEditorProps): JSX.Element {
|
|||
historyCurrentStep,
|
||||
props.configuration,
|
||||
editorRef,
|
||||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
setNewHistory
|
||||
);
|
||||
|
||||
// Context Menu
|
||||
const menuActions = new Map();
|
||||
InitActions(menuActions, history, historyCurrentStep, setHistory, setHistoryCurrentStep);
|
||||
InitActions(
|
||||
menuActions,
|
||||
props.configuration,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
setNewHistory
|
||||
);
|
||||
|
||||
// Render
|
||||
const configuration = props.configuration;
|
||||
|
@ -162,66 +209,62 @@ export function Editor(props: IEditorProps): JSX.Element {
|
|||
historyCurrentStep={historyCurrentStep}
|
||||
availableContainers={configuration.AvailableContainers}
|
||||
availableSymbols={configuration.AvailableSymbols}
|
||||
selectContainer={(container) => SelectContainer(
|
||||
container,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
)}
|
||||
deleteContainer={(containerId: string) => DeleteContainer(
|
||||
containerId,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
)}
|
||||
onPropertyChange={(key, value, type) => OnPropertyChange(
|
||||
key, value, type,
|
||||
selected,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
)}
|
||||
addContainer={(type) => AddContainerToSelectedContainer(
|
||||
type,
|
||||
selected,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
)}
|
||||
addSymbol={(type) => AddSymbol(
|
||||
type,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
)}
|
||||
onSymbolPropertyChange={(key, value) => OnSymbolPropertyChange(
|
||||
key, value,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
)}
|
||||
selectSymbol={(symbolId) => SelectSymbol(
|
||||
symbolId,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
)}
|
||||
deleteSymbol={(symbolId) => DeleteSymbol(
|
||||
symbolId,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
)}
|
||||
selectContainer={(container) => setNewHistory(
|
||||
SelectContainer(
|
||||
container,
|
||||
history,
|
||||
historyCurrentStep
|
||||
))}
|
||||
deleteContainer={(containerId: string) => setNewHistory(
|
||||
DeleteContainer(
|
||||
containerId,
|
||||
history,
|
||||
historyCurrentStep
|
||||
))}
|
||||
onPropertyChange={(key, value, type) => setNewHistory(
|
||||
OnPropertyChange(
|
||||
key, value, type,
|
||||
selected,
|
||||
history,
|
||||
historyCurrentStep
|
||||
))}
|
||||
addContainer={(type) => {
|
||||
const newHistory = AddContainerToSelectedContainer(
|
||||
type,
|
||||
selected,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep
|
||||
);
|
||||
if (newHistory !== null) {
|
||||
setNewHistory(newHistory);
|
||||
}
|
||||
}}
|
||||
addSymbol={(type) => setNewHistory(
|
||||
AddSymbol(
|
||||
type,
|
||||
configuration,
|
||||
history,
|
||||
historyCurrentStep
|
||||
))}
|
||||
onSymbolPropertyChange={(key, value) => setNewHistory(
|
||||
OnSymbolPropertyChange(
|
||||
key, value,
|
||||
history,
|
||||
historyCurrentStep
|
||||
))}
|
||||
selectSymbol={(symbolId) => setNewHistory(
|
||||
SelectSymbol(
|
||||
symbolId,
|
||||
history,
|
||||
historyCurrentStep
|
||||
))}
|
||||
deleteSymbol={(symbolId) => setNewHistory(
|
||||
DeleteSymbol(
|
||||
symbolId,
|
||||
history,
|
||||
historyCurrentStep
|
||||
))}
|
||||
saveEditorAsJSON={() => SaveEditorAsJSON(
|
||||
history,
|
||||
historyCurrentStep,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue