Final fix for XPositionReference : We are now lying to the user in the form. The transformation is applied to the value that is shown but the transformation is restored for the computing afterward #33

Merged
Siklos merged 4 commits from dev.fixtransform into dev 2022-08-16 10:56:58 -04:00
6 changed files with 59 additions and 45 deletions
Showing only changes of commit 1622816035 - Show all commits

View file

@ -7,7 +7,7 @@ import { getCurrentHistory } from './Editor';
import IProperties from '../../Interfaces/IProperties';
import { AddMethod } from '../../Enums/AddMethod';
import { IAvailableContainer } from '../../Interfaces/IAvailableContainer';
import { transformPosition } from '../SVG/Elements/Container';
import { transformX } from '../SVG/Elements/Container';
import { XPositionReference } from '../../Enums/XPositionReference';
/**
@ -267,14 +267,7 @@ function ApplyAddMethod(index: number, containerConfig: IAvailableContainer, par
const lastChild: IContainerModel | undefined = parent.children.at(index - 1);
if (lastChild !== undefined) {
const [transformedX] = transformPosition(
lastChild.properties.x,
lastChild.properties.y,
lastChild.properties.width,
lastChild.properties.XPositionReference
);
x += transformedX + lastChild.properties.width;
x += (lastChild.properties.x + lastChild.properties.width);
}
}
return x;

View file

@ -6,6 +6,7 @@ import { getCurrentHistory } from './Editor';
import { RecalculatePhysics } from './Behaviors/RigidBodyBehaviors';
import { INPUT_TYPES } from '../Properties/PropertiesInputTypes';
import { ImposePosition } from './Behaviors/AnchorBehaviors';
import { restoreX } from '../SVG/Elements/Container';
/**
* Handled the property change event in the properties form
@ -40,11 +41,7 @@ export function OnPropertyChange(
if (isStyle) {
(container.properties.style as any)[key] = value;
} else {
if (INPUT_TYPES[key] === 'number') {
(container.properties as any)[key] = Number(value);
} else {
(container.properties as any)[key] = value;
}
(container.properties as any)[key] = value;
}
if (container.properties.isAnchor) {
@ -104,10 +101,33 @@ export function OnPropertiesSubmit(
}
if (input instanceof HTMLInputElement) {
(container.properties as any)[property] = input.value;
if (INPUT_TYPES[property] === 'number') {
if (property === 'x') {
// Hardcoded fix for XPositionReference
const inputWidth: HTMLInputElement | null = (event.target as HTMLFormElement).querySelector('#width');
const inputRadio: HTMLDivElement | null = (event.target as HTMLFormElement).querySelector('#XPositionReference');
if (inputWidth === null || inputRadio === null) {
throw new Error('[OnPropertiesSubmit] Missing inputs for width or XPositionReference');
}
const radiobutton: HTMLInputElement | null = inputRadio.querySelector('input[name="XPositionReference"]:checked');
if (radiobutton === null) {
throw new Error('[OnPropertiesSubmit] Missing inputs for XPositionReference');
}
const x = restoreX(Number(input.value), Number(inputWidth.value), Number(radiobutton.value));
(container.properties as any)[property] = x;
continue;
}
(container.properties as any)[property] = Number(input.value);
continue;
}
(container.properties as any)[property] = input.value;
} else if (input instanceof HTMLDivElement) {
const radiobutton: HTMLInputElement | null = input.querySelector(`input[name="${property}"]:checked`);
@ -115,10 +135,12 @@ export function OnPropertiesSubmit(
continue;
}
(container.properties as any)[property] = radiobutton.value;
if (INPUT_TYPES[property] === 'number') {
(container.properties as any)[property] = Number(radiobutton.value);
continue;
}
(container.properties as any)[property] = radiobutton.value;
}
}

View file

@ -4,6 +4,7 @@ import { XPositionReference } from '../../Enums/XPositionReference';
import IProperties from '../../Interfaces/IProperties';
import { InputGroup } from '../InputGroup/InputGroup';
import { RadioGroupButtons } from '../RadioGroupButtons/RadioGroupButtons';
import { restoreX, transformX } from '../SVG/Elements/Container';
interface IDynamicFormProps {
properties: IProperties
@ -57,8 +58,8 @@ const DynamicForm: React.FunctionComponent<IDynamicFormProps> = (props) => {
labelClassName=''
inputClassName=''
type='number'
value={props.properties.x.toString()}
onChange={(event) => props.onChange('x', event.target.value)}
value={transformX(props.properties.x, props.properties.width, props.properties.XPositionReference).toString()}
onChange={(event) => props.onChange('x', restoreX(Number(event.target.value), props.properties.width, props.properties.XPositionReference))}
/>
<InputGroup
labelText='y'
@ -67,7 +68,7 @@ const DynamicForm: React.FunctionComponent<IDynamicFormProps> = (props) => {
inputClassName=''
type='number'
value={props.properties.y.toString()}
onChange={(event) => props.onChange('y', event.target.value)}
onChange={(event) => props.onChange('y', Number(event.target.value))}
/>
<InputGroup
labelText='Width'
@ -76,7 +77,7 @@ const DynamicForm: React.FunctionComponent<IDynamicFormProps> = (props) => {
inputClassName=''
type='number'
value={props.properties.width.toString()}
onChange={(event) => props.onChange('width', event.target.value)}
onChange={(event) => props.onChange('width', Number(event.target.value))}
/>
<InputGroup
labelText='Height'
@ -85,7 +86,7 @@ const DynamicForm: React.FunctionComponent<IDynamicFormProps> = (props) => {
inputClassName=''
type='number'
value={props.properties.height.toString()}
onChange={(event) => props.onChange('height', event.target.value)}
onChange={(event) => props.onChange('height', Number(event.target.value))}
/>
<InputGroup
labelText='Rigid'
@ -136,7 +137,7 @@ const DynamicForm: React.FunctionComponent<IDynamicFormProps> = (props) => {
value: XPositionReference.Right.toString()
}
]}
onChange={(event) => props.onChange('XPositionReference', event.target.value)}
onChange={(event) => props.onChange('XPositionReference', Number(event.target.value))}
/>
{ getCSSInputs(props.properties, props.onChange) }
</div>

View file

@ -4,6 +4,7 @@ import { XPositionReference } from '../../Enums/XPositionReference';
import IProperties from '../../Interfaces/IProperties';
import { InputGroup } from '../InputGroup/InputGroup';
import { RadioGroupButtons } from '../RadioGroupButtons/RadioGroupButtons';
import { transformX } from '../SVG/Elements/Container';
interface IStaticFormProps {
properties: IProperties
@ -57,7 +58,7 @@ const StaticForm: React.FunctionComponent<IStaticFormProps> = (props) => {
labelClassName=''
inputClassName=''
type='number'
defaultValue={props.properties.x.toString()}
defaultValue={transformX(props.properties.x, props.properties.width, props.properties.XPositionReference).toString()}
/>
<InputGroup
labelText='y'

View file

@ -18,13 +18,7 @@ export const Container: React.FC<IContainerProps> = (props: IContainerProps) =>
const xText = props.model.properties.width / 2;
const yText = props.model.properties.height / 2;
const [transformedX, transformedY] = transformPosition(
props.model.properties.x,
props.model.properties.y,
props.model.properties.width,
props.model.properties.XPositionReference
);
const transform = `translate(${transformedX}, ${transformedY})`;
const transform = `translate(${props.model.properties.x}, ${props.model.properties.y})`;
// g style
const defaultStyle: React.CSSProperties = {
@ -107,17 +101,17 @@ function GetChildrenDimensionProps(props: IContainerProps, dimensionMargin: numb
const childrenId = `dim-children-${props.model.properties.id}`;
const lastChild = props.model.children[props.model.children.length - 1];
let xChildrenStart = lastChild.properties.x;
let xChildrenEnd = lastChild.properties.x;
let xChildrenStart = transformX(lastChild.properties.x, lastChild.properties.width, lastChild.properties.XPositionReference);
let xChildrenEnd = transformX(lastChild.properties.x, lastChild.properties.width, lastChild.properties.XPositionReference);
// Find the min and max
for (let i = props.model.children.length - 2; i >= 0; i--) {
const child = props.model.children[i];
const left = child.properties.x;
const left = transformX(child.properties.x, child.properties.width, child.properties.XPositionReference);
if (left < xChildrenStart) {
xChildrenStart = left;
}
const right = child.properties.x;
const right = transformX(child.properties.x, child.properties.width, child.properties.XPositionReference);
if (right > xChildrenEnd) {
xChildrenEnd = right;
}
@ -128,12 +122,22 @@ function GetChildrenDimensionProps(props: IContainerProps, dimensionMargin: numb
return { childrenId, xChildrenStart, xChildrenEnd, yChildren, textChildren };
}
export function transformPosition(x: number, y: number, width: number, xPositionReference = XPositionReference.Left): [number, number] {
export function transformX(x: number, width: number, xPositionReference = XPositionReference.Left): number {
let transformedX = x;
if (xPositionReference === XPositionReference.Center) {
transformedX += width / 2;
} else if (xPositionReference === XPositionReference.Right) {
transformedX += width;
}
return transformedX;
}
export function restoreX(x: number, width: number, xPositionReference = XPositionReference.Left): number {
let transformedX = x;
if (xPositionReference === XPositionReference.Center) {
transformedX -= width / 2;
} else if (xPositionReference === XPositionReference.Right) {
transformedX -= width;
}
return [transformedX, y];
return transformedX;
}

View file

@ -1,7 +1,6 @@
import * as React from 'react';
import { IContainerModel } from '../../../Interfaces/IContainerModel';
import { getAbsolutePosition } from '../../../utils/itertools';
import { transformPosition } from './Container';
interface ISelectorProps {
selected: IContainerModel | null
@ -16,12 +15,6 @@ export const Selector: React.FC<ISelectorProps> = (props) => {
}
const [x, y] = getAbsolutePosition(props.selected);
const [transformedX, transformedY] = transformPosition(
x,
y,
props.selected.properties.width,
props.selected.properties.XPositionReference
);
const [width, height] = [
props.selected.properties.width,
props.selected.properties.height
@ -38,8 +31,8 @@ export const Selector: React.FC<ISelectorProps> = (props) => {
return (
<rect
x={transformedX}
y={transformedY}
x={x}
y={y}
width={width}
height={height}
style={style}