TODO: don't let clicks get swallowed, don't rerender all the time
This commit is contained in:
@ -5,12 +5,6 @@ import { useModelingContext } from 'hooks/useModelingContext'
|
||||
import { useCommandsContext } from 'hooks/useCommandsContext'
|
||||
import { ActionButton } from 'components/ActionButton'
|
||||
import { isSingleCursorInPipe } from 'lang/queryAst'
|
||||
import { useKclContext } from 'lang/KclProvider'
|
||||
import {
|
||||
NetworkHealthState,
|
||||
useNetworkStatus,
|
||||
} from 'components/NetworkHealthIndicator'
|
||||
import { useStore } from 'useStore'
|
||||
import { useShouldDisableModelingActions } from 'hooks/useShouldDisableModelingActions'
|
||||
import { useInteractionMap } from 'hooks/useInteractionMap'
|
||||
|
||||
@ -20,10 +14,18 @@ export const Toolbar = () => {
|
||||
const shouldDisableModelingActions = useShouldDisableModelingActions()
|
||||
useInteractionMap(
|
||||
[
|
||||
{
|
||||
name: 'sketch',
|
||||
title: 'Start Sketch',
|
||||
sequence: 'shift+s',
|
||||
action: () =>
|
||||
send({ type: 'Enter sketch', data: { forceNewSketch: true } }),
|
||||
guard: () => !shouldDisableModelingActions && state.matches('idle'),
|
||||
},
|
||||
{
|
||||
name: 'extrude',
|
||||
title: 'Extrude',
|
||||
sequence: 'shift+e',
|
||||
sequence: 'ctrl+c shift+e',
|
||||
action: () =>
|
||||
commandBarSend({
|
||||
type: 'Find and select command',
|
||||
@ -50,13 +52,6 @@ export const Toolbar = () => {
|
||||
context.selectionRanges
|
||||
)
|
||||
}, [engineCommandManager.artifactMap, context.selectionRanges])
|
||||
const { overallState } = useNetworkStatus()
|
||||
const { isExecuting } = useKclContext()
|
||||
const { isStreamReady } = useStore((s) => ({
|
||||
isStreamReady: s.isStreamReady,
|
||||
}))
|
||||
const disableAllButtons =
|
||||
overallState !== NetworkHealthState.Ok || isExecuting || !isStreamReady
|
||||
|
||||
function handleToolbarButtonsWheelEvent(ev: WheelEvent<HTMLSpanElement>) {
|
||||
const span = toolbarButtonsRef.current
|
||||
@ -95,7 +90,7 @@ export const Toolbar = () => {
|
||||
iconClassName,
|
||||
bgClassName,
|
||||
}}
|
||||
disabled={disableAllButtons}
|
||||
disabled={shouldDisableModelingActions}
|
||||
>
|
||||
<span data-testid="start-sketch">Start Sketch</span>
|
||||
</ActionButton>
|
||||
@ -112,7 +107,7 @@ export const Toolbar = () => {
|
||||
iconClassName,
|
||||
bgClassName,
|
||||
}}
|
||||
disabled={disableAllButtons}
|
||||
disabled={shouldDisableModelingActions}
|
||||
>
|
||||
Edit Sketch
|
||||
</ActionButton>
|
||||
@ -129,7 +124,7 @@ export const Toolbar = () => {
|
||||
iconClassName,
|
||||
bgClassName,
|
||||
}}
|
||||
disabled={disableAllButtons}
|
||||
disabled={shouldDisableModelingActions}
|
||||
>
|
||||
Exit Sketch
|
||||
</ActionButton>
|
||||
@ -152,7 +147,7 @@ export const Toolbar = () => {
|
||||
iconClassName,
|
||||
bgClassName,
|
||||
}}
|
||||
disabled={disableAllButtons}
|
||||
disabled={shouldDisableModelingActions}
|
||||
>
|
||||
Line
|
||||
</ActionButton>
|
||||
@ -175,7 +170,7 @@ export const Toolbar = () => {
|
||||
disabled={
|
||||
(!state.can('Equip tangential arc to') &&
|
||||
!state.matches('Sketch.Tangential arc to')) ||
|
||||
disableAllButtons
|
||||
shouldDisableModelingActions
|
||||
}
|
||||
>
|
||||
Tangential Arc
|
||||
@ -199,7 +194,7 @@ export const Toolbar = () => {
|
||||
disabled={
|
||||
(!state.can('Equip rectangle tool') &&
|
||||
!state.matches('Sketch.Rectangle tool')) ||
|
||||
disableAllButtons
|
||||
shouldDisableModelingActions
|
||||
}
|
||||
title={
|
||||
state.can('Equip rectangle tool')
|
||||
@ -244,7 +239,7 @@ export const Toolbar = () => {
|
||||
disabled={
|
||||
!state.nextEvents
|
||||
.filter((event) => state.can(event as any))
|
||||
.includes(eventName) || disableAllButtons
|
||||
.includes(eventName) || shouldDisableModelingActions
|
||||
}
|
||||
title={eventName}
|
||||
icon={{
|
||||
@ -270,7 +265,7 @@ export const Toolbar = () => {
|
||||
data: { name: 'Extrude', ownerMachine: 'modeling' },
|
||||
})
|
||||
}
|
||||
disabled={!state.can('Extrude') || disableAllButtons}
|
||||
disabled={!state.can('Extrude') || shouldDisableModelingActions}
|
||||
title={
|
||||
state.can('Extrude')
|
||||
? 'extrude'
|
||||
|
||||
@ -36,7 +36,6 @@ export const CommandBar = () => {
|
||||
})
|
||||
},
|
||||
guard: () => true,
|
||||
ownerId: 'commandBar',
|
||||
},
|
||||
{
|
||||
name: 'close',
|
||||
@ -46,10 +45,10 @@ export const CommandBar = () => {
|
||||
commandBarSend({ type: 'Close' })
|
||||
},
|
||||
guard: () => !commandBarState.matches('Closed'),
|
||||
ownerId: 'commandBar',
|
||||
},
|
||||
],
|
||||
[commandBarState, commandBarSend]
|
||||
[commandBarState, commandBarSend],
|
||||
'Command Bar'
|
||||
)
|
||||
|
||||
function stepBack() {
|
||||
|
||||
@ -59,6 +59,10 @@ function CommandBarSelectionInput({
|
||||
return () => kclManager.enterEditMode()
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
console.log('selectionsByType', selectionsByType)
|
||||
}, [selectionsByType])
|
||||
|
||||
// Fast-forward through this arg if it's marked as skippable
|
||||
// and we have a valid selection already
|
||||
useEffect(() => {
|
||||
|
||||
@ -173,7 +173,18 @@ export function InteractionMapMachineProvider({
|
||||
}
|
||||
|
||||
const fireEvent = (event: MouseEvent | KeyboardEvent) => {
|
||||
send({ type: 'Fire event', data: event })
|
||||
// Don't fire click events on interactable elements,
|
||||
// and make sure these fire last in the bubbling phase
|
||||
if (
|
||||
event.BUBBLING_PHASE &&
|
||||
!(
|
||||
event instanceof MouseEvent &&
|
||||
event.target instanceof HTMLElement &&
|
||||
['INPUT', 'BUTTON', 'ANCHOR'].includes(event.target.tagName)
|
||||
)
|
||||
) {
|
||||
send({ type: 'Fire event', data: event })
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', fireEvent)
|
||||
|
||||
@ -6,7 +6,7 @@ import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
||||
import { useModelingContext } from 'hooks/useModelingContext'
|
||||
import { ClientSideScene } from 'clientSideScene/ClientSideSceneComp'
|
||||
import { NetworkHealthState, useNetworkStatus } from './NetworkHealthIndicator'
|
||||
import { butName } from 'lib/cameraControls'
|
||||
import { buttonName } from 'lib/cameraControls'
|
||||
import { sendSelectEventToEngine } from 'lib/selections'
|
||||
|
||||
export const Stream = ({ className = '' }: { className?: string }) => {
|
||||
@ -63,7 +63,7 @@ export const Stream = ({ className = '' }: { className?: string }) => {
|
||||
if (state.matches('Sketch')) return
|
||||
if (state.matches('Sketch no face')) return
|
||||
|
||||
if (!didDragInStream && butName(e).left) {
|
||||
if (!didDragInStream && buttonName(e).left) {
|
||||
sendSelectEventToEngine(e, videoRef.current, streamDimensions)
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,12 @@ import { settingsMachine } from 'machines/settingsMachine'
|
||||
import { homeMachine } from 'machines/homeMachine'
|
||||
import { Command, CommandSetConfig, CommandSetSchema } from 'lib/commandTypes'
|
||||
import { useShouldDisableModelingActions } from './useShouldDisableModelingActions'
|
||||
import { useKclContext } from 'lang/KclProvider'
|
||||
import {
|
||||
NetworkHealthState,
|
||||
useNetworkStatus,
|
||||
} from 'components/NetworkHealthIndicator'
|
||||
import { useStore } from 'useStore'
|
||||
|
||||
// This might not be necessary, AnyStateMachine from xstate is working
|
||||
export type AllMachines =
|
||||
@ -42,13 +48,17 @@ export default function useStateMachineCommands<
|
||||
onCancel,
|
||||
}: UseStateMachineCommandsArgs<T, S>) {
|
||||
const { commandBarSend } = useCommandsContext()
|
||||
const shouldDisableModelingActions = useShouldDisableModelingActions()
|
||||
const { overallState } = useNetworkStatus()
|
||||
const { isExecuting } = useKclContext()
|
||||
const { isStreamReady } = useStore((s) => ({
|
||||
isStreamReady: s.isStreamReady,
|
||||
}))
|
||||
|
||||
useEffect(() => {
|
||||
const disableAllButtons =
|
||||
overallState !== NetworkHealthState.Ok || isExecuting || !isStreamReady
|
||||
const newCommands = state.nextEvents
|
||||
.filter(
|
||||
(_) => !allCommandsRequireNetwork || !shouldDisableModelingActions
|
||||
)
|
||||
.filter((_) => !allCommandsRequireNetwork || !disableAllButtons)
|
||||
.filter((e) => !['done.', 'error.'].some((n) => e.includes(n)))
|
||||
.map((type) =>
|
||||
createMachineCommand<T, S>({
|
||||
@ -71,5 +81,5 @@ export default function useStateMachineCommands<
|
||||
data: { commands: newCommands },
|
||||
})
|
||||
}
|
||||
}, [state, shouldDisableModelingActions])
|
||||
}, [state, overallState, isExecuting, isStreamReady])
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ export interface MouseGuard {
|
||||
rotate: MouseGuardHandler
|
||||
}
|
||||
|
||||
export const butName = (e: React.MouseEvent) => ({
|
||||
export const buttonName = (e: React.MouseEvent) => ({
|
||||
middle: !!(e.buttons & 4) || e.button === 1,
|
||||
right: !!(e.buttons & 2) || e.button === 2,
|
||||
left: !!(e.buttons & 1) || e.button === 0,
|
||||
@ -75,8 +75,8 @@ export const cameraMouseDragGuards: Record<CameraSystem, MouseGuard> = {
|
||||
pan: {
|
||||
description: 'Right click + Shift + drag or middle click + drag',
|
||||
callback: (e) =>
|
||||
(butName(e).middle && noModifiersPressed(e)) ||
|
||||
(butName(e).right && e.shiftKey),
|
||||
(buttonName(e).middle && noModifiersPressed(e)) ||
|
||||
(buttonName(e).right && e.shiftKey),
|
||||
},
|
||||
zoom: {
|
||||
description: 'Scroll wheel or Right click + Ctrl + drag',
|
||||
@ -85,15 +85,15 @@ export const cameraMouseDragGuards: Record<CameraSystem, MouseGuard> = {
|
||||
},
|
||||
rotate: {
|
||||
description: 'Right click + drag',
|
||||
callback: (e) => butName(e).right && noModifiersPressed(e),
|
||||
callback: (e) => buttonName(e).right && noModifiersPressed(e),
|
||||
},
|
||||
},
|
||||
OnShape: {
|
||||
pan: {
|
||||
description: 'Right click + Ctrl + drag or middle click + drag',
|
||||
callback: (e) =>
|
||||
(butName(e).right && e.ctrlKey) ||
|
||||
(butName(e).middle && noModifiersPressed(e)),
|
||||
(buttonName(e).right && e.ctrlKey) ||
|
||||
(buttonName(e).middle && noModifiersPressed(e)),
|
||||
},
|
||||
zoom: {
|
||||
description: 'Scroll wheel',
|
||||
@ -102,77 +102,77 @@ export const cameraMouseDragGuards: Record<CameraSystem, MouseGuard> = {
|
||||
},
|
||||
rotate: {
|
||||
description: 'Right click + drag',
|
||||
callback: (e) => butName(e).right && noModifiersPressed(e),
|
||||
callback: (e) => buttonName(e).right && noModifiersPressed(e),
|
||||
},
|
||||
},
|
||||
'Trackpad Friendly': {
|
||||
pan: {
|
||||
description: 'Left click + Alt + Shift + drag or middle click + drag',
|
||||
callback: (e) =>
|
||||
(butName(e).left && e.altKey && e.shiftKey && !e.metaKey) ||
|
||||
(butName(e).middle && noModifiersPressed(e)),
|
||||
(buttonName(e).left && e.altKey && e.shiftKey && !e.metaKey) ||
|
||||
(buttonName(e).middle && noModifiersPressed(e)),
|
||||
},
|
||||
zoom: {
|
||||
description: 'Scroll wheel or Left click + Alt + OS + drag',
|
||||
dragCallback: (e) => butName(e).left && e.altKey && e.metaKey,
|
||||
dragCallback: (e) => buttonName(e).left && e.altKey && e.metaKey,
|
||||
scrollCallback: () => true,
|
||||
},
|
||||
rotate: {
|
||||
description: 'Left click + Alt + drag',
|
||||
callback: (e) => butName(e).left && e.altKey && !e.shiftKey && !e.metaKey,
|
||||
callback: (e) => buttonName(e).left && e.altKey && !e.shiftKey && !e.metaKey,
|
||||
lenientDragStartButton: 0,
|
||||
},
|
||||
},
|
||||
Solidworks: {
|
||||
pan: {
|
||||
description: 'Right click + Ctrl + drag',
|
||||
callback: (e) => butName(e).right && e.ctrlKey,
|
||||
callback: (e) => buttonName(e).right && e.ctrlKey,
|
||||
lenientDragStartButton: 2,
|
||||
},
|
||||
zoom: {
|
||||
description: 'Scroll wheel or Middle click + Shift + drag',
|
||||
dragCallback: (e) => butName(e).middle && e.shiftKey,
|
||||
dragCallback: (e) => buttonName(e).middle && e.shiftKey,
|
||||
scrollCallback: () => true,
|
||||
},
|
||||
rotate: {
|
||||
description: 'Middle click + drag',
|
||||
callback: (e) => butName(e).middle && noModifiersPressed(e),
|
||||
callback: (e) => buttonName(e).middle && noModifiersPressed(e),
|
||||
},
|
||||
},
|
||||
NX: {
|
||||
pan: {
|
||||
description: 'Middle click + Shift + drag',
|
||||
callback: (e) => butName(e).middle && e.shiftKey,
|
||||
callback: (e) => buttonName(e).middle && e.shiftKey,
|
||||
},
|
||||
zoom: {
|
||||
description: 'Scroll wheel or Middle click + Ctrl + drag',
|
||||
dragCallback: (e) => butName(e).middle && e.ctrlKey,
|
||||
dragCallback: (e) => buttonName(e).middle && e.ctrlKey,
|
||||
scrollCallback: () => true,
|
||||
},
|
||||
rotate: {
|
||||
description: 'Middle click + drag',
|
||||
callback: (e) => butName(e).middle && noModifiersPressed(e),
|
||||
callback: (e) => buttonName(e).middle && noModifiersPressed(e),
|
||||
},
|
||||
},
|
||||
Creo: {
|
||||
pan: {
|
||||
description: 'Middle click + Shift + drag',
|
||||
callback: (e) => butName(e).middle && e.shiftKey,
|
||||
callback: (e) => buttonName(e).middle && e.shiftKey,
|
||||
},
|
||||
zoom: {
|
||||
description: 'Scroll wheel or Middle click + Ctrl + drag',
|
||||
dragCallback: (e) => butName(e).middle && e.ctrlKey,
|
||||
dragCallback: (e) => buttonName(e).middle && e.ctrlKey,
|
||||
scrollCallback: () => true,
|
||||
},
|
||||
rotate: {
|
||||
description: 'Middle click + drag',
|
||||
callback: (e) => butName(e).middle && noModifiersPressed(e),
|
||||
callback: (e) => buttonName(e).middle && noModifiersPressed(e),
|
||||
},
|
||||
},
|
||||
AutoCAD: {
|
||||
pan: {
|
||||
description: 'Middle click + drag',
|
||||
callback: (e) => butName(e).middle && noModifiersPressed(e),
|
||||
callback: (e) => buttonName(e).middle && noModifiersPressed(e),
|
||||
},
|
||||
zoom: {
|
||||
description: 'Scroll wheel',
|
||||
@ -181,7 +181,7 @@ export const cameraMouseDragGuards: Record<CameraSystem, MouseGuard> = {
|
||||
},
|
||||
rotate: {
|
||||
description: 'Middle click + Shift + drag',
|
||||
callback: (e) => butName(e).middle && e.shiftKey,
|
||||
callback: (e) => buttonName(e).middle && e.shiftKey,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user