Rejig state diagram for equipping tools (#2917)
* switch between line and rectangle tool * disable line tool if rectangle has started * make rectangle logic clearer from the diagram
This commit is contained in:
		@ -12,6 +12,10 @@ import { ActionButtonDropdown } from 'components/ActionButtonDropdown'
 | 
			
		||||
import { useHotkeys } from 'react-hotkeys-hook'
 | 
			
		||||
import Tooltip from 'components/Tooltip'
 | 
			
		||||
import { useAppState } from 'AppState'
 | 
			
		||||
import {
 | 
			
		||||
  canRectangleTool,
 | 
			
		||||
  isEditingExistingSketch,
 | 
			
		||||
} from 'machines/modelingMachine'
 | 
			
		||||
 | 
			
		||||
export function Toolbar({
 | 
			
		||||
  className = '',
 | 
			
		||||
@ -46,29 +50,48 @@ export function Toolbar({
 | 
			
		||||
    isExecuting ||
 | 
			
		||||
    !isStreamReady
 | 
			
		||||
 | 
			
		||||
  const disableLineButton =
 | 
			
		||||
    state.matches('Sketch.Rectangle tool.Awaiting second corner') ||
 | 
			
		||||
    disableAllButtons
 | 
			
		||||
  useHotkeys(
 | 
			
		||||
    'l',
 | 
			
		||||
    () =>
 | 
			
		||||
      state.matches('Sketch.Line tool')
 | 
			
		||||
        ? send('CancelSketch')
 | 
			
		||||
        : send('Equip Line tool'),
 | 
			
		||||
    { enabled: !disableAllButtons, scopes: ['sketch'] }
 | 
			
		||||
        : send({
 | 
			
		||||
            type: 'change tool',
 | 
			
		||||
            data: 'line',
 | 
			
		||||
          }),
 | 
			
		||||
    { enabled: !disableLineButton, scopes: ['sketch'] }
 | 
			
		||||
  )
 | 
			
		||||
  const disableTangentialArc =
 | 
			
		||||
    (!isEditingExistingSketch(context) &&
 | 
			
		||||
      !state.matches('Sketch.Tangential arc to')) ||
 | 
			
		||||
    disableAllButtons
 | 
			
		||||
  useHotkeys(
 | 
			
		||||
    'a',
 | 
			
		||||
    () =>
 | 
			
		||||
      state.matches('Sketch.Tangential arc to')
 | 
			
		||||
        ? send('CancelSketch')
 | 
			
		||||
        : send('Equip tangential arc to'),
 | 
			
		||||
    { enabled: !disableAllButtons, scopes: ['sketch'] }
 | 
			
		||||
        : send({
 | 
			
		||||
            type: 'change tool',
 | 
			
		||||
            data: 'tangentialArc',
 | 
			
		||||
          }),
 | 
			
		||||
    { enabled: !disableTangentialArc, scopes: ['sketch'] }
 | 
			
		||||
  )
 | 
			
		||||
  const disableRectangle =
 | 
			
		||||
    (!canRectangleTool(context) && !state.matches('Sketch.Rectangle tool')) ||
 | 
			
		||||
    disableAllButtons
 | 
			
		||||
  useHotkeys(
 | 
			
		||||
    'r',
 | 
			
		||||
    () =>
 | 
			
		||||
      state.matches('Sketch.Rectangle tool')
 | 
			
		||||
        ? send('CancelSketch')
 | 
			
		||||
        : send('Equip rectangle tool'),
 | 
			
		||||
    { enabled: !disableAllButtons, scopes: ['sketch'] }
 | 
			
		||||
        : send({
 | 
			
		||||
            type: 'change tool',
 | 
			
		||||
            data: 'rectangle',
 | 
			
		||||
          }),
 | 
			
		||||
    { enabled: !disableRectangle, scopes: ['sketch'] }
 | 
			
		||||
  )
 | 
			
		||||
  useHotkeys(
 | 
			
		||||
    's',
 | 
			
		||||
@ -238,7 +261,10 @@ export function Toolbar({
 | 
			
		||||
                onClick={() =>
 | 
			
		||||
                  state?.matches('Sketch.Line tool')
 | 
			
		||||
                    ? send('CancelSketch')
 | 
			
		||||
                    : send('Equip Line tool')
 | 
			
		||||
                    : send({
 | 
			
		||||
                        type: 'change tool',
 | 
			
		||||
                        data: 'line',
 | 
			
		||||
                      })
 | 
			
		||||
                }
 | 
			
		||||
                aria-pressed={state?.matches('Sketch.Line tool')}
 | 
			
		||||
                iconStart={{
 | 
			
		||||
@ -246,7 +272,7 @@ export function Toolbar({
 | 
			
		||||
                  iconClassName,
 | 
			
		||||
                  bgClassName,
 | 
			
		||||
                }}
 | 
			
		||||
                disabled={disableAllButtons}
 | 
			
		||||
                disabled={disableLineButton}
 | 
			
		||||
              >
 | 
			
		||||
                Line
 | 
			
		||||
                <Tooltip
 | 
			
		||||
@ -265,7 +291,10 @@ export function Toolbar({
 | 
			
		||||
                onClick={() =>
 | 
			
		||||
                  state.matches('Sketch.Tangential arc to')
 | 
			
		||||
                    ? send('CancelSketch')
 | 
			
		||||
                    : send('Equip tangential arc to')
 | 
			
		||||
                    : send({
 | 
			
		||||
                        type: 'change tool',
 | 
			
		||||
                        data: 'tangentialArc',
 | 
			
		||||
                      })
 | 
			
		||||
                }
 | 
			
		||||
                aria-pressed={state.matches('Sketch.Tangential arc to')}
 | 
			
		||||
                iconStart={{
 | 
			
		||||
@ -273,11 +302,7 @@ export function Toolbar({
 | 
			
		||||
                  iconClassName,
 | 
			
		||||
                  bgClassName,
 | 
			
		||||
                }}
 | 
			
		||||
                disabled={
 | 
			
		||||
                  (!state.can('Equip tangential arc to') &&
 | 
			
		||||
                    !state.matches('Sketch.Tangential arc to')) ||
 | 
			
		||||
                  disableAllButtons
 | 
			
		||||
                }
 | 
			
		||||
                disabled={disableTangentialArc}
 | 
			
		||||
              >
 | 
			
		||||
                Tangential Arc
 | 
			
		||||
                <Tooltip
 | 
			
		||||
@ -296,7 +321,10 @@ export function Toolbar({
 | 
			
		||||
                onClick={() =>
 | 
			
		||||
                  state.matches('Sketch.Rectangle tool')
 | 
			
		||||
                    ? send('CancelSketch')
 | 
			
		||||
                    : send('Equip rectangle tool')
 | 
			
		||||
                    : send({
 | 
			
		||||
                        type: 'change tool',
 | 
			
		||||
                        data: 'rectangle',
 | 
			
		||||
                      })
 | 
			
		||||
                }
 | 
			
		||||
                aria-pressed={state.matches('Sketch.Rectangle tool')}
 | 
			
		||||
                iconStart={{
 | 
			
		||||
@ -304,13 +332,9 @@ export function Toolbar({
 | 
			
		||||
                  iconClassName,
 | 
			
		||||
                  bgClassName,
 | 
			
		||||
                }}
 | 
			
		||||
                disabled={
 | 
			
		||||
                  (!state.can('Equip rectangle tool') &&
 | 
			
		||||
                    !state.matches('Sketch.Rectangle tool')) ||
 | 
			
		||||
                  disableAllButtons
 | 
			
		||||
                }
 | 
			
		||||
                disabled={disableRectangle}
 | 
			
		||||
                title={
 | 
			
		||||
                  state.can('Equip rectangle tool')
 | 
			
		||||
                  canRectangleTool(context)
 | 
			
		||||
                    ? 'Rectangle'
 | 
			
		||||
                    : 'Can only be used when a sketch is empty currently'
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -804,7 +804,7 @@ export class SceneEntities {
 | 
			
		||||
 | 
			
		||||
          // Update the primary AST and unequip the rectangle tool
 | 
			
		||||
          await kclManager.executeAstMock(_ast)
 | 
			
		||||
          sceneInfra.modelingSend({ type: 'CancelSketch' })
 | 
			
		||||
          sceneInfra.modelingSend({ type: 'Finish rectangle' })
 | 
			
		||||
 | 
			
		||||
          const { programMemory } = await executeAst({
 | 
			
		||||
            ast: _ast,
 | 
			
		||||
 | 
			
		||||
@ -441,17 +441,6 @@ export const ModelingMachineProvider = ({
 | 
			
		||||
          if (selectionRanges.codeBasedSelections.length <= 0) return false
 | 
			
		||||
          return true
 | 
			
		||||
        },
 | 
			
		||||
        'Sketch is empty': ({ sketchDetails }) => {
 | 
			
		||||
          const node = getNodeFromPath<VariableDeclaration>(
 | 
			
		||||
            kclManager.ast,
 | 
			
		||||
            sketchDetails?.sketchPathToNode || [],
 | 
			
		||||
            'VariableDeclaration'
 | 
			
		||||
          )
 | 
			
		||||
          // This should not be returning false, and it should be caught
 | 
			
		||||
          // but we need to simulate old behavior to move on.
 | 
			
		||||
          if (err(node)) return false
 | 
			
		||||
          return node.node?.declarations?.[0]?.init.type !== 'PipeExpression'
 | 
			
		||||
        },
 | 
			
		||||
        'Selection is on face': ({ selectionRanges }, { data }) => {
 | 
			
		||||
          if (data?.forceNewSketch) return false
 | 
			
		||||
          if (!isSingleCursorInPipe(selectionRanges, kclManager.ast))
 | 
			
		||||
 | 
			
		||||
@ -222,11 +222,7 @@ export default class EditorManager {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const ignoreEvents: ModelingMachineEvent['type'][] = [
 | 
			
		||||
      'Equip Line tool',
 | 
			
		||||
      'Equip tangential arc to',
 | 
			
		||||
      'Equip rectangle tool',
 | 
			
		||||
    ]
 | 
			
		||||
    const ignoreEvents: ModelingMachineEvent['type'][] = ['change tool']
 | 
			
		||||
 | 
			
		||||
    if (!this._modelingEvent) {
 | 
			
		||||
      return
 | 
			
		||||
 | 
			
		||||
@ -37,21 +37,22 @@ export const modelingMachineConfig: CommandSetConfig<
 | 
			
		||||
    description: 'Enter sketch mode.',
 | 
			
		||||
    icon: 'sketch',
 | 
			
		||||
  },
 | 
			
		||||
  'Equip Line tool': {
 | 
			
		||||
    description: 'Start drawing straight lines.',
 | 
			
		||||
    icon: 'line',
 | 
			
		||||
    displayName: 'Line',
 | 
			
		||||
  },
 | 
			
		||||
  'Equip tangential arc to': {
 | 
			
		||||
    description: 'Start drawing an arc tangent to the current segment.',
 | 
			
		||||
    icon: 'arc',
 | 
			
		||||
    displayName: 'Tangential Arc',
 | 
			
		||||
  },
 | 
			
		||||
  'Equip rectangle tool': {
 | 
			
		||||
    description: 'Start drawing a rectangle.',
 | 
			
		||||
    icon: 'rectangle',
 | 
			
		||||
    displayName: 'Rectangle',
 | 
			
		||||
  },
 | 
			
		||||
  // TODO the event is no 'change tool' with data: 'line', 'rectangle' etc
 | 
			
		||||
  // 'Equip Line tool': {
 | 
			
		||||
  //   description: 'Start drawing straight lines.',
 | 
			
		||||
  //   icon: 'line',
 | 
			
		||||
  //   displayName: 'Line',
 | 
			
		||||
  // },
 | 
			
		||||
  // 'Equip tangential arc to': {
 | 
			
		||||
  //   description: 'Start drawing an arc tangent to the current segment.',
 | 
			
		||||
  //   icon: 'arc',
 | 
			
		||||
  //   displayName: 'Tangential Arc',
 | 
			
		||||
  // },
 | 
			
		||||
  // 'Equip rectangle tool': {
 | 
			
		||||
  //   description: 'Start drawing a rectangle.',
 | 
			
		||||
  //   icon: 'rectangle',
 | 
			
		||||
  //   displayName: 'Rectangle',
 | 
			
		||||
  // },
 | 
			
		||||
  Export: {
 | 
			
		||||
    description: 'Export the current model.',
 | 
			
		||||
    icon: 'exportFile',
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Reference in New Issue
	
	Block a user