Compare commits

...

18 Commits

Author SHA1 Message Date
977e566ae4 Merge branch 'main' into franknoirot/xstate-toolbar 2023-09-14 12:24:16 -04:00
7aaf923529 Update moved useEffect hook after merge 2023-09-13 14:52:43 -04:00
bcb05d02b4 Merge branch 'main' into franknoirot/xstate-toolbar 2023-09-13 14:51:24 -04:00
ef451b70b6 Add barebones modeling machine to app
Only implementing adding to code-based selections in the text editor so far
2023-09-13 14:46:10 -04:00
c33107aa28 Add TS schema, selection actions to modelingMachine 2023-09-13 14:45:14 -04:00
26737e055a Refactor: move other engine-related useEffect into hook 2023-09-13 12:04:55 -04:00
c01590b49b Create modeling provider, move engine management to it 2023-09-13 09:50:10 -04:00
1d656d68c6 Refactor: break out engine manager setup into hook
Preparing for making a wrapper component around the App
that will manage the engine manager at the same level as
the modelingMachine.
2023-09-13 09:37:29 -04:00
e180b73c9d Merge branch 'main' into franknoirot/xstate-toolbar 2023-09-12 14:34:46 -04:00
738b1a7c21 Merge branch 'main' into franknoirot/xstate-toolbar 2023-09-01 18:04:51 -04:00
62aebaf523 Add fillet tool flow 2023-09-01 18:04:12 -04:00
2095375b37 Add initial modeling machine
This is not a full description of how the modelingMachine should work,
but begins to replicate all of the features of our useStore in XState
instead of zustand.
2023-09-01 11:49:15 -04:00
7a9a33c656 Add transitions 2023-08-29 15:26:33 -04:00
a4a393fc45 Remove ActionButton until after tool logic refactor 2023-08-29 14:35:36 -04:00
10884fd0b0 Turn toolbar buttons back on 2023-08-29 14:18:02 -04:00
bcf83dc7ee Add support for 2D and 3D mode styling 2023-08-29 13:25:10 -04:00
32f79c98f8 Fix up light mode of basic bar 2023-08-29 12:27:50 -04:00
c11149e909 Add basic Popover functionality 2023-08-29 12:21:42 -04:00
9 changed files with 778 additions and 18 deletions

View File

@ -1,7 +1,6 @@
import { useRef, useEffect, useCallback, MouseEventHandler } from 'react'
import { useEffect, useCallback, MouseEventHandler } from 'react'
import { DebugPanel } from './components/DebugPanel'
import { v4 as uuidv4 } from 'uuid'
import { _executor } from './lang/executor'
import { PaneType, useStore } from './useStore'
import { Logs, KCLErrors } from './components/Logs'
import { CollapsiblePanel } from './components/CollapsiblePanel'
@ -30,13 +29,10 @@ import { CameraDragInteractionType_type } from '@kittycad/lib/dist/types/src/mod
import { CodeMenu } from 'components/CodeMenu'
import { TextEditor } from 'components/TextEditor'
import { Themes, getSystemTheme } from 'lib/theme'
import { useSetupEngineManager } from 'hooks/useSetupEngineManager'
import { useCodeEval } from 'hooks/useCodeEval'
export function App() {
const { code: loadedCode, project } = useLoaderData() as IndexLoaderData
const streamRef = useRef<HTMLDivElement>(null)
useHotKeyListener()
const {
setCode,
@ -59,9 +55,6 @@ export function App() {
}))
const {
auth: {
context: { token },
},
settings: {
context: { showDebugPanel, onboardingStatus, cameraControls, theme },
},
@ -104,9 +97,6 @@ export function App() {
}
}, [loadedCode, setCode])
useSetupEngineManager(streamRef, token)
useCodeEval()
const debounceSocketSend = throttle<EngineCommand>((message) => {
engineCommandManager?.sendSceneCommand(message)
}, 16)
@ -186,9 +176,8 @@ export function App() {
return (
<div
className="h-screen overflow-hidden relative flex flex-col cursor-pointer select-none"
className="relative h-full flex flex-col"
onMouseMove={handleMouseMove}
ref={streamRef}
>
<AppHeader
className={

View File

@ -40,6 +40,7 @@ import { ContextFrom } from 'xstate'
import CommandBarProvider from 'components/CommandBar'
import { TEST, VITE_KC_SENTRY_DSN } from './env'
import * as Sentry from '@sentry/react'
import ModelingMachineProvider from 'components/ModelingMachineProvider'
if (VITE_KC_SENTRY_DSN && !TEST) {
Sentry.init({
@ -136,7 +137,9 @@ const router = createBrowserRouter(
element: (
<Auth>
<Outlet />
<App />
<ModelingMachineProvider>
<App />
</ModelingMachineProvider>
{!isTauri() && import.meta.env.PROD && <DownloadAppBanner />}
</Auth>
),

View File

@ -0,0 +1,106 @@
import { useMachine } from '@xstate/react'
import React, { createContext, useRef } from 'react'
import {
AnyStateMachine,
ContextFrom,
InterpreterFrom,
Prop,
StateFrom,
} from 'xstate'
import { modelingMachine } from 'machines/modelingMachine'
import { useSetupEngineManager } from 'hooks/useSetupEngineManager'
import { useCodeEval } from 'hooks/useCodeEval'
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
type MachineContext<T extends AnyStateMachine> = {
state: StateFrom<T>
context: ContextFrom<T>
send: Prop<InterpreterFrom<T>, 'send'>
}
export const ModelingMachineContext = createContext(
{} as MachineContext<typeof modelingMachine>
)
export const ModelingMachineProvider = ({
children,
}: {
children: React.ReactNode
}) => {
const {
auth: {
context: { token },
},
} = useGlobalStateContext()
const streamRef = useRef<HTMLDivElement>(null)
useSetupEngineManager(streamRef, token)
useCodeEval()
// const { commands } = useCommandsContext()
// Settings machine setup
// const retrievedSettings = useRef(
// localStorage?.getItem(MODELING_PERSIST_KEY) || '{}'
// )
// What should we persist from modeling state? Nothing?
// const persistedSettings = Object.assign(
// settingsMachine.initialState.context,
// JSON.parse(retrievedSettings.current) as Partial<
// (typeof settingsMachine)['context']
// >
// )
const [modelingState, modelingSend] = useMachine(modelingMachine, {
// context: persistedSettings,
actions: {
'Modify AST': () => {},
'Make selection horizontal': () => {},
'Make selection vertical': () => {},
'Update code selection cursors': () => {},
},
guards: {
'Can make selection horizontal': () => true,
'Can make selection vertical': () => true,
'Selection contains axis': () => true,
'Selection contains edge': () => true,
'Selection contains face': () => true,
'Selection contains line': () => true,
'Selection contains point': () => true,
'Selection is empty': () => true,
'Selection is not empty': () => true,
'Selection is one face': () => true,
'Selection is one or more edges': () => true,
},
services: {
createSketch: async () => {},
createLine: async () => {},
createExtrude: async () => {},
createFillet: async () => {},
},
})
// useStateMachineCommands({
// state: settingsState,
// send: settingsSend,
// commands,
// owner: 'settings',
// commandBarMeta: settingsCommandBarMeta,
// })
return (
<ModelingMachineContext.Provider
value={{
state: modelingState,
context: modelingState.context,
send: modelingSend,
}}
>
<div className="h-screen overflow-hidden select-none" ref={streamRef}>
{children}
</div>
</ModelingMachineContext.Provider>
)
}
export default ModelingMachineProvider

View File

@ -333,7 +333,7 @@ export const Stream = ({ className = '' }) => {
onWheel={handleScroll}
onPlay={() => setIsLoading(false)}
onMouseMoveCapture={handleMouseMove}
className={`w-full h-full ${isExecuting && 'blur-md'}`}
className={`w-full cursor-pointer h-full ${isExecuting && 'blur-md'}`}
style={{ transitionDuration: '200ms', transitionProperty: 'filter' }}
/>
{isLoading && (

View File

@ -29,6 +29,7 @@ import {
import { isOverlap, roundOff } from 'lib/utils'
import { kclErrToDiagnostic } from 'lang/errors'
import { CSSRuleObject } from 'tailwindcss/types/config'
import { useModelingContext } from 'hooks/useModelingContext'
import interact from '@replit/codemirror-interact'
export const editorShortcutMeta = {
@ -76,6 +77,11 @@ export const TextEditor = ({
sourceRangeMap: s.sourceRangeMap,
}))
const {
context: { selectionRanges: machineSelectionRanges },
send,
} = useModelingContext()
const {
settings: {
context: { textWrapping },
@ -197,6 +203,14 @@ export const TextEditor = ({
otherSelections: [],
codeBasedSelections,
})
send({
type: 'Set selection',
data: {
...machineSelectionRanges,
codeBasedSelections,
},
})
}
const editorExtensions = useMemo(() => {

View File

@ -0,0 +1,6 @@
import { ModelingMachineContext } from 'components/ModelingMachineProvider'
import { useContext } from 'react'
export const useModelingContext = () => {
return useContext(ModelingMachineContext)
}

View File

@ -0,0 +1,466 @@
import { Program } from 'lang/abstractSyntaxTreeTypes'
import { ProgramMemory } from 'lang/executor'
import { Axis, Selection, Selections } from 'useStore'
import { assign, createMachine } from 'xstate'
export const MODELING_PERSIST_KEY = 'MODELING_PERSIST_KEY'
export const modelingMachine = createMachine(
{
/** @xstate-layout N4IgpgJg5mDOIC5QFkD2EwBsCWA7KAxAMICGuAxlgNoAMAuoqAA6qzYAu2qujIAHogC0AFgCMAOgBMogOwyAzAE5hNABw0ZAVlGKANCACeQyQDZh4zTMWj5GmqfnDN8gL4v9aDDnzjsETGAEAMpg7AAEsFhg5JzctAxIICxssTyJAgiimuZOkqqSMjRqipKKcvpGCIKiqibiwrVqkjSiwpJiCm4e6Fh4UL7+gQAicFExYSx47PG8yRxcaaAZgvKqivUaJquywtYyohWIojbiqqr7NZprps2u7iCevT5+AQQjkQHjkDAziXOpvGWSnkUk0JhMVkkmmkbRMmkOVWE5mkighNHk7WaZzu3S8fQGr3eY3CJD42Fgv2YrHm3EBQhkpVBpm0q2EMi2qgRImROjRGLaahkqi6Dx63n6L0CIU+4UmuGm9Fm1IB6SE8kK4hku1MilUlgh4JkCNWIJMzQhThKiiukhFj3FBKlxLC3zAlKSyoWdKq8hMqnEinRtgaohoELB8MMiE0zikpUkpnR1sDijtYvxkuCztJ5Pd-y9qqq4PWKgjZ2yUJ0COcdXRNEUvvyMYxqfu9ozgyzMrCADMSJQ857aYWVpp1udRAVA1kTMckQiGTRxGHWtaYyYaA1NGm8c9OwBReVgABOEQA1qFyAALQcpAtLRBagNOIW7RuqRxcmz+hob-ItNoOhxUVdwlA8j1PWAL3Ya8qFEBIqTvYcHwQBll1sDRdhMZRRD9eQuTWKQVDkK5Wm0GMZB3J4wNefcAEcAFdsCYF0+HYY8GIwW8aUWfhEATGQ42tWRClwxRUWrfJ6jkK1hHkMckyoh1M3opiWLANiOK4+ClSQ3iMmkCRagxGpZDWdQJKjBAtiXBtBTBUw2VKJSO0JUZuz7AdFT+Id9LVBtxHBMQwTKLUCjZL8ynEWx1CFPYrEott0z3V5pWiElMEwbiVRQlZwWXMMxBKVZ1FKBE1kEqEtm0JxWlKEwXJS4Z3PSsISEy7L7z4n0oq0JErmyXZWiNKzRyXHQ1AafYqukRqaMCVTmN7bBMtCTrkO6yRHGi0ydAaTc1xGyprHWXVQ0sesdVtJLQMdAhFpYnsVoCaYdJ8vTvT204N1kbCajEYyEXE00NFw2dVDEDdEtxajxCCaDrwICBuDAXxcAAN1QC9xCIY8wBIdgwHPS8b28xCeO9VZBODaxVCyPIIS1BE5zjFQij9cSamUOa4YRq9iDISgsrJj0PsLSczlBeRhuaY5wq5K46jKetCnkdUIfOHn4ZJ8QAEkD0YpbvCJ9hUFQYWENFinxehSRxEnMR1QxZ2si5dVTvky65FacF0S1vm9c7NLxjlBVLfzDaMkDEEwS50plAKNQv0IrZarMaWkTphqbth7WYKvQPUudSIoAAWzAeV1r8hBrAkTc5JoaFZFaedRr9TVoRjc4rgaNpRH9nX9bcj5WtDqvvUaCxxLhfrrSFTlRvd6LwTNVY4V5LUB-zwvmpH8YS-LyuRYj6u9QkEo5F9JxG9WSQFZOaXShaWxZG3HOHTz68d4IZASAvCIwBlwruEdGJ5ODkHauPG2Y56hTk3CFRw+ErJWFOI3doatSiOH1FvL+Q9Ai-3-gfYBYQryoGPNgAAXtwdgkDj6+U+hWU4VwGxOA3C0D8bsQRq3TuqS4vpZw4ILgAGTwETAAKmbTASMUZo0xtjXG+NCZhGNlAlCWRcKBWUNfMGrJIyVBEFCAMZxlAtD9LOZwgjxAiNwOIyR4gAByqAwgAAVUBTFgAQAAghACAEw3FH3DvQ8W1ochrAbCvNQSgFb1ntrYEJF97BIksdY2x5txCuKmGEbxGAIBeJ8X4qYqjNrMgDFCa0RQtS1AhNE9YNh6zZASe0YQyTRFhAkWkkIQD5RZJ8ZAPJvix50LFihMpMdLDtE0PUjmR0hCTNqXEhpicmktJsW0uxnTD7hGyX0ogqBS5MBekTFRQzrYjPZBILIYZnDqA1iYN2ux7YxiuEUQMqdubv3xPuTSnFAjIxsbIrGqMFEEyJhpdiPyikZFZMua0pRmxjlREzKyvoQR6gSscBkvpSjQxArDL54KMD3UNupb5XETk5W6rqU6BRsiCg-HLBEEIJBQjkpMhQ0htDXRhg6fFWkFrEtYgSt0b1yYUoyAaU4id0QzgTGCRl+xQRyTkAUdodNgLth8Lyn539g7hE8m6clXUMh6lqZYMc3sFnCAXLUAMjgwZlPREkj5mrSWo11QsMIAAlfGEADBZnCBAckNCKAGsCcM7qDsQStD1LKjc8ZrW1gcHqX09ZsI4o1f0T+V4wi4CcfqrsrV9WQsQMIDcy5WiCmOM3TcMyfR232B0P6ZwV5gh5gAMWeqEaR-y8ByKBXjEFy1Vph10qcza4l6hjkcNYByeorVWVDDaxcJRSoRi0O2zt7AiVqSHS9YtNchSBQGkKWcWCWjMw0OOcxg0-RFG0Bu4d26lpPWHXBMNY7xU2taMNV8H5rB3wXZe76WQb3qBrQ+l6OrnSun3RVIizaDQlHBAvSoxwIbluOGGBkepNbOv6B24dcNiQeu9SQX1-qwjHjI9gBiFJDWRyOAUJWkylA2CxUiO5C7-oYdDBCPIVx03JXw5uojMoSM+r9bql00BQ2jrFUcWQ6wlCTOkJifYKHGPWlteoEySg41v3uLmjA8BEgZrk0a+kcgmTr1ZOyVYBEzCaj2uEtNuE37ctcmAczDGqiMh0BhSZ0IPxyHOAiUoyImVaPULbZpeHeYk286fdEpTL5mEC7fLkchqaomqhoLUVLLF4MS59DCUh9jTrEKWyw879EsvqBx9klgdCJlix5nwWarGtPaZgYr4sY322tKsRu6nKxcnTlIDkpRJzsmTCs1JmAHFOIyfKEzoqLOZEDONQb0WRvaDdicJwEZS2Z2lrhObay0lDBRr1kZ1glynYcE0PYSD9FIkEuoNoDIk1FDO3FjrKSLsLeW1s3pEAbubVwiCVE0tVjTlMXotUB31zZDMA0U72c2uZoDgD7rRGukg5yeDgypaJBqzDGY15DYEc+iR0d1H9LfuY-EFqjARPEBmn9PkQo0qHJVWrOqe20hwZ5AxB+VruKeWup3mz1CCrxnZGcFaW21rNCBXOHZ3CawbAY4l58qX7ruBeokzL0MGotSTjNGYD88kauPhQSasMRQ0dFHVUJ5nUvSO+pN0VJzWRxLZFwgoPQyC9Rq7kFsTX1hfSCJzXm-sXn3ofv4jGKeZQ0tyXMuUReII0EMjKPyBO7ndc+AIy9GXHJ7aVZC2j-9QMnCajyPkWWUfsIQdCNLxP8nULYSIsoYLNVsLU+OMoJhlopqlqhEXjN4hS-t4N7gI3ZHKhrZ86buodMGwYjy6nIf3G71olkO0FWbf2DiE98vq2XfWhKCkDUDEWosIJlt5kPfjcD8MhUGUNwbggA */
id: 'Modeling',
tsTypes: {} as import('./modelingMachine.typegen').Typegen0,
predictableActionArguments: true,
context: {
guiMode: 'default',
selection: [] as string[],
ast: null as Program | null,
selectionRanges: {
otherSelections: [],
codeBasedSelections: [],
} as Selections,
programMemory: { root: {}, pendingMemory: {} } as ProgramMemory,
// TODO: migrate engineCommandManager from useStore
// engineCommandManager?: EngineCommandManager
},
schema: {
events: {} as
| { type: 'Deselect all' }
| { type: 'Deselect edge'; data: Selection & { type: 'edge' } }
| { type: 'Deselect axis'; data: Axis }
| {
type: 'Deselect segment'
data: Selection & { type: 'line' | 'arc' }
}
| { type: 'Deselect face'; data: Selection & { type: 'face' } }
| {
type: 'Deselect point'
data: Selection & { type: 'point' | 'line-end' | 'line-mid' }
}
| { type: 'Equip extrude' }
| { type: 'Equip fillet' }
| { type: 'Enter sketch' }
| { type: 'Select all'; data: Selection & { type: 'all ' } }
| { type: 'Select edge'; data: Selection & { type: 'edge' } }
| { type: 'Select axis'; data: Axis }
| { type: 'Select segment'; data: Selection & { type: 'line' | 'arc' } }
| { type: 'Select face'; data: Selection & { type: 'face' } }
| { type: 'Set selection'; data: Selections }
| {
type: 'Select point'
data: Selection & { type: 'point' | 'line-end' | 'line-mid' }
}
| { type: 'Sketch no face' }
| { type: 'Toggle gui mode' }
| { type: 'Cancel' }
| { type: 'Add point' }
| { type: 'Equip line tool' }
| { type: 'Set radius' }
| { type: 'Make segment horizontal' }
| { type: 'Make segment vertical' }
| { type: 'Complete line' }
| { type: 'Set distance' },
},
states: {
idle: {
on: {
'Set selection': {
target: 'idle',
internal: true,
actions: 'Set selection',
},
'Deselect point': {
target: 'idle',
internal: true,
actions: [
'Remove from code-based selection',
'Update code selection cursors',
// 'Engine: remove highlight',
],
cond: 'Selection contains point',
},
'Deselect edge': {
target: 'idle',
internal: true,
actions: [
'Remove from code-based selection',
'Update code selection cursors',
// 'Engine: remove highlight',
],
cond: 'Selection contains edge',
},
'Deselect axis': {
target: 'idle',
internal: true,
actions: [
'Remove from other selection',
'Update code selection cursors',
// 'Engine: remove highlight',
],
cond: 'Selection contains axis',
},
'Select point': {
target: 'idle',
internal: true,
actions: [
'Add to code-based selection',
'Update code selection cursors',
// 'Engine: add highlight',
],
},
'Select edge': {
target: 'idle',
internal: true,
actions: [
'Add to code-based selection',
'Update code selection cursors',
// 'Engine: add highlight',
],
},
'Select axis': {
target: 'idle',
internal: true,
actions: [
'Add to other selection',
// 'Engine: add highlight',
],
},
'Select face': {
target: 'idle',
internal: true,
actions: [
'Add to code-based selection',
'Update code selection cursors',
// 'Engine: add highlight',
],
},
'Enter sketch': [
{
target: 'Sketch',
cond: 'Selection is one face',
},
'Sketch no face',
],
'Equip extrude': [
{
target: 'Extrude',
cond: 'Selection is empty',
},
{
target: 'Extrude',
cond: 'Selection is one face',
},
],
'Deselect face': {
target: 'idle',
internal: true,
actions: [
'Remove from code-based selection',
'Update code selection cursors',
// 'Engine: remove highlight',
],
cond: 'Selection contains face',
},
'Select all': {
target: 'idle',
internal: true,
actions: 'Add to code-based selection',
},
'Deselect all': {
target: 'idle',
internal: true,
actions: [
'Clear selection',
'Update code selection cursors',
// 'Engine: remove highlight',
],
cond: 'Selection is not empty',
},
'Equip fillet': [
{
target: 'Fillet',
cond: 'Selection is empty',
},
{
target: 'Fillet',
cond: 'Selection is one or more edges',
},
],
},
},
Sketch: {
states: {
Idle: {
on: {
'Equip line tool': 'Line Tool',
'Select point': {
target: 'Idle',
internal: true,
actions: [
'Update code selection cursors',
'Add to code-based selection',
],
},
'Select segment': {
target: 'Idle',
internal: true,
actions: [
'Update code selection cursors',
'Add to code-based selection',
],
},
'Deselect point': {
target: 'Idle',
internal: true,
cond: 'Selection contains point',
actions: [
'Update code selection cursors',
'Add to code-based selection',
],
},
'Deselect segment': {
target: 'Idle',
internal: true,
cond: 'Selection contains line',
actions: [
'Update code selection cursors',
'Add to code-based selection',
],
},
'Make segment vertical': {
cond: 'Can make selection vertical',
target: 'Idle',
internal: true,
actions: ['Make selection vertical'],
},
'Make segment horizontal': {
target: 'Idle',
internal: true,
cond: 'Can make selection horizontal',
actions: ['Make selection horizontal'],
},
},
},
'Line Tool': {
states: {
'No Points': {
on: {
'Add point': {
target: 'Point Added',
actions: ['Modify AST', 'Update code selection cursors'],
},
},
},
Done: {
type: 'final',
},
'Point Added': {
on: {
'Add point': {
target: 'Segment Added',
actions: ['Modify AST', 'Update code selection cursors'],
},
},
},
'Segment Added': {
on: {
'Add point': {
target: 'Segment Added',
internal: true,
actions: ['Modify AST', 'Update code selection cursors'],
},
'Complete line': {
target: 'Done',
actions: ['Modify AST', 'Update code selection cursors'],
},
},
},
},
initial: 'No Points',
invoke: {
src: 'createLine',
id: 'Create line',
onDone: 'Idle',
},
},
},
initial: 'Idle',
on: {
Cancel: '.Idle',
},
invoke: {
src: 'createSketch',
id: 'Create sketch',
onDone: 'idle',
},
},
Extrude: {
states: {
Idle: {
on: {
'Select face': 'Selection Ready',
},
},
'Selection Ready': {
on: {
'Set distance': 'Ready',
},
},
Ready: {},
},
initial: 'Idle',
on: {
'Equip extrude': [
{
target: '.Selection Ready',
cond: 'Selection is one face',
},
'.Idle',
],
},
invoke: {
src: 'createExtrude',
id: 'Create extrude',
onDone: {
target: 'idle',
actions: ['Modify AST', 'Clear selection'],
},
},
},
'Sketch no face': {
on: {
'Select face': 'Sketch',
},
},
Fillet: {
states: {
Idle: {
on: {
'Select edge': 'Selection Ready',
},
},
'Selection Ready': {
on: {
'Set radius': 'Ready',
'Select edge': {
target: 'Selection Ready',
internal: true,
},
},
},
Ready: {},
},
initial: 'Ready',
on: {
'Equip fillet': [
{
target: '.Selection Ready',
cond: 'Selection is one or more edges',
},
'.Idle',
],
},
invoke: {
src: 'createFillet',
id: 'Create fillet',
onDone: {
target: 'idle',
actions: ['Modify AST', 'Clear selection'],
},
},
},
},
initial: 'idle',
on: {
Cancel: '.idle',
},
},
{
actions: {
'Set selection': assign({
selectionRanges: (_, event) => event.data,
}),
'Add to code-based selection': assign({
selectionRanges: ({ selectionRanges }, event) => ({
...selectionRanges,
codeBasedSelections: [
...selectionRanges.codeBasedSelections,
event.data,
],
}),
}),
'Add to other selection': assign({
selectionRanges: ({ selectionRanges }, event) => ({
...selectionRanges,
otherSelections: [...selectionRanges.otherSelections, event.data],
}),
}),
'Remove from code-based selection': assign({
selectionRanges: ({ selectionRanges }, event) => ({
...selectionRanges,
codeBasedSelections: [
...selectionRanges.codeBasedSelections,
event.data,
],
}),
}),
'Remove from other selection': assign({
selectionRanges: ({ selectionRanges }, event) => ({
...selectionRanges,
otherSelections: [...selectionRanges.otherSelections, event.data],
}),
}),
'Clear selection': assign({
selectionRanges: () => ({
otherSelections: [],
codeBasedSelections: [],
}),
}),
},
}
)

View File

@ -0,0 +1,165 @@
// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
'@@xstate/typegen': true
internalEvents: {
'done.invoke.Create extrude': {
type: 'done.invoke.Create extrude'
data: unknown
__tip: 'See the XState TS docs to learn how to strongly type this.'
}
'done.invoke.Create fillet': {
type: 'done.invoke.Create fillet'
data: unknown
__tip: 'See the XState TS docs to learn how to strongly type this.'
}
'done.invoke.Create line': {
type: 'done.invoke.Create line'
data: unknown
__tip: 'See the XState TS docs to learn how to strongly type this.'
}
'done.invoke.Create sketch': {
type: 'done.invoke.Create sketch'
data: unknown
__tip: 'See the XState TS docs to learn how to strongly type this.'
}
'error.platform.Create extrude': {
type: 'error.platform.Create extrude'
data: unknown
}
'error.platform.Create fillet': {
type: 'error.platform.Create fillet'
data: unknown
}
'error.platform.Create line': {
type: 'error.platform.Create line'
data: unknown
}
'error.platform.Create sketch': {
type: 'error.platform.Create sketch'
data: unknown
}
'xstate.init': { type: 'xstate.init' }
}
invokeSrcNameMap: {
createExtrude: 'done.invoke.Create extrude'
createFillet: 'done.invoke.Create fillet'
createLine: 'done.invoke.Create line'
createSketch: 'done.invoke.Create sketch'
}
missingImplementations: {
actions:
| 'Make selection horizontal'
| 'Make selection vertical'
| 'Modify AST'
| 'Update code selection cursors'
delays: never
guards:
| 'Can make selection horizontal'
| 'Can make selection vertical'
| 'Selection contains axis'
| 'Selection contains edge'
| 'Selection contains face'
| 'Selection contains line'
| 'Selection contains point'
| 'Selection is empty'
| 'Selection is not empty'
| 'Selection is one face'
| 'Selection is one or more edges'
services: 'createExtrude' | 'createFillet' | 'createLine' | 'createSketch'
}
eventsCausingActions: {
'Add to code-based selection':
| 'Deselect point'
| 'Deselect segment'
| 'Select all'
| 'Select edge'
| 'Select face'
| 'Select point'
| 'Select segment'
'Add to other selection': 'Select axis'
'Clear selection':
| 'Deselect all'
| 'done.invoke.Create extrude'
| 'done.invoke.Create fillet'
'Make selection horizontal': 'Make segment horizontal'
'Make selection vertical': 'Make segment vertical'
'Modify AST':
| 'Add point'
| 'Complete line'
| 'done.invoke.Create extrude'
| 'done.invoke.Create fillet'
'Remove from code-based selection':
| 'Deselect edge'
| 'Deselect face'
| 'Deselect point'
'Remove from other selection': 'Deselect axis'
'Set selection': 'Set selection'
'Update code selection cursors':
| 'Add point'
| 'Complete line'
| 'Deselect all'
| 'Deselect axis'
| 'Deselect edge'
| 'Deselect face'
| 'Deselect point'
| 'Deselect segment'
| 'Select edge'
| 'Select face'
| 'Select point'
| 'Select segment'
}
eventsCausingDelays: {}
eventsCausingGuards: {
'Can make selection horizontal': 'Make segment horizontal'
'Can make selection vertical': 'Make segment vertical'
'Selection contains axis': 'Deselect axis'
'Selection contains edge': 'Deselect edge'
'Selection contains face': 'Deselect face'
'Selection contains line': 'Deselect segment'
'Selection contains point': 'Deselect point'
'Selection is empty': 'Equip extrude' | 'Equip fillet'
'Selection is not empty': 'Deselect all'
'Selection is one face': 'Enter sketch' | 'Equip extrude'
'Selection is one or more edges': 'Equip fillet'
}
eventsCausingServices: {
createExtrude: 'Equip extrude'
createFillet: 'Equip fillet'
createLine: 'Equip line tool'
createSketch: 'Enter sketch' | 'Select face'
}
matchesStates:
| 'Extrude'
| 'Extrude.Idle'
| 'Extrude.Ready'
| 'Extrude.Selection Ready'
| 'Fillet'
| 'Fillet.Idle'
| 'Fillet.Ready'
| 'Fillet.Selection Ready'
| 'Sketch'
| 'Sketch no face'
| 'Sketch.Idle'
| 'Sketch.Line Tool'
| 'Sketch.Line Tool.Done'
| 'Sketch.Line Tool.No Points'
| 'Sketch.Line Tool.Point Added'
| 'Sketch.Line Tool.Segment Added'
| 'idle'
| {
Extrude?: 'Idle' | 'Ready' | 'Selection Ready'
Fillet?: 'Idle' | 'Ready' | 'Selection Ready'
Sketch?:
| 'Idle'
| 'Line Tool'
| {
'Line Tool'?:
| 'Done'
| 'No Points'
| 'Point Added'
| 'Segment Added'
}
}
tags: never
}

View File

@ -21,12 +21,23 @@ import {
import { KCLError } from './lang/errors'
import { defferExecution } from 'lib/utils'
export type Axis = 'y-axis' | 'x-axis' | 'z-axis'
export type Selection = {
type: 'default' | 'line-end' | 'line-mid'
type:
| 'default'
| 'line-end'
| 'line-mid'
| 'face'
| 'point'
| 'edge'
| 'line'
| 'arc'
| 'all'
range: SourceRange
}
export type Selections = {
otherSelections: ('y-axis' | 'x-axis' | 'z-axis')[]
otherSelections: Axis[]
codeBasedSelections: Selection[]
}
export type TooTip =