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:
Kurt Hutten
2024-07-05 13:40:16 +10:00
committed by GitHub
parent fbc2e9d02c
commit 4f4167b247
6 changed files with 189 additions and 105 deletions

View File

@ -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'
}

View File

@ -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,

View File

@ -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))

View File

@ -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

View File

@ -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