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:
Kurt Hutten
2024-05-24 20:54:42 +10:00
committed by GitHub
parent 87c551b869
commit cf52e151fb
28 changed files with 4359 additions and 216 deletions

View File

@ -18,6 +18,7 @@ import {
engineCommandManager,
codeManager,
editorManager,
sceneEntitiesManager,
} from 'lib/singletons'
import { applyConstraintHorzVertDistance } from './Toolbar/SetHorzVertDistance'
import {
@ -39,11 +40,24 @@ import { applyConstraintAbsDistance } from './Toolbar/SetAbsDistance'
import useStateMachineCommands from 'hooks/useStateMachineCommands'
import { modelingMachineConfig } from 'lib/commandBarConfigs/modelingCommandConfig'
import {
STRAIGHT_SEGMENT,
TANGENTIAL_ARC_TO_SEGMENT,
getParentGroup,
getSketchOrientationDetails,
getSketchQuaternion,
} from 'clientSideScene/sceneEntities'
import { sketchOnExtrudedFace, startSketchOnDefault } from 'lang/modifyAst'
import { Program, VariableDeclaration, coreDump } from 'lang/wasm'
import {
moveValueIntoNewVariablePath,
sketchOnExtrudedFace,
startSketchOnDefault,
} from 'lang/modifyAst'
import {
Program,
VariableDeclaration,
coreDump,
parse,
recast,
} from 'lang/wasm'
import {
getNodeFromPath,
getNodePathFromSourceRange,
@ -57,6 +71,7 @@ import { EditorSelection } from '@uiw/react-codemirror'
import { CoreDumpManager } from 'lib/coredump'
import { useSearchParams } from 'react-router-dom'
import { letEngineAnimateAndSyncCamAfter } from 'clientSideScene/CameraControls'
import { getVarNameModal } from 'hooks/useToolbarGuards'
import useHotkeyWrapper from 'lib/hotkeyWrapper'
type MachineContext<T extends AnyStateMachine> = {
@ -127,7 +142,82 @@ export const ModelingMachineProvider = ({
},
'Set mouse state': assign({
mouseState: (_, event) => event.data,
segmentHoverMap: ({ mouseState, segmentHoverMap }, event) => {
if (event.data.type === 'isHovering') {
const parent = getParentGroup(event.data.on, [
STRAIGHT_SEGMENT,
TANGENTIAL_ARC_TO_SEGMENT,
])
const pathToNode = parent?.userData?.pathToNode
const pathToNodeString = JSON.stringify(pathToNode)
if (!parent || !pathToNode) return {}
if (segmentHoverMap[pathToNodeString] !== undefined)
clearTimeout(segmentHoverMap[JSON.stringify(pathToNode)])
return {
...segmentHoverMap,
[pathToNodeString]: 0,
}
} else if (
event.data.type === 'idle' &&
mouseState.type === 'isHovering'
) {
const mouseOnParent = getParentGroup(mouseState.on, [
STRAIGHT_SEGMENT,
TANGENTIAL_ARC_TO_SEGMENT,
])
if (!mouseOnParent || !mouseOnParent?.userData?.pathToNode)
return segmentHoverMap
const pathToNodeString = JSON.stringify(
mouseOnParent?.userData?.pathToNode
)
const timeoutId = setTimeout(() => {
sceneInfra.modelingSend({
type: 'Set mouse state',
data: {
type: 'timeoutEnd',
pathToNodeString,
},
})
}, 800) as unknown as number
return {
...segmentHoverMap,
[pathToNodeString]: timeoutId,
}
} else if (event.data.type === 'timeoutEnd') {
const copy = { ...segmentHoverMap }
delete copy[event.data.pathToNodeString]
return copy
}
return {}
},
}),
'Set Segment Overlays': assign({
segmentOverlays: ({ segmentOverlays }, { data }) => {
if (data.type === 'set-many') return data.overlays
if (data.type === 'set-one')
return {
...segmentOverlays,
[data.pathToNodeString]: data.seg,
}
if (data.type === 'delete-one') {
const copy = { ...segmentOverlays }
delete copy[data.pathToNodeString]
return copy
}
// data.type === 'clear'
return {}
},
}),
'Set sketchDetails': assign(({ sketchDetails }, event) =>
sketchDetails
? {
sketchDetails: {
...sketchDetails,
sketchPathToNode: event.data,
},
}
: {}
),
'Set selection': assign(({ selectionRanges }, event) => {
if (event.type !== 'Set selection') return {} // this was needed for ts after adding 'Set selection' action to on done modal events
const setSelections = event.data
@ -517,6 +607,27 @@ export const ModelingMachineProvider = ({
),
}
},
'Get convert to variable info': async ({ sketchDetails }, { data }) => {
if (!sketchDetails) return []
const { variableName } = await getVarNameModal({
valueName: data.variableName || 'var',
})
const { modifiedAst: _modifiedAst, pathToReplacedNode } =
moveValueIntoNewVariablePath(
parse(recast(kclManager.ast)),
kclManager.programMemory,
data.pathToNode,
variableName
)
await sceneEntitiesManager.updateAstAndRejigSketch(
pathToReplacedNode || [],
parse(recast(_modifiedAst)),
sketchDetails.zAxis,
sketchDetails.yAxis,
sketchDetails.origin
)
return pathToReplacedNode || sketchDetails.sketchPathToNode
},
},
devTools: true,
}