From d854218c9d0db9f6f7eba9035cbbec8334b195dc Mon Sep 17 00:00:00 2001 From: Siklos Date: Thu, 18 Aug 2022 13:05:47 +0200 Subject: [PATCH 01/10] Added new defaults settings --- src/Components/SVG/Elements/Container.tsx | 25 +++++++++++++---------- src/utils/default.ts | 16 ++++++++++----- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/Components/SVG/Elements/Container.tsx b/src/Components/SVG/Elements/Container.tsx index b6431fb..b6c42a9 100644 --- a/src/Components/SVG/Elements/Container.tsx +++ b/src/Components/SVG/Elements/Container.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { Interweave, Node } from 'interweave'; import { XPositionReference } from '../../../Enums/XPositionReference'; import { IContainerModel } from '../../../Interfaces/IContainerModel'; -import { DIMENSION_MARGIN } from '../../../utils/default'; +import { DIMENSION_MARGIN, SHOW_CHILDREN_DIMENSIONS, SHOW_PARENT_DIMENSION } from '../../../utils/default'; import { getDepth } from '../../../utils/itertools'; import { Dimension } from './Dimension'; import IProperties from '../../../Interfaces/IProperties'; @@ -54,7 +54,7 @@ export const Container: React.FC = (props: IContainerProps) => const text = (props.model.properties.width ?? 0).toString(); let dimensionChildren: JSX.Element | null = null; - if (props.model.children.length > 1) { + if (props.model.children.length > 1 && SHOW_CHILDREN_DIMENSIONS) { const { childrenId, xChildrenStart, @@ -79,15 +79,18 @@ export const Container: React.FC = (props: IContainerProps) => transform={transform} key={`container-${props.model.properties.id}`} > - + { SHOW_PARENT_DIMENSION + ? + : null + } { dimensionChildren } { svg } Date: Thu, 18 Aug 2022 13:06:01 +0200 Subject: [PATCH 02/10] itertools: Added bfs iterator --- src/utils/itertools.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/utils/itertools.ts b/src/utils/itertools.ts index 221d6c0..e52e034 100644 --- a/src/utils/itertools.ts +++ b/src/utils/itertools.ts @@ -22,6 +22,34 @@ export function * MakeIterator(root: IContainerModel): Generator { + const queue: IContainerModel[] = [root]; + let depth = 0; + while (queue.length > 0) { + let levelSize = queue.length; + while (levelSize-- !== 0) { + const container = queue.shift() as IContainerModel; + yield { + container, + depth + }; + + for (let i = container.children.length - 1; i >= 0; i--) { + const child = container.children[i]; + queue.push(child); + } + } + depth++; + } +} + /** * Returns the depth of the container * @returns The depth of the container -- 2.47.2 From c8d73c4fcd4450f05616fb0ab93a66e6c02fcde0 Mon Sep 17 00:00:00 2001 From: Siklos Date: Thu, 18 Aug 2022 13:07:00 +0200 Subject: [PATCH 03/10] Restore DimensionLayer with BFS algorithm and usage of getAbsolutePosition --- .../SVG/Elements/DimensionLayer.tsx | 57 +++++++++++++++++++ src/Components/SVG/SVG.tsx | 2 + 2 files changed, 59 insertions(+) create mode 100644 src/Components/SVG/Elements/DimensionLayer.tsx diff --git a/src/Components/SVG/Elements/DimensionLayer.tsx b/src/Components/SVG/Elements/DimensionLayer.tsx new file mode 100644 index 0000000..e787bc1 --- /dev/null +++ b/src/Components/SVG/Elements/DimensionLayer.tsx @@ -0,0 +1,57 @@ +import * as React from 'react'; +import { ContainerModel } from '../../../Interfaces/IContainerModel'; +import { DIMENSION_MARGIN } from '../../../utils/default'; +import { getAbsolutePosition, MakeBFSIterator } from '../../../utils/itertools'; +import { transformX } from './Container'; +import { Dimension } from './Dimension'; + +interface IDimensionLayerProps { + roots: ContainerModel | ContainerModel[] | null +} + +const getDimensionsNodes = (root: ContainerModel): React.ReactNode[] => { + const it = MakeBFSIterator(root); + const dimensions: React.ReactNode[] = []; + for (const { container, depth } of it) { + const width = container.properties.width; + const id = `dim-${container.properties.id}`; + const xStart = getAbsolutePosition(container)[0]; + const xEnd = xStart + width; + const y = (container.properties.y + container.properties.height) + (DIMENSION_MARGIN * (depth + 1)); + const strokeWidth = 1; + const text = width.toString(); + dimensions.push( + + ); + } + return dimensions; +}; + +/** + * A layer containing all dimension + * @param props + * @returns + */ +export const DimensionLayer: React.FC = (props: IDimensionLayerProps) => { + let dimensions: React.ReactNode[] = []; + if (Array.isArray(props.roots)) { + props.roots.forEach(child => { + dimensions.concat(getDimensionsNodes(child)); + }); + } else if (props.roots !== null) { + dimensions = getDimensionsNodes(props.roots); + } + return ( + + { dimensions } + + ); +}; diff --git a/src/Components/SVG/SVG.tsx b/src/Components/SVG/SVG.tsx index 652258f..56e629d 100644 --- a/src/Components/SVG/SVG.tsx +++ b/src/Components/SVG/SVG.tsx @@ -4,6 +4,7 @@ import { Container } from './Elements/Container'; import { ContainerModel } from '../../Interfaces/IContainerModel'; import { Selector } from './Elements/Selector'; import { BAR_WIDTH } from '../Bar/Bar'; +import { DimensionLayer } from './Elements/DimensionLayer'; interface ISVGProps { width: number @@ -74,6 +75,7 @@ export const SVG: React.FC = (props: ISVGProps) => { { children } + -- 2.47.2 From db0dbeaeab1257f85404639ba7a5f12b30df242e Mon Sep 17 00:00:00 2001 From: Siklos Date: Thu, 18 Aug 2022 13:45:26 +0200 Subject: [PATCH 04/10] Implement dimension per depth --- .../SVG/Elements/DepthDimensionLayer.tsx | 89 +++++++++++++++++++ src/Components/SVG/SVG.tsx | 8 +- src/utils/default.ts | 3 +- 3 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 src/Components/SVG/Elements/DepthDimensionLayer.tsx diff --git a/src/Components/SVG/Elements/DepthDimensionLayer.tsx b/src/Components/SVG/Elements/DepthDimensionLayer.tsx new file mode 100644 index 0000000..4dd0549 --- /dev/null +++ b/src/Components/SVG/Elements/DepthDimensionLayer.tsx @@ -0,0 +1,89 @@ +import * as React from 'react'; +import { ContainerModel } from '../../../Interfaces/IContainerModel'; +import { DIMENSION_MARGIN } from '../../../utils/default'; +import { getAbsolutePosition, MakeBFSIterator } from '../../../utils/itertools'; +import { transformX } from './Container'; +import { Dimension } from './Dimension'; + +interface IDimensionLayerProps { + roots: ContainerModel | ContainerModel[] | null +} + +const getDimensionsNodes = (root: ContainerModel): React.ReactNode[] => { + const it = MakeBFSIterator(root); + const dimensions: React.ReactNode[] = []; + let currentDepth = 0; + let min = Infinity; + let max = -Infinity; + let lastY = 0; + for (const { container, depth } of it) { + if (currentDepth !== depth) { + AddNewDimension(currentDepth, min, max, lastY, dimensions); + + currentDepth = depth; + min = Infinity; + max = -Infinity; + } + + const absoluteX = getAbsolutePosition(container)[0]; + const x = transformX(absoluteX, container.properties.width, container.properties.XPositionReference); + lastY = container.properties.y + container.properties.height; + if (x < min) { + min = x; + } + + if (x > max) { + max = x; + } + } + + AddNewDimension(currentDepth, min, max, lastY, dimensions); + + return dimensions; +}; + +/** + * A layer containing all dimension + * @param props + * @returns + */ +export const DepthDimensionLayer: React.FC = (props: IDimensionLayerProps) => { + let dimensions: React.ReactNode[] = []; + if (Array.isArray(props.roots)) { + props.roots.forEach(child => { + dimensions.concat(getDimensionsNodes(child)); + }); + } else if (props.roots !== null) { + dimensions = getDimensionsNodes(props.roots); + } + return ( + + { dimensions } + + ); +}; + +function AddNewDimension(currentDepth: number, min: number, max: number, lastY: number, dimensions: React.ReactNode[]): void { + const id = `dim-depth-${currentDepth}`; + const xStart = min; + const xEnd = max; + const y = lastY + (DIMENSION_MARGIN * (currentDepth + 1)); + const strokeWidth = 1; + const width = xEnd - xStart; + const text = width.toString(); + + if (width === 0) { + return; + } + + dimensions.push( + + ); +} diff --git a/src/Components/SVG/SVG.tsx b/src/Components/SVG/SVG.tsx index 56e629d..e158da3 100644 --- a/src/Components/SVG/SVG.tsx +++ b/src/Components/SVG/SVG.tsx @@ -5,6 +5,8 @@ import { ContainerModel } from '../../Interfaces/IContainerModel'; import { Selector } from './Elements/Selector'; import { BAR_WIDTH } from '../Bar/Bar'; import { DimensionLayer } from './Elements/DimensionLayer'; +import { DepthDimensionLayer } from './Elements/DepthDimensionLayer'; +import { SHOW_DIMENSIONS_PER_DEPTH } from '../../utils/default'; interface ISVGProps { width: number @@ -75,7 +77,11 @@ export const SVG: React.FC = (props: ISVGProps) => { { children } - + { + SHOW_DIMENSIONS_PER_DEPTH + ? + : null + } diff --git a/src/utils/default.ts b/src/utils/default.ts index 7428729..348100f 100644 --- a/src/utils/default.ts +++ b/src/utils/default.ts @@ -7,7 +7,8 @@ import IProperties from '../Interfaces/IProperties'; /// DIMENSIONS DEFAULTS /// export const SHOW_PARENT_DIMENSION = true; -export const SHOW_CHILDREN_DIMENSIONS = true; +export const SHOW_CHILDREN_DIMENSIONS = false; +export const SHOW_DIMENSIONS_PER_DEPTH = true; export const DIMENSION_MARGIN = 50; export const NOTCHES_LENGTH = 4; -- 2.47.2 From b4380570a266a8e99384127602b59adc2d5a2732 Mon Sep 17 00:00:00 2001 From: Siklos Date: Thu, 18 Aug 2022 14:23:25 +0200 Subject: [PATCH 05/10] Fix dimension not having keys --- src/Components/SVG/Elements/DepthDimensionLayer.tsx | 1 + src/Components/SVG/Elements/DimensionLayer.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Components/SVG/Elements/DepthDimensionLayer.tsx b/src/Components/SVG/Elements/DepthDimensionLayer.tsx index 4dd0549..a32dbda 100644 --- a/src/Components/SVG/Elements/DepthDimensionLayer.tsx +++ b/src/Components/SVG/Elements/DepthDimensionLayer.tsx @@ -78,6 +78,7 @@ function AddNewDimension(currentDepth: number, min: number, max: number, lastY: dimensions.push( { const text = width.toString(); dimensions.push( Date: Thu, 18 Aug 2022 14:23:42 +0200 Subject: [PATCH 06/10] Add option to hide text --- src/Components/SVG/Elements/Container.tsx | 16 +++++++++------- src/utils/default.ts | 5 +++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Components/SVG/Elements/Container.tsx b/src/Components/SVG/Elements/Container.tsx index b6c42a9..ff84123 100644 --- a/src/Components/SVG/Elements/Container.tsx +++ b/src/Components/SVG/Elements/Container.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { Interweave, Node } from 'interweave'; import { XPositionReference } from '../../../Enums/XPositionReference'; import { IContainerModel } from '../../../Interfaces/IContainerModel'; -import { DIMENSION_MARGIN, SHOW_CHILDREN_DIMENSIONS, SHOW_PARENT_DIMENSION } from '../../../utils/default'; +import { DIMENSION_MARGIN, SHOW_CHILDREN_DIMENSIONS, SHOW_PARENT_DIMENSION, SHOW_TEXT } from '../../../utils/default'; import { getDepth } from '../../../utils/itertools'; import { Dimension } from './Dimension'; import IProperties from '../../../Interfaces/IProperties'; @@ -93,12 +93,14 @@ export const Container: React.FC = (props: IContainerProps) => } { dimensionChildren } { svg } - - {props.model.properties.id} - + { SHOW_TEXT + ? + {props.model.properties.id} + + : null } { containersElements } ); diff --git a/src/utils/default.ts b/src/utils/default.ts index 348100f..ff556ec 100644 --- a/src/utils/default.ts +++ b/src/utils/default.ts @@ -4,6 +4,10 @@ import { IConfiguration } from '../Interfaces/IConfiguration'; import { IContainerModel } from '../Interfaces/IContainerModel'; import IProperties from '../Interfaces/IProperties'; +/// CONTAINRE DEFAULTS /// + +export const SHOW_TEXT = true; + /// DIMENSIONS DEFAULTS /// export const SHOW_PARENT_DIMENSION = true; @@ -14,6 +18,7 @@ export const NOTCHES_LENGTH = 4; /// EDITOR DEFAULTS /// +export const ENABLE_SHORTCUTS = true; export const MAX_HISTORY = 200; export const DEFAULT_CONFIG: IConfiguration = { -- 2.47.2 From 39a47659b62f167b8a82a003abf7fd0ce52be479 Mon Sep 17 00:00:00 2001 From: Siklos Date: Thu, 18 Aug 2022 14:23:56 +0200 Subject: [PATCH 07/10] Add option to disable shortcuts --- src/Components/Editor/Shortcuts.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Components/Editor/Shortcuts.ts b/src/Components/Editor/Shortcuts.ts index aa20d96..f7d7b5b 100644 --- a/src/Components/Editor/Shortcuts.ts +++ b/src/Components/Editor/Shortcuts.ts @@ -1,5 +1,6 @@ import { Dispatch, SetStateAction } from 'react'; import { IHistoryState } from '../../Interfaces/IHistoryState'; +import { ENABLE_SHORTCUTS } from '../../utils/default'; export function onKeyDown( event: KeyboardEvent, @@ -7,6 +8,10 @@ export function onKeyDown( historyCurrentStep: number, setHistoryCurrentStep: Dispatch> ): void { + if (!ENABLE_SHORTCUTS) { + return; + } + event.preventDefault(); if (event.isComposing || event.keyCode === 229) { return; -- 2.47.2 From 1d67702696eab449d61c1b9e644ce83674d99c63 Mon Sep 17 00:00:00 2001 From: Siklos Date: Thu, 18 Aug 2022 14:29:32 +0200 Subject: [PATCH 08/10] Remove unused import --- src/Components/SVG/Elements/DimensionLayer.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Components/SVG/Elements/DimensionLayer.tsx b/src/Components/SVG/Elements/DimensionLayer.tsx index a8bb56a..23d719e 100644 --- a/src/Components/SVG/Elements/DimensionLayer.tsx +++ b/src/Components/SVG/Elements/DimensionLayer.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import { ContainerModel } from '../../../Interfaces/IContainerModel'; import { DIMENSION_MARGIN } from '../../../utils/default'; import { getAbsolutePosition, MakeBFSIterator } from '../../../utils/itertools'; -import { transformX } from './Container'; import { Dimension } from './Dimension'; interface IDimensionLayerProps { -- 2.47.2 From f569e54ce0a0b51724d02837c24120b8261cf81d Mon Sep 17 00:00:00 2001 From: Siklos Date: Thu, 18 Aug 2022 14:37:49 +0200 Subject: [PATCH 09/10] Add displayed text --- src/Components/ElementsSidebar/ElementsSidebar.tsx | 4 +++- src/Components/Properties/DynamicForm.tsx | 9 +++++++++ src/Components/Properties/StaticForm.tsx | 8 ++++++++ src/Components/SVG/Elements/Container.tsx | 2 +- src/Interfaces/IProperties.ts | 3 +++ src/utils/default.ts | 2 ++ 6 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Components/ElementsSidebar/ElementsSidebar.tsx b/src/Components/ElementsSidebar/ElementsSidebar.tsx index 345ad05..6a2d688 100644 --- a/src/Components/ElementsSidebar/ElementsSidebar.tsx +++ b/src/Components/ElementsSidebar/ElementsSidebar.tsx @@ -83,7 +83,9 @@ export const ElementsSidebar: React.FC = (props: IElement const container = containers[index]; const depth: number = getDepth(container); const key = container.properties.id.toString(); - const text = '|\t'.repeat(depth) + key; + const text = container.properties.displayedText === key + ? `${'|\t'.repeat(depth)} ${key}` + : `${'|\t'.repeat(depth)} ${container.properties.displayedText} (${key})`; const selectedClass: string = props.SelectedContainer !== undefined && props.SelectedContainer !== null && props.SelectedContainer.properties.id === container.properties.id diff --git a/src/Components/Properties/DynamicForm.tsx b/src/Components/Properties/DynamicForm.tsx index 76bc4e1..a34b5bf 100644 --- a/src/Components/Properties/DynamicForm.tsx +++ b/src/Components/Properties/DynamicForm.tsx @@ -52,6 +52,15 @@ const DynamicForm: React.FunctionComponent = (props) => { value={props.properties.parentId?.toString()} isDisabled={true} /> + props.onChange('displayedText', event.target.value)} + /> = (props) => { defaultValue={props.properties.parentId?.toString()} isDisabled={true} /> + = (props: IContainerProps) => x={xText} y={yText} > - {props.model.properties.id} + {props.model.properties.displayedText} : null } { containersElements } diff --git a/src/Interfaces/IProperties.ts b/src/Interfaces/IProperties.ts index a400a0a..205d93f 100644 --- a/src/Interfaces/IProperties.ts +++ b/src/Interfaces/IProperties.ts @@ -11,6 +11,9 @@ export default interface IProperties { /** id of the parent container (null when there is no parent) */ parentId: string | null + /** Text displayed in the container */ + displayedText: string + /** horizontal offset */ x: number diff --git a/src/utils/default.ts b/src/utils/default.ts index ff556ec..f8fe20c 100644 --- a/src/utils/default.ts +++ b/src/utils/default.ts @@ -48,6 +48,7 @@ export const DEFAULT_CONFIG: IConfiguration = { export const DEFAULT_MAINCONTAINER_PROPS: IProperties = { id: 'main', parentId: 'null', + displayedText: 'main', x: 0, y: 0, minWidth: 1, @@ -72,6 +73,7 @@ export const GetDefaultContainerProps = ( ): IProperties => ({ id: `${type}-${typeCount}`, parentId: parent.properties.id, + displayedText: `${type}-${typeCount}`, x, y, width: containerConfig.Width ?? containerConfig.MinWidth ?? parent.properties.width, -- 2.47.2 From d3c8ce75775b8ff83e4204ae2709d74f792ff706 Mon Sep 17 00:00:00 2001 From: Siklos Date: Thu, 18 Aug 2022 14:45:05 +0200 Subject: [PATCH 10/10] Update test with new property --- src/Components/ElementsSidebar/ElementsSidebar.test.tsx | 7 +++++++ src/Components/Properties/Properties.test.tsx | 1 + 2 files changed, 8 insertions(+) diff --git a/src/Components/ElementsSidebar/ElementsSidebar.test.tsx b/src/Components/ElementsSidebar/ElementsSidebar.test.tsx index bf88f22..4f3b042 100644 --- a/src/Components/ElementsSidebar/ElementsSidebar.test.tsx +++ b/src/Components/ElementsSidebar/ElementsSidebar.test.tsx @@ -14,6 +14,7 @@ describe.concurrent('Elements sidebar', () => { properties: { id: 'main', parentId: null, + displayedText: 'main', x: 0, y: 0, width: 2000, @@ -47,6 +48,7 @@ describe.concurrent('Elements sidebar', () => { properties: { id: 'main', parentId: '', + displayedText: 'main', x: 0, y: 0, width: 2000, @@ -106,6 +108,7 @@ describe.concurrent('Elements sidebar', () => { properties: { id: 'main', parentId: '', + displayedText: 'main', x: 0, y: 0, minWidth: 1, @@ -125,6 +128,7 @@ describe.concurrent('Elements sidebar', () => { properties: { id: 'child-1', parentId: 'main', + displayedText: 'child-1', x: 0, y: 0, minWidth: 1, @@ -145,6 +149,7 @@ describe.concurrent('Elements sidebar', () => { properties: { id: 'child-2', parentId: 'main', + displayedText: 'child-2', x: 0, y: 0, minWidth: 1, @@ -185,6 +190,7 @@ describe.concurrent('Elements sidebar', () => { properties: { id: 'main', parentId: '', + displayedText: 'main', x: 0, y: 0, minWidth: 1, @@ -203,6 +209,7 @@ describe.concurrent('Elements sidebar', () => { properties: { id: 'child-1', parentId: 'main', + displayedText: 'child-1', x: 0, y: 0, minWidth: 1, diff --git a/src/Components/Properties/Properties.test.tsx b/src/Components/Properties/Properties.test.tsx index 0ede184..dbe0d65 100644 --- a/src/Components/Properties/Properties.test.tsx +++ b/src/Components/Properties/Properties.test.tsx @@ -23,6 +23,7 @@ describe.concurrent('Properties', () => { const prop: IProperties = { id: 'stuff', parentId: 'parentId', + displayedText: 'stuff', x: 1, y: 1, width: 1, -- 2.47.2