Merged PR 199: Add more Position for the dimensions + rename isDimensionBorrower and MarkPosition... + Refactor components in ContainerForm with Checkboxes and Selector + Add more docs
Add more Position for the dimensions Rename isDimensionBorrower and MarkPosition... Refactor components in ContainerForm with Checkboxes and Selector Add more docs
This commit is contained in:
parent
38666af314
commit
b88539e34d
13 changed files with 494 additions and 314 deletions
|
@ -1,17 +1,19 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { IInputGroup } from '../../Interfaces/IInputGroup';
|
|
||||||
|
|
||||||
interface ICheckboxGroupButtonsProps {
|
interface ICheckboxGroupButtonsProps {
|
||||||
name: string
|
name: string
|
||||||
selectedValues: number[]
|
selectedValues: number[]
|
||||||
inputClassName: string
|
inputClassName: string
|
||||||
labelText: string
|
labelText: string
|
||||||
inputGroups: IEnumCheckboxInputGroup[]
|
inputGroups: ICheckboxInputGroup[]
|
||||||
colQty: number
|
colQty: number
|
||||||
onChange: (newSelectedValues: number[]) => void
|
onChange: (newSelectedValues: number[]) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IEnumCheckboxInputGroup extends Omit<IInputGroup, 'value'> {
|
// TODO: After modeler uses Typescript >= 4.x, extends Omit<IInputGroup, 'value'>
|
||||||
|
interface ICheckboxInputGroup {
|
||||||
|
key: string
|
||||||
|
text: React.ReactNode
|
||||||
value: number
|
value: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +34,7 @@ const GRID_COLS = [
|
||||||
'grid-cols-12'
|
'grid-cols-12'
|
||||||
];
|
];
|
||||||
|
|
||||||
export function EnumCheckboxGroupButtons(props: ICheckboxGroupButtonsProps): JSX.Element {
|
export function CheckboxGroupButtons(props: ICheckboxGroupButtonsProps): JSX.Element {
|
||||||
const selectedOptions = new Set<number>(props.selectedValues);
|
const selectedOptions = new Set<number>(props.selectedValues);
|
||||||
const inputGroups = props.inputGroups.map((inputGroup) => (
|
const inputGroups = props.inputGroups.map((inputGroup) => (
|
||||||
<div key={inputGroup.key}>
|
<div key={inputGroup.key}>
|
||||||
|
@ -69,7 +71,7 @@ export function EnumCheckboxGroupButtons(props: ICheckboxGroupButtonsProps): JSX
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
function IsChecked(inputGroup: IEnumCheckboxInputGroup): boolean {
|
function IsChecked(inputGroup: ICheckboxInputGroup): boolean {
|
||||||
return selectedOptions.has(inputGroup.value);
|
return selectedOptions.has(inputGroup.value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { ChevronUpDownIcon } from '@heroicons/react/20/solid';
|
||||||
|
import { CheckboxGroupButtons } from './CheckboxGroupButtons';
|
||||||
|
import { Orientation } from '../../Enums/Orientation';
|
||||||
|
|
||||||
|
interface IOrientationCheckboxesProps {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
labelText: string
|
||||||
|
value: Orientation[]
|
||||||
|
onChange: (key: string, value: number[]) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export function OrientationCheckboxes({
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
labelText,
|
||||||
|
value,
|
||||||
|
onChange
|
||||||
|
}: IOrientationCheckboxesProps): JSX.Element {
|
||||||
|
return <CheckboxGroupButtons
|
||||||
|
key={id}
|
||||||
|
name={name}
|
||||||
|
selectedValues={value}
|
||||||
|
inputClassName='hidden'
|
||||||
|
labelText={labelText}
|
||||||
|
colQty={2}
|
||||||
|
inputGroups={[
|
||||||
|
{
|
||||||
|
key: `${id}-horizontal`,
|
||||||
|
text: (
|
||||||
|
<div title='Horizontal' aria-label='horizontal' className='radio-button-icon'>
|
||||||
|
<ChevronUpDownIcon className='heroicon p-1' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: Orientation.Horizontal
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${id}-vertical`,
|
||||||
|
text: (
|
||||||
|
<div title='Vertical' aria-label='vertical' className='radio-button-icon'>
|
||||||
|
<ChevronUpDownIcon className='heroicon rotate-90 p-1' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: Orientation.Vertical
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
onChange={(newSelectedValues) => {
|
||||||
|
onChange(id, newSelectedValues);
|
||||||
|
}}
|
||||||
|
/>;
|
||||||
|
}
|
70
src/Components/CheckboxGroupButtons/PositionCheckboxes.tsx
Normal file
70
src/Components/CheckboxGroupButtons/PositionCheckboxes.tsx
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { ArrowDownIcon, ArrowLeftIcon, ArrowRightIcon, ArrowUpIcon } from '@heroicons/react/20/solid';
|
||||||
|
import { Position } from '../../Enums/Position';
|
||||||
|
import { CheckboxGroupButtons } from './CheckboxGroupButtons';
|
||||||
|
|
||||||
|
interface IPositionCheckboxesProps {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
labelText: string
|
||||||
|
value: Position[]
|
||||||
|
onChange: (key: string, value: number[]) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export function PositionCheckboxes({
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
labelText,
|
||||||
|
value,
|
||||||
|
onChange
|
||||||
|
}: IPositionCheckboxesProps): JSX.Element {
|
||||||
|
return <CheckboxGroupButtons
|
||||||
|
key={id}
|
||||||
|
name={name}
|
||||||
|
selectedValues={value}
|
||||||
|
inputClassName='hidden'
|
||||||
|
labelText={labelText}
|
||||||
|
colQty={4}
|
||||||
|
inputGroups={[
|
||||||
|
{
|
||||||
|
key: `${id}-left`,
|
||||||
|
text: (
|
||||||
|
<div title='Left' aria-label='left' className='radio-button-icon'>
|
||||||
|
<ArrowLeftIcon className='heroicon p-1' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: Position.Left
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${id}-down`,
|
||||||
|
text: (
|
||||||
|
<div title='Down' aria-label='down' className='radio-button-icon'>
|
||||||
|
<ArrowDownIcon className='heroicon p-1' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: Position.Down
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${id}-up`,
|
||||||
|
text: (
|
||||||
|
<div title='Up' aria-label='up' className='radio-button-icon'>
|
||||||
|
<ArrowUpIcon className='heroicon p-1' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: Position.Up
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${id}-right`,
|
||||||
|
text: (
|
||||||
|
<div title='Right' aria-label='right' className='radio-button-icon'>
|
||||||
|
<ArrowRightIcon className='heroicon p-1' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: Position.Right
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
onChange={(newSelectedValues) => {
|
||||||
|
onChange(id, newSelectedValues);
|
||||||
|
}}
|
||||||
|
/>;
|
||||||
|
}
|
|
@ -1,19 +1,17 @@
|
||||||
import { Bars3BottomLeftIcon, Bars3CenterLeftIcon, Bars3Icon, Bars3BottomRightIcon, Bars2Icon } from '@heroicons/react/24/outline';
|
|
||||||
import { FlagIcon, ViewColumnsIcon } from '@heroicons/react/20/solid';
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { PropertyType } from '../../Enums/PropertyType';
|
import { PropertyType } from '../../Enums/PropertyType';
|
||||||
import { PositionReference } from '../../Enums/PositionReference';
|
|
||||||
import { IContainerProperties } from '../../Interfaces/IContainerProperties';
|
import { IContainerProperties } from '../../Interfaces/IContainerProperties';
|
||||||
import { ISymbolModel } from '../../Interfaces/ISymbolModel';
|
import { ISymbolModel } from '../../Interfaces/ISymbolModel';
|
||||||
import { SHOW_BORROWER_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS, SHOW_SELF_DIMENSIONS } from '../../utils/default';
|
import { SHOW_BORROWER_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS, SHOW_SELF_DIMENSIONS } from '../../utils/default';
|
||||||
import { ApplyWidthMargin, ApplyXMargin, RemoveWidthMargin, RemoveXMargin, RestoreX, RestoreY, TransformX, TransformY } from '../../utils/svg';
|
import { ApplyWidthMargin, ApplyXMargin, RemoveWidthMargin, RemoveXMargin, RestoreX, RestoreY, TransformX, TransformY } from '../../utils/svg';
|
||||||
import { InputGroup } from '../InputGroup/InputGroup';
|
import { InputGroup } from '../InputGroup/InputGroup';
|
||||||
import { TextInputGroup } from '../InputGroup/TextInputGroup';
|
import { TextInputGroup } from '../InputGroup/TextInputGroup';
|
||||||
import { RadioGroupButtons } from '../RadioGroupButtons/RadioGroupButtons';
|
|
||||||
import { Select } from '../Select/Select';
|
import { Select } from '../Select/Select';
|
||||||
import { ToggleButton, ToggleType } from '../ToggleButton/ToggleButton';
|
import { ToggleButton, ToggleType } from '../ToggleButton/ToggleButton';
|
||||||
import { Orientation } from '../../Enums/Orientation';
|
import { PositionReferenceSelector } from '../RadioGroupButtons/PositionReferenceSelector';
|
||||||
import { EnumCheckboxGroupButtons } from '../EnumCheckboxGroupButtons/EnumCheckboxGroupButtons';
|
import { OrientationSelector } from '../RadioGroupButtons/OrientationSelector';
|
||||||
|
import { OrientationCheckboxes } from '../CheckboxGroupButtons/OrientationCheckboxes';
|
||||||
|
import { PositionCheckboxes } from '../CheckboxGroupButtons/PositionCheckboxes';
|
||||||
|
|
||||||
interface IContainerFormProps {
|
interface IContainerFormProps {
|
||||||
properties: IContainerProperties
|
properties: IContainerProperties
|
||||||
|
@ -75,7 +73,13 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
||||||
type='string'
|
type='string'
|
||||||
value={props.properties.displayedText?.toString()}
|
value={props.properties.displayedText?.toString()}
|
||||||
onChange={(value) => props.onChange('displayedText', value)} />
|
onChange={(value) => props.onChange('displayedText', value)} />
|
||||||
<OrientationSelector {...props} />
|
<OrientationSelector
|
||||||
|
id='orientation'
|
||||||
|
name='Orientation'
|
||||||
|
labelText='Orientation'
|
||||||
|
value={props.properties.orientation}
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
<TextInputGroup
|
<TextInputGroup
|
||||||
id={`${props.properties.id}-x`}
|
id={`${props.properties.id}-x`}
|
||||||
labelText='x'
|
labelText='x'
|
||||||
|
@ -245,8 +249,12 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
||||||
type={ToggleType.Full}
|
type={ToggleType.Full}
|
||||||
checked={props.properties.isAnchor}
|
checked={props.properties.isAnchor}
|
||||||
onChange={(event) => props.onChange('isAnchor', event.target.checked)} />
|
onChange={(event) => props.onChange('isAnchor', event.target.checked)} />
|
||||||
<AlignmentSelector
|
<PositionReferenceSelector
|
||||||
{...props}
|
id='positionReference'
|
||||||
|
name='PositionReference'
|
||||||
|
labelText='Alignment'
|
||||||
|
value={props.properties.positionReference}
|
||||||
|
onChange={props.onChange}
|
||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
inputKey='linkedSymbolId'
|
inputKey='linkedSymbolId'
|
||||||
|
@ -263,206 +271,43 @@ export function ContainerForm(props: IContainerFormProps): JSX.Element {
|
||||||
{GetCSSInputs(props.properties, props.onChange)}
|
{GetCSSInputs(props.properties, props.onChange)}
|
||||||
{
|
{
|
||||||
SHOW_SELF_DIMENSIONS &&
|
SHOW_SELF_DIMENSIONS &&
|
||||||
<ToggleButton
|
<PositionCheckboxes
|
||||||
|
id='showSelfDimensions'
|
||||||
|
name='ShowSelfDimensions'
|
||||||
labelText='Show dimension'
|
labelText='Show dimension'
|
||||||
inputKey='showSelfDimensions'
|
value={props.properties.showSelfDimensions}
|
||||||
labelClassName=''
|
onChange={props.onChange}
|
||||||
inputClassName=''
|
/>
|
||||||
type={ToggleType.Full}
|
|
||||||
checked={props.properties.showSelfDimensions}
|
|
||||||
onChange={(event) => props.onChange('showSelfDimensions', event.target.checked)} />
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SHOW_CHILDREN_DIMENSIONS &&
|
SHOW_CHILDREN_DIMENSIONS &&
|
||||||
<ToggleButton
|
<PositionCheckboxes
|
||||||
|
id='showChildrenDimensions'
|
||||||
|
name='ShowChildrenDimensions'
|
||||||
labelText='Show overall dimension of its children'
|
labelText='Show overall dimension of its children'
|
||||||
inputKey='showChildrenDimensions'
|
value={props.properties.showChildrenDimensions}
|
||||||
labelClassName=''
|
onChange={props.onChange}
|
||||||
inputClassName=''
|
/>
|
||||||
type={ToggleType.Full}
|
|
||||||
checked={props.properties.showChildrenDimensions}
|
|
||||||
onChange={(event) => props.onChange('showChildrenDimensions', event.target.checked)} />
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SHOW_BORROWER_DIMENSIONS &&
|
SHOW_BORROWER_DIMENSIONS &&
|
||||||
<>
|
<>
|
||||||
<MarkPositionOptions {...props} />
|
<OrientationCheckboxes
|
||||||
<ToggleButton
|
id='markPosition'
|
||||||
|
name='MarkPosition'
|
||||||
|
value={props.properties.markPosition}
|
||||||
|
labelText='Mark the position'
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
|
<PositionCheckboxes
|
||||||
|
id='showDimensionWithMarks'
|
||||||
|
name='ShowDimensionWithMarks'
|
||||||
labelText='Show dimension with marked children'
|
labelText='Show dimension with marked children'
|
||||||
inputKey='isDimensionBorrower'
|
value={props.properties.showDimensionWithMarks}
|
||||||
labelClassName=''
|
onChange={props.onChange}
|
||||||
inputClassName=''
|
/>
|
||||||
type={ToggleType.Full}
|
|
||||||
checked={props.properties.isDimensionBorrower}
|
|
||||||
onChange={(event) => props.onChange('isDimensionBorrower', event.target.checked)} />
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement categories in the form
|
|
||||||
|
|
||||||
function MarkPositionOptions(props: IContainerFormProps): JSX.Element {
|
|
||||||
return <EnumCheckboxGroupButtons
|
|
||||||
key='markPosition'
|
|
||||||
name='MarkPosition'
|
|
||||||
selectedValues={props.properties.markPositionToDimensionBorrower}
|
|
||||||
inputClassName='hidden'
|
|
||||||
labelText='Mark the position'
|
|
||||||
colQty={2}
|
|
||||||
inputGroups={[
|
|
||||||
{
|
|
||||||
key: 'mark-position-horizontal',
|
|
||||||
text: (
|
|
||||||
<div title='Horizontal' aria-label='horizontal' className='radio-button-icon'>
|
|
||||||
<FlagIcon className='heroicon p-1' />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: Orientation.Horizontal
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'mark-position-vertical',
|
|
||||||
text: (
|
|
||||||
<div title='Vertical' aria-label='vertical' className='radio-button-icon'>
|
|
||||||
<FlagIcon className='heroicon rotate-90 p-1' />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: Orientation.Vertical
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
onChange={(newSelectedValues) => {
|
|
||||||
props.onChange('markPositionToDimensionBorrower', newSelectedValues);
|
|
||||||
}}
|
|
||||||
/>;
|
|
||||||
}
|
|
||||||
|
|
||||||
function OrientationSelector(props: IContainerFormProps): JSX.Element {
|
|
||||||
return <RadioGroupButtons
|
|
||||||
key='orientation'
|
|
||||||
name='Orientation'
|
|
||||||
value={props.properties.orientation.toString()}
|
|
||||||
inputClassName='hidden'
|
|
||||||
labelText='Orientation'
|
|
||||||
colQty={2}
|
|
||||||
inputGroups={[
|
|
||||||
{
|
|
||||||
key: 'orientation-horizontal',
|
|
||||||
text: (
|
|
||||||
<div title='Horizontal' aria-label='horizontal' className='radio-button-icon'>
|
|
||||||
<ViewColumnsIcon className='heroicon p-1' />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: Orientation.Horizontal.toString()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'orientation-vertical',
|
|
||||||
text: (
|
|
||||||
<div title='Vertical' aria-label='vertical' className='radio-button-icon'>
|
|
||||||
<ViewColumnsIcon className='heroicon rotate-90 p-1' />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: Orientation.Vertical.toString()
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
onChange={(event) => {
|
|
||||||
props.onChange('orientation', Number(event.target.value));
|
|
||||||
}}
|
|
||||||
/>;
|
|
||||||
}
|
|
||||||
|
|
||||||
function AlignmentSelector(props: IContainerFormProps): JSX.Element {
|
|
||||||
return <RadioGroupButtons
|
|
||||||
key='positionReference'
|
|
||||||
name='PositionReference'
|
|
||||||
value={props.properties.positionReference.toString()}
|
|
||||||
inputClassName='hidden'
|
|
||||||
labelText='Alignment'
|
|
||||||
colQty={3}
|
|
||||||
inputGroups={[
|
|
||||||
{
|
|
||||||
key: 'position-reference-tl',
|
|
||||||
text: (
|
|
||||||
<div title='Top Left' aria-label='top left' className='radio-button-icon'>
|
|
||||||
<Bars3BottomLeftIcon className='heroicon' />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: PositionReference.TopLeft.toString()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'position-reference-tc',
|
|
||||||
text: (
|
|
||||||
<div title='Top Center' aria-label='top center' className='radio-button-icon'>
|
|
||||||
<Bars2Icon className='heroicon -scale-y-100' />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: PositionReference.TopCenter.toString()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'position-reference-tr',
|
|
||||||
text: (
|
|
||||||
<div title='Top Right' aria-label='top right' className='radio-button-icon'>
|
|
||||||
<Bars3BottomRightIcon className='heroicon' />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: PositionReference.TopRight.toString()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'position-reference-cl',
|
|
||||||
text: (
|
|
||||||
<div title='Center Left' aria-label='center left' className='radio-button-icon'>
|
|
||||||
<Bars3CenterLeftIcon className='heroicon' />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: PositionReference.CenterLeft.toString()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'position-reference-cc',
|
|
||||||
text: (
|
|
||||||
<div title='Center Center' aria-label='center center' className='radio-button-icon'>
|
|
||||||
<Bars3Icon className='heroicon' />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: PositionReference.CenterCenter.toString()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'position-reference-cr',
|
|
||||||
text: (
|
|
||||||
<div title='Center Right' aria-label='center right' className='radio-button-icon'>
|
|
||||||
<Bars3CenterLeftIcon className='heroicon -scale-x-100' />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: PositionReference.CenterRight.toString()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'position-reference-bl',
|
|
||||||
text: (
|
|
||||||
<div title='Bottom Left' aria-label='bottom left' className='radio-button-icon'>
|
|
||||||
<Bars3BottomLeftIcon className='heroicon -scale-y-100' />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: PositionReference.BottomLeft.toString()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'position-reference-bc',
|
|
||||||
text: (
|
|
||||||
<div title='Bottom Center' aria-label='center center' className='radio-button-icon'>
|
|
||||||
<Bars2Icon className='heroicon' />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: PositionReference.BottomCenter.toString()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'position-reference-br',
|
|
||||||
text: (
|
|
||||||
<div title='Bottom Right' aria-label='bottom right' className='radio-button-icon'>
|
|
||||||
<Bars3BottomRightIcon className='heroicon -scale-y-100' />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
value: PositionReference.BottomRight.toString()
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
onChange={(event) => {
|
|
||||||
props.onChange('positionReference', Number(event.target.value));
|
|
||||||
}} />;
|
|
||||||
}
|
|
||||||
|
|
|
@ -42,10 +42,10 @@ describe.concurrent('Properties', () => {
|
||||||
isAnchor: false,
|
isAnchor: false,
|
||||||
warning: '',
|
warning: '',
|
||||||
hideChildrenInTreeview: false,
|
hideChildrenInTreeview: false,
|
||||||
showChildrenDimensions: true, // TODO: put the dimension at the top (see pdf)
|
showChildrenDimensions: [],
|
||||||
showSelfDimensions: true, // TODO: put the dimension at the bottom (see pdf)
|
showSelfDimensions: [],
|
||||||
isDimensionBorrower: true, // second dimensions from the bottom
|
showDimensionWithMarks: [],
|
||||||
markPositionToDimensionBorrower: []
|
markPosition: []
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChange = vi.fn((key, value) => {
|
const handleChange = vi.fn((key, value) => {
|
||||||
|
|
|
@ -110,10 +110,10 @@ describe.concurrent('Elements sidebar', () => {
|
||||||
isAnchor: false,
|
isAnchor: false,
|
||||||
warning: '',
|
warning: '',
|
||||||
hideChildrenInTreeview: false,
|
hideChildrenInTreeview: false,
|
||||||
showChildrenDimensions: true,
|
showChildrenDimensions: [],
|
||||||
showSelfDimensions: true,
|
showSelfDimensions: [],
|
||||||
isDimensionBorrower: true,
|
showDimensionWithMarks: [],
|
||||||
markPositionToDimensionBorrower: [],
|
markPosition: [],
|
||||||
positionReference: PositionReference.TopLeft
|
positionReference: PositionReference.TopLeft
|
||||||
},
|
},
|
||||||
userData: {}
|
userData: {}
|
||||||
|
@ -144,10 +144,10 @@ describe.concurrent('Elements sidebar', () => {
|
||||||
type: 'type',
|
type: 'type',
|
||||||
warning: '',
|
warning: '',
|
||||||
hideChildrenInTreeview: false,
|
hideChildrenInTreeview: false,
|
||||||
showChildrenDimensions: true,
|
showChildrenDimensions: [],
|
||||||
showSelfDimensions: true,
|
showSelfDimensions: [],
|
||||||
isDimensionBorrower: true,
|
showDimensionWithMarks: [],
|
||||||
markPositionToDimensionBorrower: [],
|
markPosition: [],
|
||||||
isAnchor: false
|
isAnchor: false
|
||||||
},
|
},
|
||||||
userData: {}
|
userData: {}
|
||||||
|
@ -204,10 +204,10 @@ describe.concurrent('Elements sidebar', () => {
|
||||||
maxHeight: Infinity,
|
maxHeight: Infinity,
|
||||||
type: 'type',
|
type: 'type',
|
||||||
hideChildrenInTreeview: false,
|
hideChildrenInTreeview: false,
|
||||||
showChildrenDimensions: true,
|
showChildrenDimensions: [],
|
||||||
showSelfDimensions: true,
|
showSelfDimensions: [],
|
||||||
isDimensionBorrower: true,
|
showDimensionWithMarks: [],
|
||||||
markPositionToDimensionBorrower: [],
|
markPosition: [],
|
||||||
isAnchor: false
|
isAnchor: false
|
||||||
},
|
},
|
||||||
userData: {}
|
userData: {}
|
||||||
|
|
53
src/Components/RadioGroupButtons/OrientationSelector.tsx
Normal file
53
src/Components/RadioGroupButtons/OrientationSelector.tsx
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { ViewColumnsIcon } from '@heroicons/react/20/solid';
|
||||||
|
import { Orientation } from '../../Enums/Orientation';
|
||||||
|
import { RadioGroupButtons } from './RadioGroupButtons';
|
||||||
|
|
||||||
|
// TODO: After modeler uses TypeScript >= 4.x, extends Omit<ISelectorProps, 'value'>
|
||||||
|
interface IOrientationSelectorProps {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
labelText: string
|
||||||
|
value: Orientation
|
||||||
|
onChange: (key: string, value: number) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export function OrientationSelector({
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
labelText,
|
||||||
|
value,
|
||||||
|
onChange
|
||||||
|
}: IOrientationSelectorProps): JSX.Element {
|
||||||
|
return <RadioGroupButtons
|
||||||
|
key={id}
|
||||||
|
name={name}
|
||||||
|
value={value.toString()}
|
||||||
|
inputClassName='hidden'
|
||||||
|
labelText={labelText}
|
||||||
|
colQty={2}
|
||||||
|
inputGroups={[
|
||||||
|
{
|
||||||
|
key: `${id}-horizontal`,
|
||||||
|
text: (
|
||||||
|
<div title='Horizontal' aria-label='horizontal' className='radio-button-icon'>
|
||||||
|
<ViewColumnsIcon className='heroicon p-1' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: Orientation.Horizontal.toString()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${id}-vertical`,
|
||||||
|
text: (
|
||||||
|
<div title='Vertical' aria-label='vertical' className='radio-button-icon'>
|
||||||
|
<ViewColumnsIcon className='heroicon rotate-90 p-1' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: Orientation.Vertical.toString()
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
onChange={(event) => {
|
||||||
|
onChange(id, Number(event.target.value));
|
||||||
|
}}
|
||||||
|
/>;
|
||||||
|
}
|
114
src/Components/RadioGroupButtons/PositionReferenceSelector.tsx
Normal file
114
src/Components/RadioGroupButtons/PositionReferenceSelector.tsx
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Bars3BottomLeftIcon, Bars3CenterLeftIcon, Bars3Icon, Bars3BottomRightIcon, Bars2Icon } from '@heroicons/react/24/outline';
|
||||||
|
import { PositionReference } from '../../Enums/PositionReference';
|
||||||
|
import { RadioGroupButtons } from './RadioGroupButtons';
|
||||||
|
|
||||||
|
interface IPositionReferenceSelectorProps {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
labelText: string
|
||||||
|
value: PositionReference
|
||||||
|
onChange: (key: string, value: number) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export function PositionReferenceSelector({
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
labelText,
|
||||||
|
value,
|
||||||
|
onChange
|
||||||
|
}: IPositionReferenceSelectorProps): JSX.Element {
|
||||||
|
return <RadioGroupButtons
|
||||||
|
key={id}
|
||||||
|
name={name}
|
||||||
|
value={value.toString()}
|
||||||
|
inputClassName='hidden'
|
||||||
|
labelText={labelText}
|
||||||
|
colQty={3}
|
||||||
|
inputGroups={[
|
||||||
|
{
|
||||||
|
key: `${id}-tl`,
|
||||||
|
text: (
|
||||||
|
<div title='Top Left' aria-label='top left' className='radio-button-icon'>
|
||||||
|
<Bars3BottomLeftIcon className='heroicon' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: PositionReference.TopLeft.toString()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${id}-tc`,
|
||||||
|
text: (
|
||||||
|
<div title='Top Center' aria-label='top center' className='radio-button-icon'>
|
||||||
|
<Bars2Icon className='heroicon -scale-y-100' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: PositionReference.TopCenter.toString()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${id}-tr`,
|
||||||
|
text: (
|
||||||
|
<div title='Top Right' aria-label='top right' className='radio-button-icon'>
|
||||||
|
<Bars3BottomRightIcon className='heroicon' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: PositionReference.TopRight.toString()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${id}-cl`,
|
||||||
|
text: (
|
||||||
|
<div title='Center Left' aria-label='center left' className='radio-button-icon'>
|
||||||
|
<Bars3CenterLeftIcon className='heroicon' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: PositionReference.CenterLeft.toString()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${id}-cc`,
|
||||||
|
text: (
|
||||||
|
<div title='Center Center' aria-label='center center' className='radio-button-icon'>
|
||||||
|
<Bars3Icon className='heroicon' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: PositionReference.CenterCenter.toString()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${id}-cr`,
|
||||||
|
text: (
|
||||||
|
<div title='Center Right' aria-label='center right' className='radio-button-icon'>
|
||||||
|
<Bars3CenterLeftIcon className='heroicon -scale-x-100' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: PositionReference.CenterRight.toString()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${id}-bl`,
|
||||||
|
text: (
|
||||||
|
<div title='Bottom Left' aria-label='bottom left' className='radio-button-icon'>
|
||||||
|
<Bars3BottomLeftIcon className='heroicon -scale-y-100' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: PositionReference.BottomLeft.toString()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${id}-bc`,
|
||||||
|
text: (
|
||||||
|
<div title='Bottom Center' aria-label='center center' className='radio-button-icon'>
|
||||||
|
<Bars2Icon className='heroicon' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: PositionReference.BottomCenter.toString()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: `${id}-br`,
|
||||||
|
text: (
|
||||||
|
<div title='Bottom Right' aria-label='bottom right' className='radio-button-icon'>
|
||||||
|
<Bars3BottomRightIcon className='heroicon -scale-y-100' />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: PositionReference.BottomRight.toString()
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
onChange={(event) => {
|
||||||
|
onChange(id, Number(event.target.value));
|
||||||
|
}} />;
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Orientation } from '../../../Enums/Orientation';
|
import { Orientation } from '../../../Enums/Orientation';
|
||||||
|
import { Position } from '../../../Enums/Position';
|
||||||
import { ContainerModel, IContainerModel } from '../../../Interfaces/IContainerModel';
|
import { ContainerModel, IContainerModel } from '../../../Interfaces/IContainerModel';
|
||||||
import { DIMENSION_MARGIN, SHOW_BORROWER_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS, SHOW_SELF_DIMENSIONS } from '../../../utils/default';
|
import { DIMENSION_MARGIN, SHOW_BORROWER_DIMENSIONS, SHOW_CHILDREN_DIMENSIONS, SHOW_SELF_DIMENSIONS } from '../../../utils/default';
|
||||||
import { MakeRecursionDFSIterator, Pairwise } from '../../../utils/itertools';
|
import { MakeRecursionDFSIterator, Pairwise } from '../../../utils/itertools';
|
||||||
|
@ -13,6 +14,43 @@ interface IDimensionLayerProps {
|
||||||
|
|
||||||
const MODULE_STROKE_WIDTH = 1;
|
const MODULE_STROKE_WIDTH = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fonction that call another function given the positions
|
||||||
|
* @param dimMapped Position mapped depending on the Position enum in order:
|
||||||
|
* [0:left, 1:bottom, 2:up, 3:right]
|
||||||
|
* @param positions List of positions
|
||||||
|
* @param horizontalAction Action called when a left or right position is present
|
||||||
|
* @param verticalAction Action called when a down or up position is present
|
||||||
|
* @param params Params for the actions
|
||||||
|
* (the two actions must have the same number of params, and in the same order)
|
||||||
|
*/
|
||||||
|
function ActionByPosition(
|
||||||
|
dimMapped: number[],
|
||||||
|
positions: Position[],
|
||||||
|
horizontalAction: (dim: number, ...params: any[]) => void,
|
||||||
|
verticalAction: (dim: number, ...params: any[]) => void,
|
||||||
|
params: any[]
|
||||||
|
): void {
|
||||||
|
positions.forEach((position: Position) => {
|
||||||
|
const dim = dimMapped[position];
|
||||||
|
switch (position) {
|
||||||
|
case Position.Left:
|
||||||
|
case Position.Right:
|
||||||
|
verticalAction(dim, ...params);
|
||||||
|
break;
|
||||||
|
case Position.Down:
|
||||||
|
case Position.Up:
|
||||||
|
horizontalAction(dim, ...params);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of dimensions of all containers in root
|
||||||
|
* @param param0 Object with the root container and the scale of the svg
|
||||||
|
* @returns A list of dimensions
|
||||||
|
*/
|
||||||
function Dimensions({ root, scale }: IDimensionLayerProps): React.ReactNode[] {
|
function Dimensions({ root, scale }: IDimensionLayerProps): React.ReactNode[] {
|
||||||
const it = MakeRecursionDFSIterator(root, 0, [0, 0]);
|
const it = MakeRecursionDFSIterator(root, 0, [0, 0]);
|
||||||
const dimensions: React.ReactNode[] = [];
|
const dimensions: React.ReactNode[] = [];
|
||||||
|
@ -30,39 +68,71 @@ function Dimensions({ root, scale }: IDimensionLayerProps): React.ReactNode[] {
|
||||||
const containerTopDim = topDim - (DIMENSION_MARGIN * (depth + 1)) / scale;
|
const containerTopDim = topDim - (DIMENSION_MARGIN * (depth + 1)) / scale;
|
||||||
const containerBottomDim = bottomDim + (DIMENSION_MARGIN * (depth + 1)) / scale;
|
const containerBottomDim = bottomDim + (DIMENSION_MARGIN * (depth + 1)) / scale;
|
||||||
const containerRightDim = rightDim + (DIMENSION_MARGIN * (depth + 1)) / scale;
|
const containerRightDim = rightDim + (DIMENSION_MARGIN * (depth + 1)) / scale;
|
||||||
if (SHOW_SELF_DIMENSIONS && container.properties.showSelfDimensions) {
|
const dimMapped = [containerLeftDim, containerBottomDim, containerTopDim, containerRightDim];
|
||||||
AddSelfDimension(container, currentTransform, containerTopDim, containerLeftDim, scale, dimensions);
|
if (SHOW_SELF_DIMENSIONS && container.properties.showSelfDimensions.length > 0) {
|
||||||
|
ActionByPosition(
|
||||||
|
dimMapped,
|
||||||
|
container.properties.showSelfDimensions,
|
||||||
|
AddHorizontalSelfDimension,
|
||||||
|
AddVerticalSelfDimension,
|
||||||
|
[container,
|
||||||
|
currentTransform,
|
||||||
|
dimensions,
|
||||||
|
scale]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SHOW_BORROWER_DIMENSIONS && container.properties.isDimensionBorrower) {
|
if (SHOW_BORROWER_DIMENSIONS && container.properties.showDimensionWithMarks.length > 0) {
|
||||||
AddBorrowerDimension(containerBottomDim, containerRightDim, depth, scale, container, currentTransform, dimensions);
|
ActionByPosition(
|
||||||
|
dimMapped,
|
||||||
|
container.properties.showDimensionWithMarks,
|
||||||
|
AddHorizontalBorrowerDimension,
|
||||||
|
AddVerticalBorrowerDimension,
|
||||||
|
[container,
|
||||||
|
depth,
|
||||||
|
currentTransform,
|
||||||
|
dimensions,
|
||||||
|
scale]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SHOW_CHILDREN_DIMENSIONS && container.properties.showChildrenDimensions && container.children.length > 1) {
|
if (SHOW_CHILDREN_DIMENSIONS && container.properties.showChildrenDimensions.length > 0 && container.children.length > 1) {
|
||||||
AddChildrenDimension(container, currentTransform, dimensions, containerBottomDim, containerRightDim, scale);
|
ActionByPosition(
|
||||||
|
dimMapped,
|
||||||
|
container.properties.showChildrenDimensions,
|
||||||
|
AddHorizontalChildrenDimension,
|
||||||
|
AddVerticalChildrenDimension,
|
||||||
|
[container,
|
||||||
|
currentTransform,
|
||||||
|
dimensions,
|
||||||
|
scale]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dimensions;
|
return dimensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddChildrenDimension(
|
/**
|
||||||
container: IContainerModel,
|
* A layer containing all dimension
|
||||||
currentTransform: [number, number],
|
* @param props
|
||||||
dimensions: React.ReactNode[],
|
* @returns
|
||||||
containerBottomDim: number,
|
*/
|
||||||
containerRightDim: number,
|
export function DimensionLayer(props: IDimensionLayerProps): JSX.Element {
|
||||||
scale: number
|
return (
|
||||||
): void {
|
<g>
|
||||||
AddHorizontalChildrenDimension(container, currentTransform, dimensions, containerBottomDim, scale);
|
{ Dimensions(props) }
|
||||||
AddVerticalChildrenDimension(container, currentTransform, dimensions, containerRightDim, scale);
|
</g>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Dimensions Actions ///
|
||||||
|
|
||||||
function AddHorizontalChildrenDimension(
|
function AddHorizontalChildrenDimension(
|
||||||
|
yDim: number,
|
||||||
container: IContainerModel,
|
container: IContainerModel,
|
||||||
currentTransform: [number, number],
|
currentTransform: [number, number],
|
||||||
dimensions: React.ReactNode[],
|
dimensions: React.ReactNode[],
|
||||||
containerBottomDim: number,
|
|
||||||
scale: number
|
scale: number
|
||||||
): void {
|
): void {
|
||||||
const childrenId = `dim-children-${container.properties.id}`;
|
const childrenId = `dim-children-${container.properties.id}`;
|
||||||
|
@ -94,18 +164,18 @@ function AddHorizontalChildrenDimension(
|
||||||
id={childrenId}
|
id={childrenId}
|
||||||
xStart={xChildrenStart + offset}
|
xStart={xChildrenStart + offset}
|
||||||
xEnd={xChildrenEnd + offset}
|
xEnd={xChildrenEnd + offset}
|
||||||
yStart={containerBottomDim}
|
yStart={yDim}
|
||||||
yEnd={containerBottomDim}
|
yEnd={yDim}
|
||||||
strokeWidth={MODULE_STROKE_WIDTH}
|
strokeWidth={MODULE_STROKE_WIDTH}
|
||||||
text={textChildren}
|
text={textChildren}
|
||||||
scale={scale} />);
|
scale={scale} />);
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddVerticalChildrenDimension(
|
function AddVerticalChildrenDimension(
|
||||||
|
xDim: number,
|
||||||
container: IContainerModel,
|
container: IContainerModel,
|
||||||
currentTransform: [number, number],
|
currentTransform: [number, number],
|
||||||
dimensions: React.ReactNode[],
|
dimensions: React.ReactNode[],
|
||||||
containerRightDim: number,
|
|
||||||
scale: number
|
scale: number
|
||||||
): void {
|
): void {
|
||||||
const childrenId = `dim-v-children-${container.properties.id}`;
|
const childrenId = `dim-v-children-${container.properties.id}`;
|
||||||
|
@ -135,9 +205,9 @@ function AddVerticalChildrenDimension(
|
||||||
dimensions.push(<Dimension
|
dimensions.push(<Dimension
|
||||||
key={childrenId}
|
key={childrenId}
|
||||||
id={childrenId}
|
id={childrenId}
|
||||||
xStart={containerRightDim}
|
xStart={xDim}
|
||||||
yStart={yChildrenStart + offset}
|
yStart={yChildrenStart + offset}
|
||||||
xEnd={containerRightDim}
|
xEnd={xDim}
|
||||||
yEnd={yChildrenEnd + offset}
|
yEnd={yChildrenEnd + offset}
|
||||||
strokeWidth={MODULE_STROKE_WIDTH}
|
strokeWidth={MODULE_STROKE_WIDTH}
|
||||||
text={textChildren}
|
text={textChildren}
|
||||||
|
@ -145,34 +215,20 @@ function AddVerticalChildrenDimension(
|
||||||
/>);
|
/>);
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddBorrowerDimension(
|
|
||||||
bottomDim: number,
|
|
||||||
rightDim: number,
|
|
||||||
depth: number,
|
|
||||||
scale: number,
|
|
||||||
container: IContainerModel,
|
|
||||||
currentTransform: [number, number],
|
|
||||||
dimensions: React.ReactNode[]
|
|
||||||
): void {
|
|
||||||
AddHorizontalBorrowerDimension(bottomDim, container, depth, currentTransform, dimensions, scale);
|
|
||||||
AddVerticalBorrowerDimension(rightDim, container, depth, currentTransform, dimensions, scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
function AddHorizontalBorrowerDimension(
|
function AddHorizontalBorrowerDimension(
|
||||||
bottomDim: number,
|
yDim: number,
|
||||||
container: IContainerModel,
|
container: IContainerModel,
|
||||||
depth: number,
|
depth: number,
|
||||||
currentTransform: [number, number],
|
currentTransform: [number, number],
|
||||||
dimensions: React.ReactNode[],
|
dimensions: React.ReactNode[],
|
||||||
scale: number
|
scale: number
|
||||||
): void {
|
): void {
|
||||||
const yDim = bottomDim;
|
|
||||||
const it = MakeRecursionDFSIterator(container, depth, currentTransform);
|
const it = MakeRecursionDFSIterator(container, depth, currentTransform);
|
||||||
const marks = []; // list of vertical lines for the dimension
|
const marks = []; // list of vertical lines for the dimension
|
||||||
for (const {
|
for (const {
|
||||||
container: childContainer, currentTransform: childCurrentTransform
|
container: childContainer, currentTransform: childCurrentTransform
|
||||||
} of it) {
|
} of it) {
|
||||||
const isHidden = !childContainer.properties.markPositionToDimensionBorrower.includes(Orientation.Horizontal);
|
const isHidden = !childContainer.properties.markPosition.includes(Orientation.Horizontal);
|
||||||
if (isHidden) {
|
if (isHidden) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -212,20 +268,19 @@ function AddHorizontalBorrowerDimension(
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddVerticalBorrowerDimension(
|
function AddVerticalBorrowerDimension(
|
||||||
rightDim: number,
|
xDim: number,
|
||||||
container: IContainerModel,
|
container: IContainerModel,
|
||||||
depth: number,
|
depth: number,
|
||||||
currentTransform: [number, number],
|
currentTransform: [number, number],
|
||||||
dimensions: React.ReactNode[],
|
dimensions: React.ReactNode[],
|
||||||
scale: number
|
scale: number
|
||||||
): void {
|
): void {
|
||||||
const xDim = rightDim;
|
|
||||||
const it = MakeRecursionDFSIterator(container, depth, currentTransform);
|
const it = MakeRecursionDFSIterator(container, depth, currentTransform);
|
||||||
const marks = []; // list of vertical lines for the dimension
|
const marks = []; // list of vertical lines for the dimension
|
||||||
for (const {
|
for (const {
|
||||||
container: childContainer, currentTransform: childCurrentTransform
|
container: childContainer, currentTransform: childCurrentTransform
|
||||||
} of it) {
|
} of it) {
|
||||||
const isHidden = !childContainer.properties.markPositionToDimensionBorrower.includes(Orientation.Vertical);
|
const isHidden = !childContainer.properties.markPosition.includes(Orientation.Vertical);
|
||||||
if (isHidden) {
|
if (isHidden) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -264,24 +319,17 @@ function AddVerticalBorrowerDimension(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddSelfDimension(
|
function AddVerticalSelfDimension(
|
||||||
|
xDim: number,
|
||||||
container: IContainerModel,
|
container: IContainerModel,
|
||||||
currentTransform: [number, number],
|
currentTransform: [number, number],
|
||||||
topDim: number,
|
dimensions: React.ReactNode[],
|
||||||
leftDim: number,
|
scale: number
|
||||||
scale: number,
|
|
||||||
dimensions: React.ReactNode[]
|
|
||||||
): void {
|
): void {
|
||||||
AddHorizontalSelfDimension(container, currentTransform, topDim, dimensions, scale);
|
|
||||||
AddVerticalSelfDimension(container, currentTransform, leftDim, dimensions, scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
function AddVerticalSelfDimension(container: IContainerModel, currentTransform: [number, number], leftDim: number, dimensions: React.ReactNode[], scale: number): void {
|
|
||||||
const height = container.properties.height;
|
const height = container.properties.height;
|
||||||
const idVert = `dim-v-${container.properties.id}`;
|
const idVert = `dim-v-${container.properties.id}`;
|
||||||
const yStart = container.properties.y + currentTransform[1];
|
const yStart = container.properties.y + currentTransform[1];
|
||||||
const yEnd = yStart + height;
|
const yEnd = yStart + height;
|
||||||
const x = leftDim;
|
|
||||||
const textVert = height
|
const textVert = height
|
||||||
.toFixed(0)
|
.toFixed(0)
|
||||||
.toString();
|
.toString();
|
||||||
|
@ -289,9 +337,9 @@ function AddVerticalSelfDimension(container: IContainerModel, currentTransform:
|
||||||
<Dimension
|
<Dimension
|
||||||
key={idVert}
|
key={idVert}
|
||||||
id={idVert}
|
id={idVert}
|
||||||
xStart={x}
|
xStart={xDim}
|
||||||
yStart={yStart}
|
yStart={yStart}
|
||||||
xEnd={x}
|
xEnd={xDim}
|
||||||
yEnd={yEnd}
|
yEnd={yEnd}
|
||||||
strokeWidth={MODULE_STROKE_WIDTH}
|
strokeWidth={MODULE_STROKE_WIDTH}
|
||||||
text={textVert}
|
text={textVert}
|
||||||
|
@ -300,9 +348,9 @@ function AddVerticalSelfDimension(container: IContainerModel, currentTransform:
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddHorizontalSelfDimension(
|
function AddHorizontalSelfDimension(
|
||||||
|
yDim: number,
|
||||||
container: IContainerModel,
|
container: IContainerModel,
|
||||||
currentTransform: [number, number],
|
currentTransform: [number, number],
|
||||||
topDim: number,
|
|
||||||
dimensions: React.ReactNode[],
|
dimensions: React.ReactNode[],
|
||||||
scale: number
|
scale: number
|
||||||
): void {
|
): void {
|
||||||
|
@ -310,7 +358,6 @@ function AddHorizontalSelfDimension(
|
||||||
const id = `dim-${container.properties.id}`;
|
const id = `dim-${container.properties.id}`;
|
||||||
const xStart = container.properties.x + currentTransform[0];
|
const xStart = container.properties.x + currentTransform[0];
|
||||||
const xEnd = xStart + width;
|
const xEnd = xStart + width;
|
||||||
const y = topDim;
|
|
||||||
const text = width
|
const text = width
|
||||||
.toFixed(0)
|
.toFixed(0)
|
||||||
.toString();
|
.toString();
|
||||||
|
@ -319,24 +366,11 @@ function AddHorizontalSelfDimension(
|
||||||
key={id}
|
key={id}
|
||||||
id={id}
|
id={id}
|
||||||
xStart={xStart}
|
xStart={xStart}
|
||||||
yStart={y}
|
yStart={yDim}
|
||||||
xEnd={xEnd}
|
xEnd={xEnd}
|
||||||
yEnd={y}
|
yEnd={yDim}
|
||||||
strokeWidth={MODULE_STROKE_WIDTH}
|
strokeWidth={MODULE_STROKE_WIDTH}
|
||||||
text={text}
|
text={text}
|
||||||
scale={scale} />
|
scale={scale} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A layer containing all dimension
|
|
||||||
* @param props
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function DimensionLayer(props: IDimensionLayerProps): JSX.Element {
|
|
||||||
return (
|
|
||||||
<g>
|
|
||||||
{ Dimensions(props) }
|
|
||||||
</g>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
6
src/Enums/Position.ts
Normal file
6
src/Enums/Position.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export enum Position {
|
||||||
|
Left,
|
||||||
|
Down,
|
||||||
|
Up,
|
||||||
|
Right
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import { PositionReference } from '../Enums/PositionReference';
|
||||||
import { IAction } from './IAction';
|
import { IAction } from './IAction';
|
||||||
import { IMargin } from './IMargin';
|
import { IMargin } from './IMargin';
|
||||||
import { Orientation } from '../Enums/Orientation';
|
import { Orientation } from '../Enums/Orientation';
|
||||||
|
import { Position } from '../Enums/Position';
|
||||||
|
|
||||||
/** Model of available container used in application configuration */
|
/** Model of available container used in application configuration */
|
||||||
export interface IAvailableContainer {
|
export interface IAvailableContainer {
|
||||||
|
@ -112,21 +113,21 @@ export interface IAvailableContainer {
|
||||||
HideChildrenInTreeview?: boolean
|
HideChildrenInTreeview?: boolean
|
||||||
|
|
||||||
/** if true, show the dimension of the container */
|
/** if true, show the dimension of the container */
|
||||||
ShowSelfDimensions?: boolean
|
ShowSelfDimensions?: Position[]
|
||||||
|
|
||||||
/** if true show the overall dimensions of its children */
|
/** if true show the overall dimensions of its children */
|
||||||
ShowChildrenDimensions?: boolean
|
ShowChildrenDimensions?: Position[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if true, allows a parent dimension borrower to uses its x coordinate for as a reference point for a dimension
|
* if true, allows a parent dimension borrower to uses its x coordinate for as a reference point for a dimension
|
||||||
*/
|
*/
|
||||||
MarkPositionToDimensionBorrower?: Orientation[]
|
MarkPosition?: Orientation[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if true, show a dimension from the edge of the container to end
|
* if true, show a dimension from the edge of the container to end
|
||||||
* and insert dimensions marks at lift up children (see liftDimensionToBorrower)
|
* and insert dimensions marks at lift up children (see MarkPosition)
|
||||||
*/
|
*/
|
||||||
IsDimensionBorrower?: boolean
|
ShowDimensionWithMarks?: Position[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if true, hide the entry in the sidebar (default: false)
|
* if true, hide the entry in the sidebar (default: false)
|
||||||
|
|
|
@ -2,6 +2,7 @@ import * as React from 'react';
|
||||||
import { PositionReference } from '../Enums/PositionReference';
|
import { PositionReference } from '../Enums/PositionReference';
|
||||||
import { IMargin } from './IMargin';
|
import { IMargin } from './IMargin';
|
||||||
import { Orientation } from '../Enums/Orientation';
|
import { Orientation } from '../Enums/Orientation';
|
||||||
|
import { Position } from '../Enums/Position';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties of a container
|
* Properties of a container
|
||||||
|
@ -73,22 +74,22 @@ export interface IContainerProperties {
|
||||||
hideChildrenInTreeview: boolean
|
hideChildrenInTreeview: boolean
|
||||||
|
|
||||||
/** if true, show the dimension of the container */
|
/** if true, show the dimension of the container */
|
||||||
showSelfDimensions: boolean
|
showSelfDimensions: Position[]
|
||||||
|
|
||||||
/** if true show the overall dimensions of its children */
|
/** if true show the overall dimensions of its children */
|
||||||
showChildrenDimensions: boolean
|
showChildrenDimensions: Position[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if true, allows a parent dimension borrower to borrow its x coordinate
|
* if true, allows a parent dimension borrower to borrow its x coordinate
|
||||||
* as a reference point for a dimension
|
* as a reference point for a dimension
|
||||||
*/
|
*/
|
||||||
markPositionToDimensionBorrower: Orientation[]
|
markPosition: Orientation[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if true, show a dimension from the edge of the container to end
|
* if true, show a dimension from the edge of the container to end
|
||||||
* and insert dimensions marks at lift up children (see liftDimensionToBorrower)
|
* and insert dimensions marks at lift up children (see liftDimensionToBorrower)
|
||||||
*/
|
*/
|
||||||
isDimensionBorrower: boolean
|
showDimensionWithMarks: Position[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Warnings of a container
|
* Warnings of a container
|
||||||
|
|
|
@ -7,38 +7,40 @@ import { IContainerProperties } from '../Interfaces/IContainerProperties';
|
||||||
import { IEditorState } from '../Interfaces/IEditorState';
|
import { IEditorState } from '../Interfaces/IEditorState';
|
||||||
import { ISymbolModel } from '../Interfaces/ISymbolModel';
|
import { ISymbolModel } from '../Interfaces/ISymbolModel';
|
||||||
import { Orientation } from '../Enums/Orientation';
|
import { Orientation } from '../Enums/Orientation';
|
||||||
|
import { Position } from '../Enums/Position';
|
||||||
|
|
||||||
/// EDITOR DEFAULTS ///
|
/// EDITOR DEFAULTS ///
|
||||||
|
|
||||||
/** Enable fast boot and disable main menu */
|
/** Enable fast boot and disable main menu (default = false) */
|
||||||
export const FAST_BOOT = false;
|
export const FAST_BOOT = false;
|
||||||
|
|
||||||
/** Disable any call to the API */
|
/** Disable any call to the API (default = false) */
|
||||||
export const DISABLE_API = false;
|
export const DISABLE_API = false;
|
||||||
|
|
||||||
/** Enable keyboard shortcuts */
|
/** Enable keyboard shortcuts (default = true) */
|
||||||
export const ENABLE_SHORTCUTS = true;
|
export const ENABLE_SHORTCUTS = true;
|
||||||
|
|
||||||
/** Size of the history */
|
/** Size of the history (recommanded = 200) */
|
||||||
export const MAX_HISTORY = 200;
|
export const MAX_HISTORY = 200;
|
||||||
|
|
||||||
/** Apply beheviors on children */
|
/** Apply beheviors on children (recommanded = true) */
|
||||||
export const APPLY_BEHAVIORS_ON_CHILDREN = true;
|
export const APPLY_BEHAVIORS_ON_CHILDREN = true;
|
||||||
|
|
||||||
/** Framerate of the svg controller */
|
/** Framerate of the svg controller (recommanded = 60) */
|
||||||
export const MAX_FRAMERATE = 60;
|
export const MAX_FRAMERATE = 60;
|
||||||
|
|
||||||
/// CONTAINER DEFAULTS ///
|
/// CONTAINER DEFAULTS ///
|
||||||
|
|
||||||
/** Enable the swap behavior */
|
/** Enable the swap behavior (kinda broken recommanded = false) */
|
||||||
export const ENABLE_SWAP = false;
|
export const ENABLE_SWAP = false;
|
||||||
|
|
||||||
/** Enable the rigid behavior */
|
/** Enable the rigid behavior (recommanded = true) */
|
||||||
export const ENABLE_RIGID = true;
|
export const ENABLE_RIGID = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable the hard rigid behavior
|
* Enable the hard rigid behavior
|
||||||
* disallowing the container to overlap (ENABLE_RIGID must be true)
|
* disallowing the container to overlap (ENABLE_RIGID must be true)
|
||||||
|
* (recommanded = false)
|
||||||
*/
|
*/
|
||||||
export const ENABLE_HARD_RIGID = false;
|
export const ENABLE_HARD_RIGID = false;
|
||||||
|
|
||||||
|
@ -188,10 +190,10 @@ export const DEFAULT_MAINCONTAINER_PROPS: IContainerProperties = {
|
||||||
isFlex: false,
|
isFlex: false,
|
||||||
positionReference: PositionReference.TopLeft,
|
positionReference: PositionReference.TopLeft,
|
||||||
hideChildrenInTreeview: false,
|
hideChildrenInTreeview: false,
|
||||||
showChildrenDimensions: true, // TODO: put the dimension at the top (see pdf)
|
showChildrenDimensions: [Position.Up, Position.Left],
|
||||||
showSelfDimensions: true, // TODO: put the dimension at the bottom (see pdf)
|
showSelfDimensions: [Position.Up, Position.Left],
|
||||||
isDimensionBorrower: true, // second dimensions from the bottom
|
showDimensionWithMarks: [Position.Down, Position.Right],
|
||||||
markPositionToDimensionBorrower: [],
|
markPosition: [],
|
||||||
warning: '',
|
warning: '',
|
||||||
style: {
|
style: {
|
||||||
stroke: 'black',
|
stroke: 'black',
|
||||||
|
@ -240,10 +242,10 @@ export function GetDefaultContainerProps(type: string,
|
||||||
minHeight: containerConfig.MinWidth ?? 1,
|
minHeight: containerConfig.MinWidth ?? 1,
|
||||||
maxHeight: containerConfig.MaxWidth ?? Number.MAX_SAFE_INTEGER,
|
maxHeight: containerConfig.MaxWidth ?? Number.MAX_SAFE_INTEGER,
|
||||||
hideChildrenInTreeview: containerConfig.HideChildrenInTreeview ?? false,
|
hideChildrenInTreeview: containerConfig.HideChildrenInTreeview ?? false,
|
||||||
showChildrenDimensions: containerConfig.ShowChildrenDimensions ?? false,
|
showChildrenDimensions: containerConfig.ShowChildrenDimensions ?? [],
|
||||||
showSelfDimensions: containerConfig.ShowSelfDimensions ?? false,
|
showSelfDimensions: containerConfig.ShowSelfDimensions ?? [],
|
||||||
markPositionToDimensionBorrower: containerConfig.MarkPositionToDimensionBorrower ?? [],
|
markPosition: containerConfig.MarkPosition ?? [],
|
||||||
isDimensionBorrower: containerConfig.IsDimensionBorrower ?? false,
|
showDimensionWithMarks: containerConfig.ShowDimensionWithMarks ?? [],
|
||||||
warning: '',
|
warning: '',
|
||||||
customSVG: containerConfig.CustomSVG,
|
customSVG: containerConfig.CustomSVG,
|
||||||
style: structuredClone(containerConfig.Style),
|
style: structuredClone(containerConfig.Style),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue