alignVertically/Horizontally (#106)

This commit is contained in:
Kurt Hutten
2023-04-06 12:45:56 +10:00
committed by GitHub
parent db5220467b
commit 52b2e26ac5
5 changed files with 87 additions and 32 deletions

View File

@ -171,10 +171,14 @@ export const Toolbar = () => {
<HorzVert horOrVert="vertical" /> <HorzVert horOrVert="vertical" />
<EqualLength /> <EqualLength />
<EqualAngle /> <EqualAngle />
<SetHorzVertDistance horOrVert="setHorzDistance" /> <SetHorzVertDistance buttonType="alignEndsVertically" />
<SetAbsDistance disType="xAbs" /> <SetHorzVertDistance buttonType="setHorzDistance" />
<SetHorzVertDistance horOrVert="setVertDistance" /> <SetAbsDistance buttonType="snapToYAxis" />
<SetAbsDistance disType="yAbs" /> <SetAbsDistance buttonType="xAbs" />
<SetHorzVertDistance buttonType="alignEndsHorizontally" />
<SetAbsDistance buttonType="snapToXAxis" />
<SetHorzVertDistance buttonType="setVertDistance" />
<SetAbsDistance buttonType="yAbs" />
<SetAngleLength angleOrLength="setAngle" /> <SetAngleLength angleOrLength="setAngle" />
<SetAngleLength angleOrLength="setLength" /> <SetAngleLength angleOrLength="setLength" />
<Intersect /> <Intersect />

View File

@ -10,14 +10,22 @@ import {
TransformInfo, TransformInfo,
getTransformInfos, getTransformInfos,
transformAstSketchLines, transformAstSketchLines,
ConstraintType,
} from '../../lang/std/sketchcombos' } from '../../lang/std/sketchcombos'
import { SetAngleLengthModal } from '../SetAngleLengthModal' import { SetAngleLengthModal } from '../SetAngleLengthModal'
import { createVariableDeclaration } from '../../lang/modifyAst' import {
createIdentifier,
createVariableDeclaration,
} from '../../lang/modifyAst'
import { removeDoubleNegatives } from '../AvailableVarsHelpers' import { removeDoubleNegatives } from '../AvailableVarsHelpers'
const getModalInfo = create(SetAngleLengthModal as any) const getModalInfo = create(SetAngleLengthModal as any)
export const SetAbsDistance = ({ disType }: { disType: 'xAbs' | 'yAbs' }) => { export const SetAbsDistance = ({
buttonType,
}: {
buttonType: 'xAbs' | 'yAbs' | 'snapToYAxis' | 'snapToXAxis'
}) => {
const { const {
guiMode, guiMode,
selectionRanges: selections, selectionRanges: selections,
@ -31,6 +39,12 @@ export const SetAbsDistance = ({ disType }: { disType: 'xAbs' | 'yAbs' }) => {
selectionRanges: s.selectionRanges, selectionRanges: s.selectionRanges,
programMemory: s.programMemory, programMemory: s.programMemory,
})) }))
const disType: ConstraintType =
buttonType === 'xAbs' || buttonType === 'yAbs'
? buttonType
: buttonType === 'snapToYAxis'
? 'xAbs'
: 'yAbs'
const [enableAngLen, setEnableAngLen] = useState(false) const [enableAngLen, setEnableAngLen] = useState(false)
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>() const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
useEffect(() => { useEffect(() => {
@ -69,6 +83,8 @@ export const SetAbsDistance = ({ disType }: { disType: 'xAbs' | 'yAbs' }) => {
}, [guiMode, selections]) }, [guiMode, selections])
if (guiMode.mode !== 'sketch') return null if (guiMode.mode !== 'sketch') return null
const isAlign = buttonType === 'snapToYAxis' || buttonType === 'snapToXAxis'
return ( return (
<button <button
onClick={async () => { onClick={async () => {
@ -83,11 +99,14 @@ export const SetAbsDistance = ({ disType }: { disType: 'xAbs' | 'yAbs' }) => {
try { try {
let forceVal = valueUsedInTransform || 0 let forceVal = valueUsedInTransform || 0
const { valueNode, variableName, newVariableInsertIndex, sign } = const { valueNode, variableName, newVariableInsertIndex, sign } =
await getModalInfo({ await (!isAlign &&
getModalInfo({
value: forceVal, value: forceVal,
valueName: disType === 'yAbs' ? 'yDis' : 'xDis', valueName: disType === 'yAbs' ? 'yDis' : 'xDis',
} as any) } as any))
let finalValue = removeDoubleNegatives(valueNode, sign, variableName) let finalValue = isAlign
? createIdentifier('_0')
: removeDoubleNegatives(valueNode, sign, variableName)
const { modifiedAst: _modifiedAst } = transformAstSketchLines({ const { modifiedAst: _modifiedAst } = transformAstSketchLines({
ast: JSON.parse(JSON.stringify(ast)), ast: JSON.parse(JSON.stringify(ast)),
@ -117,7 +136,7 @@ export const SetAbsDistance = ({ disType }: { disType: 'xAbs' | 'yAbs' }) => {
}`} }`}
disabled={!enableAngLen} disabled={!enableAngLen}
> >
{disType} {buttonType}
</button> </button>
) )
} }

View File

@ -15,17 +15,22 @@ import {
TransformInfo, TransformInfo,
transformSecondarySketchLinesTagFirst, transformSecondarySketchLinesTagFirst,
getTransformInfos, getTransformInfos,
ConstraintType,
} from '../../lang/std/sketchcombos' } from '../../lang/std/sketchcombos'
import { GetInfoModal } from '../SetHorVertDistanceModal' import { GetInfoModal } from '../SetHorVertDistanceModal'
import { createVariableDeclaration } from '../../lang/modifyAst' import { createLiteral, createVariableDeclaration } from '../../lang/modifyAst'
import { removeDoubleNegatives } from '../AvailableVarsHelpers' import { removeDoubleNegatives } from '../AvailableVarsHelpers'
const getModalInfo = create(GetInfoModal as any) const getModalInfo = create(GetInfoModal as any)
export const SetHorzVertDistance = ({ export const SetHorzVertDistance = ({
horOrVert, buttonType,
}: { }: {
horOrVert: 'setHorzDistance' | 'setVertDistance' buttonType:
| 'setHorzDistance'
| 'setVertDistance'
| 'alignEndsHorizontally'
| 'alignEndsVertically'
}) => { }) => {
const { guiMode, selectionRanges, ast, programMemory, updateAst } = useStore( const { guiMode, selectionRanges, ast, programMemory, updateAst } = useStore(
(s) => ({ (s) => ({
@ -36,6 +41,12 @@ export const SetHorzVertDistance = ({
programMemory: s.programMemory, programMemory: s.programMemory,
}) })
) )
const constraint: ConstraintType =
buttonType === 'setHorzDistance' || buttonType === 'setVertDistance'
? buttonType
: buttonType === 'alignEndsHorizontally'
? 'setVertDistance'
: 'setHorzDistance'
const [enable, setEnable] = useState(false) const [enable, setEnable] = useState(false)
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>() const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
useEffect(() => { useEffect(() => {
@ -74,7 +85,7 @@ export const SetHorzVertDistance = ({
codeBasedSelections: selectionRanges.codeBasedSelections.slice(1), codeBasedSelections: selectionRanges.codeBasedSelections.slice(1),
}, },
ast, ast,
horOrVert constraint
) )
setTransformInfos(theTransforms) setTransformInfos(theTransforms)
@ -87,6 +98,10 @@ export const SetHorzVertDistance = ({
}, [guiMode, selectionRanges]) }, [guiMode, selectionRanges])
if (guiMode.mode !== 'sketch') return null if (guiMode.mode !== 'sketch') return null
const isAlign =
buttonType === 'alignEndsHorizontally' ||
buttonType === 'alignEndsVertically'
return ( return (
<button <button
onClick={async () => { onClick={async () => {
@ -112,17 +127,20 @@ export const SetHorzVertDistance = ({
variableName?: string variableName?: string
newVariableInsertIndex: number newVariableInsertIndex: number
sign: number sign: number
} = await getModalInfo({ } = await (!isAlign &&
getModalInfo({
segName: tagInfo?.tag, segName: tagInfo?.tag,
isSegNameEditable: !tagInfo?.isTagExisting, isSegNameEditable: !tagInfo?.isTagExisting,
value: valueUsedInTransform, value: valueUsedInTransform,
initialVariableName: initialVariableName:
horOrVert === 'setHorzDistance' ? 'xDis' : 'yDis', constraint === 'setHorzDistance' ? 'xDis' : 'yDis',
} as any) } as any))
if (segName === tagInfo?.tag && value === valueUsedInTransform) { if (segName === tagInfo?.tag && value === valueUsedInTransform) {
updateAst(modifiedAst) updateAst(modifiedAst)
} else { } else {
const finalValue = removeDoubleNegatives( let finalValue = isAlign
? createLiteral(0)
: removeDoubleNegatives(
valueNode as BinaryPart, valueNode as BinaryPart,
sign, sign,
variableName variableName
@ -155,7 +173,7 @@ export const SetHorzVertDistance = ({
}`} }`}
disabled={!enable} disabled={!enable}
> >
{horOrVert} {buttonType}
</button> </button>
) )
} }

View File

@ -399,3 +399,13 @@ function isTypeInArrayExp(
): boolean { ): boolean {
return node.elements.some((el) => isTypeInValue(el, syntaxType)) return node.elements.some((el) => isTypeInValue(el, syntaxType))
} }
export function isValueZero(val?: Value): boolean {
return (
(val?.type === 'Literal' && Number(val.value) === 0) ||
(val?.type === 'UnaryExpression' &&
val.operator === '-' &&
val.argument.type === 'Literal' &&
Number(val.argument.value) === 0)
)
}

View File

@ -1,16 +1,17 @@
import { TransformCallback } from './stdTypes' import { TransformCallback } from './stdTypes'
import { Selections, toolTips, TooTip, Selection } from '../../useStore' import { Selections, toolTips, TooTip, Selection } from '../../useStore'
import { import {
BinaryPart,
CallExpression, CallExpression,
Program, Program,
Value, Value,
BinaryPart,
VariableDeclarator, VariableDeclarator,
} from '../abstractSyntaxTree' } from '../abstractSyntaxTree'
import { import {
getNodeFromPath, getNodeFromPath,
getNodeFromPathCurry, getNodeFromPathCurry,
getNodePathFromSourceRange, getNodePathFromSourceRange,
isValueZero,
} from '../queryAst' } from '../queryAst'
import { import {
createBinaryExpression, createBinaryExpression,
@ -252,14 +253,17 @@ const setHorzVertDistanceCreateNode =
getArgLiteralVal(args?.[index]) - (referencedSegment?.to?.[index] || 0), getArgLiteralVal(args?.[index]) - (referencedSegment?.to?.[index] || 0),
2 2
) )
const makeBinExp = createBinaryExpressionWithUnary([ let finalValue: Value = createBinaryExpressionWithUnary([
createSegEnd(referenceSegName, !index), createSegEnd(referenceSegName, !index),
(forceValueUsedInTransform as BinaryPart) || (forceValueUsedInTransform as BinaryPart) ||
createLiteral(valueUsedInTransform), createLiteral(valueUsedInTransform),
]) ])
if (isValueZero(forceValueUsedInTransform)) {
finalValue = createSegEnd(referenceSegName, !index)
}
return createCallWrapper( return createCallWrapper(
'lineTo', 'lineTo',
!index ? [makeBinExp, args[1]] : [args[0], makeBinExp], !index ? [finalValue, args[1]] : [args[0], finalValue],
tag, tag,
valueUsedInTransform valueUsedInTransform
) )