excalidraw/src/actions/manager.tsx
Gasim Gasimzada 1e4ce77612
Reintroduce multi-point arrows and add migration for it (#635)
* Revert "Revert "Feature: Multi Point Arrows (#338)" (#634)"

This reverts commit 3d2e59bfed4fa41a0cae49ee567a6f95ca26e7bf.

* Convert old arrow spec to new one

* Remove unnecessary failchecks and fix context transform issue in retina displays

* Remove old points failcheck from getArrowAbsoluteBounds

* Remove all failchecks for old arrow

* remove the rest of unnecessary checks

* Set default values for the arrow during import

* Add translations

* fix restore using unmigrated elements for state computation

* don't use width/height when migrating from new arrow spec

Co-authored-by: David Luzar <luzar.david@gmail.com>
Co-authored-by: Christopher Chedeau <vjeuxx@gmail.com>
2020-02-01 15:49:18 +04:00

93 lines
2.4 KiB
TypeScript

import React from "react";
import {
Action,
ActionsManagerInterface,
UpdaterFn,
ActionFilterFn,
} from "./types";
import { ExcalidrawElement } from "../element/types";
import { AppState } from "../types";
import { t } from "../i18n";
export class ActionManager implements ActionsManagerInterface {
actions: { [keyProp: string]: Action } = {};
updater:
| ((elements: ExcalidrawElement[], appState: AppState) => void)
| null = null;
setUpdater(
updater: (elements: ExcalidrawElement[], appState: AppState) => void,
) {
this.updater = updater;
}
registerAction(action: Action) {
this.actions[action.name] = action;
}
handleKeyDown(
event: KeyboardEvent,
elements: readonly ExcalidrawElement[],
appState: AppState,
) {
const data = Object.values(this.actions)
.sort((a, b) => (b.keyPriority || 0) - (a.keyPriority || 0))
.filter(
action => action.keyTest && action.keyTest(event, appState, elements),
);
if (data.length === 0) return null;
event.preventDefault();
return data[0].perform(elements, appState, null);
}
getContextMenuItems(
elements: readonly ExcalidrawElement[],
appState: AppState,
updater: UpdaterFn,
actionFilter: ActionFilterFn = action => action,
) {
return Object.values(this.actions)
.filter(actionFilter)
.filter(action => "contextItemLabel" in action)
.sort(
(a, b) =>
(a.contextMenuOrder !== undefined ? a.contextMenuOrder : 999) -
(b.contextMenuOrder !== undefined ? b.contextMenuOrder : 999),
)
.map(action => ({
label: action.contextItemLabel ? t(action.contextItemLabel) : "",
action: () => {
updater(action.perform(elements, appState, null));
},
}));
}
renderAction(
name: string,
elements: readonly ExcalidrawElement[],
appState: AppState,
updater: UpdaterFn,
) {
if (this.actions[name] && "PanelComponent" in this.actions[name]) {
const action = this.actions[name];
const PanelComponent = action.PanelComponent!;
const updateData = (formState: any) => {
updater(action.perform(elements, appState, formState));
};
return (
<PanelComponent
elements={elements}
appState={appState}
updateData={updateData}
/>
);
}
return null;
}
}