diff --git a/src/Components/Canvas/DimensionLayer.ts b/src/Components/Canvas/DimensionLayer.ts index d986de1..061a4e0 100644 --- a/src/Components/Canvas/DimensionLayer.ts +++ b/src/Components/Canvas/DimensionLayer.ts @@ -2,10 +2,15 @@ import { Orientation } from '../../Enums/Orientation'; import { Position } from '../../Enums/Position'; import { type IContainerModel } from '../../Interfaces/IContainerModel'; import { type ISymbolModel } from '../../Interfaces/ISymbolModel'; -import { SHOW_SELF_DIMENSIONS, SHOW_BORROWER_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS, DIMENSION_MARGIN, SHOW_SELF_MARGINS_DIMENSIONS } from '../../utils/default'; +import { + SHOW_SELF_DIMENSIONS, + SHOW_BORROWER_DIMENSIONS, + SHOW_CHILDREN_DIMENSIONS, + DIMENSION_MARGIN, + SHOW_SELF_MARGINS_DIMENSIONS, DEFAULT_DIMENSION_SYMBOL_STYLE +} from '../../utils/default'; import { FindContainerById, MakeRecursionDFSIterator, Pairwise } from '../../utils/itertools'; import { TransformX, TransformY } from '../../utils/svg'; -import { type IDimensionStyle } from '../SVG/Elements/Dimension'; import { RenderDimension } from './Dimension'; export function AddContainerDimensions( @@ -90,6 +95,16 @@ export function AddSymbolDimensions( scale: number, depth: number ): void { + if (symbol.isVertical) { + AddVerticalSymbolDimension( + ctx, + symbol, + scale, + depth + ); + return; + } + AddHorizontalSymbolDimension( ctx, symbol, @@ -100,6 +115,7 @@ export function AddSymbolDimensions( /** * Fonction that call another function given the positions + * @param ctx * @param dimMapped Position mapped depending on the Position enum in order: * [0:left, 1:bottom, 2:up, 3:right] * @param positions List of positions @@ -569,7 +585,7 @@ function AddHorizontalSymbolDimension( scale: number, depth: number ): void { - const width = symbol.x + (symbol.width / 2); + const width = TransformX(symbol.offset, symbol.width, symbol.config.PositionReference); if (width == null || width <= 0) { return; @@ -582,11 +598,6 @@ function AddHorizontalSymbolDimension( .toFixed(0) .toString(); - // TODO: Put this in default.ts - const defaultDimensionSymbolStyle: IDimensionStyle = { - color: 'black' - }; - RenderDimension(ctx, { id, xStart: 0, @@ -595,6 +606,37 @@ function AddHorizontalSymbolDimension( yEnd: -offset, text, scale, - style: defaultDimensionSymbolStyle + style: DEFAULT_DIMENSION_SYMBOL_STYLE + }); +} + +function AddVerticalSymbolDimension( + ctx: CanvasRenderingContext2D, + symbol: ISymbolModel, + scale: number, + depth: number +): void { + const height = TransformY(symbol.offset, symbol.height, symbol.config.PositionReference); + + if (height == null || height <= 0) { + return; + } + + const id = `dim-y-margin-left${symbol.width.toFixed(0)}-${symbol.id}`; + + const offset = (DIMENSION_MARGIN * (depth + 1)) / scale; + const text = height + .toFixed(0) + .toString(); + + RenderDimension(ctx, { + id, + xStart: -offset, + yStart: height, + xEnd: -offset, + yEnd: 0, + text, + scale, + style: DEFAULT_DIMENSION_SYMBOL_STYLE }); } diff --git a/src/Components/Canvas/Renderer.ts b/src/Components/Canvas/Renderer.ts index c93e615..73abdac 100644 --- a/src/Components/Canvas/Renderer.ts +++ b/src/Components/Canvas/Renderer.ts @@ -71,16 +71,15 @@ export function RenderSymbols( symbols: Map, scale: number ): void { - let count = 0; symbols.forEach((symbol: ISymbolModel) => { - RenderSymbol(ctx, symbol, scale); + RenderSymbol(ctx, symbol); if (!symbol.showDimension) { return; } - AddSymbolDimensions(ctx, symbol, scale, count); - count++; + // TODO: Implement DimensionManager + AddSymbolDimensions(ctx, symbol, scale, 0); }); } diff --git a/src/Components/Canvas/SelectorSymbol.ts b/src/Components/Canvas/SelectorSymbol.ts index ddfbb29..69f49f5 100644 --- a/src/Components/Canvas/SelectorSymbol.ts +++ b/src/Components/Canvas/SelectorSymbol.ts @@ -5,7 +5,6 @@ import { RenderSelector } from './Selector'; interface ISelectorProps { symbols: Map selected?: ISymbolModel - scale?: number } export function RenderSymbolSelector( @@ -17,15 +16,20 @@ export function RenderSymbolSelector( return; } - const scale = (props.scale ?? 1); const [width, height] = [ - props.selected.width / scale, - props.selected.height / scale + props.selected.width, + props.selected.height ]; - const [x, y] = [ - props.selected.x + props.selected.width / 2, - -SYMBOL_MARGIN - height]; + let x, y: number; + + if (props.selected.isVertical) { + x = -SYMBOL_MARGIN - props.selected.width; + y = props.selected.offset; + } else { + x = props.selected.offset; + y = -SYMBOL_MARGIN - props.selected.height; + } const text = props.selected.displayedText; RenderSelector( @@ -37,7 +41,7 @@ export function RenderSymbolSelector( y, width, height, - scale + scale: 1 } ); } diff --git a/src/Components/Canvas/Symbol.ts b/src/Components/Canvas/Symbol.ts index c85e737..842d433 100644 --- a/src/Components/Canvas/Symbol.ts +++ b/src/Components/Canvas/Symbol.ts @@ -1,12 +1,11 @@ import { type ISymbolModel } from '../../Interfaces/ISymbolModel'; -import { DIMENSION_MARGIN, SYMBOL_MARGIN } from '../../utils/default'; +import { SYMBOL_MARGIN } from '../../utils/default'; const IMAGE_CACHE = new Map(); export function RenderSymbol( ctx: CanvasRenderingContext2D, - symbol: ISymbolModel, - scale: number): void { + symbol: ISymbolModel): void { const href = symbol.config.Image.Base64Image ?? symbol.config.Image.Url; if (href === undefined) { @@ -19,28 +18,36 @@ export function RenderSymbol( newImage.src = href; IMAGE_CACHE.set(href, newImage); newImage.onload = () => { - DrawImage(ctx, scale, newImage, symbol); + DrawImage(ctx, newImage, symbol); }; return; } - DrawImage(ctx, scale, image, symbol); + DrawImage(ctx, image, symbol); } function DrawImage( ctx: CanvasRenderingContext2D, - scale: number, image: HTMLImageElement, symbol: ISymbolModel ): void { + let x, y: number; + if (symbol.isVertical) { + x = -SYMBOL_MARGIN - symbol.width; + y = symbol.offset; + } else { + x = symbol.offset; + y = -SYMBOL_MARGIN - symbol.height; + } + ctx.save(); ctx.fillStyle = '#000000'; - const width = symbol.width / scale; - const height = symbol.height / scale; + const width = symbol.width; + const height = symbol.height; ctx.drawImage( image, - symbol.x + symbol.width / 2, - -SYMBOL_MARGIN - height, + x, + y, width, height ); diff --git a/src/Components/ContainerProperties/ContainerForm.tsx b/src/Components/ContainerProperties/ContainerForm.tsx index 8b7a505..9a19743 100644 --- a/src/Components/ContainerProperties/ContainerForm.tsx +++ b/src/Components/ContainerProperties/ContainerForm.tsx @@ -5,7 +5,8 @@ import { type ISymbolModel } from '../../Interfaces/ISymbolModel'; import { SHOW_BORROWER_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS, - SHOW_SELF_DIMENSIONS, SHOW_SELF_MARGINS_DIMENSIONS + SHOW_SELF_DIMENSIONS, + SHOW_SELF_MARGINS_DIMENSIONS } from '../../utils/default'; import { ApplyWidthMargin, @@ -27,8 +28,12 @@ import { OrientationSelector } from '../RadioGroupButtons/OrientationSelector'; import { OrientationCheckboxes } from '../CheckboxGroupButtons/OrientationCheckboxes'; import { PositionCheckboxes } from '../CheckboxGroupButtons/PositionCheckboxes'; import { Category } from '../Category/Category'; +import { Orientation } from '../../Enums/Orientation'; +import { FindContainerById } from '../../utils/itertools'; +import { type IContainerModel } from '../../Interfaces/IContainerModel'; interface IContainerFormProps { + containers: Map properties: IContainerProperties symbols: Map onChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void @@ -36,6 +41,8 @@ interface IContainerFormProps { export function ContainerForm(props: IContainerFormProps): JSX.Element { const categoryHeight = 'h-11'; + const parent = FindContainerById(props.containers, props.properties.parentId); + const isVertical = parent?.properties.orientation === Orientation.Vertical; return (
{ props.onChange('width', ApplyWidthMargin(Number(value), props.properties.margin.left, props.properties.margin.right)); }} + value={(RemoveWidthMargin(props.properties.width, + props.properties.margin.left, + props.properties.margin.right)).toString()} + onChange={(value) => { + props.onChange('width', ApplyWidthMargin(Number(value), + props.properties.margin.left, + props.properties.margin.right)); + }} isDisabled={props.properties.isFlex}/> { props.onChange('height', ApplyWidthMargin(Number(value), props.properties.margin.top, props.properties.margin.bottom)); }} + value={(RemoveWidthMargin(props.properties.height, + props.properties.margin.top, + props.properties.margin.bottom)).toString()} + onChange={(value) => { + props.onChange('height', ApplyWidthMargin(Number(value), + props.properties.margin.top, + props.properties.margin.bottom)); + }} isDisabled={props.properties.isFlex} /> ({ + inputs={[...props.symbols.values()].filter(symbol => (symbol.isVertical === isVertical)).map(symbol => ({ key: symbol.id, text: symbol.id, value: symbol.id @@ -366,7 +385,7 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element { labelClassName='' inputClassName='' type='color' - value={props.properties.dimensionOptions.selfDimensions.color} + value={props.properties.dimensionOptions.selfDimensions.color ?? '#000000'} onChange={(e) => { props.onChange('color', e.target.value, PropertyType.SelfDimension); }}/> { props.onChange('color', e.target.value, PropertyType.SelfMarginDimension); }}/> { props.onChange('color', e.target.value, PropertyType.ChildrenDimensions); }}/> { props.onChange('color', e.target.value, PropertyType.DimensionWithMarks); }}/>
- { props.onChange('stroke', value, PropertyType.Style); }} - /> + type='color' + value={props.properties.style.stroke ?? '#000000'} + onChange={(e) => { props.onChange('stroke', e.target.value, PropertyType.Style); }}/> { props.onChange('strokeWidth', Number(value), PropertyType.Style); }} /> - { props.onChange('fill', value, PropertyType.Style); }} - /> + type='color' + value={props.properties.style.fill ?? '#000000'} + onChange={(e) => { props.onChange('fill', e.target.value, PropertyType.Style); }}/> properties?: IContainerProperties symbols: Map onChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void @@ -18,6 +20,7 @@ export function ContainerProperties(props: IPropertiesProps): JSX.Element { return (
diff --git a/src/Components/Editor/Actions/SymbolOperations.ts b/src/Components/Editor/Actions/SymbolOperations.ts index 7464193..abff45f 100644 --- a/src/Components/Editor/Actions/SymbolOperations.ts +++ b/src/Components/Editor/Actions/SymbolOperations.ts @@ -1,10 +1,10 @@ -import { IConfiguration } from '../../../Interfaces/IConfiguration'; -import { IContainerModel } from '../../../Interfaces/IContainerModel'; -import { IHistoryState } from '../../../Interfaces/IHistoryState'; -import { ISymbolModel } from '../../../Interfaces/ISymbolModel'; +import { type IConfiguration } from '../../../Interfaces/IConfiguration'; +import { type IContainerModel } from '../../../Interfaces/IContainerModel'; +import { type IHistoryState } from '../../../Interfaces/IHistoryState'; +import { type ISymbolModel } from '../../../Interfaces/ISymbolModel'; import { GetDefaultSymbolModel } from '../../../utils/default'; import { FindContainerById } from '../../../utils/itertools'; -import { RestoreX } from '../../../utils/svg'; +import {RestoreX, RestoreY} from '../../../utils/svg'; import { ApplyBehaviors, ApplyBehaviorsOnSiblingsChildren } from '../Behaviors/Behaviors'; import { GetCurrentHistory, GetCurrentHistoryState, UpdateCounters } from '../Editor'; import { AddContainers } from './AddContainer'; @@ -32,7 +32,12 @@ export function AddSymbol( const newSymbols = structuredClone(current.symbols); const newSymbol: ISymbolModel = GetDefaultSymbolModel(name, typeCounters, type, symbolConfig); const containers = structuredClone(current.containers); - newSymbol.x = RestoreX(newSymbol.x, newSymbol.width, newSymbol.config.PositionReference); + + if (newSymbol.isVertical) { + newSymbol.offset = RestoreY(newSymbol.offset, newSymbol.height, newSymbol.config.PositionReference); + } else { + newSymbol.offset = RestoreX(newSymbol.offset, newSymbol.width, newSymbol.config.PositionReference); + } newSymbols.set(newSymbol.id, newSymbol); diff --git a/src/Components/Editor/Behaviors/SymbolBehaviors.ts b/src/Components/Editor/Behaviors/SymbolBehaviors.ts index 5efde19..97c872d 100644 --- a/src/Components/Editor/Behaviors/SymbolBehaviors.ts +++ b/src/Components/Editor/Behaviors/SymbolBehaviors.ts @@ -1,16 +1,39 @@ -import { IContainerModel } from '../../../Interfaces/IContainerModel'; -import { ISymbolModel } from '../../../Interfaces/ISymbolModel'; +import { type IContainerModel } from '../../../Interfaces/IContainerModel'; +import { type ISymbolModel } from '../../../Interfaces/ISymbolModel'; import { ApplyParentTransform, FindContainerById } from '../../../utils/itertools'; -import { RestoreX, TransformX } from '../../../utils/svg'; +import { RestoreX, RestoreY, TransformX, TransformY } from '../../../utils/svg'; -export function ApplySymbol(containers: Map, container: IContainerModel, symbol: ISymbolModel): IContainerModel { - container.properties.x = TransformX(symbol.x, symbol.width, symbol.config.PositionReference); - container.properties.x = RestoreX(container.properties.x, container.properties.width, container.properties.positionReference); - const parent = FindContainerById(containers, container.properties.parentId); - let x = 0; - if (parent !== undefined && parent !== null) { - ([x] = ApplyParentTransform(containers, parent, container.properties.x, 0)); +export function ApplySymbol(containers: Map, + container: IContainerModel, + symbol: ISymbolModel): IContainerModel { + if (symbol.isVertical) { + container.properties.y = TransformY(symbol.offset, + symbol.height, + symbol.config.PositionReference); + container.properties.y = RestoreY(container.properties.y, + container.properties.height, + container.properties.positionReference); + const parent = FindContainerById(containers, container.properties.parentId); + let y = 0; + if (parent !== undefined && parent !== null) { + ([,y] = ApplyParentTransform(containers, parent, 0, container.properties.y)); + } + container.properties.y = y; + return container; + } else { + container.properties.x = TransformX( + symbol.offset, + symbol.width, + symbol.config.PositionReference); + container.properties.x = RestoreX(container.properties.x, + container.properties.width, + container.properties.positionReference); + const parent = FindContainerById(containers, container.properties.parentId); + let x = 0; + if (parent !== undefined && parent !== null) { + ([x] = ApplyParentTransform(containers, parent, container.properties.x, 0)); + } + container.properties.x = x; + return container; } - container.properties.x = x; - return container; } diff --git a/src/Components/ElementsSidebar/ElementsSidebar.tsx b/src/Components/ElementsSidebar/ElementsSidebar.tsx index e39bf2d..c583413 100644 --- a/src/Components/ElementsSidebar/ElementsSidebar.tsx +++ b/src/Components/ElementsSidebar/ElementsSidebar.tsx @@ -169,6 +169,7 @@ export function ElementsSidebar(props: IElementsSidebarProps): JSX.Element { {props.selectedExtendedSidebar === ExtendedSidebar.Property &&
{ const dim = dimMapped[position]; switch (position) { + case Position.Right: case Position.Left: - case Position.Right: { - const isRight = position === Position.Right; - verticalAction(dim, isRight, ...params); + verticalAction(dim, false, ...params); break; - } - case Position.Down: case Position.Up: + case Position.Down: horizontalAction(dim, ...params); break; } @@ -94,7 +93,8 @@ function Dimensions({ containers, symbols, root, scale }: IDimensionLayerProps): ); } - if (SHOW_SELF_MARGINS_DIMENSIONS && container.properties.dimensionOptions.selfMarginsDimensions.positions.length > 0) { + if (SHOW_SELF_MARGINS_DIMENSIONS && + container.properties.dimensionOptions.selfMarginsDimensions.positions.length > 0) { ActionByPosition( dimMapped, container.properties.dimensionOptions.selfMarginsDimensions.positions, @@ -127,7 +127,9 @@ function Dimensions({ containers, symbols, root, scale }: IDimensionLayerProps): ); } - if (SHOW_CHILDREN_DIMENSIONS && container.properties.dimensionOptions.childrenDimensions.positions.length > 0 && container.children.length >= 2) { + if (SHOW_CHILDREN_DIMENSIONS && + container.properties.dimensionOptions.childrenDimensions.positions.length > 0 && + container.children.length >= 2) { ActionByPosition( dimMapped, container.properties.dimensionOptions.childrenDimensions.positions, @@ -144,24 +146,76 @@ function Dimensions({ containers, symbols, root, scale }: IDimensionLayerProps): } } - let startDepthSymbols: number = 0; - symbols.forEach((symbol: ISymbolModel) => { - if (!symbol.showDimension) { - return; + // TODO: Implement DimensionManager + symbols.forEach((symbol) => { + if (symbol.showDimension) { + if (symbol.isVertical) { + AddVerticalSymbolDimension(symbol, dimensions, scale, 0); + } else { + AddHorizontalSymbolDimension(symbol, dimensions, scale, 0); + } } - - startDepthSymbols++; - AddHorizontalSymbolDimension( - symbol, - dimensions, - scale, - startDepthSymbols - ); }); return dimensions; } +function AddHorizontalSymbolDimension(symbol: ISymbolModel, + dimensions: React.ReactNode[], + scale: number, + depth: number +): void { + const width = TransformX(symbol.offset, symbol.width, symbol.config.PositionReference); + if (width != null && width > 0) { + const id = `dim-y-margin-left${symbol.width.toFixed(0)}-${symbol.id}`; + + const offset = (DIMENSION_MARGIN * (depth + 1)) / scale; + const text = width + .toFixed(0) + .toString(); + dimensions.push( + + ); + } +} + +function AddVerticalSymbolDimension(symbol: ISymbolModel, + dimensions: React.ReactNode[], + scale: number, + depth: number +): void { + const height = TransformY(symbol.offset, symbol.height, symbol.config.PositionReference); + if (height != null && height > 0) { + const id = `dim-x-margin-left${symbol.height.toFixed(0)}-${symbol.id}`; + + const offset = (DIMENSION_MARGIN * (depth + 1)) / scale; + const text = height + .toFixed(0) + .toString(); + dimensions.push( + + ); + } +} + /** * A layer containing all dimension * @param props @@ -195,8 +249,12 @@ function AddHorizontalChildrenDimension( return; } - let xChildrenStart = TransformX(lastChild.properties.x, lastChild.properties.width, lastChild.properties.positionReference); - let xChildrenEnd = TransformX(lastChild.properties.x, lastChild.properties.width, lastChild.properties.positionReference); + let xChildrenStart = TransformX(lastChild.properties.x, + lastChild.properties.width, + lastChild.properties.positionReference); + let xChildrenEnd = TransformX(lastChild.properties.x, + lastChild.properties.width, + lastChild.properties.positionReference); // Find the min and max for (let i = container.children.length - 2; i >= 0; i--) { @@ -258,8 +316,12 @@ function AddVerticalChildrenDimension( return; } - let yChildrenStart = TransformY(lastChild.properties.y, lastChild.properties.height, lastChild.properties.positionReference); - let yChildrenEnd = TransformY(lastChild.properties.y, lastChild.properties.height, lastChild.properties.positionReference); + let yChildrenStart = TransformY(lastChild.properties.y, + lastChild.properties.height, + lastChild.properties.positionReference); + let yChildrenEnd = TransformY(lastChild.properties.y, + lastChild.properties.height, + lastChild.properties.positionReference); // Find the min and max for (let i = container.children.length - 2; i >= 0; i--) { @@ -611,40 +673,3 @@ function AddVerticalSelfMarginDimension( ); } } - -function AddHorizontalSymbolDimension( - symbol: ISymbolModel, - dimensions: React.ReactNode[], - scale: number, - depth: number -): void { - const width = symbol.x + (symbol.width / 2); - - if (width == null || width <= 0) { - return; - } - - const id = `dim-y-margin-left${symbol.width.toFixed(0)}-${symbol.id}`; - - const offset = (DIMENSION_MARGIN * (depth + 1)) / scale; - const text = width - .toFixed(0) - .toString(); - - // TODO: Put this in default.ts - const defaultDimensionSymbolStyle: IDimensionStyle = { - color: 'black' - }; - dimensions.push( - - ); -} diff --git a/src/Components/SVG/Elements/SelectorSymbol/SelectorSymbol.tsx b/src/Components/SVG/Elements/SelectorSymbol/SelectorSymbol.tsx index 01133fb..22f4800 100644 --- a/src/Components/SVG/Elements/SelectorSymbol/SelectorSymbol.tsx +++ b/src/Components/SVG/Elements/SelectorSymbol/SelectorSymbol.tsx @@ -1,13 +1,12 @@ import '../Selector.scss'; import * as React from 'react'; -import { SYMBOL_MARGIN } from '../../../../utils/default'; +import { DIMENSION_MARGIN, SYMBOL_MARGIN } from '../../../../utils/default'; import { type ISymbolModel } from '../../../../Interfaces/ISymbolModel'; import { Selector } from '../Selector/Selector'; interface ISelectorSymbolProps { symbols: Map selected?: ISymbolModel - scale?: number } export function SelectorSymbol(props: ISelectorSymbolProps): JSX.Element { @@ -18,30 +17,27 @@ export function SelectorSymbol(props: ISelectorSymbolProps): JSX.Element { ); } - const scale = (props.scale ?? 1); - const [width, height] = [ - props.selected.width / scale, - props.selected.height / scale - ]; + let x, y: number; - const [x, y] = [ - props.selected.x + props.selected.width / 2, - -SYMBOL_MARGIN - height]; + const scaledHeight = props.selected.height; + const scaledWidth = props.selected.width; - const style: React.CSSProperties = { - transform: 'translateX(-50%)', - transformBox: 'fill-box' - }; + if (props.selected.isVertical) { + x = -SYMBOL_MARGIN - props.selected.width; + y = props.selected.offset; + } else { + x = props.selected.offset; + y = -SYMBOL_MARGIN - props.selected.height; + } return ( ); } diff --git a/src/Components/SVG/Elements/Symbol.tsx b/src/Components/SVG/Elements/Symbol.tsx index 09a19f9..c3a6eb8 100644 --- a/src/Components/SVG/Elements/Symbol.tsx +++ b/src/Components/SVG/Elements/Symbol.tsx @@ -1,7 +1,7 @@ import { Interweave } from 'interweave'; import * as React from 'react'; -import { ISymbolModel } from '../../../Interfaces/ISymbolModel'; -import { DIMENSION_MARGIN, SYMBOL_MARGIN } from '../../../utils/default'; +import { type ISymbolModel } from '../../../Interfaces/ISymbolModel'; +import { SYMBOL_MARGIN } from '../../../utils/default'; interface ISymbolProps { model: ISymbolModel @@ -12,11 +12,22 @@ export function Symbol(props: ISymbolProps): JSX.Element { const href = props.model.config.Image.Base64Image ?? props.model.config.Image.Url; const hasSVG = props.model.config.Image.Svg !== undefined && props.model.config.Image.Svg !== null; + + let x, y: number; + + if (props.model.isVertical) { + x = -SYMBOL_MARGIN - props.model.width; + y = props.model.offset; + } else { + x = props.model.offset; + y = -SYMBOL_MARGIN - props.model.height; + } + if (hasSVG) { return ( + x={x} + y={y} + height={props.model.height} + width={props.model.width} /> ); } diff --git a/src/Components/SymbolProperties/SymbolForm.tsx b/src/Components/SymbolProperties/SymbolForm.tsx index 9ffc727..61a9f6e 100644 --- a/src/Components/SymbolProperties/SymbolForm.tsx +++ b/src/Components/SymbolProperties/SymbolForm.tsx @@ -1,11 +1,11 @@ import * as React from 'react'; -import { ISymbolModel } from '../../Interfaces/ISymbolModel'; -import { RestoreX, TransformX } from '../../utils/svg'; +import { type ISymbolModel } from '../../Interfaces/ISymbolModel'; +import { RestoreX, RestoreY, TransformX, TransformY } from '../../utils/svg'; import { InputGroup } from '../InputGroup/InputGroup'; import { TextInputGroup } from '../InputGroup/TextInputGroup'; import { Text } from '../Text/Text'; -import { PropertyType } from '../../Enums/PropertyType'; import { ToggleButton } from '../ToggleButton/ToggleButton'; +import { type PositionReference } from '../../Enums/PositionReference'; interface ISymbolFormProps { symbol: ISymbolModel @@ -13,6 +13,29 @@ interface ISymbolFormProps { onChange: (key: string, value: string | number | boolean) => void } +function Restore(offset: number, + isVertical: boolean, + height: number, + width: number, + position: PositionReference | undefined): number { + if (isVertical) { + return RestoreY(offset, height, position); + } else { + return RestoreX(offset, width, position); + } +} +function Transform(offset: number, + isVertical: boolean, + height: number, + width: number, + position: PositionReference | undefined): number { + if (isVertical) { + return TransformY(offset, height, position); + } else { + return TransformX(offset, width, position); + } +} + export function SymbolForm(props: ISymbolFormProps): JSX.Element { return (
@@ -32,16 +55,34 @@ export function SymbolForm(props: ISymbolFormProps): JSX.Element { inputClassName='' type='string' value={props.symbol.displayedText} - onChange={(value) => props.onChange('displayedText', value)} /> + onChange={(value) => { props.onChange('displayedText', value); }} /> props.onChange('x', RestoreX(Number(value), props.symbol.width, props.symbol.config.PositionReference))} /> + value={Transform(props.symbol.offset, + props.symbol.isVertical, + props.symbol.height, + props.symbol.width, + props.symbol.config.PositionReference).toString()} + onChange={(value) => { + props.onChange('offset', + Restore(Number(value), + props.symbol.isVertical, + props.symbol.height, + props.symbol.width, + props.symbol.config.PositionReference)); + }} /> + { props.onChange('isVertical', e.target.checked); }}/> props.onChange('height', Number(value))} /> + onChange={(value) => { props.onChange('height', Number(value)); }} /> props.onChange('width', Number(value))} /> + onChange={(value) => { props.onChange('width', Number(value)); }} /> props.onChange('showDimension', e.target.checked)}/> + onChange={(e) => { props.onChange('showDimension', e.target.checked); }}/>
); } diff --git a/src/Interfaces/IAvailableSymbol.ts b/src/Interfaces/IAvailableSymbol.ts index e69a996..fe085a6 100644 --- a/src/Interfaces/IAvailableSymbol.ts +++ b/src/Interfaces/IAvailableSymbol.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { PositionReference } from '../Enums/PositionReference'; -import { IAvailableContainer } from './IAvailableContainer'; -import { IImage } from './IImage'; +import { type PositionReference } from '../Enums/PositionReference'; +import { type IAvailableContainer } from './IAvailableContainer'; +import { type IImage } from './IImage'; /** * Model of available symbol to configure the application */ @@ -13,9 +13,9 @@ export interface IAvailableSymbol { /** displayed text */ DisplayedText?: string - X?: number + isVertical?: boolean - Y?: number + offset?: number Width?: number diff --git a/src/Interfaces/ISymbolModel.ts b/src/Interfaces/ISymbolModel.ts index ca0604b..ff91b00 100644 --- a/src/Interfaces/ISymbolModel.ts +++ b/src/Interfaces/ISymbolModel.ts @@ -13,10 +13,10 @@ export interface ISymbolModel { /** Configuration of the symbol */ config: IAvailableSymbol - /** Horizontal offset */ - x: number + isVertical: boolean - // TODO: Implement Y and verticality + /** offset */ + offset: number /** Width */ width: number diff --git a/src/Translations/translation.en.json b/src/Translations/translation.en.json index 844b572..0ac3c3c 100644 --- a/src/Translations/translation.en.json +++ b/src/Translations/translation.en.json @@ -76,7 +76,9 @@ "@SymbolName": "Name", "@SymbolDisplayedText": "Displayed text", - "@SymbolX": "x", + "@SymbolOffset" : "Offset", + "@IsVertical" : "Vertical", + "@ShowDimension" : "Dimension", "@SymbolHeight": "Height", "@SymbolWidth": "Width" } diff --git a/src/Translations/translation.fr.json b/src/Translations/translation.fr.json index 6d01aef..60b9cfe 100644 --- a/src/Translations/translation.fr.json +++ b/src/Translations/translation.fr.json @@ -76,7 +76,9 @@ "@SymbolName": "Nom", "@SymbolDisplayedText": "Texte affiché", - "@SymbolX": "x", + "@SymbolOffset" : "Décalage", + "@IsVertical" : "Vertical", + "@ShowDimension" : "Cotation", "@SymbolHeight": "Hauteur", "@SymbolWidth": "Largeur" } diff --git a/src/utils/default.ts b/src/utils/default.ts index 5977edd..de8b91e 100644 --- a/src/utils/default.ts +++ b/src/utils/default.ts @@ -9,6 +9,7 @@ import { type ISymbolModel } from '../Interfaces/ISymbolModel'; import { Orientation } from '../Enums/Orientation'; import { AppState } from '../Enums/AppState'; import { type IDimensionOptions } from '../Interfaces/IDimensionOptions'; +import { type IDimensionStyle } from '../Components/SVG/Elements/Dimension'; /// EDITOR DEFAULTS /// @@ -69,10 +70,14 @@ export const SHOW_BORROWER_DIMENSIONS = true; export const DIMENSION_MARGIN = 50; export const SYMBOL_MARGIN = 25; export const NOTCHES_LENGTH = 10; +export const DEFAULT_DIMENSION_SYMBOL_STYLE: IDimensionStyle = { + color: '#000000' +}; /// SYMBOL DEFAULTS /// export const DEFAULT_SYMBOL_WIDTH = 32; +export const DEFAULT_SYMBOL_IS_VERTICAL = false; export const DEFAULT_SYMBOL_HEIGHT = 32; /** @@ -270,7 +275,7 @@ export function GetDefaultContainerProps(type: string, hideChildrenInTreeview: containerConfig.HideChildrenInTreeview ?? false, dimensionOptions: { childrenDimensions: { - ...containerConfig.DimensionOptions?.selfDimensions, + ...containerConfig.DimensionOptions?.childrenDimensions, positions: containerConfig.DimensionOptions?.childrenDimensions.positions ?? [] }, selfDimensions: { @@ -304,7 +309,8 @@ export function GetDefaultSymbolModel(name: string, displayedText: symbolConfig.DisplayedText ?? id, type: name, config: structuredClone(symbolConfig), - x: 0, + offset: 0, + isVertical: symbolConfig.isVertical ?? DEFAULT_SYMBOL_IS_VERTICAL, width: symbolConfig.Width ?? DEFAULT_SYMBOL_WIDTH, height: symbolConfig.Height ?? DEFAULT_SYMBOL_HEIGHT, linkedContainers: new Set(), diff --git a/test-server/http.js b/test-server/http.js index 73f8755..9c64416 100644 --- a/test-server/http.js +++ b/test-server/http.js @@ -81,7 +81,7 @@ const GetSVGLayoutConfiguration = () => { Style: { fillOpacity: 1, strokeWidth: 2, - stroke: 'red', + stroke: '#ff0000', fill: '#d3c9b7', }, IsFlex: true, @@ -96,7 +96,7 @@ const GetSVGLayoutConfiguration = () => { Style: { fillOpacity: 1, strokeWidth: 2, - stroke: 'red', + stroke: '#ff0000', fill: '#d3c9b7', }, IsFlex: true, @@ -115,8 +115,8 @@ const GetSVGLayoutConfiguration = () => { Style: { fillOpacity: 1, strokeWidth: 2, - stroke: 'green', - fill: 'white' + stroke: '#00ff00', + fill: '#ffffff' }, Category: "Stuff", IsFlex: true, @@ -258,8 +258,8 @@ const GetSVGLayoutConfiguration = () => { Style: { fillOpacity: 1, strokeWidth: 2, - stroke: 'blue', - fill: 'blue', + stroke: '#0000ff', + fill: '#0000ff', } }, { @@ -270,8 +270,8 @@ const GetSVGLayoutConfiguration = () => { Style: { fillOpacity: 1, strokeWidth: 2, - stroke: 'red', - fill: 'red', + stroke: '#ff0000', + fill: '#ff0000', } } ], @@ -286,8 +286,8 @@ const GetSVGLayoutConfiguration = () => { Svg: null, Url: 'https://www.manutan.fr/img/S/GRP/ST/AIG3930272.jpg' }, - Name: 'Poteau structure', - PositionReference: 1, + Name: 'Poteau CenterCenter', + PositionReference: 4, AssociatedContainer: { Type: 'Montant' } @@ -297,13 +297,49 @@ const GetSVGLayoutConfiguration = () => { Height: 32, Image: { Base64Image: null, - Name: 'Arrow', + Name: 'ArrowTopLeft', Svg: null, Url: './images/arrow-down.svg' }, - Name: 'Arrow', + Name: 'ArrowTopLeft', PositionReference: 0 }, + { + Width: 32, + Height: 32, + Image: { + Base64Image: null, + Name: 'ArrowTopRight', + Svg: null, + Url: './images/arrow-down.svg' + }, + Name: 'ArrowTopRight', + PositionReference: 2 + }, + { + Width: 32, + Height: 32, + Image: { + Base64Image: null, + Name: 'ArrowCenterRight', + Svg: null, + Url: './images/arrow-down.svg' + }, + Name: 'ArrowCenterRight', + PositionReference: 5 + }, + { + Width: 32, + Height: 32, + Image: { + Base64Image: null, + Name: 'ArrowBottomRight', + Svg: null, + Url: './images/arrow-down.svg' + }, + Name: 'ArrowBottomRight', + PositionReference: 8 + }, { Width: 32, Height: 32, @@ -334,7 +370,7 @@ const GetSVGLayoutConfiguration = () => { Height: 200, Orientation: 0, Style: { - stroke: 'black', + stroke: '#000000', strokeWidth: 2, fillOpacity: 0 }