import { PositionReference } from '../Enums/PositionReference'; import { IAvailableContainer } from '../Interfaces/IAvailableContainer'; import { IAvailableSymbol } from '../Interfaces/IAvailableSymbol'; import { IConfiguration } from '../Interfaces/IConfiguration'; import { ContainerModel, IContainerModel } from '../Interfaces/IContainerModel'; import { IContainerProperties } from '../Interfaces/IContainerProperties'; import { IEditorState } from '../Interfaces/IEditorState'; import { ISymbolModel } from '../Interfaces/ISymbolModel'; import { Orientation } from '../Enums/Orientation'; import { Position } from '../Enums/Position'; /// EDITOR DEFAULTS /// /** Enable fast boot and disable main menu (default = false) */ export const FAST_BOOT = false; /** Disable any call to the API (default = false) */ export const DISABLE_API = false; /** * Replace the SVG viewer by a canvas * EXPERIMENTAL: svg export wont work and it won't be possible to insert a custom svg) */ export const USE_EXPERIMENTAL_CANVAS_API = false; /** Enable keyboard shortcuts (default = true) */ export const ENABLE_SHORTCUTS = true; /** Size of the history (recommanded = 200) */ export const MAX_HISTORY = 200; /** Apply beheviors on children (recommanded = true) */ export const APPLY_BEHAVIORS_ON_CHILDREN = true; /** Framerate of the svg controller (recommanded = 60) */ export const MAX_FRAMERATE = 60; /// CONTAINER DEFAULTS /// /** Enable the swap behavior (kinda broken recommanded = false) */ export const ENABLE_SWAP = false; /** Enable the rigid behavior (recommanded = true) */ export const ENABLE_RIGID = true; /** * Enable the hard rigid behavior * disallowing the container to overlap (ENABLE_RIGID must be true) * (recommanded = false) */ export const ENABLE_HARD_RIGID = false; /** Enalbe the text in the containers */ export const SHOW_TEXT = false; export const SHOW_SELECTOR_TEXT = true; export const DEFAULTCHILDTYPE_ALLOW_CYCLIC = false; export const DEFAULTCHILDTYPE_MAX_DEPTH = 10; /// DIMENSIONS DEFAULTS /// export const SHOW_SELF_DIMENSIONS = true; export const SHOW_CHILDREN_DIMENSIONS = true; export const SHOW_BORROWER_DIMENSIONS = true; export const SHOW_DIMENSIONS_PER_DEPTH = false; export const DIMENSION_MARGIN = 50; export const SYMBOL_MARGIN = 25; export const NOTCHES_LENGTH = 10; /// SYMBOL DEFAULTS /// export const DEFAULT_SYMBOL_WIDTH = 32; export const DEFAULT_SYMBOL_HEIGHT = 32; /** * Returns the default editor state given the configuration */ export function GetDefaultEditorState(configuration: IConfiguration): IEditorState { if (configuration.MainContainer.Width === undefined || configuration.MainContainer.Height === undefined) { throw new Error('Cannot initialize project! Main container has an undefined size'); } const containerConfig = configuration.AvailableContainers.find(config => config.Type === configuration.MainContainer.Type); let mainContainerConfig: IContainerProperties; if (containerConfig !== undefined) { const clone = structuredClone(containerConfig); const extendedContainerConfig = Object.assign(clone, configuration.MainContainer); if (containerConfig.Style !== undefined) { const styleClone = structuredClone(containerConfig.Style); extendedContainerConfig.Style = Object.assign(styleClone, configuration.MainContainer.Style); } if (extendedContainerConfig.Width === undefined || extendedContainerConfig.Height === undefined) { throw new Error('Cannot initialize project! Main container has an undefined size'); } mainContainerConfig = GetDefaultContainerProps( extendedContainerConfig.Type, 0, null, 0, 0, extendedContainerConfig.Width, extendedContainerConfig.Height, extendedContainerConfig ); } else { mainContainerConfig = GetDefaultContainerProps( configuration.MainContainer.Type, 0, null, 0, 0, configuration.MainContainer.Width, configuration.MainContainer.Height, configuration.MainContainer ); } const mainContainer = new ContainerModel( null, mainContainerConfig ); const typeCounters = {}; (typeCounters as any)[mainContainer.properties.type] = 0; return { configuration, history: [ { lastAction: '', mainContainer, selectedContainerId: mainContainer.properties.id, typeCounters, symbols: new Map(), selectedSymbolId: '' } ], historyCurrentStep: 0 }; } /** * Default config when the API is not available */ export const DEFAULT_CONFIG: IConfiguration = { /* eslint-disable @typescript-eslint/naming-convention */ AvailableContainers: [ { Type: 'Container', MaxWidth: 200, Height: 100, Style: { fillOpacity: 0, stroke: 'green' } } ], AvailableSymbols: [], Categories: [], Patterns: [], MainContainer: { Type: 'Container', Width: 800, Height: 100, Style: { fillOpacity: 0, stroke: 'black' } } /* eslint-enable */ }; /** * Default Main container properties */ export const DEFAULT_MAINCONTAINER_PROPS: IContainerProperties = { id: 'main', type: 'container', parentId: '', linkedSymbolId: '', displayedText: 'main', orientation: Orientation.Horizontal, x: 0, y: 0, margin: {}, minWidth: 1, maxWidth: Number.MAX_SAFE_INTEGER, minHeight: 1, maxHeight: Number.MAX_SAFE_INTEGER, width: Number(DEFAULT_CONFIG.MainContainer.Width), height: Number(DEFAULT_CONFIG.MainContainer.Height), isAnchor: false, isFlex: false, positionReference: PositionReference.TopLeft, hideChildrenInTreeview: false, showChildrenDimensions: [Position.Up, Position.Left], showSelfDimensions: [Position.Up, Position.Left], showDimensionWithMarks: [Position.Down, Position.Right], markPosition: [], warning: '', style: { stroke: 'black', fillOpacity: 0 } }; /** * Returns the default properties of a newly created container * @param type Type of the container * @param typeCount index of the container * @param parent Parent of the container * @param x horizontal offset * @param y vertical offset * @param containerConfig default config of the container sent by the API * @returns {IContainerProperties} Default properties of a newly created container */ export function GetDefaultContainerProps(type: string, typeCount: number, parent: IContainerModel | undefined | null, x: number, y: number, width: number, height: number, containerConfig: IAvailableContainer): IContainerProperties { const orientation = containerConfig.Orientation ?? Orientation.Horizontal; const defaultIsFlex = (orientation === Orientation.Vertical && containerConfig.Height === undefined) || (orientation === Orientation.Horizontal && containerConfig.Width === undefined); return ({ id: `${type}-${typeCount}`, type, parentId: parent?.properties.id ?? '', linkedSymbolId: '', displayedText: `${containerConfig.DisplayedText ?? type}-${typeCount}`, orientation, x, y, margin: containerConfig.Margin ?? {}, width, height, isAnchor: containerConfig.IsAnchor ?? false, isFlex: containerConfig.IsFlex ?? defaultIsFlex, positionReference: containerConfig.PositionReference ?? PositionReference.TopLeft, minWidth: containerConfig.MinWidth ?? 1, maxWidth: containerConfig.MaxWidth ?? Number.MAX_SAFE_INTEGER, minHeight: containerConfig.MinWidth ?? 1, maxHeight: containerConfig.MaxWidth ?? Number.MAX_SAFE_INTEGER, hideChildrenInTreeview: containerConfig.HideChildrenInTreeview ?? false, showChildrenDimensions: containerConfig.ShowChildrenDimensions ?? [], showSelfDimensions: containerConfig.ShowSelfDimensions ?? [], markPosition: containerConfig.MarkPosition ?? [], showDimensionWithMarks: containerConfig.ShowDimensionWithMarks ?? [], warning: '', customSVG: containerConfig.CustomSVG, style: structuredClone(containerConfig.Style), userData: structuredClone(containerConfig.UserData) }); } export function GetDefaultSymbolModel(name: string, newCounters: Record, type: string, symbolConfig: IAvailableSymbol): ISymbolModel { return { id: `${name}-${newCounters[type]}`, type: name, config: structuredClone(symbolConfig), x: 0, width: symbolConfig.Width ?? DEFAULT_SYMBOL_WIDTH, height: symbolConfig.Height ?? DEFAULT_SYMBOL_HEIGHT, linkedContainers: new Set() }; }