Fixing up edit flows for transforms, and WIP for simpler feature tree action
This commit is contained in:
@ -24,7 +24,12 @@ import {
|
||||
getOperationVariableName,
|
||||
stdLibMap,
|
||||
} from '@src/lib/operations'
|
||||
import { editorManager, kclManager, rustContext } from '@src/lib/singletons'
|
||||
import {
|
||||
commandBarActor,
|
||||
editorManager,
|
||||
kclManager,
|
||||
rustContext,
|
||||
} from '@src/lib/singletons'
|
||||
import {
|
||||
featureTreeMachine,
|
||||
featureTreeMachineDefaultContext,
|
||||
@ -59,6 +64,15 @@ export const FeatureTreePane = () => {
|
||||
scrollToError: () => {
|
||||
editorManager.scrollToFirstErrorDiagnosticIfExists()
|
||||
},
|
||||
sendTranslateCommand: ({ context }) => {
|
||||
commandBarActor.send({
|
||||
type: 'Find and select command',
|
||||
data: {
|
||||
name: 'Translate',
|
||||
groupId: 'modeling',
|
||||
},
|
||||
})
|
||||
},
|
||||
sendSelectionEvent: ({ context }) => {
|
||||
if (!context.targetSourceRange) {
|
||||
return
|
||||
@ -354,10 +368,6 @@ const OperationItem = (props: {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* For now we can only enter the "edit" flow for the startSketchOn operation.
|
||||
* TODO: https://github.com/KittyCAD/modeling-app/issues/4442
|
||||
*/
|
||||
function enterEditFlow() {
|
||||
if (
|
||||
props.item.type === 'StdLibCall' ||
|
||||
|
||||
@ -32,15 +32,17 @@ export function addTranslate({
|
||||
z,
|
||||
global,
|
||||
nodeToEdit,
|
||||
callName,
|
||||
}: {
|
||||
ast: Node<Program>
|
||||
artifactGraph: ArtifactGraph
|
||||
objects: Selections
|
||||
x: KclCommandValue
|
||||
y: KclCommandValue
|
||||
z: KclCommandValue
|
||||
x?: KclCommandValue
|
||||
y?: KclCommandValue
|
||||
z?: KclCommandValue
|
||||
global?: boolean
|
||||
nodeToEdit?: PathToNode
|
||||
callName?: string
|
||||
}): Error | { modifiedAst: Node<Program>; pathToNode: PathToNode } {
|
||||
// 1. Clone the ast so we can edit it
|
||||
const modifiedAst = structuredClone(ast)
|
||||
@ -58,26 +60,28 @@ export function addTranslate({
|
||||
return variableExpressions
|
||||
}
|
||||
|
||||
// Extra labeled args expression
|
||||
const xExpr = x ? [createLabeledArg('x', valueOrVariable(x))] : []
|
||||
const yExpr = y ? [createLabeledArg('y', valueOrVariable(y))] : []
|
||||
const zExpr = z ? [createLabeledArg('z', valueOrVariable(z))] : []
|
||||
const globalExpr = global
|
||||
? [createLabeledArg('global', createLiteral(global))]
|
||||
: []
|
||||
|
||||
const objectsExpr = createVariableExpressionsArray(variableExpressions.exprs)
|
||||
const call = createCallExpressionStdLibKw('translate', objectsExpr, [
|
||||
createLabeledArg('x', valueOrVariable(x)),
|
||||
createLabeledArg('y', valueOrVariable(y)),
|
||||
createLabeledArg('z', valueOrVariable(z)),
|
||||
...globalExpr,
|
||||
])
|
||||
const call = createCallExpressionStdLibKw(
|
||||
callName ?? 'translate',
|
||||
objectsExpr,
|
||||
[...xExpr, ...yExpr, ...zExpr, ...globalExpr]
|
||||
)
|
||||
|
||||
// Insert variables for labeled arguments if provided
|
||||
if ('variableName' in x && x.variableName) {
|
||||
if (x && 'variableName' in x && x.variableName) {
|
||||
insertVariableAndOffsetPathToNode(x, modifiedAst, nodeToEdit)
|
||||
}
|
||||
if ('variableName' in y && y.variableName) {
|
||||
if (y && 'variableName' in y && y.variableName) {
|
||||
insertVariableAndOffsetPathToNode(y, modifiedAst, nodeToEdit)
|
||||
}
|
||||
if ('variableName' in z && z.variableName) {
|
||||
if (z && 'variableName' in z && z.variableName) {
|
||||
insertVariableAndOffsetPathToNode(z, modifiedAst, nodeToEdit)
|
||||
}
|
||||
|
||||
@ -108,9 +112,9 @@ export function addRotate({
|
||||
ast: Node<Program>
|
||||
artifactGraph: ArtifactGraph
|
||||
objects: Selections
|
||||
roll: KclCommandValue
|
||||
pitch: KclCommandValue
|
||||
yaw: KclCommandValue
|
||||
roll?: KclCommandValue
|
||||
pitch?: KclCommandValue
|
||||
yaw?: KclCommandValue
|
||||
global?: boolean
|
||||
nodeToEdit?: PathToNode
|
||||
}): Error | { modifiedAst: Node<Program>; pathToNode: PathToNode } {
|
||||
@ -130,27 +134,32 @@ export function addRotate({
|
||||
return variableExpressions
|
||||
}
|
||||
|
||||
// Extra labeled args expression
|
||||
const rollExpr = roll ? [createLabeledArg('roll', valueOrVariable(roll))] : []
|
||||
const pitchExpr = pitch
|
||||
? [createLabeledArg('pitch', valueOrVariable(pitch))]
|
||||
: []
|
||||
const yawExpr = yaw ? [createLabeledArg('yaw', valueOrVariable(yaw))] : []
|
||||
const globalExpr = global
|
||||
? [createLabeledArg('global', createLiteral(global))]
|
||||
: []
|
||||
|
||||
const objectsExpr = createVariableExpressionsArray(variableExpressions.exprs)
|
||||
const call = createCallExpressionStdLibKw('rotate', objectsExpr, [
|
||||
createLabeledArg('roll', valueOrVariable(roll)),
|
||||
createLabeledArg('pitch', valueOrVariable(pitch)),
|
||||
createLabeledArg('yaw', valueOrVariable(yaw)),
|
||||
...rollExpr,
|
||||
...pitchExpr,
|
||||
...yawExpr,
|
||||
...globalExpr,
|
||||
])
|
||||
|
||||
// Insert variables for labeled arguments if provided
|
||||
if ('variableName' in roll && roll.variableName) {
|
||||
if (roll && 'variableName' in roll && roll.variableName) {
|
||||
insertVariableAndOffsetPathToNode(roll, modifiedAst, nodeToEdit)
|
||||
}
|
||||
if ('variableName' in roll && roll.variableName) {
|
||||
insertVariableAndOffsetPathToNode(roll, modifiedAst, nodeToEdit)
|
||||
if (pitch && 'variableName' in pitch && pitch.variableName) {
|
||||
insertVariableAndOffsetPathToNode(pitch, modifiedAst, nodeToEdit)
|
||||
}
|
||||
if ('variableName' in roll && roll.variableName) {
|
||||
insertVariableAndOffsetPathToNode(roll, modifiedAst, nodeToEdit)
|
||||
if (yaw && 'variableName' in yaw && yaw.variableName) {
|
||||
insertVariableAndOffsetPathToNode(yaw, modifiedAst, nodeToEdit)
|
||||
}
|
||||
|
||||
// 3. If edit, we assign the new function call declaration to the existing node,
|
||||
@ -180,63 +189,23 @@ export function addScale({
|
||||
ast: Node<Program>
|
||||
artifactGraph: ArtifactGraph
|
||||
objects: Selections
|
||||
x: KclCommandValue
|
||||
y: KclCommandValue
|
||||
z: KclCommandValue
|
||||
x?: KclCommandValue
|
||||
y?: KclCommandValue
|
||||
z?: KclCommandValue
|
||||
global?: boolean
|
||||
nodeToEdit?: PathToNode
|
||||
}): Error | { modifiedAst: Node<Program>; pathToNode: PathToNode } {
|
||||
// 1. Clone the ast so we can edit it
|
||||
const modifiedAst = structuredClone(ast)
|
||||
|
||||
// 2. Prepare unlabeled and labeled arguments
|
||||
// Map the sketches selection into a list of kcl expressions to be passed as unlabelled argument
|
||||
const variableExpressions = getVariableExprsFromSelection(
|
||||
return addTranslate({
|
||||
ast,
|
||||
artifactGraph,
|
||||
objects,
|
||||
modifiedAst,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
global,
|
||||
nodeToEdit,
|
||||
true,
|
||||
artifactGraph
|
||||
)
|
||||
if (err(variableExpressions)) {
|
||||
return variableExpressions
|
||||
}
|
||||
|
||||
// Extra labeled args expression
|
||||
const globalExpr = global
|
||||
? [createLabeledArg('global', createLiteral(global))]
|
||||
: []
|
||||
const objectsExpr = createVariableExpressionsArray(variableExpressions.exprs)
|
||||
const call = createCallExpressionStdLibKw('scale', objectsExpr, [
|
||||
createLabeledArg('x', valueOrVariable(x)),
|
||||
createLabeledArg('y', valueOrVariable(y)),
|
||||
createLabeledArg('z', valueOrVariable(z)),
|
||||
...globalExpr,
|
||||
])
|
||||
|
||||
// Insert variables for labeled arguments if provided
|
||||
if ('variableName' in x && x.variableName) {
|
||||
insertVariableAndOffsetPathToNode(x, modifiedAst, nodeToEdit)
|
||||
}
|
||||
if ('variableName' in y && y.variableName) {
|
||||
insertVariableAndOffsetPathToNode(y, modifiedAst, nodeToEdit)
|
||||
}
|
||||
if ('variableName' in z && z.variableName) {
|
||||
insertVariableAndOffsetPathToNode(z, modifiedAst, nodeToEdit)
|
||||
}
|
||||
|
||||
// 3. If edit, we assign the new function call declaration to the existing node,
|
||||
// otherwise just push to the end
|
||||
const lastPath = variableExpressions.paths.pop() // TODO: check if this is correct
|
||||
const pathToNode = setCallInAst(modifiedAst, call, nodeToEdit, lastPath)
|
||||
if (err(pathToNode)) {
|
||||
return pathToNode
|
||||
}
|
||||
|
||||
return {
|
||||
modifiedAst,
|
||||
pathToNode,
|
||||
}
|
||||
callName: 'scale',
|
||||
})
|
||||
}
|
||||
|
||||
export function retrievePathToNodeFromTransformSelection(
|
||||
|
||||
@ -187,25 +187,25 @@ export type ModelingCommandSchema = {
|
||||
Translate: {
|
||||
nodeToEdit?: PathToNode
|
||||
objects: Selections
|
||||
x: KclCommandValue
|
||||
y: KclCommandValue
|
||||
z: KclCommandValue
|
||||
x?: KclCommandValue
|
||||
y?: KclCommandValue
|
||||
z?: KclCommandValue
|
||||
global?: boolean
|
||||
}
|
||||
Rotate: {
|
||||
nodeToEdit?: PathToNode
|
||||
objects: Selections
|
||||
roll: KclCommandValue
|
||||
pitch: KclCommandValue
|
||||
yaw: KclCommandValue
|
||||
roll?: KclCommandValue
|
||||
pitch?: KclCommandValue
|
||||
yaw?: KclCommandValue
|
||||
global?: boolean
|
||||
}
|
||||
Scale: {
|
||||
nodeToEdit?: PathToNode
|
||||
objects: Selections
|
||||
x: KclCommandValue
|
||||
y: KclCommandValue
|
||||
z: KclCommandValue
|
||||
x?: KclCommandValue
|
||||
y?: KclCommandValue
|
||||
z?: KclCommandValue
|
||||
global?: boolean
|
||||
}
|
||||
Clone: {
|
||||
|
||||
@ -1524,28 +1524,22 @@ export async function enterAppearanceFlow({
|
||||
)
|
||||
}
|
||||
|
||||
async function prepareToEditTranslate({
|
||||
operation,
|
||||
artifact,
|
||||
}: EnterEditFlowProps) {
|
||||
async function prepareToEditTranslate({ operation }: EnterEditFlowProps) {
|
||||
const baseCommand = {
|
||||
name: 'Translate',
|
||||
groupId: 'modeling',
|
||||
}
|
||||
// const isModuleImport = operation.type === 'GroupBegin'
|
||||
// const isSupportedStdLibCall =
|
||||
// operation.type === 'StdLibCall' &&
|
||||
// stdLibMap[operation.name]?.supportsTransform
|
||||
// if (!isModuleImport && !isSupportedStdLibCall) {
|
||||
// return {
|
||||
// reason: 'Unsupported operation type. Please edit in the code editor.',
|
||||
// }
|
||||
// }
|
||||
if (operation.type !== 'StdLibCall') {
|
||||
return { reason: 'Wrong operation type' }
|
||||
const isModuleImport = operation.type === 'GroupBegin'
|
||||
const isSupportedStdLibCall =
|
||||
operation.type === 'StdLibCall' &&
|
||||
stdLibMap[operation.name]?.supportsTransform
|
||||
if (!isModuleImport && !isSupportedStdLibCall) {
|
||||
return {
|
||||
reason: 'Unsupported operation type. Please edit in the code editor.',
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Map the unlabeled arguments to solid2d selections
|
||||
// 1. Map the unlabeled arguments to selections
|
||||
const objects = getObjectSelectionsFromOperation(
|
||||
operation,
|
||||
kclManager.artifactGraph
|
||||
@ -1555,44 +1549,57 @@ async function prepareToEditTranslate({
|
||||
}
|
||||
|
||||
// 2. Convert the x y z arguments from a string to a KCL expression
|
||||
const x = await stringToKclExpression(
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.x?.sourceRange[0],
|
||||
operation.labeledArgs.x?.sourceRange[1]
|
||||
)
|
||||
)
|
||||
if (err(x) || 'errors' in x) {
|
||||
return { reason: "Couldn't retrieve x argument" }
|
||||
}
|
||||
|
||||
const y = await stringToKclExpression(
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.y?.sourceRange[0],
|
||||
operation.labeledArgs.y?.sourceRange[1]
|
||||
)
|
||||
)
|
||||
if (err(y) || 'errors' in y) {
|
||||
return { reason: "Couldn't retrieve y argument" }
|
||||
}
|
||||
|
||||
const z = await stringToKclExpression(
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.z?.sourceRange[0],
|
||||
operation.labeledArgs.z?.sourceRange[1]
|
||||
)
|
||||
)
|
||||
if (err(z) || 'errors' in z) {
|
||||
return { reason: "Couldn't retrieve z argument" }
|
||||
}
|
||||
|
||||
// symmetric argument from a string to boolean
|
||||
let x: KclCommandValue | undefined = undefined
|
||||
let y: KclCommandValue | undefined = undefined
|
||||
let z: KclCommandValue | undefined = undefined
|
||||
let global: boolean | undefined
|
||||
if ('global' in operation.labeledArgs && operation.labeledArgs.global) {
|
||||
global =
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.global.sourceRange[0],
|
||||
operation.labeledArgs.global.sourceRange[1]
|
||||
) === 'true'
|
||||
if (isSupportedStdLibCall) {
|
||||
if (operation.labeledArgs.x) {
|
||||
const result = await stringToKclExpression(
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.x.sourceRange[0],
|
||||
operation.labeledArgs.x.sourceRange[1]
|
||||
)
|
||||
)
|
||||
if (err(result) || 'errors' in result) {
|
||||
return { reason: "Couldn't retrieve x argument" }
|
||||
}
|
||||
x = result
|
||||
}
|
||||
|
||||
if (operation.labeledArgs.y) {
|
||||
const result = await stringToKclExpression(
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.y.sourceRange[0],
|
||||
operation.labeledArgs.y.sourceRange[1]
|
||||
)
|
||||
)
|
||||
if (err(result) || 'errors' in result) {
|
||||
return { reason: "Couldn't retrieve y argument" }
|
||||
}
|
||||
y = result
|
||||
}
|
||||
|
||||
if (operation.labeledArgs.z) {
|
||||
const result = await stringToKclExpression(
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.z.sourceRange[0],
|
||||
operation.labeledArgs.z.sourceRange[1]
|
||||
)
|
||||
)
|
||||
if (err(result) || 'errors' in result) {
|
||||
return { reason: "Couldn't retrieve z argument" }
|
||||
}
|
||||
z = result
|
||||
}
|
||||
|
||||
if (operation.labeledArgs.global) {
|
||||
global =
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.global.sourceRange[0],
|
||||
operation.labeledArgs.global.sourceRange[1]
|
||||
) === 'true'
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Assemble the default argument values for the command,
|
||||
@ -1641,49 +1648,80 @@ async function prepareToEditScale({ operation }: EnterEditFlowProps) {
|
||||
}
|
||||
}
|
||||
|
||||
const nodeToEdit = pathToNodeFromRustNodePath(operation.nodePath)
|
||||
let x: KclExpression | undefined = undefined
|
||||
let y: KclExpression | undefined = undefined
|
||||
let z: KclExpression | undefined = undefined
|
||||
let global: boolean | undefined
|
||||
const pipeLookupFromOperation = getNodeFromPath<PipeExpression>(
|
||||
kclManager.ast,
|
||||
nodeToEdit,
|
||||
'PipeExpression'
|
||||
// 1. Map the unlabeled arguments to selections
|
||||
const objects = getObjectSelectionsFromOperation(
|
||||
operation,
|
||||
kclManager.artifactGraph
|
||||
)
|
||||
let pipe: PipeExpression | undefined
|
||||
const ast = kclManager.ast
|
||||
if (
|
||||
err(pipeLookupFromOperation) ||
|
||||
pipeLookupFromOperation.node.type !== 'PipeExpression'
|
||||
) {
|
||||
// Look for the last pipe with the import alias and a call to scale
|
||||
const pipes = findPipesWithImportAlias(ast, nodeToEdit, 'scale')
|
||||
pipe = pipes.at(-1)?.expression
|
||||
} else {
|
||||
pipe = pipeLookupFromOperation.node
|
||||
if (err(objects)) {
|
||||
return { reason: "Couldn't retrieve objects" }
|
||||
}
|
||||
|
||||
if (pipe) {
|
||||
const scale = pipe.body.find(
|
||||
(n) => n.type === 'CallExpressionKw' && n.callee.name.name === 'scale'
|
||||
)
|
||||
if (scale?.type === 'CallExpressionKw') {
|
||||
x = await retrieveArgFromPipedCallExpression(scale, 'x')
|
||||
y = await retrieveArgFromPipedCallExpression(scale, 'y')
|
||||
z = await retrieveArgFromPipedCallExpression(scale, 'z')
|
||||
|
||||
// optional global argument
|
||||
const result = await retrieveArgFromPipedCallExpression(scale, 'global')
|
||||
if (result) {
|
||||
global = result.valueText === 'true'
|
||||
// 2. Convert the x y z arguments from a string to a KCL expression
|
||||
let x: KclCommandValue | undefined = undefined
|
||||
let y: KclCommandValue | undefined = undefined
|
||||
let z: KclCommandValue | undefined = undefined
|
||||
let global: boolean | undefined
|
||||
if (isSupportedStdLibCall) {
|
||||
if (operation.labeledArgs.x) {
|
||||
const result = await stringToKclExpression(
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.x.sourceRange[0],
|
||||
operation.labeledArgs.x.sourceRange[1]
|
||||
)
|
||||
)
|
||||
if (err(result) || 'errors' in result) {
|
||||
return { reason: "Couldn't retrieve x argument" }
|
||||
}
|
||||
x = result
|
||||
}
|
||||
|
||||
if (operation.labeledArgs.y) {
|
||||
const result = await stringToKclExpression(
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.y.sourceRange[0],
|
||||
operation.labeledArgs.y.sourceRange[1]
|
||||
)
|
||||
)
|
||||
if (err(result) || 'errors' in result) {
|
||||
return { reason: "Couldn't retrieve y argument" }
|
||||
}
|
||||
y = result
|
||||
}
|
||||
|
||||
if (operation.labeledArgs.z) {
|
||||
const result = await stringToKclExpression(
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.z.sourceRange[0],
|
||||
operation.labeledArgs.z.sourceRange[1]
|
||||
)
|
||||
)
|
||||
if (err(result) || 'errors' in result) {
|
||||
return { reason: "Couldn't retrieve z argument" }
|
||||
}
|
||||
z = result
|
||||
}
|
||||
|
||||
if (operation.labeledArgs.global) {
|
||||
global =
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.global.sourceRange[0],
|
||||
operation.labeledArgs.global.sourceRange[1]
|
||||
) === 'true'
|
||||
}
|
||||
}
|
||||
|
||||
// Won't be used since we provide nodeToEdit
|
||||
const selection: Selections = { graphSelections: [], otherSelections: [] }
|
||||
const argDefaultValues = { nodeToEdit, selection, x, y, z, global }
|
||||
// 3. Assemble the default argument values for the command,
|
||||
// with `nodeToEdit` set, which will let the actor know
|
||||
// to edit the node that corresponds to the StdLibCall.
|
||||
const argDefaultValues: ModelingCommandSchema['Scale'] = {
|
||||
objects,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
global,
|
||||
nodeToEdit: pathToNodeFromRustNodePath(operation.nodePath),
|
||||
}
|
||||
return {
|
||||
...baseCommand,
|
||||
argDefaultValues,
|
||||
@ -1719,42 +1757,80 @@ async function prepareToEditRotate({ operation }: EnterEditFlowProps) {
|
||||
}
|
||||
}
|
||||
|
||||
const nodeToEdit = pathToNodeFromRustNodePath(operation.nodePath)
|
||||
let roll: KclExpression | undefined = undefined
|
||||
let pitch: KclExpression | undefined = undefined
|
||||
let yaw: KclExpression | undefined = undefined
|
||||
const pipeLookupFromOperation = getNodeFromPath<PipeExpression>(
|
||||
kclManager.ast,
|
||||
nodeToEdit,
|
||||
'PipeExpression'
|
||||
// 1. Map the unlabeled arguments to selections
|
||||
const objects = getObjectSelectionsFromOperation(
|
||||
operation,
|
||||
kclManager.artifactGraph
|
||||
)
|
||||
let pipe: PipeExpression | undefined
|
||||
const ast = kclManager.ast
|
||||
if (
|
||||
err(pipeLookupFromOperation) ||
|
||||
pipeLookupFromOperation.node.type !== 'PipeExpression'
|
||||
) {
|
||||
// Look for the last pipe with the import alias and a call to rotate
|
||||
const pipes = findPipesWithImportAlias(ast, nodeToEdit, 'rotate')
|
||||
pipe = pipes.at(-1)?.expression
|
||||
} else {
|
||||
pipe = pipeLookupFromOperation.node
|
||||
if (err(objects)) {
|
||||
return { reason: "Couldn't retrieve objects" }
|
||||
}
|
||||
|
||||
if (pipe) {
|
||||
const rotate = pipe.body.find(
|
||||
(n) => n.type === 'CallExpressionKw' && n.callee.name.name === 'rotate'
|
||||
)
|
||||
if (rotate?.type === 'CallExpressionKw') {
|
||||
roll = await retrieveArgFromPipedCallExpression(rotate, 'roll')
|
||||
pitch = await retrieveArgFromPipedCallExpression(rotate, 'pitch')
|
||||
yaw = await retrieveArgFromPipedCallExpression(rotate, 'yaw')
|
||||
// 2. Convert the x y z arguments from a string to a KCL expression
|
||||
let roll: KclCommandValue | undefined = undefined
|
||||
let pitch: KclCommandValue | undefined = undefined
|
||||
let yaw: KclCommandValue | undefined = undefined
|
||||
let global: boolean | undefined
|
||||
if (isSupportedStdLibCall) {
|
||||
if (operation.labeledArgs.roll) {
|
||||
const result = await stringToKclExpression(
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.roll.sourceRange[0],
|
||||
operation.labeledArgs.roll.sourceRange[1]
|
||||
)
|
||||
)
|
||||
if (err(result) || 'errors' in result) {
|
||||
return { reason: "Couldn't retrieve roll argument" }
|
||||
}
|
||||
roll = result
|
||||
}
|
||||
|
||||
if (operation.labeledArgs.pitch) {
|
||||
const result = await stringToKclExpression(
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.pitch.sourceRange[0],
|
||||
operation.labeledArgs.pitch.sourceRange[1]
|
||||
)
|
||||
)
|
||||
if (err(result) || 'errors' in result) {
|
||||
return { reason: "Couldn't retrieve pitch argument" }
|
||||
}
|
||||
pitch = result
|
||||
}
|
||||
|
||||
if (operation.labeledArgs.yaw) {
|
||||
const result = await stringToKclExpression(
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.yaw.sourceRange[0],
|
||||
operation.labeledArgs.yaw.sourceRange[1]
|
||||
)
|
||||
)
|
||||
if (err(result) || 'errors' in result) {
|
||||
return { reason: "Couldn't retrieve yaw argument" }
|
||||
}
|
||||
yaw = result
|
||||
}
|
||||
|
||||
if (operation.labeledArgs.global) {
|
||||
global =
|
||||
codeManager.code.slice(
|
||||
operation.labeledArgs.global.sourceRange[0],
|
||||
operation.labeledArgs.global.sourceRange[1]
|
||||
) === 'true'
|
||||
}
|
||||
}
|
||||
|
||||
// Won't be used since we provide nodeToEdit
|
||||
const selection: Selections = { graphSelections: [], otherSelections: [] }
|
||||
const argDefaultValues = { nodeToEdit, selection, roll, pitch, yaw }
|
||||
// 3. Assemble the default argument values for the command,
|
||||
// with `nodeToEdit` set, which will let the actor know
|
||||
// to edit the node that corresponds to the StdLibCall.
|
||||
const argDefaultValues: ModelingCommandSchema['Rotate'] = {
|
||||
objects,
|
||||
roll,
|
||||
pitch,
|
||||
yaw,
|
||||
global,
|
||||
nodeToEdit: pathToNodeFromRustNodePath(operation.nodePath),
|
||||
}
|
||||
return {
|
||||
...baseCommand,
|
||||
argDefaultValues,
|
||||
|
||||
@ -280,6 +280,7 @@ export const featureTreeMachine = setup({
|
||||
targetSourceRange: undefined,
|
||||
}),
|
||||
sendSelectionEvent: () => {},
|
||||
sendTranslateCommand: () => {},
|
||||
openCodePane: () => {},
|
||||
scrollToError: () => {},
|
||||
},
|
||||
@ -312,8 +313,12 @@ export const featureTreeMachine = setup({
|
||||
},
|
||||
|
||||
enterTranslateFlow: {
|
||||
target: 'enteringTranslateFlow',
|
||||
actions: ['saveTargetSourceRange', 'saveCurrentOperation'],
|
||||
target: 'enteringTranslateFlow2',
|
||||
actions: [
|
||||
'saveTargetSourceRange',
|
||||
'saveCurrentOperation',
|
||||
'sendSelectionEvent',
|
||||
],
|
||||
},
|
||||
|
||||
enterRotateFlow: {
|
||||
@ -388,6 +393,25 @@ export const featureTreeMachine = setup({
|
||||
initial: 'selecting',
|
||||
},
|
||||
|
||||
enteringTranslateFlow2: {
|
||||
states: {
|
||||
enteringTranslateFlow2: {
|
||||
on: {
|
||||
selected: 'done',
|
||||
},
|
||||
|
||||
entry: 'sendTranslateCommand',
|
||||
},
|
||||
|
||||
done: {
|
||||
always: '#featureTree.idle',
|
||||
entry: 'clearContext',
|
||||
},
|
||||
},
|
||||
|
||||
initial: 'enteringTranslateFlow2',
|
||||
},
|
||||
|
||||
enteringEditFlow: {
|
||||
states: {
|
||||
selecting: {
|
||||
|
||||
Reference in New Issue
Block a user