Files
modeling-app/src/lang/util.ts
Kevin Nadro 14ba66378d Nadro/adhoc/center rectangle (#4480)
* fix: big commit, doing this to save work then do a PR cleanup; center rectangle

* fix: making a center function for each scenario

* fix: reverting the update rectangle code since I have a center rectangle one

* fix: does not allow seletcing circle or rectangle tool while selecting a face

* chore: adding comment to better read the HTML

* fix: cleaning up for PR

* fix: pushing broken code for someone to checkout

* fix: fixed the typescript issues, removed the as keyword for my center rectangle expressions

* fix: removing comment

* fix: removed as for type narrowing checks
2024-11-18 09:04:09 -06:00

110 lines
3.0 KiB
TypeScript

import { Selections } from 'lib/selections'
import {
Program,
PathToNode,
CallExpression,
Literal,
ArrayExpression,
BinaryExpression,
} from './wasm'
import { getNodeFromPath } from './queryAst'
import { ArtifactGraph, filterArtifacts } from 'lang/std/artifactGraph'
import { isOverlap } from 'lib/utils'
import { err } from 'lib/trap'
export function pathMapToSelections(
ast: Program,
prevSelections: Selections,
pathToNodeMap: { [key: number]: PathToNode }
): Selections {
const newSelections: Selections = {
...prevSelections,
codeBasedSelections: [],
}
Object.entries(pathToNodeMap).forEach(([index, path]) => {
const nodeMeta = getNodeFromPath<any>(ast, path)
if (err(nodeMeta)) return
const node = nodeMeta.node as any
const selection = prevSelections.codeBasedSelections[Number(index)]
if (node) {
if (
selection.type === 'base-edgeCut' ||
selection.type === 'adjacent-edgeCut' ||
selection.type === 'opposite-edgeCut'
) {
newSelections.codeBasedSelections.push({
range: [node.start, node.end],
type: selection.type,
secondaryRange: selection.secondaryRange,
})
} else {
newSelections.codeBasedSelections.push({
range: [node.start, node.end],
type: selection.type,
})
}
}
})
return newSelections
}
export function updatePathToNodeFromMap(
oldPath: PathToNode,
pathToNodeMap: { [key: number]: PathToNode }
): PathToNode {
const updatedPathToNode = structuredClone(oldPath)
let max = 0
Object.values(pathToNodeMap).forEach((path) => {
const index = Number(path[1][0])
if (index > max) {
max = index
}
})
updatedPathToNode[1][0] = max
return updatedPathToNode
}
export function isCursorInSketchCommandRange(
artifactGraph: ArtifactGraph,
selectionRanges: Selections
): string | false {
const overlappingEntries = filterArtifacts(
{
types: ['segment', 'path'],
predicate: (artifact) => {
return selectionRanges.codeBasedSelections.some(
(selection) =>
Array.isArray(selection?.range) &&
Array.isArray(artifact?.codeRef?.range) &&
isOverlap(selection.range, artifact.codeRef.range)
)
},
},
artifactGraph
)
const firstEntry = [...overlappingEntries.values()]?.[0]
const parentId = firstEntry?.type === 'segment' ? firstEntry.pathId : false
return parentId
? parentId
: [...overlappingEntries].find(
([, artifact]) => artifact.type === 'path'
)?.[0] || false
}
export function isCallExpression(e: any): e is CallExpression {
return e && e.type === 'CallExpression'
}
export function isArrayExpression(e: any): e is ArrayExpression {
return e && e.type === 'ArrayExpression'
}
export function isLiteral(e: any): e is Literal {
return e && e.type === 'Literal'
}
export function isBinaryExpression(e: any): e is BinaryExpression {
return e && e.type === 'BinaryExpression'
}