Select axis for horz/vert distances (#102)

This commit is contained in:
Kurt Hutten
2023-04-05 15:08:46 +10:00
committed by GitHub
parent a1848f2563
commit 1a6bcba6ca
4 changed files with 211 additions and 5 deletions

View File

@ -6,9 +6,10 @@ import { RemoveConstrainingValues } from './components/Toolbar/RemoveConstrainin
import { EqualLength } from './components/Toolbar/EqualLength' import { EqualLength } from './components/Toolbar/EqualLength'
import { EqualAngle } from './components/Toolbar/EqualAngle' import { EqualAngle } from './components/Toolbar/EqualAngle'
import { Intersect } from './components/Toolbar/Intersect' import { Intersect } from './components/Toolbar/Intersect'
import { SetHorzDistance } from './components/Toolbar/SetHorzDistance' import { SetHorzVertDistance } from './components/Toolbar/SetHorzVertDistance'
import { SetAngleLength } from './components/Toolbar/SetAngleLength' import { SetAngleLength } from './components/Toolbar/SetAngleLength'
import { ConvertToVariable } from './components/Toolbar/ConvertVariable' import { ConvertToVariable } from './components/Toolbar/ConvertVariable'
import { SetAbsDistance } from './components/Toolbar/SetAbsDistance'
export const Toolbar = () => { export const Toolbar = () => {
const { const {
@ -169,8 +170,10 @@ export const Toolbar = () => {
<HorzVert horOrVert="vertical" /> <HorzVert horOrVert="vertical" />
<EqualLength /> <EqualLength />
<EqualAngle /> <EqualAngle />
<SetHorzDistance horOrVert="setHorzDistance" /> <SetHorzVertDistance horOrVert="setHorzDistance" />
<SetHorzDistance horOrVert="setVertDistance" /> <SetAbsDistance disType="xAbs" />
<SetHorzVertDistance horOrVert="setVertDistance" />
<SetAbsDistance disType="yAbs" />
<SetAngleLength angleOrLength="setAngle" /> <SetAngleLength angleOrLength="setAngle" />
<SetAngleLength angleOrLength="setLength" /> <SetAngleLength angleOrLength="setLength" />
<Intersect /> <Intersect />

View File

@ -0,0 +1,123 @@
import { useState, useEffect } from 'react'
import { create } from 'react-modal-promise'
import { toolTips, useStore } from '../../useStore'
import { Value } from '../../lang/abstractSyntaxTree'
import {
getNodePathFromSourceRange,
getNodeFromPath,
} from '../../lang/queryAst'
import {
TransformInfo,
getTransformInfos,
transformAstSketchLines,
} from '../../lang/std/sketchcombos'
import { SetAngleLengthModal } from '../SetAngleLengthModal'
import { createVariableDeclaration } from '../../lang/modifyAst'
import { removeDoubleNegatives } from '../AvailableVarsHelpers'
const getModalInfo = create(SetAngleLengthModal as any)
export const SetAbsDistance = ({ disType }: { disType: 'xAbs' | 'yAbs' }) => {
const {
guiMode,
selectionRanges: selections,
ast,
programMemory,
updateAst,
} = useStore((s) => ({
guiMode: s.guiMode,
ast: s.ast,
updateAst: s.updateAst,
selectionRanges: s.selectionRanges,
programMemory: s.programMemory,
}))
const [enableAngLen, setEnableAngLen] = useState(false)
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
useEffect(() => {
if (!ast) return
const paths = selections.codeBasedSelections.map(({ range }) =>
getNodePathFromSourceRange(ast, range)
)
const nodes = paths.map(
(pathToNode) =>
getNodeFromPath<Value>(ast, pathToNode, 'CallExpression').node
)
const isAllTooltips = nodes.every(
(node) =>
node?.type === 'CallExpression' &&
toolTips.includes(node.callee.name as any)
)
const theTransforms = getTransformInfos(selections, ast, disType)
setTransformInfos(theTransforms)
const enableY =
disType === 'yAbs' &&
selections.otherSelections.length === 1 &&
selections.otherSelections[0] === 'x-axis' // select the x axis to set the distance from it i.e. y
const enableX =
disType === 'xAbs' &&
selections.otherSelections.length === 1 &&
selections.otherSelections[0] === 'y-axis' // select the y axis to set the distance from it i.e. x
const _enableHorz =
isAllTooltips &&
theTransforms.every(Boolean) &&
selections.codeBasedSelections.length === 1 &&
(enableX || enableY)
setEnableAngLen(_enableHorz)
}, [guiMode, selections])
if (guiMode.mode !== 'sketch') return null
return (
<button
onClick={async () => {
if (!(transformInfos && ast)) return
const { valueUsedInTransform } = transformAstSketchLines({
ast: JSON.parse(JSON.stringify(ast)),
selectionRanges: selections,
transformInfos,
programMemory,
referenceSegName: '',
})
try {
let forceVal = valueUsedInTransform || 0
const { valueNode, variableName, newVariableInsertIndex, sign } =
await getModalInfo({
value: forceVal,
valueName: disType === 'yAbs' ? 'yDis' : 'xDis',
} as any)
let finalValue = removeDoubleNegatives(valueNode, sign, variableName)
const { modifiedAst: _modifiedAst } = transformAstSketchLines({
ast: JSON.parse(JSON.stringify(ast)),
selectionRanges: selections,
transformInfos,
programMemory,
referenceSegName: '',
forceValueUsedInTransform: finalValue,
})
if (variableName) {
const newBody = [..._modifiedAst.body]
newBody.splice(
newVariableInsertIndex,
0,
createVariableDeclaration(variableName, valueNode)
)
_modifiedAst.body = newBody
}
updateAst(_modifiedAst)
} catch (e) {
console.log('e', e)
}
}}
className={`border m-1 px-1 rounded text-xs ${
enableAngLen ? 'bg-gray-50 text-gray-800' : 'bg-gray-200 text-gray-400'
}`}
disabled={!enableAngLen}
>
{disType}
</button>
)
}

View File

@ -25,7 +25,7 @@ import { removeDoubleNegatives } from '../AvailableVarsHelpers'
const getModalInfo = create(GetInfoModal as any) const getModalInfo = create(GetInfoModal as any)
export const SetHorzDistance = ({ export const SetHorzVertDistance = ({
horOrVert, horOrVert,
}: { }: {
horOrVert: 'setHorzDistance' | 'setVertDistance' horOrVert: 'setHorzDistance' | 'setVertDistance'

View File

@ -13,7 +13,6 @@ import {
getNodePathFromSourceRange, getNodePathFromSourceRange,
} from '../queryAst' } from '../queryAst'
import { import {
createBinaryExpression,
createBinaryExpressionWithUnary, createBinaryExpressionWithUnary,
createCallExpression, createCallExpression,
createIdentifier, createIdentifier,
@ -47,6 +46,8 @@ export type ConstraintType =
| 'setLength' | 'setLength'
| 'intersect' | 'intersect'
| 'removeConstrainingValues' | 'removeConstrainingValues'
| 'xAbs'
| 'yAbs'
function createCallWrapper( function createCallWrapper(
a: TooTip, a: TooTip,
@ -287,6 +288,61 @@ const setHorzVertDistanceForAngleLineCreateNode =
} }
} }
const setAbsDistanceCreateNode =
(
xOrY: 'x' | 'y',
isXOrYLine = false,
index = xOrY === 'x' ? 0 : 1
): TransformInfo['createNode'] =>
({ tag, forceValueUsedInTransform, ...rest }) => {
return (args, referencedSegment, ...rest2) => {
const valueUsedInTransform = roundOff(
getArgLiteralVal(args?.[index]) - (referencedSegment?.to?.[index] || 0),
2
)
console.log(rest, rest2)
const val =
(forceValueUsedInTransform as BinaryPart) ||
createLiteral(valueUsedInTransform)
if (isXOrYLine) {
return createCallWrapper(
xOrY === 'x' ? 'xLineTo' : 'yLineTo',
val,
tag,
valueUsedInTransform
)
}
return createCallWrapper(
'lineTo',
!index ? [val, args[1]] : [args[0], val],
tag,
valueUsedInTransform
)
}
}
const setAbsDistanceForAngleLineCreateNode =
(
xOrY: 'x' | 'y',
index = xOrY === 'x' ? 0 : 1
): TransformInfo['createNode'] =>
({ tag, forceValueUsedInTransform, varValA }) => {
return (args, referencedSegment) => {
const valueUsedInTransform = roundOff(
getArgLiteralVal(args?.[1]) - (referencedSegment?.to?.[index] || 0),
2
)
const val =
(forceValueUsedInTransform as BinaryPart) ||
createLiteral(valueUsedInTransform)
return createCallWrapper(
xOrY === 'x' ? 'angledLineToX' : 'angledLineToY',
[varValA, val],
tag,
valueUsedInTransform
)
}
}
const setHorVertDistanceForXYLines = const setHorVertDistanceForXYLines =
(xOrY: 'x' | 'y'): TransformInfo['createNode'] => (xOrY: 'x' | 'y'): TransformInfo['createNode'] =>
({ referenceSegName, tag, forceValueUsedInTransform }) => { ({ referenceSegName, tag, forceValueUsedInTransform }) => {
@ -459,10 +515,18 @@ const transformMap: TransformMap = {
tooltip: 'lineTo', tooltip: 'lineTo',
createNode: setHorzVertDistanceCreateNode('x'), createNode: setHorzVertDistanceCreateNode('x'),
}, },
xAbs: {
tooltip: 'lineTo',
createNode: setAbsDistanceCreateNode('x'),
},
setVertDistance: { setVertDistance: {
tooltip: 'lineTo', tooltip: 'lineTo',
createNode: setHorzVertDistanceCreateNode('y'), createNode: setHorzVertDistanceCreateNode('y'),
}, },
yAbs: {
tooltip: 'lineTo',
createNode: setAbsDistanceCreateNode('y'),
},
setAngle: { setAngle: {
tooltip: 'angledLine', tooltip: 'angledLine',
createNode: basicAngledLineCreateNode('none', 'ang'), createNode: basicAngledLineCreateNode('none', 'ang'),
@ -595,10 +659,18 @@ const transformMap: TransformMap = {
tooltip: 'angledLineToY', tooltip: 'angledLineToY',
createNode: setHorzVertDistanceForAngleLineCreateNode('y'), createNode: setHorzVertDistanceForAngleLineCreateNode('y'),
}, },
yAbs: {
tooltip: 'angledLineToY',
createNode: setAbsDistanceForAngleLineCreateNode('y'),
},
setHorzDistance: { setHorzDistance: {
tooltip: 'angledLineToX', tooltip: 'angledLineToX',
createNode: setHorzVertDistanceForAngleLineCreateNode('x'), createNode: setHorzVertDistanceForAngleLineCreateNode('x'),
}, },
xAbs: {
tooltip: 'angledLineToX',
createNode: setAbsDistanceForAngleLineCreateNode('x'),
},
intersect: { intersect: {
tooltip: 'angledLineThatIntersects', tooltip: 'angledLineThatIntersects',
createNode: setAngledIntersectForAngledLines, createNode: setAngledIntersectForAngledLines,
@ -881,6 +953,10 @@ const transformMap: TransformMap = {
tooltip: 'angledLineThatIntersects', tooltip: 'angledLineThatIntersects',
createNode: setAngledIntersectLineForLines, createNode: setAngledIntersectLineForLines,
}, },
xAbs: {
tooltip: 'xLineTo',
createNode: setAbsDistanceCreateNode('x', true),
},
}, },
}, },
yLine: { yLine: {
@ -908,6 +984,10 @@ const transformMap: TransformMap = {
tooltip: 'angledLineThatIntersects', tooltip: 'angledLineThatIntersects',
createNode: setAngledIntersectLineForLines, createNode: setAngledIntersectLineForLines,
}, },
yAbs: {
tooltip: 'yLineTo',
createNode: setAbsDistanceCreateNode('y', true),
},
}, },
}, },
xLineTo: { xLineTo: {