diff --git a/src/Components/ContainerProperties/ContainerForm.tsx b/src/Components/ContainerProperties/ContainerForm.tsx index 8b7a505..f70e42d 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 diff --git a/src/Components/ContainerProperties/ContainerProperties.tsx b/src/Components/ContainerProperties/ContainerProperties.tsx index b296e3a..642126c 100644 --- a/src/Components/ContainerProperties/ContainerProperties.tsx +++ b/src/Components/ContainerProperties/ContainerProperties.tsx @@ -1,10 +1,12 @@ import React from 'react'; -import { PropertyType } from '../../Enums/PropertyType'; -import { IContainerProperties } from '../../Interfaces/IContainerProperties'; -import { ISymbolModel } from '../../Interfaces/ISymbolModel'; +import { type PropertyType } from '../../Enums/PropertyType'; +import { type IContainerProperties } from '../../Interfaces/IContainerProperties'; +import { type ISymbolModel } from '../../Interfaces/ISymbolModel'; import { ContainerForm } from './ContainerForm'; +import { type IContainerModel } from '../../Interfaces/IContainerModel'; interface IPropertiesProps { + containers: Map 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/Behaviors/SymbolBehaviors.ts b/src/Components/Editor/Behaviors/SymbolBehaviors.ts index 67af838..df375d0 100644 --- a/src/Components/Editor/Behaviors/SymbolBehaviors.ts +++ b/src/Components/Editor/Behaviors/SymbolBehaviors.ts @@ -7,8 +7,8 @@ export function ApplySymbol(containers: Map, container: IContainerModel, symbol: ISymbolModel): IContainerModel { if (symbol.isVertical) { - container.properties.y = TransformY(symbol.offset + symbol.height / 2, - symbol.height, + container.properties.y = TransformY(symbol.offset, + symbol.height * 2, symbol.config.PositionReference); container.properties.y = RestoreY(container.properties.y, container.properties.height, @@ -21,7 +21,7 @@ export function ApplySymbol(containers: Map, container.properties.y = y; return container; } else { - container.properties.x = TransformX(symbol.offset, symbol.width, symbol.config.PositionReference); + container.properties.x = TransformX(symbol.offset, symbol.width * 2, symbol.config.PositionReference); container.properties.x = RestoreX(container.properties.x, container.properties.width, container.properties.positionReference); 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 &&
0) { const id = `dim-y-margin-left${symbol.width.toFixed(0)}-${symbol.id}`; @@ -213,7 +213,7 @@ function AddVerticalSymbolDimension(symbol: ISymbolModel, scale: number, depth: number ): void { - const height = symbol.offset + (symbol.height / 2); + const height = TransformY(symbol.offset, symbol.height * 2, symbol.config.PositionReference); if (height != null && height > 0) { const id = `dim-x-margin-left${symbol.height.toFixed(0)}-${symbol.id}`; diff --git a/src/Components/SVG/Elements/SelectorSymbol/SelectorSymbol.tsx b/src/Components/SVG/Elements/SelectorSymbol/SelectorSymbol.tsx index 87ec519..842527e 100644 --- a/src/Components/SVG/Elements/SelectorSymbol/SelectorSymbol.tsx +++ b/src/Components/SVG/Elements/SelectorSymbol/SelectorSymbol.tsx @@ -3,6 +3,8 @@ import * as React from 'react'; import { SYMBOL_MARGIN } from '../../../../utils/default'; import { type ISymbolModel } from '../../../../Interfaces/ISymbolModel'; import { Selector } from '../Selector/Selector'; +import { TransformX, TransformY } from '../../../../utils/svg'; +import { PositionReference } from '../../../../Enums/PositionReference'; interface ISelectorSymbolProps { symbols: Map @@ -19,20 +21,44 @@ 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 scaledHeight = props.selected.height / scale; + const scaledWidth = props.selected.width / scale; + if (props.selected.isVertical) { - x = -SYMBOL_MARGIN / scale - width; - y = (props.selected.offset + props.selected.height / 2) - (props.selected.height / scale / 2); + x = (-SYMBOL_MARGIN - props.selected.width) / scale; + y = TransformY(props.selected.offset, props.selected.height * 2, props.selected.config.PositionReference); + + switch (props.selected.config.PositionReference) { + case PositionReference.CenterLeft: + case PositionReference.CenterCenter: + case PositionReference.CenterRight: + y -= scaledHeight / 2; + break; + case PositionReference.BottomLeft: + case PositionReference.BottomCenter: + case PositionReference.BottomRight: + y -= scaledHeight; + break; + } } else { - [x, y] = [ - (props.selected.offset + props.selected.width / 2) - (props.selected.width / scale / 2), - -SYMBOL_MARGIN / scale - height]; + x = TransformX(props.selected.offset, props.selected.width * 2, props.selected.config.PositionReference); + + switch (props.selected.config.PositionReference) { + case PositionReference.TopCenter: + case PositionReference.CenterCenter: + case PositionReference.BottomCenter: + x -= scaledWidth / 2; + break; + case PositionReference.TopRight: + case PositionReference.CenterRight: + case PositionReference.BottomRight: + x -= scaledWidth; + break; + } + y = (-SYMBOL_MARGIN - props.selected.height) / scale; } return ( @@ -40,8 +66,8 @@ export function SelectorSymbol(props: ISelectorSymbolProps): JSX.Element { text={props.selected.displayedText} x={x} y={y} - width={width} - height={height} + width={scaledWidth} + height={scaledHeight} scale={scale} /> ); diff --git a/src/Components/SVG/Elements/Symbol.tsx b/src/Components/SVG/Elements/Symbol.tsx index 1103bff..78978f9 100644 --- a/src/Components/SVG/Elements/Symbol.tsx +++ b/src/Components/SVG/Elements/Symbol.tsx @@ -2,6 +2,8 @@ import { Interweave } from 'interweave'; import * as React from 'react'; import { type ISymbolModel } from '../../../Interfaces/ISymbolModel'; import { DIMENSION_MARGIN, SYMBOL_MARGIN } from '../../../utils/default'; +import { TransformX, TransformY } from '../../../utils/svg'; +import { PositionReference } from '../../../Enums/PositionReference'; interface ISymbolProps { model: ISymbolModel @@ -38,9 +40,36 @@ export function Symbol(props: ISymbolProps): JSX.Element { } if (props.model.isVertical) { x = (-SYMBOL_MARGIN - props.model.width) / props.scale; - y = (props.model.offset + props.model.height / 2) - (props.model.height / props.scale / 2); + y = TransformY(props.model.offset, props.model.height * 2, props.model.config.PositionReference); + + switch (props.model.config.PositionReference) { + case PositionReference.CenterLeft: + case PositionReference.CenterCenter: + case PositionReference.CenterRight: + y -= props.model.height / props.scale / 2; + break; + case PositionReference.BottomLeft: + case PositionReference.BottomCenter: + case PositionReference.BottomRight: + y -= props.model.height / props.scale; + break; + } } else { - x = (props.model.offset + props.model.width / 2) - (props.model.width / props.scale / 2); + x = TransformX(props.model.offset, props.model.width * 2, props.model.config.PositionReference); + + switch (props.model.config.PositionReference) { + case PositionReference.TopCenter: + case PositionReference.CenterCenter: + case PositionReference.BottomCenter: + x -= props.model.width / props.scale / 2; + break; + case PositionReference.TopRight: + case PositionReference.CenterRight: + case PositionReference.BottomRight: + x -= props.model.width / props.scale; + break; + } + y = (-SYMBOL_MARGIN - props.model.height) / props.scale; } return ( diff --git a/test-server/http.js b/test-server/http.js index 73f8755..ade40aa 100644 --- a/test-server/http.js +++ b/test-server/http.js @@ -286,7 +286,7 @@ const GetSVGLayoutConfiguration = () => { Svg: null, Url: 'https://www.manutan.fr/img/S/GRP/ST/AIG3930272.jpg' }, - Name: 'Poteau structure', + Name: 'Poteau CenterCenter', PositionReference: 1, 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,