Merged PR 189: Simplify usage of SmartComponent
- Added new Events : - AddContainer, AddContainerToSelectedContainer, AppendContainer, AppendContainerToSelectedContainer, SelectContainer, DeleteContainer - AddSymbol, SelectSymbol, DeleteSymbol - Changed the component to an iframe (you only need to copy the whole dist now) - Added callbacks to every methods in the component - Create event listener on demand: no need to initialize the event listener! - Update d.ts - Added Fastboot and enable it by default on production build
This commit is contained in:
parent
07dbac1b12
commit
23ed3ed1ad
14 changed files with 1047 additions and 108 deletions
19
README.md
19
README.md
|
@ -104,3 +104,22 @@ Inside `.vscode/settings.json`, set the following :
|
|||
```
|
||||
|
||||
Change the `url` to the dev server url. Set the `runtimeExecutable` to your favorite chromium browser.
|
||||
|
||||
|
||||
# Generate definition files for SmartModeler
|
||||
|
||||
Pre-requisite: `typescript`, `python3`
|
||||
|
||||
Go to the `src/dts` directory and run the following command
|
||||
|
||||
```
|
||||
tsc --project tsconfig.dts.json
|
||||
```
|
||||
|
||||
Then, run `python3` (or `py` on Windows) on `generate_dts.py`:
|
||||
|
||||
```
|
||||
python3 generate_dts.py SVGLD svgld.d.ts
|
||||
```
|
||||
|
||||
A definition will be generated as `svgld.d.ts` with the namespace `SVGLD`.
|
|
@ -9,6 +9,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
<script type="module" src="./src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
65
public/Interfaces.d.ts
vendored
65
public/Interfaces.d.ts
vendored
|
@ -1,65 +0,0 @@
|
|||
declare interface IHistoryState {
|
||||
LastAction: string
|
||||
MainContainer: IContainerModel
|
||||
SelectedContainer: IContainerModel | null
|
||||
SelectedContainerId: string
|
||||
TypeCounters: Record<string, number>
|
||||
}
|
||||
|
||||
declare interface IAvailableContainer {
|
||||
Type: string
|
||||
Width: number
|
||||
Height: number
|
||||
XPositionReference?: XPositionReference
|
||||
Style: React.CSSProperties
|
||||
}
|
||||
|
||||
declare interface IEditorState {
|
||||
history: IHistoryState[]
|
||||
historyCurrentStep: number
|
||||
configuration: IConfiguration
|
||||
}
|
||||
|
||||
declare interface IConfiguration {
|
||||
AvailableContainers: IAvailableContainer[]
|
||||
AvailableSymbols: IAvailableSymbol[]
|
||||
MainContainer: IAvailableContainer
|
||||
}
|
||||
|
||||
declare interface IContainerModel {
|
||||
children: IContainerModel[]
|
||||
parent: IContainerModel | null
|
||||
properties: IProperties
|
||||
userData: Record<string, string | number>
|
||||
}
|
||||
|
||||
declare interface IProperties extends React.CSSProperties {
|
||||
id: string
|
||||
parentId: string | null
|
||||
x: number
|
||||
y: number
|
||||
|
||||
XPositionReference?: XPositionReference
|
||||
}
|
||||
|
||||
declare enum XPositionReference {
|
||||
Left,
|
||||
Center,
|
||||
Right
|
||||
}
|
||||
|
||||
declare interface IAvailableSymbol {
|
||||
Name: string
|
||||
XPositionReference: XPositionReference
|
||||
Image: IImage
|
||||
Width: number
|
||||
Height: number
|
||||
}
|
||||
|
||||
declare interface IImage {
|
||||
Name: string
|
||||
Url: string
|
||||
Base64Image: string
|
||||
Svg: string
|
||||
}
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
<div id="root">
|
||||
</div>
|
||||
<iframe src="./Components/svg-layout-designer/index.html" style="border:none; width:100%; height:100%">
|
||||
</iframe>
|
|
@ -1,40 +1,99 @@
|
|||
namespace SmartBusiness.Web.Components {
|
||||
import IHistoryState = SVGLD.IHistoryState;
|
||||
import IEditorState = SVGLD.IEditorState;
|
||||
|
||||
export class SVGLayoutDesigner extends Components.ComponentBase {
|
||||
|
||||
public constructor(componentInfo: KnockoutComponentTypes.ComponentInfo, params: any) {
|
||||
super(componentInfo, params);
|
||||
setTimeout(() => (window as any).SVGLayoutDesigner.Render(this.$component[0]));
|
||||
this.InitEventsListener();
|
||||
}
|
||||
|
||||
public GetEditorComponent() {
|
||||
return this.$component[0].querySelector('.Editor');
|
||||
const component = this.$component[0]
|
||||
.querySelector('iframe')
|
||||
.contentDocument
|
||||
.querySelector('.Editor');
|
||||
|
||||
if (component === undefined) {
|
||||
throw new Error('[SVGLD] Cannot hook the event because the editor is not yet open')
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
public GetCurrentHistoryState() {
|
||||
this.GetEditorComponent().dispatchEvent(new CustomEvent('getCurrentHistoryState'));
|
||||
public GetRootComponent() {
|
||||
return this.$component[0]
|
||||
.querySelector('iframe')
|
||||
.contentDocument;
|
||||
}
|
||||
|
||||
public GetEditorState() {
|
||||
this.GetEditorComponent().dispatchEvent(new CustomEvent('getEditorState'));
|
||||
public GetCurrentHistoryState(callback: (state: IHistoryState) => void) {
|
||||
const component = this.GetEditorComponent();
|
||||
const eventType = 'getCurrentHistoryState';
|
||||
component.dispatchEvent(new CustomEvent(eventType));
|
||||
this.AddEventListener(callback, eventType);
|
||||
}
|
||||
|
||||
public SetEditorState(editorState: IEditorState) {
|
||||
this.GetEditorComponent().dispatchEvent(new CustomEvent('SetEditorState', { detail: editorState }));
|
||||
public GetEditorState(callback: (state: IEditorState) => void) {
|
||||
const component = this.GetEditorComponent();
|
||||
const eventType = 'getEditorState';
|
||||
component.dispatchEvent(new CustomEvent(eventType));
|
||||
this.AddEventListener(callback, eventType);
|
||||
}
|
||||
|
||||
public AppendNewHistoryState(historyState: IHistoryState) {
|
||||
this.GetEditorComponent().dispatchEvent(new CustomEvent('appendNewState', { detail: historyState }));
|
||||
public AppendNewHistoryState(historyState: SVGLD.IHistoryState, callback?: (state: IEditorState) => void) {
|
||||
const eventType = 'appendNewState';
|
||||
this.GetEditorComponent().dispatchEvent(new CustomEvent(eventType, { detail: historyState }));
|
||||
this.AddEventListener(callback, eventType);
|
||||
}
|
||||
|
||||
public OHistoryState: KnockoutObservable<any>;
|
||||
public AddContainer(index: number, type: string, parentId: string, callback?: (state: IEditorState) => void) {
|
||||
const detail = {
|
||||
index,
|
||||
type,
|
||||
parentId
|
||||
}
|
||||
const eventType = 'addContainer';
|
||||
this.GetEditorComponent().dispatchEvent(new CustomEvent(eventType, { detail }));
|
||||
this.AddEventListener(callback, eventType);
|
||||
}
|
||||
|
||||
private InitEventsListener() {
|
||||
this.$component[0].addEventListener('getCurrentHistoryState', (e: CustomEvent) => {
|
||||
this.OHistoryState(e.detail);
|
||||
console.log(this.OHistoryState());
|
||||
});
|
||||
this.$component[0].addEventListener('getEditorState', (e) => console.log((e as any).detail));
|
||||
public AddContainerToSelectedContainer(index: number, type: string, callback?: (state: IEditorState) => void) {
|
||||
const detail = {
|
||||
index,
|
||||
type
|
||||
}
|
||||
const eventType = 'addContainerToSelectedContainer';
|
||||
this.GetEditorComponent().dispatchEvent(new CustomEvent(eventType, { detail }));
|
||||
this.AddEventListener(callback, eventType);
|
||||
}
|
||||
|
||||
public AppendContainer(type: string, parentId: string, callback?: (state: IEditorState) => void) {
|
||||
const detail = {
|
||||
type,
|
||||
parentId
|
||||
}
|
||||
const eventType = 'appendContainer';
|
||||
this.GetEditorComponent().dispatchEvent(new CustomEvent(eventType, { detail }));
|
||||
this.AddEventListener(callback, eventType);
|
||||
}
|
||||
|
||||
public AppendContainerToSelectedContainer(type: string, callback?: (state: IEditorState) => void) {
|
||||
const detail = {
|
||||
type
|
||||
}
|
||||
const eventType = 'appendContainerToSelectedContainer';
|
||||
this.GetEditorComponent().dispatchEvent(new CustomEvent(eventType, { detail }));
|
||||
this.AddEventListener(callback, eventType);
|
||||
}
|
||||
|
||||
private AddEventListener(callback: (...args: any[]) => void, eventType: string) {
|
||||
const root = this.GetRootComponent();
|
||||
const listener = (e: CustomEvent) => {
|
||||
e.target.removeEventListener(e.type, listener);
|
||||
callback && callback(e.detail);
|
||||
};
|
||||
root.addEventListener(eventType, listener);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ function UseShortcuts(
|
|||
});
|
||||
}
|
||||
|
||||
function UseWindowEvents(
|
||||
function UseCustomEvents(
|
||||
root: Element | Document,
|
||||
history: IHistoryState[],
|
||||
historyCurrentStep: number,
|
||||
|
@ -178,7 +178,7 @@ export function Editor(props: IEditorProps): JSX.Element {
|
|||
|
||||
// Events
|
||||
UseShortcuts(history, historyCurrentStep, setHistoryCurrentStep);
|
||||
UseWindowEvents(
|
||||
UseCustomEvents(
|
||||
props.root,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
|
|
59
src/Components/Loader/Loader.scss
Normal file
59
src/Components/Loader/Loader.scss
Normal file
|
@ -0,0 +1,59 @@
|
|||
$foreground: #3b82f6;
|
||||
|
||||
.loader,
|
||||
.loader:before,
|
||||
.loader:after {
|
||||
background:$foreground;
|
||||
-webkit-animation:load1 1s infinite ease-in-out;
|
||||
animation:load1 1s infinite ease-in-out;
|
||||
width:1em;
|
||||
height:4em;
|
||||
}
|
||||
|
||||
.loader {
|
||||
color:$foreground;
|
||||
text-indent:-9999em;
|
||||
margin:88px auto;
|
||||
position:relative;
|
||||
font-size:11px;
|
||||
-webkit-transform: translateZ(0);
|
||||
-ms-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
-webkit-animation-delay:-0.16s;
|
||||
animation-delay:-0.16s;
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
position:absolute;
|
||||
top:0;
|
||||
content:'';
|
||||
}
|
||||
|
||||
&:before {
|
||||
left:-1.5em;
|
||||
-webkit-animation-delay:-0.32s;
|
||||
animation-delay:-0.32s;
|
||||
}
|
||||
|
||||
&:after {
|
||||
left:1.5em;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@mixin load1-frames {
|
||||
0%,
|
||||
80%,
|
||||
100% {
|
||||
box-shadow:0 0;
|
||||
height:4em;
|
||||
}
|
||||
|
||||
40% {
|
||||
box-shadow:0 -2em;
|
||||
height:5em;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes load1 {@include load1-frames;}
|
||||
@keyframes load1 {@include load1-frames;}
|
14
src/Components/Loader/Loader.tsx
Normal file
14
src/Components/Loader/Loader.tsx
Normal file
|
@ -0,0 +1,14 @@
|
|||
import './Loader.scss';
|
||||
|
||||
import * as React from 'react';
|
||||
|
||||
export interface ILoaderProps {
|
||||
}
|
||||
|
||||
export function Loader(props: ILoaderProps): JSX.Element {
|
||||
return (
|
||||
<div className='loader'>
|
||||
Loading...
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
import * as React from 'react';
|
||||
import { FAST_BOOT } from '../../utils/default';
|
||||
import { Loader } from '../Loader/Loader';
|
||||
|
||||
interface IMainMenuProps {
|
||||
newEditor: () => void
|
||||
|
@ -8,10 +10,21 @@ interface IMainMenuProps {
|
|||
enum WindowState {
|
||||
Main,
|
||||
Load,
|
||||
Loading,
|
||||
}
|
||||
|
||||
export function MainMenu(props: IMainMenuProps): JSX.Element {
|
||||
const [windowState, setWindowState] = React.useState(WindowState.Main);
|
||||
|
||||
if (FAST_BOOT) {
|
||||
props.newEditor();
|
||||
return (
|
||||
<div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'>
|
||||
<Loader />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
switch (windowState) {
|
||||
case WindowState.Load:
|
||||
return (
|
||||
|
@ -46,10 +59,19 @@ export function MainMenu(props: IMainMenuProps): JSX.Element {
|
|||
</div>
|
||||
|
||||
);
|
||||
case WindowState.Loading:
|
||||
return (
|
||||
<div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'>
|
||||
<Loader />
|
||||
</div>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<div className='absolute bg-blue-50 p-12 rounded-lg drop-shadow-lg grid grid-cols-1 md:grid-cols-2 gap-8 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'>
|
||||
<button type="button" className='mainmenu-btn' onClick={props.newEditor}>Start from scratch</button>
|
||||
<button type="button" className='mainmenu-btn' onClick={() => {
|
||||
setWindowState(WindowState.Loading);
|
||||
props.newEditor();
|
||||
}}>Start from scratch</button>
|
||||
<button type="button" className='mainmenu-btn' onClick={() => setWindowState(WindowState.Load)}>Load a configuration file</button>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
import { Dispatch, SetStateAction } from 'react';
|
||||
import { AddContainer as AddContainerAction, AddContainerToSelectedContainer as AddContainerToSelectedContainerAction } from '../Components/Editor/Actions/AddContainer';
|
||||
import { DeleteContainer as DeleteContainerAction, SelectContainer as SelectContainerAction } from '../Components/Editor/Actions/ContainerOperations';
|
||||
import { AddSymbol as AddSymbolAction, DeleteSymbol as DeleteSymbolAction, SelectSymbol as SelectSymbolAction } from '../Components/Editor/Actions/SymbolOperations';
|
||||
import { GetCurrentHistory } from '../Components/Editor/Editor';
|
||||
import { IConfiguration } from '../Interfaces/IConfiguration';
|
||||
import { IEditorState } from '../Interfaces/IEditorState';
|
||||
import { IHistoryState } from '../Interfaces/IHistoryState';
|
||||
import { FindContainerById } from '../utils/itertools';
|
||||
import { ReviveState } from '../utils/saveload';
|
||||
|
||||
function InitEditor(configuration: IConfiguration): void {
|
||||
// faire comme la callback de fetch
|
||||
}
|
||||
|
||||
function GetEditorState(root: Element | Document,
|
||||
editorState: IEditorState): void {
|
||||
const customEvent = new CustomEvent<IEditorState>('getEditorState', { detail: editorState });
|
||||
const customEvent = new CustomEvent<IEditorState>('getEditorState', { detail: structuredClone(editorState) });
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
|
@ -19,7 +17,7 @@ function GetCurrentHistoryState(root: Element | Document,
|
|||
editorState: IEditorState): void {
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'getCurrentHistoryState',
|
||||
{ detail: editorState.history[editorState.historyCurrentStep] });
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
|
@ -33,6 +31,244 @@ function AppendNewState(root: Element | Document,
|
|||
|
||||
history.push(state);
|
||||
setNewHistory(history);
|
||||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'appendNewState',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
function AddContainer(root: Element | Document,
|
||||
editorState: IEditorState,
|
||||
setNewHistory: (newHistory: IHistoryState[]) => void,
|
||||
eventInitDict?: CustomEventInit): void {
|
||||
const {
|
||||
index,
|
||||
type,
|
||||
parentId
|
||||
} = eventInitDict?.detail;
|
||||
|
||||
const history = GetCurrentHistory(editorState.history, editorState.historyCurrentStep);
|
||||
const newHistory = AddContainerAction(
|
||||
index,
|
||||
type,
|
||||
parentId,
|
||||
editorState.configuration,
|
||||
history,
|
||||
editorState.historyCurrentStep
|
||||
);
|
||||
setNewHistory(newHistory);
|
||||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'addContainer',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
function AddContainerToSelectedContainer(root: Element | Document,
|
||||
editorState: IEditorState,
|
||||
setNewHistory: (newHistory: IHistoryState[]) => void,
|
||||
eventInitDict?: CustomEventInit): void {
|
||||
const {
|
||||
index,
|
||||
type
|
||||
} = eventInitDict?.detail;
|
||||
|
||||
const history = GetCurrentHistory(editorState.history, editorState.historyCurrentStep);
|
||||
const currentState = history[editorState.historyCurrentStep];
|
||||
|
||||
const newHistory = AddContainerAction(
|
||||
index,
|
||||
type,
|
||||
currentState.selectedContainerId,
|
||||
editorState.configuration,
|
||||
history,
|
||||
editorState.historyCurrentStep
|
||||
);
|
||||
setNewHistory(newHistory);
|
||||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'addContainerToSelectedContainer',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
function AppendContainer(root: Element | Document,
|
||||
editorState: IEditorState,
|
||||
setNewHistory: (newHistory: IHistoryState[]) => void,
|
||||
eventInitDict?: CustomEventInit): void {
|
||||
const {
|
||||
type,
|
||||
parentId
|
||||
} = eventInitDict?.detail;
|
||||
|
||||
const history = GetCurrentHistory(editorState.history, editorState.historyCurrentStep);
|
||||
const currentState = history[editorState.historyCurrentStep];
|
||||
|
||||
const parent = FindContainerById(currentState.mainContainer, parentId);
|
||||
|
||||
const newHistory = AddContainerAction(
|
||||
parent?.children.length ?? 0,
|
||||
type,
|
||||
parentId,
|
||||
editorState.configuration,
|
||||
history,
|
||||
editorState.historyCurrentStep
|
||||
);
|
||||
setNewHistory(newHistory);
|
||||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'appendContainerToSelectedContainer',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
function AppendContainerToSelectedContainer(root: Element | Document,
|
||||
editorState: IEditorState,
|
||||
setNewHistory: (newHistory: IHistoryState[]) => void,
|
||||
eventInitDict?: CustomEventInit): void {
|
||||
const {
|
||||
type
|
||||
} = eventInitDict?.detail;
|
||||
|
||||
const history = GetCurrentHistory(editorState.history, editorState.historyCurrentStep);
|
||||
const currentState = history[editorState.historyCurrentStep];
|
||||
|
||||
const selected = FindContainerById(currentState.mainContainer, currentState.selectedContainerId);
|
||||
|
||||
const newHistory = AddContainerToSelectedContainerAction(
|
||||
type,
|
||||
selected,
|
||||
editorState.configuration,
|
||||
history,
|
||||
editorState.historyCurrentStep
|
||||
);
|
||||
|
||||
if (newHistory === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setNewHistory(newHistory);
|
||||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'appendContainerToSelectedContainer',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
function SelectContainer(root: Element | Document,
|
||||
editorState: IEditorState,
|
||||
setNewHistory: (newHistory: IHistoryState[]) => void,
|
||||
eventInitDict?: CustomEventInit): void {
|
||||
const {
|
||||
containerId
|
||||
} = eventInitDict?.detail;
|
||||
|
||||
const history = GetCurrentHistory(editorState.history, editorState.historyCurrentStep);
|
||||
|
||||
const newHistory = SelectContainerAction(
|
||||
containerId,
|
||||
history,
|
||||
editorState.historyCurrentStep
|
||||
);
|
||||
setNewHistory(newHistory);
|
||||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'selectContainer',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
function DeleteContainer(root: Element | Document,
|
||||
editorState: IEditorState,
|
||||
setNewHistory: (newHistory: IHistoryState[]) => void,
|
||||
eventInitDict?: CustomEventInit): void {
|
||||
const {
|
||||
containerId
|
||||
} = eventInitDict?.detail;
|
||||
|
||||
const history = GetCurrentHistory(editorState.history, editorState.historyCurrentStep);
|
||||
|
||||
const newHistory = DeleteContainerAction(
|
||||
containerId,
|
||||
history,
|
||||
editorState.historyCurrentStep
|
||||
);
|
||||
setNewHistory(newHistory);
|
||||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'deleteContainer',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
function AddSymbol(root: Element | Document,
|
||||
editorState: IEditorState,
|
||||
setNewHistory: (newHistory: IHistoryState[]) => void,
|
||||
eventInitDict?: CustomEventInit): void {
|
||||
const {
|
||||
name
|
||||
} = eventInitDict?.detail;
|
||||
|
||||
const history = GetCurrentHistory(editorState.history, editorState.historyCurrentStep);
|
||||
|
||||
const newHistory = AddSymbolAction(
|
||||
name,
|
||||
editorState.configuration,
|
||||
history,
|
||||
editorState.historyCurrentStep
|
||||
);
|
||||
setNewHistory(newHistory);
|
||||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'AddSymbol',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
function SelectSymbol(root: Element | Document,
|
||||
editorState: IEditorState,
|
||||
setNewHistory: (newHistory: IHistoryState[]) => void,
|
||||
eventInitDict?: CustomEventInit): void {
|
||||
const {
|
||||
symbolId
|
||||
} = eventInitDict?.detail;
|
||||
|
||||
const history = GetCurrentHistory(editorState.history, editorState.historyCurrentStep);
|
||||
|
||||
const newHistory = SelectSymbolAction(
|
||||
symbolId,
|
||||
history,
|
||||
editorState.historyCurrentStep
|
||||
);
|
||||
setNewHistory(newHistory);
|
||||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'SelectSymbol',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
function DeleteSymbol(root: Element | Document,
|
||||
editorState: IEditorState,
|
||||
setNewHistory: (newHistory: IHistoryState[]) => void,
|
||||
eventInitDict?: CustomEventInit): void {
|
||||
const {
|
||||
symbolId
|
||||
} = eventInitDict?.detail;
|
||||
|
||||
const history = GetCurrentHistory(editorState.history, editorState.historyCurrentStep);
|
||||
const newHistory = DeleteSymbolAction(
|
||||
symbolId,
|
||||
history,
|
||||
editorState.historyCurrentStep
|
||||
);
|
||||
setNewHistory(newHistory);
|
||||
|
||||
const customEvent = new CustomEvent<IHistoryState>(
|
||||
'DeleteSymbol',
|
||||
{ detail: structuredClone(editorState.history[editorState.historyCurrentStep]) });
|
||||
root.dispatchEvent(customEvent);
|
||||
}
|
||||
|
||||
export interface IEditorEvent {
|
||||
|
@ -48,5 +284,14 @@ export interface IEditorEvent {
|
|||
export const events: IEditorEvent[] = [
|
||||
{ name: 'getEditorState', func: GetEditorState },
|
||||
{ name: 'getCurrentHistoryState', func: GetCurrentHistoryState },
|
||||
{ name: 'appendNewState', func: AppendNewState }
|
||||
{ name: 'appendNewState', func: AppendNewState },
|
||||
{ name: 'addContainer', func: AddContainer },
|
||||
{ name: 'addContainerToSelectedContainer', func: AddContainerToSelectedContainer },
|
||||
{ name: 'appendContainer', func: AppendContainer },
|
||||
{ name: 'appendContainerToSelectedContainer', func: AppendContainerToSelectedContainer },
|
||||
{ name: 'selectContainer', func: SelectContainer },
|
||||
{ name: 'deleteContainer', func: DeleteContainer },
|
||||
{ name: 'addSymbol', func: AddSymbol },
|
||||
{ name: 'selectSymbol', func: SelectSymbol },
|
||||
{ name: 'deleteSymbol', func: DeleteSymbol }
|
||||
];
|
||||
|
|
101
src/dts/generate_dts.py
Normal file
101
src/dts/generate_dts.py
Normal file
|
@ -0,0 +1,101 @@
|
|||
'''
|
||||
Generate a definition file with a global namespace
|
||||
from a typescript module definition file
|
||||
'''
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
import argparse
|
||||
|
||||
parser = parser = argparse.ArgumentParser(description='Generate a definition file with a global namespace from a typescript module definition file')
|
||||
parser.add_argument('namespace',
|
||||
help='Namespace used in the global script. (example: Three.js use THREE as its namespace)')
|
||||
parser.add_argument('output_filename',
|
||||
help='Output d.ts definition file. (example: three.d.ts)')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
output_filename = args.output_filename
|
||||
namespace = args.namespace
|
||||
|
||||
|
||||
import_pattern = re.compile(
|
||||
r"import(?:[\"'\s]*([\w*{}\n\r\t, ]+)from\s*)?[\"'\s].*([@\w_-]+)[\"'\s].*;"
|
||||
)
|
||||
export_pattern = re.compile(
|
||||
r"export ([*] from [\"'\s].*[\"'\s]|{.*}(?: from [\"'\s].*[\"'\s])?);"
|
||||
)
|
||||
|
||||
filter_directories = ["./Enums", "./Interfaces"]
|
||||
|
||||
def main():
|
||||
'''
|
||||
Entry point function
|
||||
'''
|
||||
with open(output_filename, 'w') as output_file:
|
||||
output_file.write(('declare namespace {} {{\n'.format(namespace)))
|
||||
for root, subdirs, files in os.walk('./'):
|
||||
if root not in filter_directories:
|
||||
continue
|
||||
|
||||
print('--\nroot = ' + root)
|
||||
|
||||
for subdir in subdirs:
|
||||
print('\t- subdirectory ' + subdir)
|
||||
|
||||
for filename in files:
|
||||
if filename == 'output.d.ts':
|
||||
continue
|
||||
|
||||
if filename == 'my-directory-list.txt':
|
||||
os.remove(os.path.join(root, filename))
|
||||
continue
|
||||
|
||||
suffixes = pathlib.Path(filename).suffixes
|
||||
if (suffixes != ['.d', '.ts']):
|
||||
continue
|
||||
|
||||
file_path = os.path.join(root, filename)
|
||||
file_path = file_path.replace('\\', '/')
|
||||
|
||||
print('\t- file %s (full path: %s)' % (filename, file_path))
|
||||
with open(file_path, 'r') as cur_file:
|
||||
f_content = cur_file.read()
|
||||
|
||||
# removes imports
|
||||
# see https://gist.github.com/manekinekko/7e58a17bc62a9be47172
|
||||
f_content = import_pattern.sub('', f_content)
|
||||
|
||||
# Replace 'export { my_class as synonym };'
|
||||
# => 'class synonym extend my_class {}'
|
||||
f_content = re.sub(
|
||||
r"export ({ ([A-Z].*) as ([A-Z].*) });",
|
||||
"export class \\g<3> extends \\g<2> {}",
|
||||
f_content,
|
||||
0,
|
||||
re.MULTILINE
|
||||
)
|
||||
|
||||
# Replace 'export declare class' => 'export class'
|
||||
f_content = re.sub(r"export (declare) class", 'export class', f_content, 0, re.MULTILINE)
|
||||
f_content = re.sub(r"export (declare) enum", 'export enum', f_content, 0, re.MULTILINE)
|
||||
f_content = re.sub(r"export (declare) function", 'export function', f_content, 0, re.MULTILINE)
|
||||
f_content = re.sub(r"export (declare) type", 'export type', f_content, 0, re.MULTILINE)
|
||||
|
||||
# Replace 'export { my_func as synonym }' => 'export function synonym = my_func'
|
||||
|
||||
# Replace 'export default class' => 'export class'
|
||||
f_content = re.sub(r"(export) default", "\\1", f_content, 0, re.MULTILINE)
|
||||
|
||||
# Replace other exports : 'export { .* } from '.*';' and 'export [*] from '.*';
|
||||
f_content = export_pattern.sub('', f_content)
|
||||
|
||||
# Specific to your module
|
||||
f_content = re.sub('export as namespace {};'.format(namespace), '', f_content)
|
||||
|
||||
output_file.write(f_content)
|
||||
output_file.write('\n')
|
||||
output_file.write(('}\n'))
|
||||
|
||||
main()
|
469
src/dts/svgld.d.ts
vendored
Normal file
469
src/dts/svgld.d.ts
vendored
Normal file
|
@ -0,0 +1,469 @@
|
|||
declare namespace SVGLD {
|
||||
/**
|
||||
* Add method when creating a container
|
||||
* - Append will append to the last children in list
|
||||
* - Insert will always place it at the begining
|
||||
* - Replace will remove the selected container and insert a new one
|
||||
* (default: Append)
|
||||
*/
|
||||
export enum AddMethod {
|
||||
Append = 0,
|
||||
Insert = 1,
|
||||
Replace = 2
|
||||
}
|
||||
|
||||
export enum MessageType {
|
||||
Normal = 0,
|
||||
Success = 1,
|
||||
Warning = 2,
|
||||
Error = 3
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe the type of the property.
|
||||
* Used for the assignation in the OnPropertyChange function
|
||||
* See ContainerOperations.ts's OnPropertyChange
|
||||
*/
|
||||
export enum PropertyType {
|
||||
/**
|
||||
* Simple property: is not inside any object: id, x, width... (default)
|
||||
*/
|
||||
Simple = 0,
|
||||
/**
|
||||
* Style property: is inside the style object: stroke, fillOpacity...
|
||||
*/
|
||||
Style = 1,
|
||||
/**
|
||||
* Margin property: is inside the margin property: left, bottom, top, right...
|
||||
*/
|
||||
Margin = 2
|
||||
}
|
||||
|
||||
export enum XPositionReference {
|
||||
Left = 0,
|
||||
Center = 1,
|
||||
Right = 2
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface IAction {
|
||||
Id: string;
|
||||
CustomLogo: IImage;
|
||||
Label: string;
|
||||
Description: string;
|
||||
Action: string;
|
||||
AddingBehavior: AddMethod;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Model of available container used in application configuration */
|
||||
export interface IAvailableContainer {
|
||||
/** type */
|
||||
Type: string;
|
||||
/** displayed text */
|
||||
DisplayedText?: string;
|
||||
/** category */
|
||||
Category?: string;
|
||||
/** horizontal offset */
|
||||
X?: number;
|
||||
/** vertical offset */
|
||||
Y?: number;
|
||||
/** width */
|
||||
Width?: number;
|
||||
/** height */
|
||||
Height?: number;
|
||||
/**
|
||||
* Minimum width (min=1)
|
||||
* Allows the container to set isRigidBody to false when it gets squeezed
|
||||
* by an anchor
|
||||
*/
|
||||
MinWidth?: number;
|
||||
/**
|
||||
* Maximum width
|
||||
*/
|
||||
MaxWidth?: number;
|
||||
/** margin */
|
||||
Margin?: IMargin;
|
||||
/** true if anchor, false otherwise */
|
||||
IsAnchor?: boolean;
|
||||
/** true if flex, false otherwise */
|
||||
IsFlex?: boolean;
|
||||
/** Method used on container add */
|
||||
AddMethod?: AddMethod;
|
||||
/** Horizontal alignment, also determines the visual location of x {Left = 0, Center, Right } */
|
||||
XPositionReference?: XPositionReference;
|
||||
/**
|
||||
* (optional)
|
||||
* Replace a <rect> by a customized "SVG". It is not really an svg but it at least allows
|
||||
* to draw some patterns that can be bind to the properties of the container
|
||||
* Use {prop} to bind a property. Use {{ styleProp }} to use an object.
|
||||
* Example :
|
||||
* ```
|
||||
* `<rect width="{width}" height="{height}" style="{style}"></rect>
|
||||
* <rect width="{width}" height="{height}" stroke="black" fill-opacity="0"></rect>
|
||||
* <line x1="0" y1="0" x2="{width}" y2="{height}" stroke="black" style='{{ "transform":"scaleY(0.5)"}}'></line>
|
||||
* <line x1="{width}" y1="0" x2="0" y2="{height}" stroke="black" style='{userData.styleLine}'></line>
|
||||
* `
|
||||
* ```
|
||||
*/
|
||||
CustomSVG?: string;
|
||||
/**
|
||||
* (optional)
|
||||
* Disabled when Pattern is used.
|
||||
*
|
||||
* Replace a <rect> by a customized "SVG". It is not really an svg but it at least allows
|
||||
* to draw some patterns that can be bind to the properties of the container
|
||||
* Use {prop} to bind a property. Use {{ styleProp }} to use an object.
|
||||
* Example :
|
||||
* ```
|
||||
* `<rect width="{width}" height="{height}" style="{style}"></rect>
|
||||
* <rect width="{width}" height="{height}" stroke="black" fill-opacity="0"></rect>
|
||||
* <line x1="0" y1="0" x2="{width}" y2="{height}" stroke="black" style='{{ "transform":"scaleY(0.5)"}}'></line>
|
||||
* <line x1="{width}" y1="0" x2="0" y2="{height}" stroke="black" style='{userData.styleLine}'></line>
|
||||
* `
|
||||
* ```
|
||||
*/
|
||||
DefaultChildType?: string;
|
||||
/**
|
||||
* Allow to use a Pattern to create the list of children
|
||||
* Cannot be used with DefaultChildType,
|
||||
* DefaultChildType will be disabled for this container and the children
|
||||
*/
|
||||
Pattern?: string;
|
||||
/** if true, show the dimension of the container */
|
||||
ShowSelfDimensions?: boolean;
|
||||
/** if true show the overall dimensions of its children */
|
||||
ShowChildrenDimensions?: boolean;
|
||||
/**
|
||||
* if true, allows a parent dimension borrower to uses its x coordinate for as a reference point for a dimension
|
||||
*/
|
||||
MarkPositionToDimensionBorrower?: boolean;
|
||||
/**
|
||||
* if true, show a dimension from the edge of the container to end
|
||||
* and insert dimensions marks at lift up children (see liftDimensionToBorrower)
|
||||
*/
|
||||
IsDimensionBorrower?: boolean;
|
||||
/**
|
||||
* if true, hide the entry in the sidebar (default: false)
|
||||
*/
|
||||
IsHidden?: boolean;
|
||||
/**
|
||||
* Disable a list of available container to be added inside
|
||||
*/
|
||||
Blacklist?: string[];
|
||||
/**
|
||||
* Cannot be used with blacklist. Whitelist will be prioritized.
|
||||
* To disable the whitelist, Whitelist must be undefined.
|
||||
* Only allow a set of available container to be added inside
|
||||
*/
|
||||
Whitelist?: string[];
|
||||
/**
|
||||
* (optional)
|
||||
* Style of the <rect>
|
||||
*/
|
||||
Style?: React.CSSProperties;
|
||||
/**
|
||||
* List of possible actions shown on right-click
|
||||
*/
|
||||
Actions?: IAction[];
|
||||
/**
|
||||
* (optional)
|
||||
* User data that can be used for data storage or custom SVG
|
||||
*/
|
||||
UserData?: object;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Model of available symbol to configure the application */
|
||||
export interface IAvailableSymbol {
|
||||
Name: string;
|
||||
Image: IImage;
|
||||
Width?: number;
|
||||
Height?: number;
|
||||
XPositionReference?: XPositionReference;
|
||||
}
|
||||
|
||||
export interface ICategory {
|
||||
Type: string;
|
||||
DisplayedText?: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Model of configuration for the application to configure it */
|
||||
export interface IConfiguration {
|
||||
AvailableContainers: IAvailableContainer[];
|
||||
AvailableSymbols: IAvailableSymbol[];
|
||||
Categories: ICategory[];
|
||||
Patterns: IPattern[];
|
||||
MainContainer: IAvailableContainer;
|
||||
}
|
||||
|
||||
|
||||
export interface IContainerModel {
|
||||
children: IContainerModel[];
|
||||
parent: IContainerModel | null;
|
||||
properties: IContainerProperties;
|
||||
userData: Record<string, string | number>;
|
||||
}
|
||||
/**
|
||||
* Macro for creating the interface
|
||||
* Do not add methods since they will be lost during serialization
|
||||
*/
|
||||
export class ContainerModel implements IContainerModel {
|
||||
children: IContainerModel[];
|
||||
parent: IContainerModel | null;
|
||||
properties: IContainerProperties;
|
||||
userData: Record<string, string | number>;
|
||||
constructor(parent: IContainerModel | null, properties: IContainerProperties, children?: IContainerModel[], userData?: {});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Properties of a container
|
||||
*/
|
||||
export interface IContainerProperties {
|
||||
/** id of the container */
|
||||
id: string;
|
||||
/** type matching the configuration on construction */
|
||||
type: string;
|
||||
/** id of the parent container (null when there is no parent) */
|
||||
parentId: string;
|
||||
/** id of the linked symbol ('' when there is no parent) */
|
||||
linkedSymbolId: string;
|
||||
/** Text displayed in the container */
|
||||
displayedText: string;
|
||||
/** horizontal offset */
|
||||
x: number;
|
||||
/** vertical offset */
|
||||
y: number;
|
||||
/** margin */
|
||||
margin: IMargin;
|
||||
/**
|
||||
* Minimum width (min=1)
|
||||
* Allows the container to set isRigidBody to false when it gets squeezed
|
||||
* by an anchor
|
||||
*/
|
||||
minWidth: number;
|
||||
/**
|
||||
* Maximum width
|
||||
*/
|
||||
maxWidth: number;
|
||||
/** width */
|
||||
width: number;
|
||||
/** height */
|
||||
height: number;
|
||||
/** true if anchor, false otherwise */
|
||||
isAnchor: boolean;
|
||||
/** true if flex, false otherwise */
|
||||
isFlex: boolean;
|
||||
/** Horizontal alignment, also determines the visual location of x {Left = 0, Center, Right } */
|
||||
xPositionReference: XPositionReference;
|
||||
/** if true, show the dimension of the container */
|
||||
showSelfDimensions: boolean;
|
||||
/** if true show the overall dimensions of its children */
|
||||
showChildrenDimensions: boolean;
|
||||
/**
|
||||
* if true, allows a parent dimension borrower to borrow its x coordinate
|
||||
* as a reference point for a dimension
|
||||
*/
|
||||
markPositionToDimensionBorrower: boolean;
|
||||
/**
|
||||
* if true, show a dimension from the edge of the container to end
|
||||
* and insert dimensions marks at lift up children (see liftDimensionToBorrower)
|
||||
*/
|
||||
isDimensionBorrower: boolean;
|
||||
/**
|
||||
* Warnings of a container
|
||||
*/
|
||||
warning: string;
|
||||
/**
|
||||
* (optional)
|
||||
* Replace a <rect> by a customized "SVG". It is not really an svg but it at least allows
|
||||
* to draw some patterns that can be bind to the properties of the container
|
||||
* Use {prop} to bind a property. Use {{ styleProp }} to use an object.
|
||||
* Example :
|
||||
* ```
|
||||
* `<rect width="{width}" height="{height}" style="{style}"></rect>
|
||||
* <rect width="{width}" height="{height}" stroke="black" fill-opacity="0"></rect>
|
||||
* <line x1="0" y1="0" x2="{width}" y2="{height}" stroke="black" style='{{ "transform":"scaleY(0.5)"}}'></line>
|
||||
* <line x1="{width}" y1="0" x2="0" y2="{height}" stroke="black" style='{userData.styleLine}'></line>
|
||||
* `
|
||||
* ```
|
||||
*/
|
||||
customSVG?: string;
|
||||
/**
|
||||
* (optional)
|
||||
* Style of the <rect>
|
||||
*/
|
||||
style?: React.CSSProperties;
|
||||
/**
|
||||
* (optional)
|
||||
* User data that can be used for data storage or custom SVG
|
||||
*/
|
||||
userData?: object;
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface IEditorState {
|
||||
history: IHistoryState[];
|
||||
historyCurrentStep: number;
|
||||
configuration: IConfiguration;
|
||||
}
|
||||
|
||||
|
||||
export interface IGetFeedbackRequest {
|
||||
/** Current application state */
|
||||
ApplicationState: IHistoryState;
|
||||
}
|
||||
|
||||
|
||||
export interface IGetFeedbackResponse {
|
||||
messages: IMessage[];
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface IHistoryState {
|
||||
/** Last editor action */
|
||||
lastAction: string;
|
||||
/** Reference to the main container */
|
||||
mainContainer: IContainerModel;
|
||||
/** Id of the selected container */
|
||||
selectedContainerId: string;
|
||||
/** Counter of type of container. Used for ids. */
|
||||
typeCounters: Record<string, number>;
|
||||
/** List of symbols */
|
||||
symbols: Map<string, ISymbolModel>;
|
||||
/** Selected symbols id */
|
||||
selectedSymbolId: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Model of an image with multiple source
|
||||
* It must at least have one source.
|
||||
*
|
||||
* If Url/Base64Image and Svg are set,
|
||||
* Url/Base64Image will be shown in the menu while SVG will be drawn
|
||||
*/
|
||||
export interface IImage {
|
||||
/** Name of the image */
|
||||
Name: string;
|
||||
/** (optional) Url of the image */
|
||||
Url?: string;
|
||||
/** (optional) base64 data of the image */
|
||||
Base64Image?: string;
|
||||
/** (optional) SVG string */
|
||||
Svg?: string;
|
||||
}
|
||||
|
||||
|
||||
export interface IInputGroup {
|
||||
text: React.ReactNode;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface IMargin {
|
||||
left?: number;
|
||||
bottom?: number;
|
||||
top?: number;
|
||||
right?: number;
|
||||
}
|
||||
|
||||
|
||||
export interface IMessage {
|
||||
text: string;
|
||||
type: MessageType;
|
||||
}
|
||||
|
||||
|
||||
export interface IPattern {
|
||||
/**
|
||||
* Unique id for the pattern
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Text to display in the sidebar
|
||||
*/
|
||||
text: string;
|
||||
/**
|
||||
* IAvailableContainer id used to wrap the children.
|
||||
*/
|
||||
wrapper: string;
|
||||
/**
|
||||
* List of ids of Pattern or IAvailableContainer
|
||||
* If a IAvailableContainer and a Pattern have the same id,
|
||||
* IAvailableContainer will be prioritized
|
||||
*/
|
||||
children: string[];
|
||||
}
|
||||
export type ContainerOrPattern = IAvailableContainer | IPattern;
|
||||
export function GetPattern(id: string, configs: Map<string, IAvailableContainer>, patterns: Map<string, IPattern>): ContainerOrPattern | undefined;
|
||||
export function IsPattern(id: string, configs: Map<string, IAvailableContainer>, patterns: Map<string, IPattern>): boolean;
|
||||
|
||||
export interface IPoint {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface ISetContainerListRequest {
|
||||
/** Name of the action declared in the API */
|
||||
Action: string;
|
||||
/** Selected container */
|
||||
Container: IContainerModel;
|
||||
/** The previous sibling container */
|
||||
PreviousContainer: IContainerModel | undefined;
|
||||
/** The next sibling container */
|
||||
NextContainer: IContainerModel | undefined;
|
||||
/** Current application state */
|
||||
ApplicationState: IHistoryState;
|
||||
}
|
||||
|
||||
|
||||
export interface ISetContainerListResponse {
|
||||
Containers: IAvailableContainer[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A SizePointer is a pointer in a 1 dimensional array of width/space
|
||||
* x being the address where the pointer is pointing
|
||||
* width being the overall (un)allocated space affected to the address
|
||||
*/
|
||||
export interface ISizePointer {
|
||||
x: number;
|
||||
width: number;
|
||||
}
|
||||
|
||||
|
||||
export interface ISymbolModel {
|
||||
/** Identifier */
|
||||
id: string;
|
||||
/** Type */
|
||||
type: string;
|
||||
/** Configuration of the symbol */
|
||||
config: IAvailableSymbol;
|
||||
/** Horizontal offset */
|
||||
x: number;
|
||||
/** Width */
|
||||
width: number;
|
||||
/** Height */
|
||||
height: number;
|
||||
/** List of linked container id */
|
||||
linkedContainers: Set<string>;
|
||||
}
|
||||
|
||||
}
|
15
src/dts/tsconfig.dts.json
Normal file
15
src/dts/tsconfig.dts.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
// Change this to match your project
|
||||
"include": ["../Enums/*", "../Interfaces/*"],
|
||||
"compilerOptions": {
|
||||
"target": "ES2021",
|
||||
"module": "es2020",
|
||||
"allowJs": false,
|
||||
"declaration": true,
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "dist",
|
||||
"declarationMap": false
|
||||
}
|
||||
}
|
|
@ -7,6 +7,14 @@ import { IContainerProperties } from '../Interfaces/IContainerProperties';
|
|||
import { IEditorState } from '../Interfaces/IEditorState';
|
||||
import { ISymbolModel } from '../Interfaces/ISymbolModel';
|
||||
|
||||
/// EDITOR DEFAULTS ///
|
||||
|
||||
export const FAST_BOOT = import.meta.env.PROD;
|
||||
export const ENABLE_SHORTCUTS = true;
|
||||
export const MAX_HISTORY = 200;
|
||||
export const APPLY_BEHAVIORS_ON_CHILDREN = true;
|
||||
export const MAX_FRAMERATE = 60;
|
||||
|
||||
/// CONTAINER DEFAULTS ///
|
||||
|
||||
/** Enable the swap behavior */
|
||||
|
@ -41,13 +49,6 @@ export const NOTCHES_LENGTH = 10;
|
|||
export const DEFAULT_SYMBOL_WIDTH = 32;
|
||||
export const DEFAULT_SYMBOL_HEIGHT = 32;
|
||||
|
||||
/// EDITOR DEFAULTS ///
|
||||
|
||||
export const ENABLE_SHORTCUTS = true;
|
||||
export const MAX_HISTORY = 200;
|
||||
export const APPLY_BEHAVIORS_ON_CHILDREN = true;
|
||||
export const MAX_FRAMERATE = 60;
|
||||
|
||||
/**
|
||||
* Returns the default editor state given the configuration
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue