Add modal typing back in, and clean up old constraints code (#865)
* Revert "Revert "Improve Prop Typings for Modals. Remove instances of `any`. (… (#813)"
This reverts commit 9822576077
.
* tsc
* refactor all buttons
* add parallel constraint
* typegen?
* add constraint removal constraint
* add perpendicular distance constraint
* state diagram layout
* fmt
* improve modal typing for setAngleLength
This commit is contained in:
@ -1,102 +1,78 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import { Value, VariableDeclarator } from '../../lang/wasm'
|
||||
import { Selections, toolTips } from '../../useStore'
|
||||
import { Program, Value, VariableDeclarator } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
} from '../../lang/queryAst'
|
||||
import { isSketchVariablesLinked } from '../../lang/std/sketchConstraints'
|
||||
import {
|
||||
TransformInfo,
|
||||
transformSecondarySketchLinesTagFirst,
|
||||
getTransformInfos,
|
||||
PathToNodeMap,
|
||||
} from '../../lang/std/sketchcombos'
|
||||
import { ActionIcon } from 'components/ActionIcon'
|
||||
import { sketchButtonClassnames } from 'Toolbar'
|
||||
import { kclManager } from 'lang/KclSinglton'
|
||||
|
||||
/*
|
||||
export const EqualAngle = () => {
|
||||
const { guiMode, selectionRanges, setCursor } = useStore((s) => ({
|
||||
guiMode: s.guiMode,
|
||||
selectionRanges: s.selectionRanges,
|
||||
setCursor: s.setCursor,
|
||||
}))
|
||||
const [enableEqual, setEnableEqual] = useState(false)
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(kclManager.ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(kclManager.ast, pathToNode).node
|
||||
)
|
||||
const varDecs = paths.map(
|
||||
(pathToNode) =>
|
||||
getNodeFromPath<VariableDeclarator>(
|
||||
kclManager.ast,
|
||||
pathToNode,
|
||||
'VariableDeclarator'
|
||||
)?.node
|
||||
)
|
||||
const primaryLine = varDecs[0]
|
||||
const secondaryVarDecs = varDecs.slice(1)
|
||||
const isOthersLinkedToPrimary = secondaryVarDecs.every((secondary) =>
|
||||
isSketchVariablesLinked(secondary, primaryLine, kclManager.ast)
|
||||
)
|
||||
const isAllTooltips = nodes.every(
|
||||
(node) =>
|
||||
node?.type === 'CallExpression' &&
|
||||
toolTips.includes(node.callee.name as any)
|
||||
)
|
||||
|
||||
const theTransforms = getTransformInfos(
|
||||
{
|
||||
...selectionRanges,
|
||||
codeBasedSelections: selectionRanges.codeBasedSelections.slice(1),
|
||||
},
|
||||
kclManager.ast,
|
||||
'equalAngle'
|
||||
)
|
||||
setTransformInfos(theTransforms)
|
||||
|
||||
const _enableEqual =
|
||||
!!secondaryVarDecs.length &&
|
||||
isAllTooltips &&
|
||||
isOthersLinkedToPrimary &&
|
||||
theTransforms.every(Boolean)
|
||||
setEnableEqual(_enableEqual)
|
||||
}, [guiMode, selectionRanges])
|
||||
if (guiMode.mode !== 'sketch') return null
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={async () => {
|
||||
if (!transformInfos) return
|
||||
const { modifiedAst, pathToNodeMap } =
|
||||
transformSecondarySketchLinesTagFirst({
|
||||
ast: kclManager.ast,
|
||||
selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
})
|
||||
kclManager.updateAst(modifiedAst, true, {
|
||||
callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
})
|
||||
}}
|
||||
disabled={!enableEqual}
|
||||
title="Parallel (or equal angle)"
|
||||
className="group"
|
||||
>
|
||||
<ActionIcon
|
||||
icon="parallel"
|
||||
className="!p-0.5"
|
||||
bgClassName={sketchButtonClassnames.background}
|
||||
iconClassName={sketchButtonClassnames.icon}
|
||||
size="md"
|
||||
/>
|
||||
Parallel
|
||||
</button>
|
||||
export function equalAngleInfo({
|
||||
selectionRanges,
|
||||
}: {
|
||||
selectionRanges: Selections
|
||||
}) {
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(kclManager.ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(kclManager.ast, pathToNode).node
|
||||
)
|
||||
const varDecs = paths.map(
|
||||
(pathToNode) =>
|
||||
getNodeFromPath<VariableDeclarator>(
|
||||
kclManager.ast,
|
||||
pathToNode,
|
||||
'VariableDeclarator'
|
||||
)?.node
|
||||
)
|
||||
const primaryLine = varDecs[0]
|
||||
const secondaryVarDecs = varDecs.slice(1)
|
||||
const isOthersLinkedToPrimary = secondaryVarDecs.every((secondary) =>
|
||||
isSketchVariablesLinked(secondary, primaryLine, kclManager.ast)
|
||||
)
|
||||
const isAllTooltips = nodes.every(
|
||||
(node) =>
|
||||
node?.type === 'CallExpression' &&
|
||||
toolTips.includes(node.callee.name as any)
|
||||
)
|
||||
|
||||
const transforms = getTransformInfos(
|
||||
{
|
||||
...selectionRanges,
|
||||
codeBasedSelections: selectionRanges.codeBasedSelections.slice(1),
|
||||
},
|
||||
kclManager.ast,
|
||||
'equalAngle'
|
||||
)
|
||||
|
||||
const enabled =
|
||||
!!secondaryVarDecs.length &&
|
||||
isAllTooltips &&
|
||||
isOthersLinkedToPrimary &&
|
||||
transforms.every(Boolean)
|
||||
return { enabled, transforms }
|
||||
}
|
||||
|
||||
export function applyConstraintEqualAngle({
|
||||
selectionRanges,
|
||||
}: {
|
||||
selectionRanges: Selections
|
||||
}): {
|
||||
modifiedAst: Program
|
||||
pathToNodeMap: PathToNodeMap
|
||||
} {
|
||||
const { transforms } = equalAngleInfo({ selectionRanges })
|
||||
const { modifiedAst, pathToNodeMap } = transformSecondarySketchLinesTagFirst({
|
||||
ast: kclManager.ast,
|
||||
selectionRanges,
|
||||
transformInfos: transforms,
|
||||
programMemory: kclManager.programMemory,
|
||||
})
|
||||
return { modifiedAst, pathToNodeMap }
|
||||
}
|
||||
*/
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Selections, toolTips, useStore } from '../../useStore'
|
||||
import { Selections, toolTips } from '../../useStore'
|
||||
import { Program, Value, VariableDeclarator } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
@ -7,63 +6,12 @@ import {
|
||||
} from '../../lang/queryAst'
|
||||
import { isSketchVariablesLinked } from '../../lang/std/sketchConstraints'
|
||||
import {
|
||||
TransformInfo,
|
||||
transformSecondarySketchLinesTagFirst,
|
||||
getTransformInfos,
|
||||
PathToNodeMap,
|
||||
} from '../../lang/std/sketchcombos'
|
||||
import { ActionIcon } from 'components/ActionIcon'
|
||||
import { sketchButtonClassnames } from 'Toolbar'
|
||||
import { kclManager } from 'lang/KclSinglton'
|
||||
|
||||
/*
|
||||
export const EqualLength = () => {
|
||||
const { guiMode, selectionRanges, setCursor } = useStore((s) => ({
|
||||
guiMode: s.guiMode,
|
||||
selectionRanges: s.selectionRanges,
|
||||
setCursor: s.setCursor,
|
||||
}))
|
||||
const [enableEqual, setEnableEqual] = useState(false)
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
const { enabled, transforms } = setEqualLengthInfo({ selectionRanges })
|
||||
|
||||
setTransformInfos(transforms)
|
||||
setEnableEqual(enabled)
|
||||
}, [guiMode, selectionRanges])
|
||||
if (guiMode.mode !== 'sketch') return null
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={() => {
|
||||
if (!transformInfos) return
|
||||
const { modifiedAst, pathToNodeMap } =
|
||||
transformSecondarySketchLinesTagFirst({
|
||||
ast: kclManager.ast,
|
||||
selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
})
|
||||
kclManager.updateAst(modifiedAst, true, {
|
||||
callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
})
|
||||
}}
|
||||
disabled={!enableEqual}
|
||||
className="group"
|
||||
title="Equal Length"
|
||||
>
|
||||
<ActionIcon
|
||||
icon="equal"
|
||||
className="!p-0.5"
|
||||
bgClassName={sketchButtonClassnames.background}
|
||||
iconClassName={sketchButtonClassnames.icon}
|
||||
size="md"
|
||||
/>
|
||||
Equal Length
|
||||
</button>
|
||||
)
|
||||
}
|
||||
*/
|
||||
export function setEqualLengthInfo({
|
||||
selectionRanges,
|
||||
}: {
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import { toolTips } from '../../useStore'
|
||||
import { Program, ProgramMemory, Value } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
@ -7,67 +6,12 @@ import {
|
||||
} from '../../lang/queryAst'
|
||||
import {
|
||||
PathToNodeMap,
|
||||
TransformInfo,
|
||||
getTransformInfos,
|
||||
transformAstSketchLines,
|
||||
} from '../../lang/std/sketchcombos'
|
||||
import { ActionIcon } from 'components/ActionIcon'
|
||||
import { sketchButtonClassnames } from 'Toolbar'
|
||||
import { kclManager } from 'lang/KclSinglton'
|
||||
import { Selections } from 'useStore'
|
||||
|
||||
/*
|
||||
export const HorzVert = ({
|
||||
horOrVert,
|
||||
}: {
|
||||
horOrVert: 'vertical' | 'horizontal'
|
||||
}) => {
|
||||
const { guiMode, selectionRanges, setCursor } = useStore((s) => ({
|
||||
guiMode: s.guiMode,
|
||||
selectionRanges: s.selectionRanges,
|
||||
setCursor: s.setCursor,
|
||||
}))
|
||||
const [enableHorz, setEnableHorz] = useState(false)
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
const { enabled, transforms } = horzVertInfo(selectionRanges, horOrVert)
|
||||
setTransformInfos(transforms)
|
||||
setEnableHorz(enabled)
|
||||
}, [guiMode, selectionRanges])
|
||||
if (guiMode.mode !== 'sketch') return null
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={() => {
|
||||
if (!transformInfos) return
|
||||
const { modifiedAst, pathToNodeMap } = transformAstSketchLines({
|
||||
ast: kclManager.ast,
|
||||
selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
referenceSegName: '',
|
||||
})
|
||||
kclManager.updateAst(modifiedAst, true, {
|
||||
callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
})
|
||||
}}
|
||||
disabled={!enableHorz}
|
||||
className="group"
|
||||
title={horOrVert === 'horizontal' ? 'Horizontal' : 'Vertical'}
|
||||
>
|
||||
<ActionIcon
|
||||
icon={horOrVert === 'horizontal' ? 'horizontal' : 'vertical'}
|
||||
className="!p-0.5"
|
||||
bgClassName={sketchButtonClassnames.background}
|
||||
iconClassName={sketchButtonClassnames.icon}
|
||||
size="md"
|
||||
/>
|
||||
{horOrVert === 'horizontal' ? 'Horizontal' : 'Vertical'}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
*/
|
||||
|
||||
export function horzVertInfo(
|
||||
selectionRanges: Selections,
|
||||
horOrVert: 'vertical' | 'horizontal'
|
||||
@ -110,7 +54,4 @@ export function applyConstraintHorzVert(
|
||||
programMemory,
|
||||
referenceSegName: '',
|
||||
})
|
||||
// kclManager.updateAst(modifiedAst, true, {
|
||||
// callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
// })
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { create } from 'react-modal-promise'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import { BinaryPart, Value, VariableDeclarator } from '../../lang/wasm'
|
||||
import { Selections, toolTips } from '../../useStore'
|
||||
import { BinaryPart, Program, Value, VariableDeclarator } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
@ -9,181 +7,170 @@ import {
|
||||
} from '../../lang/queryAst'
|
||||
import { isSketchVariablesLinked } from '../../lang/std/sketchConstraints'
|
||||
import {
|
||||
TransformInfo,
|
||||
transformSecondarySketchLinesTagFirst,
|
||||
getTransformInfos,
|
||||
PathToNodeMap,
|
||||
} from '../../lang/std/sketchcombos'
|
||||
import { GetInfoModal } from '../SetHorVertDistanceModal'
|
||||
import { GetInfoModal, createInfoModal } from '../SetHorVertDistanceModal'
|
||||
import { createVariableDeclaration } from '../../lang/modifyAst'
|
||||
import { removeDoubleNegatives } from '../AvailableVarsHelpers'
|
||||
import { kclManager } from 'lang/KclSinglton'
|
||||
|
||||
const getModalInfo = create(GetInfoModal as any)
|
||||
const getModalInfo = createInfoModal(GetInfoModal)
|
||||
|
||||
/*
|
||||
export const Intersect = () => {
|
||||
const { guiMode, selectionRanges, setCursor } = useStore((s) => ({
|
||||
guiMode: s.guiMode,
|
||||
selectionRanges: s.selectionRanges,
|
||||
setCursor: s.setCursor,
|
||||
}))
|
||||
const [enable, setEnable] = useState(false)
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
const [forecdSelectionRanges, setForcedSelectionRanges] =
|
||||
useState<typeof selectionRanges>()
|
||||
useEffect(() => {
|
||||
if (selectionRanges.codeBasedSelections.length < 2) {
|
||||
setEnable(false)
|
||||
setForcedSelectionRanges({ ...selectionRanges })
|
||||
return
|
||||
export function intersectInfo({
|
||||
selectionRanges,
|
||||
}: {
|
||||
selectionRanges: Selections
|
||||
}) {
|
||||
if (selectionRanges.codeBasedSelections.length < 2) {
|
||||
return {
|
||||
enabled: false,
|
||||
transforms: [],
|
||||
forcedSelectionRanges: { ...selectionRanges },
|
||||
}
|
||||
}
|
||||
|
||||
const previousSegment =
|
||||
selectionRanges.codeBasedSelections.length > 1 &&
|
||||
isLinesParallelAndConstrained(
|
||||
kclManager.ast,
|
||||
kclManager.programMemory,
|
||||
selectionRanges.codeBasedSelections[0],
|
||||
selectionRanges.codeBasedSelections[1]
|
||||
)
|
||||
const shouldUsePreviousSegment =
|
||||
selectionRanges.codeBasedSelections?.[1]?.type !== 'line-end' &&
|
||||
previousSegment &&
|
||||
previousSegment.isParallelAndConstrained
|
||||
|
||||
const _forcedSelectionRanges: typeof selectionRanges = {
|
||||
...selectionRanges,
|
||||
codeBasedSelections: [
|
||||
selectionRanges.codeBasedSelections?.[0],
|
||||
shouldUsePreviousSegment
|
||||
? {
|
||||
range: previousSegment.sourceRange,
|
||||
type: 'line-end',
|
||||
}
|
||||
: selectionRanges.codeBasedSelections?.[1],
|
||||
],
|
||||
}
|
||||
setForcedSelectionRanges(_forcedSelectionRanges)
|
||||
|
||||
const paths = _forcedSelectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(kclManager.ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(kclManager.ast, pathToNode).node
|
||||
)
|
||||
const varDecs = paths.map(
|
||||
(pathToNode) =>
|
||||
getNodeFromPath<VariableDeclarator>(
|
||||
kclManager.ast,
|
||||
pathToNode,
|
||||
'VariableDeclarator'
|
||||
)?.node
|
||||
)
|
||||
const primaryLine = varDecs[0]
|
||||
const secondaryVarDecs = varDecs.slice(1)
|
||||
const isOthersLinkedToPrimary = secondaryVarDecs.every((secondary) =>
|
||||
isSketchVariablesLinked(secondary, primaryLine, kclManager.ast)
|
||||
)
|
||||
const isAllTooltips = nodes.every(
|
||||
(node) =>
|
||||
node?.type === 'CallExpression' &&
|
||||
[
|
||||
...toolTips,
|
||||
'startSketchAt', // TODO probably a better place for this to live
|
||||
].includes(node.callee.name as any)
|
||||
)
|
||||
|
||||
const theTransforms = getTransformInfos(
|
||||
{
|
||||
...selectionRanges,
|
||||
codeBasedSelections:
|
||||
_forcedSelectionRanges.codeBasedSelections.slice(1),
|
||||
},
|
||||
const previousSegment =
|
||||
selectionRanges.codeBasedSelections.length > 1 &&
|
||||
isLinesParallelAndConstrained(
|
||||
kclManager.ast,
|
||||
'intersect'
|
||||
kclManager.programMemory,
|
||||
selectionRanges.codeBasedSelections[0],
|
||||
selectionRanges.codeBasedSelections[1]
|
||||
)
|
||||
setTransformInfos(theTransforms)
|
||||
const shouldUsePreviousSegment =
|
||||
selectionRanges.codeBasedSelections?.[1]?.type !== 'line-end' &&
|
||||
previousSegment &&
|
||||
previousSegment.isParallelAndConstrained
|
||||
|
||||
const _enableEqual =
|
||||
secondaryVarDecs.length === 1 &&
|
||||
isAllTooltips &&
|
||||
isOthersLinkedToPrimary &&
|
||||
theTransforms.every(Boolean) &&
|
||||
_forcedSelectionRanges?.codeBasedSelections?.[1]?.type === 'line-end'
|
||||
setEnable(_enableEqual)
|
||||
}, [guiMode, selectionRanges])
|
||||
if (guiMode.mode !== 'sketch') return null
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={async () => {
|
||||
if (!(transformInfos && forecdSelectionRanges)) return
|
||||
const { modifiedAst, tagInfo, valueUsedInTransform, pathToNodeMap } =
|
||||
transformSecondarySketchLinesTagFirst({
|
||||
ast: JSON.parse(JSON.stringify(kclManager.ast)),
|
||||
selectionRanges: forecdSelectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
})
|
||||
const {
|
||||
segName,
|
||||
value,
|
||||
valueNode,
|
||||
variableName,
|
||||
newVariableInsertIndex,
|
||||
sign,
|
||||
}: {
|
||||
segName: string
|
||||
value: number
|
||||
valueNode: Value
|
||||
variableName?: string
|
||||
newVariableInsertIndex: number
|
||||
sign: number
|
||||
} = await getModalInfo({
|
||||
segName: tagInfo?.tag,
|
||||
isSegNameEditable: !tagInfo?.isTagExisting,
|
||||
value: valueUsedInTransform,
|
||||
initialVariableName: 'offset',
|
||||
} as any)
|
||||
if (segName === tagInfo?.tag && value === valueUsedInTransform) {
|
||||
kclManager.updateAst(modifiedAst, true, {
|
||||
callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
})
|
||||
} else {
|
||||
// transform again but forcing certain values
|
||||
const finalValue = removeDoubleNegatives(
|
||||
valueNode as BinaryPart,
|
||||
sign,
|
||||
variableName
|
||||
)
|
||||
const { modifiedAst: _modifiedAst, pathToNodeMap } =
|
||||
transformSecondarySketchLinesTagFirst({
|
||||
ast: kclManager.ast,
|
||||
selectionRanges: forecdSelectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
forceSegName: segName,
|
||||
forceValueUsedInTransform: finalValue,
|
||||
})
|
||||
if (variableName) {
|
||||
const newBody = [..._modifiedAst.body]
|
||||
newBody.splice(
|
||||
newVariableInsertIndex,
|
||||
0,
|
||||
createVariableDeclaration(variableName, valueNode)
|
||||
)
|
||||
_modifiedAst.body = newBody
|
||||
const _forcedSelectionRanges: typeof selectionRanges = {
|
||||
...selectionRanges,
|
||||
codeBasedSelections: [
|
||||
selectionRanges.codeBasedSelections?.[0],
|
||||
shouldUsePreviousSegment
|
||||
? {
|
||||
range: previousSegment.sourceRange,
|
||||
type: 'line-end',
|
||||
}
|
||||
kclManager.updateAst(_modifiedAst, true, {
|
||||
callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
})
|
||||
}
|
||||
}}
|
||||
disabled={!enable}
|
||||
title="Set Perpendicular Distance"
|
||||
>
|
||||
Set Perpendicular Distance
|
||||
</button>
|
||||
: selectionRanges.codeBasedSelections?.[1],
|
||||
],
|
||||
}
|
||||
|
||||
const paths = _forcedSelectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(kclManager.ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(kclManager.ast, pathToNode).node
|
||||
)
|
||||
const varDecs = paths.map(
|
||||
(pathToNode) =>
|
||||
getNodeFromPath<VariableDeclarator>(
|
||||
kclManager.ast,
|
||||
pathToNode,
|
||||
'VariableDeclarator'
|
||||
)?.node
|
||||
)
|
||||
const primaryLine = varDecs[0]
|
||||
const secondaryVarDecs = varDecs.slice(1)
|
||||
const isOthersLinkedToPrimary = secondaryVarDecs.every((secondary) =>
|
||||
isSketchVariablesLinked(secondary, primaryLine, kclManager.ast)
|
||||
)
|
||||
const isAllTooltips = nodes.every(
|
||||
(node) =>
|
||||
node?.type === 'CallExpression' &&
|
||||
[
|
||||
...toolTips,
|
||||
'startSketchAt', // TODO probably a better place for this to live
|
||||
].includes(node.callee.name as any)
|
||||
)
|
||||
|
||||
const theTransforms = getTransformInfos(
|
||||
{
|
||||
...selectionRanges,
|
||||
codeBasedSelections: _forcedSelectionRanges.codeBasedSelections.slice(1),
|
||||
},
|
||||
kclManager.ast,
|
||||
'intersect'
|
||||
)
|
||||
|
||||
const _enableEqual =
|
||||
secondaryVarDecs.length === 1 &&
|
||||
isAllTooltips &&
|
||||
isOthersLinkedToPrimary &&
|
||||
theTransforms.every(Boolean) &&
|
||||
_forcedSelectionRanges?.codeBasedSelections?.[1]?.type === 'line-end'
|
||||
|
||||
return {
|
||||
enabled: _enableEqual,
|
||||
transforms: theTransforms,
|
||||
forcedSelectionRanges: _forcedSelectionRanges,
|
||||
}
|
||||
}
|
||||
|
||||
export async function applyConstraintIntersect({
|
||||
selectionRanges,
|
||||
}: {
|
||||
selectionRanges: Selections
|
||||
}): Promise<{
|
||||
modifiedAst: Program
|
||||
pathToNodeMap: PathToNodeMap
|
||||
}> {
|
||||
const { transforms, forcedSelectionRanges } = intersectInfo({
|
||||
selectionRanges,
|
||||
})
|
||||
const { modifiedAst, tagInfo, valueUsedInTransform, pathToNodeMap } =
|
||||
transformSecondarySketchLinesTagFirst({
|
||||
ast: JSON.parse(JSON.stringify(kclManager.ast)),
|
||||
selectionRanges: forcedSelectionRanges,
|
||||
transformInfos: transforms,
|
||||
programMemory: kclManager.programMemory,
|
||||
})
|
||||
const {
|
||||
segName,
|
||||
value,
|
||||
valueNode,
|
||||
variableName,
|
||||
newVariableInsertIndex,
|
||||
sign,
|
||||
} = await getModalInfo({
|
||||
segName: tagInfo?.tag,
|
||||
isSegNameEditable: !tagInfo?.isTagExisting,
|
||||
value: valueUsedInTransform,
|
||||
initialVariableName: 'offset',
|
||||
})
|
||||
if (segName === tagInfo?.tag && Number(value) === valueUsedInTransform) {
|
||||
return {
|
||||
modifiedAst,
|
||||
pathToNodeMap,
|
||||
}
|
||||
}
|
||||
// transform again but forcing certain values
|
||||
const finalValue = removeDoubleNegatives(
|
||||
valueNode as BinaryPart,
|
||||
sign,
|
||||
variableName
|
||||
)
|
||||
const { modifiedAst: _modifiedAst, pathToNodeMap: _pathToNodeMap } =
|
||||
transformSecondarySketchLinesTagFirst({
|
||||
ast: kclManager.ast,
|
||||
selectionRanges: forcedSelectionRanges,
|
||||
transformInfos: transforms,
|
||||
programMemory: kclManager.programMemory,
|
||||
forceSegName: segName,
|
||||
forceValueUsedInTransform: finalValue,
|
||||
})
|
||||
if (variableName) {
|
||||
const newBody = [..._modifiedAst.body]
|
||||
newBody.splice(
|
||||
newVariableInsertIndex,
|
||||
0,
|
||||
createVariableDeclaration(variableName, valueNode)
|
||||
)
|
||||
_modifiedAst.body = newBody
|
||||
}
|
||||
return {
|
||||
modifiedAst: _modifiedAst,
|
||||
pathToNodeMap: _pathToNodeMap,
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -1,75 +1,62 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import { Value } from '../../lang/wasm'
|
||||
import { Selections, toolTips } from '../../useStore'
|
||||
import { Program, Value } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
} from '../../lang/queryAst'
|
||||
import {
|
||||
TransformInfo,
|
||||
PathToNodeMap,
|
||||
getRemoveConstraintsTransforms,
|
||||
transformAstSketchLines,
|
||||
} from '../../lang/std/sketchcombos'
|
||||
import { kclManager } from 'lang/KclSinglton'
|
||||
|
||||
/*
|
||||
export const RemoveConstrainingValues = () => {
|
||||
const { guiMode, selectionRanges, setCursor } = useStore((s) => ({
|
||||
guiMode: s.guiMode,
|
||||
selectionRanges: s.selectionRanges,
|
||||
setCursor: s.setCursor,
|
||||
}))
|
||||
const [enableHorz, setEnableHorz] = useState(false)
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(kclManager.ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(kclManager.ast, pathToNode).node
|
||||
)
|
||||
const isAllTooltips = nodes.every(
|
||||
(node) =>
|
||||
node?.type === 'CallExpression' &&
|
||||
toolTips.includes(node.callee.name as any)
|
||||
)
|
||||
|
||||
try {
|
||||
const theTransforms = getRemoveConstraintsTransforms(
|
||||
selectionRanges,
|
||||
kclManager.ast,
|
||||
'removeConstrainingValues'
|
||||
)
|
||||
setTransformInfos(theTransforms)
|
||||
|
||||
const _enableHorz = isAllTooltips && theTransforms.every(Boolean)
|
||||
setEnableHorz(_enableHorz)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}, [guiMode, selectionRanges])
|
||||
if (guiMode.mode !== 'sketch') return null
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={() => {
|
||||
if (!transformInfos) return
|
||||
const { modifiedAst, pathToNodeMap } = transformAstSketchLines({
|
||||
ast: kclManager.ast,
|
||||
selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
referenceSegName: '',
|
||||
})
|
||||
kclManager.updateAst(modifiedAst, true, {
|
||||
callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
})
|
||||
}}
|
||||
disabled={!enableHorz}
|
||||
title="Remove Constraining Values"
|
||||
>
|
||||
Remove Constraining Values
|
||||
</button>
|
||||
export function removeConstrainingValuesInfo({
|
||||
selectionRanges,
|
||||
}: {
|
||||
selectionRanges: Selections
|
||||
}) {
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(kclManager.ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) => getNodeFromPath<Value>(kclManager.ast, pathToNode).node
|
||||
)
|
||||
const isAllTooltips = nodes.every(
|
||||
(node) =>
|
||||
node?.type === 'CallExpression' &&
|
||||
toolTips.includes(node.callee.name as any)
|
||||
)
|
||||
|
||||
try {
|
||||
const transforms = getRemoveConstraintsTransforms(
|
||||
selectionRanges,
|
||||
kclManager.ast,
|
||||
'removeConstrainingValues'
|
||||
)
|
||||
|
||||
const enabled = isAllTooltips && transforms.every(Boolean)
|
||||
return { enabled, transforms }
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return { enabled: false, transforms: [] }
|
||||
}
|
||||
}
|
||||
|
||||
export function applyRemoveConstrainingValues({
|
||||
selectionRanges,
|
||||
}: {
|
||||
selectionRanges: Selections
|
||||
}): {
|
||||
modifiedAst: Program
|
||||
pathToNodeMap: PathToNodeMap
|
||||
} {
|
||||
const { transforms } = removeConstrainingValuesInfo({ selectionRanges })
|
||||
return transformAstSketchLines({
|
||||
ast: kclManager.ast,
|
||||
selectionRanges,
|
||||
transformInfos: transforms,
|
||||
programMemory: kclManager.programMemory,
|
||||
referenceSegName: '',
|
||||
})
|
||||
}
|
||||
*/
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { create } from 'react-modal-promise'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import { Value } from '../../lang/wasm'
|
||||
import { Selections, toolTips } from '../../useStore'
|
||||
import { BinaryPart, Program, Value } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
} from '../../lang/queryAst'
|
||||
import {
|
||||
TransformInfo,
|
||||
getTransformInfos,
|
||||
transformAstSketchLines,
|
||||
ConstraintType,
|
||||
PathToNodeMap,
|
||||
} from '../../lang/std/sketchcombos'
|
||||
import { SetAngleLengthModal } from '../SetAngleLengthModal'
|
||||
import {
|
||||
SetAngleLengthModal,
|
||||
createSetAngleLengthModal,
|
||||
} from '../SetAngleLengthModal'
|
||||
import {
|
||||
createIdentifier,
|
||||
createVariableDeclaration,
|
||||
@ -20,128 +20,132 @@ import {
|
||||
import { removeDoubleNegatives } from '../AvailableVarsHelpers'
|
||||
import { kclManager } from 'lang/KclSinglton'
|
||||
|
||||
const getModalInfo = create(SetAngleLengthModal as any)
|
||||
const getModalInfo = createSetAngleLengthModal(SetAngleLengthModal)
|
||||
|
||||
type ButtonType = 'xAbs' | 'yAbs' | 'snapToYAxis' | 'snapToXAxis'
|
||||
type Constraint = 'xAbs' | 'yAbs' | 'snapToYAxis' | 'snapToXAxis'
|
||||
|
||||
const buttonLabels: Record<ButtonType, string> = {
|
||||
xAbs: 'Set distance from X Axis',
|
||||
yAbs: 'Set distance from Y Axis',
|
||||
snapToYAxis: 'Snap To Y Axis',
|
||||
snapToXAxis: 'Snap To X Axis',
|
||||
}
|
||||
|
||||
/*
|
||||
export const SetAbsDistance = ({ buttonType }: { buttonType: ButtonType }) => {
|
||||
const { guiMode, selectionRanges, setCursor } = useStore((s) => ({
|
||||
guiMode: s.guiMode,
|
||||
selectionRanges: s.selectionRanges,
|
||||
setCursor: s.setCursor,
|
||||
}))
|
||||
const disType: ConstraintType =
|
||||
buttonType === 'xAbs' || buttonType === 'yAbs'
|
||||
? buttonType
|
||||
: buttonType === 'snapToYAxis'
|
||||
export function absDistanceInfo({
|
||||
selectionRanges,
|
||||
constraint,
|
||||
}: {
|
||||
selectionRanges: Selections
|
||||
constraint: Constraint
|
||||
}) {
|
||||
const disType =
|
||||
constraint === 'xAbs' || constraint === 'yAbs'
|
||||
? constraint
|
||||
: constraint === 'snapToYAxis'
|
||||
? 'xAbs'
|
||||
: 'yAbs'
|
||||
const [enableAngLen, setEnableAngLen] = useState(false)
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(kclManager.ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) =>
|
||||
getNodeFromPath<Value>(kclManager.ast, pathToNode, 'CallExpression')
|
||||
.node
|
||||
)
|
||||
const isAllTooltips = nodes.every(
|
||||
(node) =>
|
||||
node?.type === 'CallExpression' &&
|
||||
toolTips.includes(node.callee.name as any)
|
||||
)
|
||||
|
||||
const theTransforms = getTransformInfos(
|
||||
selectionRanges,
|
||||
kclManager.ast,
|
||||
disType
|
||||
)
|
||||
setTransformInfos(theTransforms)
|
||||
|
||||
const enableY =
|
||||
disType === 'yAbs' &&
|
||||
selectionRanges.otherSelections.length === 1 &&
|
||||
selectionRanges.otherSelections[0] === 'x-axis' // select the x axis to set the distance from it i.e. y
|
||||
const enableX =
|
||||
disType === 'xAbs' &&
|
||||
selectionRanges.otherSelections.length === 1 &&
|
||||
selectionRanges.otherSelections[0] === 'y-axis' // select the y axis to set the distance from it i.e. x
|
||||
|
||||
const _enableHorz =
|
||||
isAllTooltips &&
|
||||
theTransforms.every(Boolean) &&
|
||||
selectionRanges.codeBasedSelections.length === 1 &&
|
||||
(enableX || enableY)
|
||||
setEnableAngLen(_enableHorz)
|
||||
}, [guiMode, selectionRanges])
|
||||
if (guiMode.mode !== 'sketch') return null
|
||||
|
||||
const isAlign = buttonType === 'snapToYAxis' || buttonType === 'snapToXAxis'
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={async () => {
|
||||
if (!transformInfos) return
|
||||
const { valueUsedInTransform } = transformAstSketchLines({
|
||||
ast: JSON.parse(JSON.stringify(kclManager.ast)),
|
||||
selectionRanges: selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
referenceSegName: '',
|
||||
})
|
||||
try {
|
||||
let forceVal = valueUsedInTransform || 0
|
||||
const { valueNode, variableName, newVariableInsertIndex, sign } =
|
||||
await (!isAlign &&
|
||||
getModalInfo({
|
||||
value: forceVal,
|
||||
valueName: disType === 'yAbs' ? 'yDis' : 'xDis',
|
||||
} as any))
|
||||
let finalValue = isAlign
|
||||
? createIdentifier('_0')
|
||||
: removeDoubleNegatives(valueNode, sign, variableName)
|
||||
|
||||
const { modifiedAst: _modifiedAst, pathToNodeMap } =
|
||||
transformAstSketchLines({
|
||||
ast: JSON.parse(JSON.stringify(kclManager.ast)),
|
||||
selectionRanges: selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
referenceSegName: '',
|
||||
forceValueUsedInTransform: finalValue,
|
||||
})
|
||||
if (variableName) {
|
||||
const newBody = [..._modifiedAst.body]
|
||||
newBody.splice(
|
||||
newVariableInsertIndex,
|
||||
0,
|
||||
createVariableDeclaration(variableName, valueNode)
|
||||
)
|
||||
_modifiedAst.body = newBody
|
||||
}
|
||||
|
||||
kclManager.updateAst(_modifiedAst, true, {
|
||||
callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
})
|
||||
} catch (e) {
|
||||
console.log('error', e)
|
||||
}
|
||||
}}
|
||||
disabled={!enableAngLen}
|
||||
title={buttonLabels[buttonType]}
|
||||
>
|
||||
{buttonLabels[buttonType]}
|
||||
</button>
|
||||
const paths = selectionRanges.codeBasedSelections.map(({ range }) =>
|
||||
getNodePathFromSourceRange(kclManager.ast, range)
|
||||
)
|
||||
const nodes = paths.map(
|
||||
(pathToNode) =>
|
||||
getNodeFromPath<Value>(kclManager.ast, pathToNode, 'CallExpression').node
|
||||
)
|
||||
const isAllTooltips = nodes.every(
|
||||
(node) =>
|
||||
node?.type === 'CallExpression' &&
|
||||
toolTips.includes(node.callee.name as any)
|
||||
)
|
||||
|
||||
const transforms = getTransformInfos(selectionRanges, kclManager.ast, disType)
|
||||
|
||||
const enableY =
|
||||
disType === 'yAbs' &&
|
||||
selectionRanges.otherSelections.length === 1 &&
|
||||
selectionRanges.otherSelections[0] === 'x-axis' // select the x axis to set the distance from it i.e. y
|
||||
const enableX =
|
||||
disType === 'xAbs' &&
|
||||
selectionRanges.otherSelections.length === 1 &&
|
||||
selectionRanges.otherSelections[0] === 'y-axis' // select the y axis to set the distance from it i.e. x
|
||||
|
||||
const enabled =
|
||||
isAllTooltips &&
|
||||
transforms.every(Boolean) &&
|
||||
selectionRanges.codeBasedSelections.length === 1 &&
|
||||
(enableX || enableY)
|
||||
|
||||
return { enabled, transforms }
|
||||
}
|
||||
|
||||
export async function applyConstraintAbsDistance({
|
||||
selectionRanges,
|
||||
constraint,
|
||||
}: {
|
||||
selectionRanges: Selections
|
||||
constraint: 'xAbs' | 'yAbs'
|
||||
}): Promise<{
|
||||
modifiedAst: Program
|
||||
pathToNodeMap: PathToNodeMap
|
||||
}> {
|
||||
const transformInfos = absDistanceInfo({
|
||||
selectionRanges,
|
||||
constraint,
|
||||
}).transforms
|
||||
const { valueUsedInTransform } = transformAstSketchLines({
|
||||
ast: JSON.parse(JSON.stringify(kclManager.ast)),
|
||||
selectionRanges: selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
referenceSegName: '',
|
||||
})
|
||||
let forceVal = valueUsedInTransform || 0
|
||||
const { valueNode, variableName, newVariableInsertIndex, sign } =
|
||||
await getModalInfo({
|
||||
value: forceVal,
|
||||
valueName: constraint === 'yAbs' ? 'yDis' : 'xDis',
|
||||
})
|
||||
let finalValue = removeDoubleNegatives(
|
||||
valueNode as BinaryPart,
|
||||
sign,
|
||||
variableName
|
||||
)
|
||||
|
||||
const { modifiedAst: _modifiedAst, pathToNodeMap } = transformAstSketchLines({
|
||||
ast: JSON.parse(JSON.stringify(kclManager.ast)),
|
||||
selectionRanges: selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
referenceSegName: '',
|
||||
forceValueUsedInTransform: finalValue,
|
||||
})
|
||||
if (variableName) {
|
||||
const newBody = [..._modifiedAst.body]
|
||||
newBody.splice(
|
||||
newVariableInsertIndex,
|
||||
0,
|
||||
createVariableDeclaration(variableName, valueNode)
|
||||
)
|
||||
_modifiedAst.body = newBody
|
||||
}
|
||||
return { modifiedAst: _modifiedAst, pathToNodeMap }
|
||||
}
|
||||
|
||||
export function applyConstraintAxisAlign({
|
||||
selectionRanges,
|
||||
constraint,
|
||||
}: {
|
||||
selectionRanges: Selections
|
||||
constraint: 'snapToYAxis' | 'snapToXAxis'
|
||||
}): {
|
||||
modifiedAst: Program
|
||||
pathToNodeMap: PathToNodeMap
|
||||
} {
|
||||
const transformInfos = absDistanceInfo({
|
||||
selectionRanges,
|
||||
constraint,
|
||||
}).transforms
|
||||
|
||||
let finalValue = createIdentifier('_0')
|
||||
|
||||
return transformAstSketchLines({
|
||||
ast: JSON.parse(JSON.stringify(kclManager.ast)),
|
||||
selectionRanges: selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
referenceSegName: '',
|
||||
forceValueUsedInTransform: finalValue,
|
||||
})
|
||||
}
|
||||
*/
|
||||
|
@ -1,6 +1,4 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { create } from 'react-modal-promise'
|
||||
import { Selections, toolTips, useStore } from '../../useStore'
|
||||
import { Selections, toolTips } from '../../useStore'
|
||||
import { BinaryPart, Program, Value, VariableDeclarator } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
@ -8,107 +6,16 @@ import {
|
||||
} from '../../lang/queryAst'
|
||||
import { isSketchVariablesLinked } from '../../lang/std/sketchConstraints'
|
||||
import {
|
||||
TransformInfo,
|
||||
transformSecondarySketchLinesTagFirst,
|
||||
getTransformInfos,
|
||||
PathToNodeMap,
|
||||
} from '../../lang/std/sketchcombos'
|
||||
import { GetInfoModal } from '../SetHorVertDistanceModal'
|
||||
import { GetInfoModal, createInfoModal } from '../SetHorVertDistanceModal'
|
||||
import { createVariableDeclaration } from '../../lang/modifyAst'
|
||||
import { removeDoubleNegatives } from '../AvailableVarsHelpers'
|
||||
import { kclManager } from 'lang/KclSinglton'
|
||||
|
||||
const getModalInfo = create(GetInfoModal as any)
|
||||
|
||||
/*
|
||||
export const SetAngleBetween = () => {
|
||||
const { guiMode, selectionRanges, setCursor } = useStore((s) => ({
|
||||
guiMode: s.guiMode,
|
||||
selectionRanges: s.selectionRanges,
|
||||
setCursor: s.setCursor,
|
||||
}))
|
||||
const [enable, setEnable] = useState(false)
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
const { enabled, transforms } = angleBetweenInfo({ selectionRanges })
|
||||
setTransformInfos(transforms)
|
||||
setEnable(enabled)
|
||||
}, [guiMode, selectionRanges])
|
||||
if (guiMode.mode !== 'sketch') return null
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={async () => {
|
||||
if (!transformInfos) return
|
||||
const { modifiedAst, tagInfo, valueUsedInTransform, pathToNodeMap } =
|
||||
transformSecondarySketchLinesTagFirst({
|
||||
ast: JSON.parse(JSON.stringify(kclManager.ast)),
|
||||
selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
})
|
||||
const {
|
||||
segName,
|
||||
value,
|
||||
valueNode,
|
||||
variableName,
|
||||
newVariableInsertIndex,
|
||||
sign,
|
||||
}: {
|
||||
segName: string
|
||||
value: number
|
||||
valueNode: Value
|
||||
variableName?: string
|
||||
newVariableInsertIndex: number
|
||||
sign: number
|
||||
} = await getModalInfo({
|
||||
segName: tagInfo?.tag,
|
||||
isSegNameEditable: !tagInfo?.isTagExisting,
|
||||
value: valueUsedInTransform,
|
||||
initialVariableName: 'angle',
|
||||
} as any)
|
||||
if (segName === tagInfo?.tag && value === valueUsedInTransform) {
|
||||
kclManager.updateAst(modifiedAst, true, {
|
||||
callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
})
|
||||
} else {
|
||||
const finalValue = removeDoubleNegatives(
|
||||
valueNode as BinaryPart,
|
||||
sign,
|
||||
variableName
|
||||
)
|
||||
// transform again but forcing certain values
|
||||
const { modifiedAst: _modifiedAst, pathToNodeMap } =
|
||||
transformSecondarySketchLinesTagFirst({
|
||||
ast: kclManager.ast,
|
||||
selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
forceSegName: segName,
|
||||
forceValueUsedInTransform: finalValue,
|
||||
})
|
||||
if (variableName) {
|
||||
const newBody = [..._modifiedAst.body]
|
||||
newBody.splice(
|
||||
newVariableInsertIndex,
|
||||
0,
|
||||
createVariableDeclaration(variableName, valueNode)
|
||||
)
|
||||
_modifiedAst.body = newBody
|
||||
}
|
||||
kclManager.updateAst(_modifiedAst, true, {
|
||||
callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
})
|
||||
}
|
||||
}}
|
||||
disabled={!enable}
|
||||
title="Set Angle Between"
|
||||
>
|
||||
Set Angle Between
|
||||
</button>
|
||||
)
|
||||
}
|
||||
*/
|
||||
const getModalInfo = createInfoModal(GetInfoModal)
|
||||
|
||||
export function angleBetweenInfo({
|
||||
selectionRanges,
|
||||
@ -183,28 +90,17 @@ export async function applyConstraintAngleBetween({
|
||||
variableName,
|
||||
newVariableInsertIndex,
|
||||
sign,
|
||||
}: {
|
||||
segName: string
|
||||
value: number
|
||||
valueNode: Value
|
||||
variableName?: string
|
||||
newVariableInsertIndex: number
|
||||
sign: number
|
||||
} = await getModalInfo({
|
||||
segName: tagInfo?.tag,
|
||||
isSegNameEditable: !tagInfo?.isTagExisting,
|
||||
value: valueUsedInTransform,
|
||||
initialVariableName: 'angle',
|
||||
} as any)
|
||||
if (segName === tagInfo?.tag && value === valueUsedInTransform) {
|
||||
if (segName === tagInfo?.tag && Number(value) === valueUsedInTransform) {
|
||||
return {
|
||||
modifiedAst,
|
||||
pathToNodeMap,
|
||||
}
|
||||
// kclManager.updateAst(modifiedAst, true, {
|
||||
// TODO handle cursor
|
||||
// callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
// })
|
||||
}
|
||||
|
||||
const finalValue = removeDoubleNegatives(
|
||||
@ -235,8 +131,4 @@ export async function applyConstraintAngleBetween({
|
||||
modifiedAst: _modifiedAst,
|
||||
pathToNodeMap: _pathToNodeMap,
|
||||
}
|
||||
// kclManager.updateAst(_modifiedAst, true, {
|
||||
// TODO handle cursor
|
||||
// callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
// })
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { create } from 'react-modal-promise'
|
||||
import { toolTips, useStore } from '../../useStore'
|
||||
import { toolTips } from '../../useStore'
|
||||
import { BinaryPart, Program, Value, VariableDeclarator } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
@ -8,139 +6,17 @@ import {
|
||||
} from '../../lang/queryAst'
|
||||
import { isSketchVariablesLinked } from '../../lang/std/sketchConstraints'
|
||||
import {
|
||||
TransformInfo,
|
||||
transformSecondarySketchLinesTagFirst,
|
||||
getTransformInfos,
|
||||
ConstraintType,
|
||||
PathToNodeMap,
|
||||
} from '../../lang/std/sketchcombos'
|
||||
import { GetInfoModal } from '../SetHorVertDistanceModal'
|
||||
import { GetInfoModal, createInfoModal } from '../SetHorVertDistanceModal'
|
||||
import { createLiteral, createVariableDeclaration } from '../../lang/modifyAst'
|
||||
import { removeDoubleNegatives } from '../AvailableVarsHelpers'
|
||||
import { kclManager } from 'lang/KclSinglton'
|
||||
import { Selections } from 'useStore'
|
||||
|
||||
const getModalInfo = create(GetInfoModal as any)
|
||||
|
||||
type ButtonType =
|
||||
| 'setHorzDistance'
|
||||
| 'setVertDistance'
|
||||
| 'alignEndsHorizontally'
|
||||
| 'alignEndsVertically'
|
||||
|
||||
const buttonLabels: Record<ButtonType, string> = {
|
||||
setHorzDistance: 'Set Horizontal Distance',
|
||||
setVertDistance: 'Set Vertical Distance',
|
||||
alignEndsHorizontally: 'Align Ends Horizontally',
|
||||
alignEndsVertically: 'Align Ends Vertically',
|
||||
}
|
||||
|
||||
/*
|
||||
export const SetHorzVertDistance = ({
|
||||
buttonType,
|
||||
}: {
|
||||
buttonType: ButtonType
|
||||
}) => {
|
||||
const { guiMode, selectionRanges, setCursor } = useStore((s) => ({
|
||||
guiMode: s.guiMode,
|
||||
selectionRanges: s.selectionRanges,
|
||||
setCursor: s.setCursor,
|
||||
}))
|
||||
const constraint: ConstraintType =
|
||||
buttonType === 'setHorzDistance' || buttonType === 'setVertDistance'
|
||||
? buttonType
|
||||
: buttonType === 'alignEndsHorizontally'
|
||||
? 'setVertDistance'
|
||||
: 'setHorzDistance'
|
||||
const [enable, setEnable] = useState(false)
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
const { transforms, enabled } = horzVertDistanceInfo({
|
||||
selectionRanges,
|
||||
constraint,
|
||||
})
|
||||
setTransformInfos(transforms)
|
||||
setEnable(enabled)
|
||||
}, [guiMode, selectionRanges])
|
||||
if (guiMode.mode !== 'sketch') return null
|
||||
|
||||
const isAlign =
|
||||
buttonType === 'alignEndsHorizontally' ||
|
||||
buttonType === 'alignEndsVertically'
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={async () => {
|
||||
if (!transformInfos) return
|
||||
const { modifiedAst, tagInfo, valueUsedInTransform, pathToNodeMap } =
|
||||
transformSecondarySketchLinesTagFirst({
|
||||
ast: JSON.parse(JSON.stringify(kclManager.ast)),
|
||||
selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
})
|
||||
const {
|
||||
segName,
|
||||
value,
|
||||
valueNode,
|
||||
variableName,
|
||||
newVariableInsertIndex,
|
||||
sign,
|
||||
}: {
|
||||
segName: string
|
||||
value: number
|
||||
valueNode: Value
|
||||
variableName?: string
|
||||
newVariableInsertIndex: number
|
||||
sign: number
|
||||
} = await (!isAlign &&
|
||||
getModalInfo({
|
||||
segName: tagInfo?.tag,
|
||||
isSegNameEditable: !tagInfo?.isTagExisting,
|
||||
value: valueUsedInTransform,
|
||||
initialVariableName:
|
||||
constraint === 'setHorzDistance' ? 'xDis' : 'yDis',
|
||||
} as any))
|
||||
if (segName === tagInfo?.tag && value === valueUsedInTransform) {
|
||||
kclManager.updateAst(modifiedAst, true, {
|
||||
callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
})
|
||||
} else {
|
||||
let finalValue = isAlign
|
||||
? createLiteral(0)
|
||||
: removeDoubleNegatives(valueNode as BinaryPart, sign, variableName)
|
||||
// transform again but forcing certain values
|
||||
const { modifiedAst: _modifiedAst, pathToNodeMap } =
|
||||
transformSecondarySketchLinesTagFirst({
|
||||
ast: kclManager.ast,
|
||||
selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
forceSegName: segName,
|
||||
forceValueUsedInTransform: finalValue,
|
||||
})
|
||||
if (variableName) {
|
||||
const newBody = [..._modifiedAst.body]
|
||||
newBody.splice(
|
||||
newVariableInsertIndex,
|
||||
0,
|
||||
createVariableDeclaration(variableName, valueNode)
|
||||
)
|
||||
_modifiedAst.body = newBody
|
||||
}
|
||||
kclManager.updateAst(_modifiedAst, true, {
|
||||
callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
})
|
||||
}
|
||||
}}
|
||||
disabled={!enable}
|
||||
title={buttonLabels[buttonType]}
|
||||
>
|
||||
{buttonLabels[buttonType]}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
*/
|
||||
const getModalInfo = createInfoModal(GetInfoModal)
|
||||
|
||||
export function horzVertDistanceInfo({
|
||||
selectionRanges,
|
||||
@ -201,7 +77,7 @@ export async function applyConstraintHorzVertDistance({
|
||||
}: {
|
||||
selectionRanges: Selections
|
||||
constraint: 'setHorzDistance' | 'setVertDistance'
|
||||
isAlign?: boolean
|
||||
isAlign?: false
|
||||
}): Promise<{
|
||||
modifiedAst: Program
|
||||
pathToNodeMap: PathToNodeMap
|
||||
@ -224,29 +100,17 @@ export async function applyConstraintHorzVertDistance({
|
||||
variableName,
|
||||
newVariableInsertIndex,
|
||||
sign,
|
||||
}: {
|
||||
segName: string
|
||||
value: number
|
||||
valueNode: Value
|
||||
variableName?: string
|
||||
newVariableInsertIndex: number
|
||||
sign: number
|
||||
} = await (!isAlign &&
|
||||
getModalInfo({
|
||||
segName: tagInfo?.tag,
|
||||
isSegNameEditable: !tagInfo?.isTagExisting,
|
||||
value: valueUsedInTransform,
|
||||
initialVariableName: constraint === 'setHorzDistance' ? 'xDis' : 'yDis',
|
||||
} as any))
|
||||
if (segName === tagInfo?.tag && value === valueUsedInTransform) {
|
||||
} = await getModalInfo({
|
||||
segName: tagInfo?.tag,
|
||||
isSegNameEditable: !tagInfo?.isTagExisting,
|
||||
value: valueUsedInTransform,
|
||||
initialVariableName: constraint === 'setHorzDistance' ? 'xDis' : 'yDis',
|
||||
} as any)
|
||||
if (segName === tagInfo?.tag && Number(value) === valueUsedInTransform) {
|
||||
return {
|
||||
modifiedAst,
|
||||
pathToNodeMap,
|
||||
}
|
||||
// TODO handle cursor stuff
|
||||
// kclManager.updateAst(modifiedAst, true, {
|
||||
// callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
// })
|
||||
} else {
|
||||
let finalValue = isAlign
|
||||
? createLiteral(0)
|
||||
@ -274,10 +138,6 @@ export async function applyConstraintHorzVertDistance({
|
||||
modifiedAst: _modifiedAst,
|
||||
pathToNodeMap,
|
||||
}
|
||||
// TODO handle cursor stuff
|
||||
// kclManager.updateAst(_modifiedAst, true, {
|
||||
// callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
// })
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,8 +167,4 @@ export function applyConstraintHorzVertAlign({
|
||||
modifiedAst: modifiedAst,
|
||||
pathToNodeMap,
|
||||
}
|
||||
// TODO handle cursor stuff
|
||||
// kclManager.updateAst(_modifiedAst, true, {
|
||||
// callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
// })
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { create } from 'react-modal-promise'
|
||||
import { Selections, toolTips, useStore } from '../../useStore'
|
||||
import { Program, Value } from '../../lang/wasm'
|
||||
import { Selections, toolTips } from '../../useStore'
|
||||
import { BinaryPart, Program, Value } from '../../lang/wasm'
|
||||
import {
|
||||
getNodePathFromSourceRange,
|
||||
getNodeFromPath,
|
||||
} from '../../lang/queryAst'
|
||||
import {
|
||||
PathToNodeMap,
|
||||
TransformInfo,
|
||||
getTransformInfos,
|
||||
transformAstSketchLines,
|
||||
} from '../../lang/std/sketchcombos'
|
||||
import { SetAngleLengthModal } from '../SetAngleLengthModal'
|
||||
import {
|
||||
SetAngleLengthModal,
|
||||
createSetAngleLengthModal,
|
||||
} from '../SetAngleLengthModal'
|
||||
import {
|
||||
createBinaryExpressionWithUnary,
|
||||
createIdentifier,
|
||||
@ -22,128 +22,7 @@ import { removeDoubleNegatives } from '../AvailableVarsHelpers'
|
||||
import { normaliseAngle } from '../../lib/utils'
|
||||
import { kclManager } from 'lang/KclSinglton'
|
||||
|
||||
const getModalInfo = create(SetAngleLengthModal as any)
|
||||
|
||||
type ButtonType = 'setAngle' | 'setLength'
|
||||
|
||||
const buttonLabels: Record<ButtonType, string> = {
|
||||
setAngle: 'Set Angle',
|
||||
setLength: 'Set Length',
|
||||
}
|
||||
|
||||
/*
|
||||
export const SetAngleLength = ({
|
||||
angleOrLength,
|
||||
}: {
|
||||
angleOrLength: ButtonType
|
||||
}) => {
|
||||
const { guiMode, selectionRanges, setCursor } = useStore((s) => ({
|
||||
guiMode: s.guiMode,
|
||||
selectionRanges: s.selectionRanges,
|
||||
setCursor: s.setCursor,
|
||||
}))
|
||||
const [enableAngLen, setEnableAngLen] = useState(false)
|
||||
const [transformInfos, setTransformInfos] = useState<TransformInfo[]>()
|
||||
useEffect(() => {
|
||||
const { enabled, transforms } = setAngleLengthInfo({
|
||||
selectionRanges,
|
||||
angleOrLength,
|
||||
})
|
||||
|
||||
setTransformInfos(transforms)
|
||||
setEnableAngLen(enabled)
|
||||
}, [guiMode, selectionRanges])
|
||||
if (guiMode.mode !== 'sketch') return null
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={async () => {
|
||||
if (!transformInfos) return
|
||||
const { valueUsedInTransform } = transformAstSketchLines({
|
||||
ast: JSON.parse(JSON.stringify(kclManager.ast)),
|
||||
selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
referenceSegName: '',
|
||||
})
|
||||
try {
|
||||
const isReferencingYAxis =
|
||||
selectionRanges.otherSelections.length === 1 &&
|
||||
selectionRanges.otherSelections[0] === 'y-axis'
|
||||
const isReferencingYAxisAngle =
|
||||
isReferencingYAxis && angleOrLength === 'setAngle'
|
||||
|
||||
const isReferencingXAxis =
|
||||
selectionRanges.otherSelections.length === 1 &&
|
||||
selectionRanges.otherSelections[0] === 'x-axis'
|
||||
const isReferencingXAxisAngle =
|
||||
isReferencingXAxis && angleOrLength === 'setAngle'
|
||||
|
||||
let forceVal = valueUsedInTransform || 0
|
||||
let calcIdentifier = createIdentifier('_0')
|
||||
if (isReferencingYAxisAngle) {
|
||||
calcIdentifier = createIdentifier(forceVal < 0 ? '_270' : '_90')
|
||||
forceVal = normaliseAngle(forceVal + (forceVal < 0 ? 90 : -90))
|
||||
} else if (isReferencingXAxisAngle) {
|
||||
calcIdentifier = createIdentifier(
|
||||
Math.abs(forceVal) > 90 ? '_180' : '_0'
|
||||
)
|
||||
forceVal =
|
||||
Math.abs(forceVal) > 90
|
||||
? normaliseAngle(forceVal - 180)
|
||||
: forceVal
|
||||
}
|
||||
const { valueNode, variableName, newVariableInsertIndex, sign } =
|
||||
await getModalInfo({
|
||||
value: forceVal,
|
||||
valueName: angleOrLength === 'setAngle' ? 'angle' : 'length',
|
||||
shouldCreateVariable: true,
|
||||
} as any)
|
||||
let finalValue = removeDoubleNegatives(valueNode, sign, variableName)
|
||||
if (
|
||||
isReferencingYAxisAngle ||
|
||||
(isReferencingXAxisAngle && calcIdentifier.name !== '_0')
|
||||
) {
|
||||
finalValue = createBinaryExpressionWithUnary([
|
||||
calcIdentifier,
|
||||
finalValue,
|
||||
])
|
||||
}
|
||||
|
||||
const { modifiedAst: _modifiedAst, pathToNodeMap } =
|
||||
transformAstSketchLines({
|
||||
ast: JSON.parse(JSON.stringify(kclManager.ast)),
|
||||
selectionRanges,
|
||||
transformInfos,
|
||||
programMemory: kclManager.programMemory,
|
||||
referenceSegName: '',
|
||||
forceValueUsedInTransform: finalValue,
|
||||
})
|
||||
if (variableName) {
|
||||
const newBody = [..._modifiedAst.body]
|
||||
newBody.splice(
|
||||
newVariableInsertIndex,
|
||||
0,
|
||||
createVariableDeclaration(variableName, valueNode)
|
||||
)
|
||||
_modifiedAst.body = newBody
|
||||
}
|
||||
|
||||
kclManager.updateAst(_modifiedAst, true, {
|
||||
callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
})
|
||||
} catch (e) {
|
||||
console.log('erorr', e)
|
||||
}
|
||||
}}
|
||||
disabled={!enableAngLen}
|
||||
title={buttonLabels[angleOrLength]}
|
||||
>
|
||||
{buttonLabels[angleOrLength]}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
*/
|
||||
const getModalInfo = createSetAngleLengthModal(SetAngleLengthModal)
|
||||
|
||||
export function setAngleLengthInfo({
|
||||
selectionRanges,
|
||||
@ -220,8 +99,13 @@ export async function applyConstraintAngleLength({
|
||||
value: forceVal,
|
||||
valueName: angleOrLength === 'setAngle' ? 'angle' : 'length',
|
||||
shouldCreateVariable: true,
|
||||
} as any)
|
||||
let finalValue = removeDoubleNegatives(valueNode, sign, variableName)
|
||||
})
|
||||
|
||||
let finalValue = removeDoubleNegatives(
|
||||
valueNode as BinaryPart,
|
||||
sign,
|
||||
variableName
|
||||
)
|
||||
if (
|
||||
isReferencingYAxisAngle ||
|
||||
(isReferencingXAxisAngle && calcIdentifier.name !== '_0')
|
||||
@ -251,9 +135,6 @@ export async function applyConstraintAngleLength({
|
||||
modifiedAst: _modifiedAst,
|
||||
pathToNodeMap,
|
||||
}
|
||||
// kclManager.updateAst(_modifiedAst, true, {
|
||||
// callBack: updateCursors(setCursor, selectionRanges, pathToNodeMap),
|
||||
// })
|
||||
} catch (e) {
|
||||
console.log('erorr', e)
|
||||
throw e
|
||||
|
Reference in New Issue
Block a user