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