From 9f9ec8dc658533697c065ecc9f86580fdeadafde Mon Sep 17 00:00:00 2001 From: Siklos Date: Thu, 18 Aug 2022 15:51:45 +0200 Subject: [PATCH] Implement DefaultChildType --- src/Components/Editor/ContainerOperations.ts | 79 ++++++++++++++++++-- src/Interfaces/IAvailableContainer.ts | 1 + src/utils/default.ts | 2 + test-server/http.js | 3 + 4 files changed, 78 insertions(+), 7 deletions(-) diff --git a/src/Components/Editor/ContainerOperations.ts b/src/Components/Editor/ContainerOperations.ts index 09e35a7..8c327e8 100644 --- a/src/Components/Editor/ContainerOperations.ts +++ b/src/Components/Editor/ContainerOperations.ts @@ -6,7 +6,7 @@ import { findContainerById } from '../../utils/itertools'; import { getCurrentHistory } from './Editor'; import { AddMethod } from '../../Enums/AddMethod'; import { IAvailableContainer } from '../../Interfaces/IAvailableContainer'; -import { GetDefaultContainerProps } from '../../utils/default'; +import { GetDefaultContainerProps, DEFAULTCHILDTYPE_ALLOW_CYCLIC, DEFAULTCHILDTYPE_MAX_DEPTH } from '../../utils/default'; import { ApplyBehaviors } from './Behaviors/Behaviors'; /** @@ -181,12 +181,7 @@ export function AddContainer( // Set the counter of the object type in order to assign an unique id const newCounters = Object.assign({}, current.TypeCounters); - if (newCounters[type] === null || - newCounters[type] === undefined) { - newCounters[type] = 0; - } else { - newCounters[type]++; - } + UpdateCounters(newCounters, type); const count = newCounters[type]; // Create maincontainer model @@ -234,6 +229,8 @@ export function AddContainer( parentClone.children.splice(index, 0, newContainer); } + InitializeDefaultChild(configuration, containerConfig, newContainer, newCounters); + // Update the state history.push({ LastAction: `Add ${newContainer.properties.id} in ${parentClone.properties.id}`, @@ -246,6 +243,74 @@ export function AddContainer( setHistoryCurrentStep(history.length - 1); } +function UpdateCounters(counters: Record, type: string): void { + if (counters[type] === null || + counters[type] === undefined) { + counters[type] = 0; + } else { + counters[type]++; + } +} + +function InitializeDefaultChild( + configuration: IConfiguration, + containerConfig: IAvailableContainer, + newContainer: ContainerModel, + newCounters: Record +): void { + if (containerConfig.DefaultChildType === undefined) { + return; + } + + let currentConfig = configuration.AvailableContainers + .find(option => option.Type === containerConfig.DefaultChildType); + let parent = newContainer; + let depth = 0; + const seen = new Set([containerConfig.Type]); + + while (currentConfig !== undefined && + depth <= DEFAULTCHILDTYPE_MAX_DEPTH + ) { + if (!DEFAULTCHILDTYPE_ALLOW_CYCLIC && seen.has(currentConfig.Type)) { + return; + } + + seen.add(currentConfig.Type); + const x = currentConfig.DefaultX ?? 0; + const y = currentConfig.DefaultY ?? 0; + + UpdateCounters(newCounters, currentConfig.Type); + const count = newCounters[currentConfig.Type]; + const defaultChildProperties = GetDefaultContainerProps( + currentConfig.Type, + count, + parent, + x, + y, + currentConfig + ); + + // Create the container + const newChildContainer = new ContainerModel( + parent, + defaultChildProperties, + [], + { + type: currentConfig.Type + } + ); + + // And push it the the parent children + parent.children.push(newChildContainer); + + // iterate + depth++; + parent = newChildContainer; + currentConfig = configuration.AvailableContainers + .find(option => option.Type === (currentConfig as IAvailableContainer).DefaultChildType); + } +} + /** * Returns a new offset by applying an Add method (append, insert etc.) * See AddMethod diff --git a/src/Interfaces/IAvailableContainer.ts b/src/Interfaces/IAvailableContainer.ts index 8dd0a83..67ad2af 100644 --- a/src/Interfaces/IAvailableContainer.ts +++ b/src/Interfaces/IAvailableContainer.ts @@ -13,6 +13,7 @@ export interface IAvailableContainer { AddMethod?: AddMethod XPositionReference?: XPositionReference CustomSVG?: string + DefaultChildType?: string Style?: React.CSSProperties UserData?: object } diff --git a/src/utils/default.ts b/src/utils/default.ts index f8fe20c..90d3c1c 100644 --- a/src/utils/default.ts +++ b/src/utils/default.ts @@ -7,6 +7,8 @@ import IProperties from '../Interfaces/IProperties'; /// CONTAINRE DEFAULTS /// export const SHOW_TEXT = true; +export const DEFAULTCHILDTYPE_ALLOW_CYCLIC = false; +export const DEFAULTCHILDTYPE_MAX_DEPTH = 10; /// DIMENSIONS DEFAULTS /// diff --git a/test-server/http.js b/test-server/http.js index e8bd15c..0cc4bd9 100644 --- a/test-server/http.js +++ b/test-server/http.js @@ -55,6 +55,7 @@ const GetSVGLayoutConfiguration = () => { Type: 'Chassis', Width: 500, MinWidth: 200, + DefaultChildType: 'Trou', Style: { fillOpacity: 1, strokeWidth: 2, @@ -68,6 +69,7 @@ const GetSVGLayoutConfiguration = () => { DefaultY: 10, Width: 480, Height: 180, + DefaultChildType: 'Remplissage', Style: { fillOpacity: 1, strokeWidth: 2, @@ -77,6 +79,7 @@ const GetSVGLayoutConfiguration = () => { }, { Type: 'Remplissage', + DefaultChildType: 'Trou', CustomSVG: ` -- 2.47.2