Symbols overlay (#2033)
* start of overlay work
* add new icons
* add constraint symbols
* add three dots
* add primary colours
* refactor how we get constraint info for overlays
* refactor how we get constraint info for overlays
* get symbols working for tangential arc too
* extra data on constraint info
* add initial delete
* fix types and circular dep issue after rebase
* fix quirk with horz vert line overlays
* fix setup and tear down of overlays
* remove overlays that are too small
* throttle overlay updates and prove tests selecting html instead of hardcoded px coords
* initial show overaly on segment hover
* remove overlays when tool is equipped
* dounce overlay updates
* tsc
* make higlighting robust to small changes in source ranges
* replace with variable for unconstrained values, and improve styles for popover
* background tweak
* make overlays unconstrain inputs
* fix small regression
* write query for finding related tag references
* make delete segment safe
* typo
* un used imports
* test deleteSegmentFromPipeExpression
* add getConstraintInfo test
* test removeSingleConstraintInfo
* more tests
* tsc
* add tests for overlay buttons
* rename tests
* fmt
* better naming structure
* more reliablity
* more test tweaks
* fix selection test
* add delete segments with overlays tests
* dependant tag tests for segment delet
* typo
* test clean up
* fix some perf issus
* clean up
* clean up
* make things a little more dry
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* trigger ci
* Make constraint hover popovers readable on light mode
* Touch up the new variable dialog
* Little touch-up to three-dot menu style
* fix highlight issue
* fmt
* use optional chain
* Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)"
This reverts commit be3d61e4a3
.
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* disable var panel in sketch mode
* fix overlay tests after mergi in main
* test tweak
* try fix ubuntu
* fmt
* more test tweaks
* tweak
* tweaks
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Frank Noirot <frank@kittycad.io>
This commit is contained in:
@ -15,17 +15,26 @@ import {
|
||||
BinaryExpression,
|
||||
PathToNode,
|
||||
ProgramMemory,
|
||||
SourceRange,
|
||||
} from './wasm'
|
||||
import {
|
||||
isNodeSafeToReplacePath,
|
||||
findAllPreviousVariables,
|
||||
findAllPreviousVariablesPath,
|
||||
getNodeFromPath,
|
||||
getNodePathFromSourceRange,
|
||||
isNodeSafeToReplace,
|
||||
} from './queryAst'
|
||||
import { addTagForSketchOnFace } from './std/sketch'
|
||||
import { isLiteralArrayOrStatic } from './std/sketchcombos'
|
||||
import { addTagForSketchOnFace, getConstraintInfo } from './std/sketch'
|
||||
import {
|
||||
PathToNodeMap,
|
||||
isLiteralArrayOrStatic,
|
||||
removeSingleConstraint,
|
||||
transformAstSketchLines,
|
||||
} from './std/sketchcombos'
|
||||
import { DefaultPlaneStr } from 'clientSideScene/sceneEntities'
|
||||
import { roundOff } from 'lib/utils'
|
||||
import { isOverlap, roundOff } from 'lib/utils'
|
||||
import { ConstrainInfo } from './std/stdTypes'
|
||||
|
||||
export function startSketchOnDefault(
|
||||
node: Program,
|
||||
@ -241,11 +250,7 @@ export function extrudeSketch(
|
||||
pathToExtrudeArg: PathToNode
|
||||
} {
|
||||
const _node = { ...node }
|
||||
const { node: sketchExpression } = getNodeFromPath(
|
||||
_node,
|
||||
pathToNode,
|
||||
'SketchExpression' // TODO fix this #25
|
||||
)
|
||||
const { node: sketchExpression } = getNodeFromPath(_node, pathToNode)
|
||||
|
||||
// determine if sketchExpression is in a pipeExpression or not
|
||||
const { node: pipeExpression } = getNodeFromPath<PipeExpression>(
|
||||
@ -619,6 +624,34 @@ export function giveSketchFnCallTag(
|
||||
}
|
||||
}
|
||||
|
||||
export function moveValueIntoNewVariablePath(
|
||||
ast: Program,
|
||||
programMemory: ProgramMemory,
|
||||
pathToNode: PathToNode,
|
||||
variableName: string
|
||||
): {
|
||||
modifiedAst: Program
|
||||
pathToReplacedNode?: PathToNode
|
||||
} {
|
||||
const { isSafe, value, replacer } = isNodeSafeToReplacePath(ast, pathToNode)
|
||||
if (!isSafe || value.type === 'Identifier') return { modifiedAst: ast }
|
||||
|
||||
const { insertIndex } = findAllPreviousVariablesPath(
|
||||
ast,
|
||||
programMemory,
|
||||
pathToNode
|
||||
)
|
||||
let _node = JSON.parse(JSON.stringify(ast))
|
||||
const boop = replacer(_node, variableName)
|
||||
_node = boop.modifiedAst
|
||||
_node.body.splice(
|
||||
insertIndex,
|
||||
0,
|
||||
createVariableDeclaration(variableName, value)
|
||||
)
|
||||
return { modifiedAst: _node, pathToReplacedNode: boop.pathToReplaced }
|
||||
}
|
||||
|
||||
export function moveValueIntoNewVariable(
|
||||
ast: Program,
|
||||
programMemory: ProgramMemory,
|
||||
@ -626,6 +659,7 @@ export function moveValueIntoNewVariable(
|
||||
variableName: string
|
||||
): {
|
||||
modifiedAst: Program
|
||||
pathToReplacedNode?: PathToNode
|
||||
} {
|
||||
const { isSafe, value, replacer } = isNodeSafeToReplace(ast, sourceRange)
|
||||
if (!isSafe || value.type === 'Identifier') return { modifiedAst: ast }
|
||||
@ -636,11 +670,124 @@ export function moveValueIntoNewVariable(
|
||||
sourceRange
|
||||
)
|
||||
let _node = JSON.parse(JSON.stringify(ast))
|
||||
_node = replacer(_node, variableName).modifiedAst
|
||||
const { modifiedAst, pathToReplaced } = replacer(_node, variableName)
|
||||
_node = modifiedAst
|
||||
_node.body.splice(
|
||||
insertIndex,
|
||||
0,
|
||||
createVariableDeclaration(variableName, value)
|
||||
)
|
||||
return { modifiedAst: _node }
|
||||
return { modifiedAst: _node, pathToReplacedNode: pathToReplaced }
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a segment from a pipe expression, if the segment has a tag that other segments use, it will remove that value and replace it with the equivalent literal
|
||||
* @param dependentRanges - The ranges of the segments that are dependent on the segment being deleted, this is usually the output of `findUsesOfTagInPipe`
|
||||
*/
|
||||
export function deleteSegmentFromPipeExpression(
|
||||
dependentRanges: SourceRange[],
|
||||
modifiedAst: Program,
|
||||
programMemory: ProgramMemory,
|
||||
code: string,
|
||||
pathToNode: PathToNode
|
||||
): Program {
|
||||
let _modifiedAst: Program = JSON.parse(JSON.stringify(modifiedAst))
|
||||
|
||||
dependentRanges.forEach((range) => {
|
||||
const path = getNodePathFromSourceRange(_modifiedAst, range)
|
||||
|
||||
const callExp = getNodeFromPath<CallExpression>(
|
||||
_modifiedAst,
|
||||
path,
|
||||
'CallExpression',
|
||||
true
|
||||
)
|
||||
const constraintInfo = getConstraintInfo(callExp.node, code, path).find(
|
||||
({ sourceRange }) => isOverlap(sourceRange, range)
|
||||
)
|
||||
if (!constraintInfo) return
|
||||
const input = makeRemoveSingleConstraintInput(
|
||||
constraintInfo.argPosition,
|
||||
callExp.shallowPath
|
||||
)
|
||||
if (!input) return
|
||||
const transform = removeSingleConstraintInfo(
|
||||
{
|
||||
...input,
|
||||
},
|
||||
_modifiedAst,
|
||||
programMemory
|
||||
)
|
||||
if (!transform) return
|
||||
_modifiedAst = transform.modifiedAst
|
||||
})
|
||||
|
||||
const pipeExpression = getNodeFromPath<PipeExpression>(
|
||||
_modifiedAst,
|
||||
pathToNode,
|
||||
'PipeExpression'
|
||||
).node
|
||||
|
||||
const pipeInPathIndex = pathToNode.findIndex(
|
||||
([_, desc]) => desc === 'PipeExpression'
|
||||
)
|
||||
const segmentIndexInPipe = pathToNode[pipeInPathIndex + 1][0] as number
|
||||
pipeExpression.body.splice(segmentIndexInPipe, 1)
|
||||
|
||||
return _modifiedAst
|
||||
}
|
||||
|
||||
export function makeRemoveSingleConstraintInput(
|
||||
argPosition: ConstrainInfo['argPosition'],
|
||||
pathToNode: PathToNode
|
||||
): Parameters<typeof removeSingleConstraintInfo>[0] | false {
|
||||
return argPosition?.type === 'singleValue'
|
||||
? {
|
||||
pathToCallExp: pathToNode,
|
||||
}
|
||||
: argPosition?.type === 'arrayItem'
|
||||
? {
|
||||
pathToCallExp: pathToNode,
|
||||
arrayIndex: argPosition.index,
|
||||
}
|
||||
: argPosition?.type === 'objectProperty'
|
||||
? {
|
||||
pathToCallExp: pathToNode,
|
||||
objectProperty: argPosition.key,
|
||||
}
|
||||
: false
|
||||
}
|
||||
|
||||
export function removeSingleConstraintInfo(
|
||||
{
|
||||
pathToCallExp,
|
||||
arrayIndex,
|
||||
objectProperty,
|
||||
}: {
|
||||
pathToCallExp: PathToNode
|
||||
arrayIndex?: number
|
||||
objectProperty?: string
|
||||
},
|
||||
ast: Program,
|
||||
programMemory: ProgramMemory
|
||||
):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
pathToNodeMap: PathToNodeMap
|
||||
}
|
||||
| false {
|
||||
const transform = removeSingleConstraint({
|
||||
pathToCallExp,
|
||||
arrayIndex,
|
||||
objectProperty,
|
||||
ast,
|
||||
})
|
||||
if (!transform) return false
|
||||
return transformAstSketchLines({
|
||||
ast,
|
||||
selectionRanges: [pathToCallExp],
|
||||
transformInfos: [transform],
|
||||
programMemory,
|
||||
referenceSegName: '',
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user